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

com.clickzetta.client.jdbc.core.CZPreparedStatment Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package com.clickzetta.client.jdbc.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.sql.Date;
import java.util.*;

public class CZPreparedStatment implements PreparedStatement {
  private String sql = "";
  private final CZConnectContext context;
  private final CZStatement statement;
  private boolean closed;
  private ResultSet resultSet;
  private List parameterBindings = new ArrayList<>();
  private int fetchSize = 0;
  private int fetchDirection = 0;
  private int maxRows = 0;

  Logger logger = LoggerFactory.getLogger(CZPreparedStatment.class);

  public CZPreparedStatment(String s, CZConnectContext context) {
    statement = new CZStatement(context);
    logger.info("Init PreparedStatement by statement: " + statement);
    this.sql = s;
    this.context = context;
  }

  private String getFullSql(String sql) {
    String[] parts = sql.split("\\?");
    logger.info("executeQueryInternal: {}, {}, {}, {}", sql, parts.length,
            parameterBindings.size(), parameterBindings);
    int index = 0;
    StringBuilder fullSql = new StringBuilder(parts[index++]);
    for (CZParameterBinding parameterBinding : parameterBindings) {
      fullSql.append(parameterBinding.getValue());
      if (index >= parts.length) break;
      fullSql.append(parts[index++]);
    }
    return fullSql.toString();
  }

  private ResultSet executeQueryInternal(String sql) throws SQLException {
    String fullSql = getFullSql(sql);
    logger.info("executeQueryInternal, full SQL: {} by statement: {}", fullSql, statement);
    resultSet = statement.executeQuery(fullSql);
    return resultSet;
  }

  private boolean executeInternal(String sql) throws SQLException {
    String fullSql = getFullSql(sql);
    logger.info("executeInternal, full SQL: {}", fullSql);
    boolean result = statement.execute(fullSql);
    resultSet = statement.getResultSet();
    return result;
  }

  @Override
  public ResultSet executeQuery() throws SQLException {
    return executeQueryInternal(this.sql);
  }

  @Override
  public int executeUpdate() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeUpdate");
  }

  private void addParamBinding(int parameterIndex, CZParameterBinding binding) throws CZExceptionNotSupported {
    if (parameterBindings.size() >= parameterIndex) {
      parameterBindings.set(parameterIndex - 1, binding);
    } else if (parameterBindings.size() == parameterIndex - 1) {
      parameterBindings.add(binding);
    } else {
      throw new CZExceptionNotSupported("preparedStatement setError " + parameterIndex + " " + binding.toString());
    }
  }

  @Override
  public void setNull(int parameterIndex, int sqlType) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.NULL, null);
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.BOOLEAN, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setByte(int parameterIndex, byte x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.TINYINT, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setShort(int parameterIndex, short x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.SMALLINT, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setInt(int parameterIndex, int x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.INTEGER, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setLong(int parameterIndex, long x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.BIGINT, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setFloat(int parameterIndex, float x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.FLOAT, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setDouble(int parameterIndex, double x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.DOUBLE, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.DECIMAL, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setString(int parameterIndex, String x) throws SQLException {
    if (!x.startsWith("'") && !x.startsWith("\"")) {
      x = "'" + x + "'";
    }
    CZParameterBinding binding = new CZParameterBinding(Types.VARCHAR, x);
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.BINARY, String.valueOf(x));
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setDate(int parameterIndex, Date x) throws SQLException {
    if (x == null) {
      setNull(parameterIndex, Types.DATE);
    } else {
      CZParameterBinding binding = new CZParameterBinding(Types.DATE, "'" + x.toString()+ "'");
      addParamBinding(parameterIndex, binding);
    }
  }

  @Override
  public void setTime(int parameterIndex, Time x) throws SQLException {
    if (x == null) {
      setNull(parameterIndex, Types.DATE);
    } else {
      CZParameterBinding binding = new CZParameterBinding(Types.TIME, "'" + x.toString()+ "'");
      addParamBinding(parameterIndex, binding);
    }
  }

  @Override
  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
    CZParameterBinding binding = new CZParameterBinding(Types.TIMESTAMP, "timestamp '" + x.toString()+ "'");
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setAsciiStream");
  }

  @Override
  public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setUnicodeStream");
  }

  @Override
  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBinaryStream");
  }

  @Override
  public void clearParameters() throws SQLException {
    parameterBindings.clear();
  }

  @Override
  public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
    String v = String.valueOf(x);
    if (targetSqlType == Types.VARCHAR) {
      v = "\"" + v + "\"";
    }
    CZParameterBinding binding = new CZParameterBinding(targetSqlType, v);
    addParamBinding(parameterIndex, binding);
  }

  @Override
  public void setObject(int parameterIndex, Object x) throws SQLException {
    if (x == null) {
      setNull(parameterIndex, Types.NULL);
    } else if (x instanceof String) {
      setString(parameterIndex, (String) x);
    } else if (x instanceof BigDecimal) {
      setBigDecimal(parameterIndex, (BigDecimal) x);
    } else if (x instanceof Short) {
      setShort(parameterIndex, (Short) x);
    } else if (x instanceof Integer) {
      setInt(parameterIndex, (Integer) x);
    } else if (x instanceof Long) {
      setLong(parameterIndex, (Long) x);
    } else if (x instanceof Float) {
      setFloat(parameterIndex, (Float) x);
    } else if (x instanceof Double) {
      setDouble(parameterIndex, (Double) x);
    } else if (x instanceof Date) {
      setDate(parameterIndex, (Date) x);
    } else if (x instanceof Time) {
      setTime(parameterIndex, (Time) x);
    } else if (x instanceof Timestamp) {
      setTimestamp(parameterIndex, (Timestamp) x);
    } else if (x instanceof Boolean) {
      setBoolean(parameterIndex, (Boolean) x);
    } else if (x instanceof byte[]) {
      setBytes(parameterIndex, (byte[]) x);
    } else {
      throw new SQLException("Unknown Object type: " + x.getClass());
    }
  }

  @Override
  public boolean execute() throws SQLException {
    return executeInternal(this.sql);
  }

  @Override
  public void addBatch() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.addBatch");
  }

  @Override
  public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setCharacterStream");
  }

  @Override
  public void setRef(int parameterIndex, Ref x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setRef");
  }

  @Override
  public void setBlob(int parameterIndex, Blob x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBlob");
  }

  @Override
  public void setClob(int parameterIndex, Clob x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setClob");
  }

  @Override
  public void setArray(int parameterIndex, Array x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setArray");
  }

  @Override
  public ResultSetMetaData getMetaData() throws SQLException {
    resultSet = statement.executeQuery(sql);
    if (resultSet == null) {
      throw new SQLException("Get metadata failed.");
    }
    return resultSet.getMetaData();
  }

  @Override
  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
    if (x == null) {
      setNull(parameterIndex, Types.DATE);
    } else {
      String value =
              String.valueOf(
                      x.getTime()
                              + cal.getTimeZone().getOffset(x.getTime())
                              - msDiffJulianToGregorian(x));

      CZParameterBinding binding = new CZParameterBinding(Types.DATE, value);
      addParamBinding(parameterIndex, binding);
    }
  }

  @Override
  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
    setTime(parameterIndex, x);
    // throw new CZExceptionNotSupported("CZPreparedStatment.setTime");
  }

  @Override
  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
    setTimestamp(parameterIndex, x);
    //throw new CZExceptionNotSupported("CZPreparedStatment.setTimestamp");
  }

  @Override
  public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
    setNull(parameterIndex, sqlType);
    // throw new CZExceptionNotSupported("CZPreparedStatment.setNull");
  }

  @Override
  public void setURL(int parameterIndex, URL x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setURL");
  }

  @Override
  public ParameterMetaData getParameterMetaData() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getParameterMetaData");
  }

  @Override
  public void setRowId(int parameterIndex, RowId x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setRowId");
  }

  @Override
  public void setNString(int parameterIndex, String value) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNString");
  }

  @Override
  public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNCharacterStream");
  }

  @Override
  public void setNClob(int parameterIndex, NClob value) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNClob");
  }

  @Override
  public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setClob");
  }

  @Override
  public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBlob");
  }

  @Override
  public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNClob");
  }

  @Override
  public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setSQLXML");
  }

  @Override
  public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setObject");
  }

  @Override
  public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setAsciiStream");
  }

  @Override
  public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBinaryStream");
  }

  @Override
  public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setCharacterStream");
  }

  @Override
  public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setAsciiStream");
  }

  @Override
  public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBinaryStream");
  }

  @Override
  public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setCharacterStream");
  }

  @Override
  public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNCharacterStream");
  }

  @Override
  public void setClob(int parameterIndex, Reader reader) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setClob");
  }

  @Override
  public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setBlob");
  }

  @Override
  public void setNClob(int parameterIndex, Reader reader) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setNClob");
  }

  @Override
  public ResultSet executeQuery(String sql) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeQuery");
  }

  @Override
  public int executeUpdate(String sql) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeUpdate");
  }

  @Override
  public void close() throws SQLException {
    if (resultSet != null) {
      logger.info("Prepared statement: {} start closing resultSet: {}", statement, resultSet);
      resultSet.close();
      resultSet = null;
    }
    closed = true;
  }

  @Override
  public int getMaxFieldSize() throws SQLException {
    return 16777216;  // 16 * 1024 * 1024
  }

  @Override
  public void setMaxFieldSize(int max) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setMaxFieldSize");
  }

  @Override
  public int getMaxRows() throws SQLException {
    return this.maxRows;
  }

  @Override
  public void setMaxRows(int max) throws SQLException {
    if (max > 1000000) {
      throw new SQLException("setMaxRows larger than 1000000.");
    }
    this.maxRows = max;
    context.setMaxRowSize(max);
  }

  @Override
  public void setEscapeProcessing(boolean enable) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setEscapeProcessing");
  }

  @Override
  public int getQueryTimeout() throws SQLException {
    return statement.getQueryTimeout();
  }

  @Override
  public void setQueryTimeout(int seconds) throws SQLException {
    statement.setQueryTimeout(seconds);
  }

  @Override
  public void cancel() throws SQLException {
    statement.cancel();
  }

  @Override
  public SQLWarning getWarnings() throws SQLException {
    return statement.getWarnings();
  }

  @Override
  public void clearWarnings() throws SQLException {
    statement.clearWarnings();
  }

  @Override
  public void setCursorName(String name) throws SQLException {
    statement.setCursorName(name);
  }

  @Override
  public boolean execute(String sql) throws SQLException {
    executeQueryInternal(sql);
    return true;
  }

  @Override
  public ResultSet getResultSet() throws SQLException {
    logger.info("Prepared statement: {} get resultSet: {}", statement, resultSet);
    return resultSet;
  }

  @Override
  public int getUpdateCount() throws SQLException {
    return -1;
  }

  @Override
  public boolean getMoreResults() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getMoreResults");
  }

  @Override
  public void setFetchDirection(int direction) throws SQLException {
    this.fetchDirection = direction;
  }

  @Override
  public int getFetchDirection() throws SQLException {
    return fetchDirection;
  }

  @Override
  public void setFetchSize(int rows) throws SQLException {
    this.fetchSize = rows;
  }

  @Override
  public int getFetchSize() throws SQLException {
    return this.fetchSize;
  }

  @Override
  public int getResultSetConcurrency() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getResultSetConcurrency");
  }

  @Override
  public int getResultSetType() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getResultSetType");
  }

  @Override
  public void addBatch(String sql) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.addBatch");
  }

  @Override
  public void clearBatch() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.clearBatch");
  }

  @Override
  public int[] executeBatch() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeBatch");
  }

  @Override
  public Connection getConnection() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getConnection");
  }

  @Override
  public boolean getMoreResults(int current) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getMoreResults");
  }

  @Override
  public ResultSet getGeneratedKeys() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getGeneratedKeys");
  }

  @Override
  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeUpdate");
  }

  @Override
  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeUpdate");
  }

  @Override
  public int executeUpdate(String sql, String[] columnNames) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.executeUpdate");
  }

  @Override
  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.execute");
  }

  @Override
  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.execute");
  }

  @Override
  public boolean execute(String sql, String[] columnNames) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.execute");
  }

  @Override
  public int getResultSetHoldability() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.getResultSetHoldability");
  }

  @Override
  public boolean isClosed() throws SQLException {
    return closed;
  }

  @Override
  public void setPoolable(boolean poolable) throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.setPoolable");
  }

  @Override
  public boolean isPoolable() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.isPoolable");
  }

  @Override
  public void closeOnCompletion() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.closeOnCompletion");
  }

  @Override
  public boolean isCloseOnCompletion() throws SQLException {
    throw new CZExceptionNotSupported("CZPreparedStatment.isCloseOnCompletion");
  }

  @Override
  public  T unwrap(Class iface) throws SQLException {
    return null;
  }

  @Override
  public boolean isWrapperFor(Class iface) throws SQLException {
    return false;
  }


  /**
   * helper utils
   */
  private static final int MILLIS_IN_ONE_DAY = 86400000;

  private static long msDiffJulianToGregorian(java.util.Date date) {
    // if date is before 1582-10-05, apply the difference
    // by (H-(H/4)-2) where H is the hundreds digit of the year according to:
    // http://en.wikipedia.org/wiki/Gregorian_calendar
    if (date.getTime() < -12220156800000L) {
      // get the year of the date
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      int year = cal.get(Calendar.YEAR);
      int month = cal.get(Calendar.MONTH);
      int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);

      // for dates on or before 02/28, use the previous year otherwise use
      // current year.
      // TODO: we need to revisit this since there is a potential issue using
      // the year/month/day from the calendar since that may not be the same
      // year/month/day as the original date (which is the problem we are
      // trying to solve here).

      if (month == 0 || (month == 1 && dayOfMonth <= 28)) {
        year = year - 1;
      }

      int hundreds = year / 100;
      int differenceInDays = hundreds - (hundreds / 4) - 2;

      return differenceInDays * MILLIS_IN_ONE_DAY;
    } else {
      return 0;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy