All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.torodb.backend.SqlHelper Maven / Gradle / Ivy

There is a newer version: 0.50.3
Show newest version
/*
 * ToroDB
 * Copyright © 2014 8Kdata Technology (www.8kdata.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see .
 */

package com.torodb.backend;

import com.torodb.backend.ErrorHandler.Context;
import com.torodb.backend.converters.jooq.DataTypeForKv;
import com.torodb.backend.converters.jooq.KvValueConverter;
import com.torodb.backend.converters.sql.SqlBinding;
import com.torodb.core.exceptions.user.UserException;
import com.torodb.core.transaction.metainf.FieldType;
import com.torodb.kvdocument.values.KvValue;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.jooq.Converter;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.impl.DSL;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.inject.Inject;
import javax.inject.Singleton;

@Singleton
@SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
public class SqlHelper {

  private final DataTypeProvider dataTypeProvider;
  private final ErrorHandler errorHandler;

  @Inject
  public SqlHelper(DataTypeProvider dataTypeProvider, ErrorHandler errorHandler) {
    super();
    this.dataTypeProvider = dataTypeProvider;
    this.errorHandler = errorHandler;
  }

  public void executeStatement(DSLContext dsl, String statement, Context context) {
    Connection c = dsl.configuration().connectionProvider().acquire();
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      ps.execute();
    } catch (SQLException ex) {
      throw errorHandler.handleException(context, ex);
    } finally {
      dsl.configuration().connectionProvider().release(c);
    }
  }

  @FunctionalInterface
  public interface SetupPreparedStatement {

    public void accept(PreparedStatement ps) throws SQLException;
  }

  public Result executeStatementWithResult(DSLContext dsl, String statement,
      Context context) {
    return executeStatementWithResult(dsl, statement, context, ps -> {
    });
  }

  public Result executeStatementWithResult(DSLContext dsl, String statement,
      Context context,
      SetupPreparedStatement statementSetup) {
    Connection c = dsl.configuration().connectionProvider().acquire();
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      statementSetup.accept(ps);
      try (ResultSet resultSet = ps.executeQuery()) {
        return dsl.fetch(resultSet);
      }
    } catch (SQLException ex) {
      throw errorHandler.handleException(context, ex);
    } finally {
      dsl.configuration().connectionProvider().release(c);
    }
  }

  public int executeUpdate(DSLContext dsl, String statement, Context context) {
    Connection c = dsl.configuration().connectionProvider().acquire();
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      return ps.executeUpdate();
    } catch (SQLException ex) {
      throw errorHandler.handleException(context, ex);
    } finally {
      dsl.configuration().connectionProvider().release(c);
    }
  }

  public int executeUpdate(Connection c, String statement, Context context) {
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      return ps.executeUpdate();
    } catch (SQLException ex) {
      throw errorHandler.handleException(context, ex);
    }
  }

  public int executeUpdateOrThrow(DSLContext dsl, String statement, Context context) throws
      UserException {
    Connection c = dsl.configuration().connectionProvider().acquire();
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      return ps.executeUpdate();
    } catch (SQLException ex) {
      throw errorHandler.handleUserException(context, ex);
    } finally {
      dsl.configuration().connectionProvider().release(c);
    }
  }

  public int executeUpdateOrThrow(Connection c, String statement, Context context) throws
      UserException {
    try (PreparedStatement ps = c.prepareStatement(statement)) {
      return ps.executeUpdate();
    } catch (SQLException ex) {
      throw errorHandler.handleUserException(context, ex);
    }
  }

  public String renderVal(String value) {
    return dsl().render(DSL.val(value));
  }

  public DSLContext dsl() {
    return DSL.using(dataTypeProvider.getDialect());
  }

  @SuppressWarnings({"rawtypes"})
  public Object getResultSetValue(FieldType fieldType, ResultSet resultSet, int index) throws
      SQLException {
    DataTypeForKv dataType = dataTypeProvider.getDataType(fieldType);
    KvValueConverter valueConverter = dataType.getKvValueConverter();
    SqlBinding sqlBinding = valueConverter.getSqlBinding();
    return sqlBinding.get(resultSet, index);
  }

  @SuppressWarnings({"unchecked"})
  public KvValue getResultSetKvValue(FieldType fieldType, DataTypeForKv dataTypeForKv,
      ResultSet resultSet, int index) throws SQLException {
    Object databaseValue = getResultSetValue(FieldType.from(dataTypeForKv.getKvValueConverter()
        .getErasuredType()), resultSet, index);
    if (resultSet.wasNull()) {
      return null;
    }

    return ((Converter>) dataTypeForKv.getConverter()).from(databaseValue);
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  public void setPreparedStatementNullableValue(PreparedStatement preparedStatement,
      int parameterIndex,
      FieldType fieldType, KvValue value) throws SQLException {
    DataTypeForKv dataType = dataTypeProvider.getDataType(fieldType);
    if (value != null) {
      KvValueConverter valueConverter = dataType.getKvValueConverter();
      SqlBinding sqlBinding = valueConverter.getSqlBinding();
      Converter converter = dataType.getConverter();
      sqlBinding.set(preparedStatement, parameterIndex, converter.to(value));
    } else {
      preparedStatement.setNull(parameterIndex, dataType.getSQLType());
    }
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  public void setPreparedStatementValue(PreparedStatement preparedStatement, int parameterIndex,
      FieldType fieldType, KvValue value) throws SQLException {
    DataTypeForKv dataType = dataTypeProvider.getDataType(fieldType);
    KvValueConverter valueConverter = dataType.getKvValueConverter();
    Converter converter = dataType.getConverter();
    SqlBinding sqlBinding = valueConverter.getSqlBinding();
    sqlBinding.set(preparedStatement, parameterIndex, converter.to(value));
  }

  @SuppressWarnings({"rawtypes"})
  public String getPlaceholder(FieldType fieldType) {
    DataTypeForKv dataType = dataTypeProvider.getDataType(fieldType);
    KvValueConverter valueConverter = dataType.getKvValueConverter();
    SqlBinding sqlBinding = valueConverter.getSqlBinding();
    return sqlBinding.getPlaceholder();
  }

  @SuppressWarnings("rawtypes")
  public String getSqlTypeName(FieldType fieldType) {
    DataTypeForKv dataType = dataTypeProvider.getDataType(fieldType);

    return dataType.getTypeName();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy