java基础类库学习 java.sql(3)mysql数据库对jdbc接口的具体实现

 

既然我们知道jdbc只是提供了一组数据库的统一接口,由各个数据库厂商提供对应的实现类,那我们大概的看一下

以mysql厂商对应的实现举例

jdbc提供的接口Driver在mysql中的实现j

package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver
  implements java.sql.Driver
{
  public Driver()
    throws SQLException
  {
  }

  static
  {
    try
    {
      DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException("Can't register driver!");
    }
  }
}

jdbc提供的接口preparedStatement在mysql中的实现

package com.mysql.jdbc;

public class PreparedStatement extends Statement
  implements java.sql.PreparedStatement
{


 

  public synchronized void close()
    throws SQLException
  {
    realClose(true, true);
  }

  private final void escapeblockFast(byte[] buf, Buffer packet, int size) throws SQLException
  {
    int lastwritten = 0;

    for (int i = 0; i < size; i++) {
      byte b = buf[i];

      if (b == 0)
      {
        if (i > lastwritten) {
          packet.writeBytesNoNull(buf, lastwritten, i - lastwritten);
        }

        packet.writeByte((byte)92);
        packet.writeByte((byte)48);
        lastwritten = i + 1;
      }
      else if ((b == 92) || (b == 39) || ((!this.usingAnsiMode) && (b == 34)))
      {
        if (i > lastwritten) {
          packet.writeBytesNoNull(buf, lastwritten, i - lastwritten);
        }

        packet.writeByte((byte)92);
        lastwritten = i;
      }

    }

    if (lastwritten < size)
      packet.writeBytesNoNull(buf, lastwritten, size - lastwritten);
  }

  private final void escapeblockFast(byte[] buf, ByteArrayOutputStream bytesOut, int size)
  {
    int lastwritten = 0;

    for (int i = 0; i < size; i++) {
      byte b = buf[i];

      if (b == 0)
      {
        if (i > lastwritten) {
          bytesOut.write(buf, lastwritten, i - lastwritten);
        }

        bytesOut.write(92);
        bytesOut.write(48);
        lastwritten = i + 1;
      }
      else if ((b == 92) || (b == 39) || ((!this.usingAnsiMode) && (b == 34)))
      {
        if (i > lastwritten) {
          bytesOut.write(buf, lastwritten, i - lastwritten);
        }

        bytesOut.write(92);
        lastwritten = i;
      }

    }

    if (lastwritten < size)
      bytesOut.write(buf, lastwritten, size - lastwritten);
  }

  public boolean execute()
    throws SQLException
  {
    checkClosed();

    Connection locallyScopedConn = this.connection;

    if ((locallyScopedConn.isReadOnly()) && (this.firstCharOfStmt != 'S')) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.20") + Messages.getString("PreparedStatement.21"), "S1009");
    }

    ResultSet rs = null;

    CachedResultSetMetaData cachedMetadata = null;

    synchronized (locallyScopedConn.getMutex()) {
      clearWarnings();

      this.batchedGeneratedKeys = null;

      Buffer sendPacket = fillSendPacket();

      String oldCatalog = null;

      if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) {
        oldCatalog = locallyScopedConn.getCatalog();
        locallyScopedConn.setCatalog(this.currentCatalog);
      }

      if (locallyScopedConn.getCacheResultSetMetadata()) {
        cachedMetadata = locallyScopedConn.getCachedMetaData(this.originalSql);
      }

      Field[] metadataFromCache = null;

      if (cachedMetadata != null) {
        metadataFromCache = cachedMetadata.fields;
      }

      boolean oldInfoMsgState = false;

      if (this.retrieveGeneratedKeys) {
        oldInfoMsgState = locallyScopedConn.isReadInfoMsgEnabled();
        locallyScopedConn.setReadInfoMsgEnabled(true);
      }

      if (locallyScopedConn.useMaxRows()) {
        int rowLimit = -1;

        if (this.firstCharOfStmt == 'S') {
          if (this.hasLimitClause) {
            rowLimit = this.maxRows;
          }
          else if (this.maxRows <= 0) {
            locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, 1003, 1007, false, this.currentCatalog, true);
          }
          else
          {
            locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, null, 1003, 1007, false, this.currentCatalog, true);
          }

        }
        else
        {
          locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, 1003, 1007, false, this.currentCatalog, true);
        }

        rs = executeInternal(rowLimit, sendPacket, createStreamingResultSet(), this.firstCharOfStmt == 'S', true, metadataFromCache, false);
      }
      else
      {
        rs = executeInternal(-1, sendPacket, createStreamingResultSet(), this.firstCharOfStmt == 'S', true, metadataFromCache, false);
      }

      if (cachedMetadata != null) {
        locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, cachedMetadata, this.results);
      }
      else if ((rs.reallyResult()) && (locallyScopedConn.getCacheResultSetMetadata())) {
        locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, null, this.results);
      }

      if (this.retrieveGeneratedKeys) {
        locallyScopedConn.setReadInfoMsgEnabled(oldInfoMsgState);
        rs.setFirstCharOfQuery('R');
      }

      if (oldCatalog != null) {
        locallyScopedConn.setCatalog(oldCatalog);
      }

      this.lastInsertId = rs.getUpdateID();

      if (rs != null) {
        this.results = rs;
      }
    }

    return (rs != null) && (rs.reallyResult());
  }

  public int[] executeBatch()
    throws SQLException
  {
    checkClosed();

    if (this.connection.isReadOnly()) {
      throw new SQLException(Messages.getString("PreparedStatement.25") + Messages.getString("PreparedStatement.26"), "S1009");
    }

    synchronized (this.connection.getMutex()) {
      try {
        clearWarnings();

        if ((!this.batchHasPlainStatements) && (this.connection.getRewriteBatchedStatements()))
        {
          if (canRewriteAsMultivalueInsertStatement()) {
            arrayOfInt = executeBatchedInserts();

            clearBatch(); return arrayOfInt;
          }
        }
        int[] arrayOfInt = executeBatchSerially();

        clearBatch(); return arrayOfInt;
      }
      catch (NullPointerException npe)
      {
        throw npe;
      } finally {
        clearBatch();
      }
    }
  }

  public synchronized boolean canRewriteAsMultivalueInsertStatement() {
    if (!this.hasCheckedForRewrite) {
      this.canRewrite = StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, "INSERT", this.statementAfterCommentsPos);

      this.hasCheckedForRewrite = true;
    }

    return this.canRewrite;
  }

  protected int[] executeBatchedInserts()
    throws SQLException
  {
    String valuesClause = extractValuesClause();

    Connection locallyScopedConn = this.connection;

    if (valuesClause == null) {
      return executeBatchSerially();
    }

    int numBatchedArgs = this.batchedArgs.size();

    if (this.retrieveGeneratedKeys) {
      this.batchedGeneratedKeys = new ArrayList(numBatchedArgs);
    }

    int numValuesPerBatch = computeBatchSize(numBatchedArgs);

    if (numBatchedArgs < numValuesPerBatch) {
      numValuesPerBatch = numBatchedArgs;
    }

    java.sql.PreparedStatement batchedStatement = null;

    int batchedParamIndex = 1;
    int updateCountRunningTotal = 0;
    int numberToExecuteAsMultiValue = 0;
    int batchCounter = 0;
    try
    {
      if (this.retrieveGeneratedKeys) {
        batchedStatement = locallyScopedConn.prepareStatement(generateBatchedInsertSQL(valuesClause, numValuesPerBatch), 1);
      }
      else
      {
        batchedStatement = locallyScopedConn.prepareStatement(generateBatchedInsertSQL(valuesClause, numValuesPerBatch));
      }

      if (numBatchedArgs < numValuesPerBatch)
        numberToExecuteAsMultiValue = numBatchedArgs;
      else {
        numberToExecuteAsMultiValue = numBatchedArgs / numValuesPerBatch;
      }

      int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch;

      for (int i = 0; i < numberArgsToExecute; i++) {
        if ((i != 0) && (i % numValuesPerBatch == 0)) {
          updateCountRunningTotal += batchedStatement.executeUpdate();

          getBatchedGeneratedKeys(batchedStatement);
          batchedStatement.clearParameters();
          batchedParamIndex = 1;
        }

        batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.batchedArgs.get(batchCounter++));
      }

      updateCountRunningTotal += batchedStatement.executeUpdate();
      getBatchedGeneratedKeys(batchedStatement);

      numValuesPerBatch = numBatchedArgs - batchCounter;
    } finally {
      if (batchedStatement != null) {
        batchedStatement.close();
      }
    }
    try
    {
      if (numValuesPerBatch > 0)
      {
        if (this.retrieveGeneratedKeys) {
          batchedStatement = locallyScopedConn.prepareStatement(generateBatchedInsertSQL(valuesClause, numValuesPerBatch), 1);
        }
        else
        {
          batchedStatement = locallyScopedConn.prepareStatement(generateBatchedInsertSQL(valuesClause, numValuesPerBatch));
        }

        batchedParamIndex = 1;

        while (batchCounter < numBatchedArgs) {
          batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.batchedArgs.get(batchCounter++));
        }

        updateCountRunningTotal += batchedStatement.executeUpdate();
        getBatchedGeneratedKeys(batchedStatement);
      }

      int[] updateCounts = new int[this.batchedArgs.size()];

      for (int i = 0; i < this.batchedArgs.size(); i++) {
        updateCounts[i] = 1;
      }

      return updateCounts;
    } finally {
      if (batchedStatement != null)
        batchedStatement.close();
    }
  }

  protected int computeBatchSize(int numBatchedArgs)
  {
    long[] combinedValues = computeMaxParameterSetSizeAndBatchSize(numBatchedArgs);

    long maxSizeOfParameterSet = combinedValues[0];
    long sizeOfEntireBatch = combinedValues[1];

    int maxAllowedPacket = this.connection.getMaxAllowedPacket();

    if (sizeOfEntireBatch < maxAllowedPacket - this.originalSql.length()) {
      return numBatchedArgs;
    }

    return (int)Math.max(1L, maxAllowedPacket - this.originalSql.length() / maxSizeOfParameterSet);
  }

  protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs)
  {
    long sizeOfEntireBatch = 0L;
    long maxSizeOfParameterSet = 0L;

    for (int i = 0; i < numBatchedArgs; i++) {
      BatchParams paramArg = (BatchParams)this.batchedArgs.get(i);

      boolean[] isNullBatch = paramArg.isNull;
      boolean[] isStreamBatch = paramArg.isStream;

      long sizeOfParameterSet = 0L;

      for (int j = 0; j < isNullBatch.length; j++) {
        if (isNullBatch[j] == 0)
        {
          if (isStreamBatch[j] != 0) {
            int streamLength = paramArg.streamLengths[j];

            if (streamLength != -1)
              sizeOfParameterSet += streamLength * 2;
          }
          else {
            sizeOfParameterSet += paramArg.parameterStrings[j].length;
          }
        }
        else sizeOfParameterSet += 4L;

      }

      sizeOfParameterSet += this.batchedValuesClause.length() + 1;
      sizeOfEntireBatch += sizeOfParameterSet;

      if (sizeOfParameterSet > maxSizeOfParameterSet) {
        maxSizeOfParameterSet = sizeOfParameterSet;
      }
    }

    return new long[] { maxSizeOfParameterSet, sizeOfEntireBatch };
  }

  protected int[] executeBatchSerially()
    throws SQLException
  {
    Connection locallyScopedConn = this.connection;

    if (locallyScopedConn == null) {
      checkClosed();
    }

    int[] updateCounts = null;

    if (this.batchedArgs != null) {
      int nbrCommands = this.batchedArgs.size();
      updateCounts = new int[nbrCommands];

      for (int i = 0; i < nbrCommands; i++) {
        updateCounts[i] = -3;
      }

      SQLException sqlEx = null;

      int commandIndex = 0;

      if (this.retrieveGeneratedKeys) {
        this.batchedGeneratedKeys = new ArrayList(nbrCommands);
      }

      for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) {
        Object arg = this.batchedArgs.get(commandIndex);

        if ((arg instanceof String)) {
          updateCounts[commandIndex] = executeUpdate((String)arg);
        } else {
          BatchParams paramArg = (BatchParams)arg;
          try
          {
            updateCounts[commandIndex] = executeUpdate(paramArg.parameterStrings, paramArg.parameterStreams, paramArg.isStream, paramArg.streamLengths, paramArg.isNull, true);

            if (this.retrieveGeneratedKeys) {
              java.sql.ResultSet rs = null;
              try
              {
                rs = getGeneratedKeysInternal();

                while (rs.next())
                  this.batchedGeneratedKeys.add(new byte[][] { rs.getBytes(1) });
              }
              finally
              {
                if (rs != null)
                  rs.close();
              }
            }
          }
          catch (SQLException ex) {
            updateCounts[commandIndex] = -3;

            if (this.continueBatchOnError) {
              sqlEx = ex;
            } else {
              int[] newUpdateCounts = new int[commandIndex];
              System.arraycopy(updateCounts, 0, newUpdateCounts, 0, commandIndex);

              throw new BatchUpdateException(ex.getMessage(), ex.getSQLState(), ex.getErrorCode(), newUpdateCounts);
            }
          }

        }

      }

      if (sqlEx != null) {
        throw new BatchUpdateException(sqlEx.getMessage(), sqlEx.getSQLState(), sqlEx.getErrorCode(), updateCounts);
      }

    }

    return updateCounts != null ? updateCounts : new int[0];
  }

  protected ResultSet executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, boolean unpackFields, Field[] cachedFields, boolean isBatch)
    throws SQLException
  {
    try
    {
      synchronized (this.cancelTimeoutMutex) {
        this.wasCancelled = false;
      }
Connection locallyScopedConnection = this.connection;

      this.numberOfExecutions += 1;

      Statement.CancelTask timeoutTask = null;
      ResultSet rs;
      try {
        if ((this.timeoutInMillis != 0) && (locallyScopedConnection.versionMeetsMinimum(5, 0, 0)))
        {
          timeoutTask = new Statement.CancelTask(this);
          Connection.getCancelTimer().schedule(timeoutTask, this.timeoutInMillis);
        }

        rs = locallyScopedConnection.execSQL(this, null, maxRowsToRetrieve, sendPacket, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, unpackFields, isBatch);

        if (timeoutTask != null) {
          timeoutTask.cancel();

          if (timeoutTask.caughtWhileCancelling != null) {
            throw timeoutTask.caughtWhileCancelling;
          }

          timeoutTask = null;
        }

        synchronized (this.cancelTimeoutMutex) {
          if (this.wasCancelled) {
            this.wasCancelled = false;
            throw new MySQLTimeoutException();
          }
        }
      } finally {
        if (timeoutTask != null) {
          timeoutTask.cancel();
        }
      }

      return rs;
    } catch (NullPointerException npe) {
      checkClosed();

      throw npe;
    }
  }

  public java.sql.ResultSet executeQuery()
    throws SQLException
  {
    checkClosed();

    Connection locallyScopedConn = this.connection;

    checkForDml(this.originalSql, this.firstCharOfStmt);

    CachedResultSetMetaData cachedMetadata = null;

    synchronized (locallyScopedConn.getMutex()) {
      clearWarnings();

      this.batchedGeneratedKeys = null;

      Buffer sendPacket = fillSendPacket();

      if ((this.results != null) && 
        (!this.connection.getHoldResultsOpenOverStatementClose()) && 
        (!this.holdResultsOpenOverClose)) {
        this.results.realClose(false);
      }

      String oldCatalog = null;

      if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) {
        oldCatalog = locallyScopedConn.getCatalog();
        locallyScopedConn.setCatalog(this.currentCatalog);
      }

      if (locallyScopedConn.getCacheResultSetMetadata()) {
        cachedMetadata = locallyScopedConn.getCachedMetaData(this.originalSql);
      }

      Field[] metadataFromCache = null;

      if (cachedMetadata != null) {
        metadataFromCache = cachedMetadata.fields;
      }

      if (locallyScopedConn.useMaxRows())
      {
        if (this.hasLimitClause) {
          this.results = executeInternal(this.maxRows, sendPacket, createStreamingResultSet(), true, cachedMetadata == null, metadataFromCache, false);
        }
        else
        {
          if (this.maxRows <= 0) {
            locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, 1003, 1007, false, this.currentCatalog, true);
          }
          else
          {
            locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, null, 1003, 1007, false, this.currentCatalog, true);
          }

          this.results = executeInternal(-1, sendPacket, createStreamingResultSet(), true, cachedMetadata == null, metadataFromCache, false);

          if (oldCatalog != null)
            this.connection.setCatalog(oldCatalog);
        }
      }
      else {
        this.results = executeInternal(-1, sendPacket, createStreamingResultSet(), true, cachedMetadata == null, metadataFromCache, false);
      }

      if (oldCatalog != null) {
        locallyScopedConn.setCatalog(oldCatalog);
      }

      if (cachedMetadata != null) {
        locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, cachedMetadata, this.results);
      }
      else if (locallyScopedConn.getCacheResultSetMetadata()) {
        locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, null, this.results);
      }

    }

    this.lastInsertId = this.results.getUpdateID();

    return this.results;
  }

  public int executeUpdate()
    throws SQLException
  {
    return executeUpdate(true, false);
  }

  protected int executeUpdate(boolean clearBatchedGeneratedKeysAndWarnings, boolean isBatch)
    throws SQLException
  {
    if (clearBatchedGeneratedKeysAndWarnings) {
      clearWarnings();
      this.batchedGeneratedKeys = null;
    }

    return executeUpdate(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull, isBatch);
  }

  protected int executeUpdate(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths, boolean[] batchedIsNull, boolean isReallyBatch)
    throws SQLException
  {
    checkClosed();

    Connection locallyScopedConn = this.connection;

    if (locallyScopedConn.isReadOnly()) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") + Messages.getString("PreparedStatement.35"), "S1009");
    }

    if ((this.firstCharOfStmt == 'S') && (StringUtils.startsWithIgnoreCaseAndWs(this.originalSql, "SELECT")))
    {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03");
    }

    if ((this.results != null) && 
      (!locallyScopedConn.getHoldResultsOpenOverStatementClose())) {
      this.results.realClose(false);
    }

    ResultSet rs = null;

    synchronized (locallyScopedConn.getMutex()) {
      Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths);

      String oldCatalog = null;

      if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) {
        oldCatalog = locallyScopedConn.getCatalog();
        locallyScopedConn.setCatalog(this.currentCatalog);
      }

      if (locallyScopedConn.useMaxRows()) {
        locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, 1003, 1007, false, this.currentCatalog, true);
      }

      boolean oldInfoMsgState = false;

      if (this.retrieveGeneratedKeys) {
        oldInfoMsgState = locallyScopedConn.isReadInfoMsgEnabled();
        locallyScopedConn.setReadInfoMsgEnabled(true);
      }

      rs = executeInternal(-1, sendPacket, false, false, true, null, isReallyBatch);

      if (this.retrieveGeneratedKeys) {
        locallyScopedConn.setReadInfoMsgEnabled(oldInfoMsgState);
        rs.setFirstCharOfQuery(this.firstCharOfStmt);
      }

      if (oldCatalog != null) {
        locallyScopedConn.setCatalog(oldCatalog);
      }
    }

    this.results = rs;

    this.updateCount = rs.getUpdateCount();

    int truncatedUpdateCount = 0;

    if (this.updateCount > 2147483647L)
      truncatedUpdateCount = 2147483647;
    else {
      truncatedUpdateCount = (int)this.updateCount;
    }

    this.lastInsertId = rs.getUpdateID();

    return truncatedUpdateCount;
  }

  private String extractValuesClause() throws SQLException {
    if (this.batchedValuesClause == null) {
      String quoteCharStr = this.connection.getMetaData().getIdentifierQuoteString();

      int indexOfValues = -1;

      if (quoteCharStr.length() > 0) {
        indexOfValues = StringUtils.indexOfIgnoreCaseRespectQuotes(this.statementAfterCommentsPos, this.originalSql, "VALUES ", quoteCharStr.charAt(0), false);
      }
      else
      {
        indexOfValues = StringUtils.indexOfIgnoreCase(this.statementAfterCommentsPos, this.originalSql, "VALUES ");
      }

      if (indexOfValues == -1) {
        return null;
      }

      int indexOfFirstParen = this.originalSql.indexOf('(', indexOfValues + 7);

      if (indexOfFirstParen == -1) {
        return null;
      }

      int indexOfLastParen = this.originalSql.lastIndexOf(')');

      if (indexOfLastParen == -1) {
        return null;
      }

      this.batchedValuesClause = this.originalSql.substring(indexOfFirstParen, indexOfLastParen + 1);
    }

    return this.batchedValuesClause;
  }

  protected Buffer fillSendPacket()
    throws SQLException
  {
    return fillSendPacket(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths);
  }

  protected Buffer fillSendPacket(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths)
    throws SQLException
  {
    Buffer sendPacket = this.connection.getIO().getSharedSendPacket();

    sendPacket.clear();

    sendPacket.writeByte((byte)3);

    boolean useStreamLengths = this.connection.getUseStreamLengthsInPrepStmts();

    int ensurePacketSize = 0;

    for (int i = 0; i < batchedParameterStrings.length; i++) {
      if ((batchedIsStream[i] != 0) && (useStreamLengths)) {
        ensurePacketSize += batchedStreamLengths[i];
      }
    }

    if (ensurePacketSize != 0) {
      sendPacket.ensureCapacity(ensurePacketSize);
    }

    for (int i = 0; i < batchedParameterStrings.length; i++) {
      if ((batchedParameterStrings[i] == null) && (batchedParameterStreams[i] == null))
      {
        throw SQLError.createSQLException(Messages.getString("PreparedStatement.40") + (i + 1), "07001");
      }

      sendPacket.writeBytesNoNull(this.staticSqlStrings[i]);

      if (batchedIsStream[i] != 0) {
        streamToBytes(sendPacket, batchedParameterStreams[i], true, batchedStreamLengths[i], useStreamLengths);
      }
      else {
        sendPacket.writeBytesNoNull(batchedParameterStrings[i]);
      }
    }

    sendPacket.writeBytesNoNull(this.staticSqlStrings[batchedParameterStrings.length]);

    return sendPacket;
  }

  private String generateBatchedInsertSQL(String valuesClause, int numBatches) {
    StringBuffer newStatementSql = new StringBuffer(this.originalSql.length() + numBatches * (valuesClause.length() + 1));

    newStatementSql.append(this.originalSql);

    for (int i = 0; i < numBatches - 1; i++) {
      newStatementSql.append(',');
      newStatementSql.append(valuesClause);
    }

    return newStatementSql.toString();
  }

  public byte[] getBytesRepresentation(int parameterIndex)
    throws SQLException
  {
    if (this.isStream[parameterIndex] != 0) {
      return streamToBytes(this.parameterStreams[parameterIndex], false, this.streamLengths[parameterIndex], this.connection.getUseStreamLengthsInPrepStmts());
    }

    byte[] parameterVal = this.parameterValues[parameterIndex];

    if (parameterVal == null) {
      return null;
    }

    if ((parameterVal[0] == 39) && (parameterVal[(parameterVal.length - 1)] == 39))
    {
      byte[] valNoQuotes = new byte[parameterVal.length - 2];
      System.arraycopy(parameterVal, 1, valNoQuotes, 0, parameterVal.length - 2);

      return valNoQuotes;
    }

    return parameterVal;
  }

  private final String getDateTimePattern(String dt, boolean toTime)
    throws Exception
  {
    int dtLength = dt != null ? dt.length() : 0;

    if ((dtLength >= 8) && (dtLength <= 10)) {
      int dashCount = 0;
      boolean isDateOnly = true;

      for (int i = 0; i < dtLength; i++) {
        char c = dt.charAt(i);

        if ((!Character.isDigit(c)) && (c != '-')) {
          isDateOnly = false;

          break;
        }

        if (c == '-') {
          dashCount++;
        }
      }

      if ((isDateOnly) && (dashCount == 2)) {
        return "yyyy-MM-dd";
      }

    }

    boolean colonsOnly = true;

    for (int i = 0; i < dtLength; i++) {
      char c = dt.charAt(i);

      if ((!Character.isDigit(c)) && (c != ':')) {
        colonsOnly = false;

        break;
      }
    }

    if (colonsOnly) {
      return "HH:mm:ss";
    }

    StringReader reader = new StringReader(dt + " ");
    ArrayList vec = new ArrayList();
    ArrayList vecRemovelist = new ArrayList();
    Object[] nv = new Object[3];

    nv[0] = new Character('y');
    nv[1] = new StringBuffer();
    nv[2] = new Integer(0);
    vec.add(nv);

    if (toTime) {
      nv = new Object[3];
      nv[0] = new Character('h');
      nv[1] = new StringBuffer();
      nv[2] = new Integer(0);
      vec.add(nv);
    }
    int z;
    while ((z = reader.read()) != -1) {
      char separator = (char)z;
      int maxvecs = vec.size();

      for (int count = 0; count < maxvecs; count++) {
        Object[] v = (Object[])vec.get(count);
        int n = ((Integer)v[2]).intValue();
        char c = getSuccessor(((Character)v[0]).charValue(), n);

        if (!Character.isLetterOrDigit(separator)) {
          if ((c == ((Character)v[0]).charValue()) && (c != 'S')) {
            vecRemovelist.add(v);
          } else {
            ((StringBuffer)v[1]).append(separator);

            if ((c == 'X') || (c == 'Y'))
              v[2] = new Integer(4);
          }
        }
        else {
          if (c == 'X') {
            c = 'y';
            nv = new Object[3];
            nv[1] = new StringBuffer(((StringBuffer)v[1]).toString()).append('M');

            nv[0] = new Character('M');
            nv[2] = new Integer(1);
            vec.add(nv);
          } else if (c == 'Y') {
            c = 'M';
            nv = new Object[3];
            nv[1] = new StringBuffer(((StringBuffer)v[1]).toString()).append('d');

            nv[0] = new Character('d');
            nv[2] = new Integer(1);
            vec.add(nv);
          }

          ((StringBuffer)v[1]).append(c);

          if (c == ((Character)v[0]).charValue()) {
            v[2] = new Integer(n + 1);
          } else {
            v[0] = new Character(c);
            v[2] = new Integer(1);
          }
        }
      }

      int size = vecRemovelist.size();

      for (int i = 0; i < size; i++) {
        Object[] v = (Object[])vecRemovelist.get(i);
        vec.remove(v);
      }

      vecRemovelist.clear();
    }

    int size = vec.size();

    for (int i = 0; i < size; i++) {
      Object[] v = (Object[])vec.get(i);
      char c = ((Character)v[0]).charValue();
      int n = ((Integer)v[2]).intValue();

      boolean bk = getSuccessor(c, n) != c;
      boolean atEnd = ((c == 's') || (c == 'm') || ((c == 'h') && (toTime))) && (bk);
      boolean finishesAtDate = (bk) && (c == 'd') && (!toTime);
      boolean containsEnd = ((StringBuffer)v[1]).toString().indexOf('W') != -1;

      if (((!atEnd) && (!finishesAtDate)) || (containsEnd)) {
        vecRemovelist.add(v);
      }
    }

    size = vecRemovelist.size();

    for (int i = 0; i < size; i++) {
      vec.remove(vecRemovelist.get(i));
    }

    vecRemovelist.clear();
    Object[] v = (Object[])vec.get(0);

    StringBuffer format = (StringBuffer)v[1];
    format.setLength(format.length() - 1);

    return format.toString();
  }

  public java.sql.ResultSetMetaData getMetaData()
    throws SQLException
  {
    if (!StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(this.originalSql, "SELECT"))
    {
      return null;
    }

    PreparedStatement mdStmt = null;
    java.sql.ResultSet mdRs = null;

    if (this.pstmtResultMetaData == null) {
      try {
        mdStmt = new PreparedStatement(this.connection, this.originalSql, this.currentCatalog, this.parseInfo);

        mdStmt.setMaxRows(0);

        int paramCount = this.parameterValues.length;

        for (int i = 1; i <= paramCount; i++) {
          mdStmt.setString(i, "");
        }

        boolean hadResults = mdStmt.execute();

        if (hadResults) {
          mdRs = mdStmt.getResultSet();

          this.pstmtResultMetaData = mdRs.getMetaData();
        } else {
          this.pstmtResultMetaData = new ResultSetMetaData(new Field[0], this.connection.getUseOldAliasMetadataBehavior());
        }
      }
      finally
      {
        SQLException sqlExRethrow = null;

        if (mdRs != null) {
          try {
            mdRs.close();
          } catch (SQLException sqlEx) {
            sqlExRethrow = sqlEx;
          }

          mdRs = null;
        }

        if (mdStmt != null) {
          try {
            mdStmt.close();
          } catch (SQLException sqlEx) {
            sqlExRethrow = sqlEx;
          }

          mdStmt = null;
        }

        if (sqlExRethrow != null) {
          throw sqlExRethrow;
        }
      }
    }

    return this.pstmtResultMetaData;
  }

  public ParameterMetaData getParameterMetaData()
    throws SQLException
  {
    if (this.parameterMetaData == null) {
      if (this.connection.getGenerateSimpleParameterMetadata())
        this.parameterMetaData = new MysqlParameterMetadata(this.parameterCount);
      else {
        this.parameterMetaData = new MysqlParameterMetadata(null, this.parameterCount);
      }

    }

    return this.parameterMetaData;
  }

  ParseInfo getParseInfo() {
    return this.parseInfo;
  }

  private final char getSuccessor(char c, int n) {
    return (c == 's') && (n < 2) ? 's' : c == 'm' ? 's' : (c == 'm') && (n < 2) ? 'm' : c == 'H' ? 'm' : (c == 'H') && (n < 2) ? 'H' : c == 'd' ? 'H' : (c == 'd') && (n < 2) ? 'd' : c == 'M' ? 'd' : (c == 'M') && (n < 3) ? 'M' : (c == 'M') && (n == 2) ? 'Y' : c == 'y' ? 'M' : (c == 'y') && (n < 4) ? 'y' : (c == 'y') && (n == 2) ? 'X' : 'W';
  }

  private final void hexEscapeBlock(byte[] buf, Buffer packet, int size)
    throws SQLException
  {
    for (int i = 0; i < size; i++) {
      byte b = buf[i];
      int lowBits = (b & 0xFF) / 16;
      int highBits = (b & 0xFF) % 16;

      packet.writeByte(HEX_DIGITS[lowBits]);
      packet.writeByte(HEX_DIGITS[highBits]);
    }
  }

  private void initializeFromParseInfo() throws SQLException {
    this.staticSqlStrings = this.parseInfo.staticSql;
    this.hasLimitClause = this.parseInfo.foundLimitClause;
    this.isLoadDataQuery = this.parseInfo.foundLoadData;
    this.firstCharOfStmt = this.parseInfo.firstStmtChar;

    this.parameterCount = (this.staticSqlStrings.length - 1);

    this.parameterValues = new byte[this.parameterCount][];
    this.parameterStreams = new InputStream[this.parameterCount];
    this.isStream = new boolean[this.parameterCount];
    this.streamLengths = new int[this.parameterCount];
    this.isNull = new boolean[this.parameterCount];

    clearParameters();

    for (int j = 0; j < this.parameterCount; j++) {
      this.isStream[j] = false;
    }

    this.statementAfterCommentsPos = this.parseInfo.statementStartPos;
  }

  boolean isNull(int paramIndex) {
    return this.isNull[paramIndex];
  }

  private final int readblock(InputStream i, byte[] b) throws SQLException {
    try {
      return i.read(b);
    } catch (Throwable E) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.56") + E.getClass().getName(), "S1000");
    }
  }

  private final int readblock(InputStream i, byte[] b, int length) throws SQLException
  {
    try
    {
      int lengthToRead = length;

      if (lengthToRead > b.length) {
        lengthToRead = b.length;
      }

      return i.read(b, 0, lengthToRead);
    } catch (Throwable E) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.55") + E.getClass().getName(), "S1000");
    }
  }

  protected void realClose(boolean calledExplicitly, boolean closeOpenResults)
    throws SQLException
  {
    if ((this.useUsageAdvisor) && 
      (this.numberOfExecutions <= 1)) {
      String message = Messages.getString("PreparedStatement.43");

      this.eventSink.consumeEvent(new ProfilerEvent((byte)0, "", this.currentCatalog, this.connectionId, getId(), -1, System.currentTimeMillis(), 0, null, this.pointOfOrigin, message));
    }

    super.realClose(calledExplicitly, closeOpenResults);

    this.dbmd = null;
    this.originalSql = null;
    this.staticSqlStrings = ((byte[][])null);
    this.parameterValues = ((byte[][])null);
    this.parameterStreams = null;
    this.isStream = null;
    this.streamLengths = null;
    this.isNull = null;
    this.streamConvertBuf = null;
  }

  public void setArray(int i, Array x)
    throws SQLException
  {
    throw new NotImplemented();
  }

  public void setAsciiStream(int parameterIndex, InputStream x, int length)
    throws SQLException
  {
    if (x == null)
      setNull(parameterIndex, 12);
    else
      setBinaryStream(parameterIndex, x, length);
  }

  public void setBigDecimal(int parameterIndex, BigDecimal x)
    throws SQLException
  {
    if (x == null)
      setNull(parameterIndex, 3);
    else
      setInternal(parameterIndex, StringUtils.fixDecimalExponent(StringUtils.consistentToString(x)));
  }

  public void setBinaryStream(int parameterIndex, InputStream x, int length)
    throws SQLException
  {
    if (x == null) {
      setNull(parameterIndex, -2);
    } else {
      int parameterIndexOffset = getParameterIndexOffset();

      if ((parameterIndex < 1) || (parameterIndex > this.staticSqlStrings.length))
      {
        throw SQLError.createSQLException(Messages.getString("PreparedStatement.2") + parameterIndex + Messages.getString("PreparedStatement.3") + this.staticSqlStrings.length + Messages.getString("PreparedStatement.4"), "S1009");
      }

      if ((parameterIndexOffset == -1) && (parameterIndex == 1)) {
        throw SQLError.createSQLException("Can't set IN parameter for return value of stored function call.", "S1009");
      }

      this.parameterStreams[(parameterIndex - 1 + parameterIndexOffset)] = x;
      this.isStream[(parameterIndex - 1 + parameterIndexOffset)] = true;
      this.streamLengths[(parameterIndex - 1 + parameterIndexOffset)] = length;
      this.isNull[(parameterIndex - 1 + parameterIndexOffset)] = false;
    }
  }

  public void setBlob(int i, Blob x)
    throws SQLException
  {
    if (x == null) {
      setNull(i, 2004);
    } else {
      ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();

      bytesOut.write(39);
      escapeblockFast(x.getBytes(1L, (int)x.length()), bytesOut, (int)x.length());

      bytesOut.write(39);

      setInternal(i, bytesOut.toByteArray());
    }
  }

  public void setBoolean(int parameterIndex, boolean x)
    throws SQLException
  {
    if (this.useTrueBoolean)
      setInternal(parameterIndex, x ? "1" : "0");
    else
      setInternal(parameterIndex, x ? "'t'" : "'f'");
  }

  public void setByte(int parameterIndex, byte x)
    throws SQLException
  {
    setInternal(parameterIndex, String.valueOf(x));
  }

  public void setBytes(int parameterIndex, byte[] x)
    throws SQLException
  {
    setBytes(parameterIndex, x, true, true);
  }

  protected void setBytes(int parameterIndex, byte[] x, boolean checkForIntroducer, boolean escapeForMBChars)
    throws SQLException
  {
    if (x == null) {
      setNull(parameterIndex, -2);
    } else {
      String connectionEncoding = this.connection.getEncoding();

      if ((this.connection.isNoBackslashEscapesSet()) || ((escapeForMBChars) && (this.connection.getUseUnicode()) && (connectionEncoding != null) && (CharsetMapping.isMultibyteCharset(connectionEncoding))))
      {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream(x.length * 2 + 3);

        bOut.write(120);
        bOut.write(39);

        for (int i = 0; i < x.length; i++) {
          int lowBits = (x[i] & 0xFF) / 16;
          int highBits = (x[i] & 0xFF) % 16;

          bOut.write(HEX_DIGITS[lowBits]);
          bOut.write(HEX_DIGITS[highBits]);
        }

        bOut.write(39);

        setInternal(parameterIndex, bOut.toByteArray());

        return;
      }

      int numBytes = x.length;

      int pad = 2;

      boolean needsIntroducer = (checkForIntroducer) && (this.connection.versionMeetsMinimum(4, 1, 0));

      if (needsIntroducer) {
        pad += 7;
      }

      ByteArrayOutputStream bOut = new ByteArrayOutputStream(numBytes + pad);

      if (needsIntroducer) {
        bOut.write(95);
        bOut.write(98);
        bOut.write(105);
        bOut.write(110);
        bOut.write(97);
        bOut.write(114);
        bOut.write(121);
      }
      bOut.write(39);

      for (int i = 0; i < numBytes; i++) {
        byte b = x[i];

        switch (b) {
        case 0:
          bOut.write(92);
          bOut.write(48);

          break;
        case 10:
          bOut.write(92);
          bOut.write(110);

          break;
        case 13:
          bOut.write(92);
          bOut.write(114);

          break;
        case 92:
          bOut.write(92);
          bOut.write(92);

          break;
        case 39:
          bOut.write(92);
          bOut.write(39);

          break;
        case 34:
          bOut.write(92);
          bOut.write(34);

          break;
        case 26:
          bOut.write(92);
          bOut.write(90);

          break;
        default:
          bOut.write(b);
        }
      }

      bOut.write(39);

      setInternal(parameterIndex, bOut.toByteArray());
    }
  }

  protected void setBytesNoEscape(int parameterIndex, byte[] parameterAsBytes)
    throws SQLException
  {
    byte[] parameterWithQuotes = new byte[parameterAsBytes.length + 2];
    parameterWithQuotes[0] = 39;
    System.arraycopy(parameterAsBytes, 0, parameterWithQuotes, 1, parameterAsBytes.length);

    parameterWithQuotes[(parameterAsBytes.length + 1)] = 39;

    setInternal(parameterIndex, parameterWithQuotes);
  }

  protected void setBytesNoEscapeNoQuotes(int parameterIndex, byte[] parameterAsBytes) throws SQLException
  {
    setInternal(parameterIndex, parameterAsBytes);
  }

  public void setCharacterStream(int parameterIndex, Reader reader, int length)
    throws SQLException
  {
    try
    {
      if (reader == null) {
        setNull(parameterIndex, -1);
      } else {
        char[] c = null;
        int len = 0;

        boolean useLength = this.connection.getUseStreamLengthsInPrepStmts();

        String forcedEncoding = this.connection.getClobCharacterEncoding();

        if ((useLength) && (length != -1)) {
          c = new char[length];

          int numCharsRead = readFully(reader, c, length);

          if (forcedEncoding == null)
            setString(parameterIndex, new String(c, 0, numCharsRead));
          else
            try {
              setBytes(parameterIndex, new String(c, 0, numCharsRead).getBytes(forcedEncoding));
            }
            catch (UnsupportedEncodingException uee)
            {
              throw SQLError.createSQLException("Unsupported character encoding " + forcedEncoding, "S1009");
            }
        }
        else
        {
          c = new char[4096];

          StringBuffer buf = new StringBuffer();

          while ((len = reader.read(c)) != -1) {
            buf.append(c, 0, len);
          }

          if (forcedEncoding == null)
            setString(parameterIndex, buf.toString());
          else
            try {
              setBytes(parameterIndex, buf.toString().getBytes(forcedEncoding));
            }
            catch (UnsupportedEncodingException uee) {
              throw SQLError.createSQLException("Unsupported character encoding " + forcedEncoding, "S1009");
            }
        }
      }
    }
    catch (IOException ioEx)
    {
      throw SQLError.createSQLException(ioEx.toString(), "S1000");
    }
  }

  public void setClob(int i, Clob x)
    throws SQLException
  {
    if (x == null) {
      setNull(i, 2005);

      return;
    }

    String forcedEncoding = this.connection.getClobCharacterEncoding();

    if (forcedEncoding == null)
      setString(i, x.getSubString(1L, (int)x.length()));
    else
      try {
        setBytes(i, x.getSubString(1L, (int)x.length()).getBytes(forcedEncoding));
      }
      catch (UnsupportedEncodingException uee) {
        throw SQLError.createSQLException("Unsupported character encoding " + forcedEncoding, "S1009");
      }
  }

  public void setDate(int parameterIndex, java.sql.Date x)
    throws SQLException
  {
    if (x == null) {
      setNull(parameterIndex, 91);
    }
    else
    {
      SimpleDateFormat dateFormatter = new SimpleDateFormat("''yyyy-MM-dd''", Locale.US);

      setInternal(parameterIndex, dateFormatter.format(x));
    }
  }

  public void setDate(int parameterIndex, java.sql.Date x, Calendar cal)
    throws SQLException
  {
    setDate(parameterIndex, x);
  }

  public void setDouble(int parameterIndex, double x)
    throws SQLException
  {
    if ((!this.connection.getAllowNanAndInf()) && ((x == (1.0D / 0.0D)) || (x == (-1.0D / 0.0D)) || (Double.isNaN(x))))
    {
      throw SQLError.createSQLException("'" + x + "' is not a valid numeric or approximate numeric value", "S1009");
    }

    setInternal(parameterIndex, StringUtils.fixDecimalExponent(String.valueOf(x)));
  }

  public void setFloat(int parameterIndex, float x)
    throws SQLException
  {
    setInternal(parameterIndex, StringUtils.fixDecimalExponent(String.valueOf(x)));
  }

  public void setInt(int parameterIndex, int x)
    throws SQLException
  {
    setInternal(parameterIndex, String.valueOf(x));
  }

  private final void setInternal(int paramIndex, byte[] val) throws SQLException
  {
    if (this.isClosed) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.48"), "S1009");
    }

    int parameterIndexOffset = getParameterIndexOffset();

    if (paramIndex < 1) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.49") + paramIndex + Messages.getString("PreparedStatement.50"), "S1009");
    }

    if (paramIndex > this.parameterCount) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.51") + paramIndex + Messages.getString("PreparedStatement.52") + this.parameterValues.length + Messages.getString("PreparedStatement.53"), "S1009");
    }

    if ((parameterIndexOffset == -1) && (paramIndex == 1)) {
      throw SQLError.createSQLException("Can't set IN parameter for return value of stored function call.", "S1009");
    }

    this.isStream[(paramIndex - 1 + parameterIndexOffset)] = false;
    this.isNull[(paramIndex - 1 + parameterIndexOffset)] = false;
    this.parameterStreams[(paramIndex - 1 + parameterIndexOffset)] = null;
    this.parameterValues[(paramIndex - 1 + parameterIndexOffset)] = val;
  }

  private final void setInternal(int paramIndex, String val) throws SQLException
  {
    checkClosed();

    byte[] parameterAsBytes = null;

    if (this.charConverter != null)
      parameterAsBytes = this.charConverter.toBytes(val);
    else {
      parameterAsBytes = StringUtils.getBytes(val, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
    }

    setInternal(paramIndex, parameterAsBytes);
  }

  public void setLong(int parameterIndex, long x)
    throws SQLException
  {
    setInternal(parameterIndex, String.valueOf(x));
  }

  public void setNull(int parameterIndex, int sqlType)
    throws SQLException
  {
    setInternal(parameterIndex, "null");
    this.isNull[(parameterIndex - 1)] = true;
  }

  public void setNull(int parameterIndex, int sqlType, String arg)
    throws SQLException
  {
    setNull(parameterIndex, sqlType);
  }

  private void setNumericObject(int parameterIndex, Object parameterObj, int targetSqlType, int scale)
    throws SQLException
  {
    Number parameterAsNum;
    Number parameterAsNum;
    if ((parameterObj instanceof Boolean)) {
      parameterAsNum = ((Boolean)parameterObj).booleanValue() ? new Integer(1) : new Integer(0);
    }
    else if ((parameterObj instanceof String))
    {
      Number parameterAsNum;
      Number parameterAsNum;
      Number parameterAsNum;
      Number parameterAsNum;
      Number parameterAsNum;
      Number parameterAsNum;
      switch (targetSqlType) {
      case -7:
        boolean parameterAsBoolean = "true".equalsIgnoreCase((String)parameterObj);

        parameterAsNum = parameterAsBoolean ? new Integer(1) : new Integer(0);

        break;
      case -6:
      case 4:
      case 5:
        parameterAsNum = Integer.valueOf((String)parameterObj);

        break;
      case -5:
        parameterAsNum = Long.valueOf((String)parameterObj);

        break;
      case 7:
        parameterAsNum = Float.valueOf((String)parameterObj);

        break;
      case 6:
      case 8:
        parameterAsNum = Double.valueOf((String)parameterObj);

        break;
      case -4:
      case -3:
      case -2:
      case -1:
      case 0:
      case 1:
      case 2:
      case 3:
      default:
        parameterAsNum = new BigDecimal((String)parameterObj); break;
      }
    }
    else {
      parameterAsNum = (Number)parameterObj;
    }

    switch (targetSqlType) {
    case -7:
    case -6:
    case 4:
    case 5:
      setInt(parameterIndex, parameterAsNum.intValue());

      break;
    case -5:
      setLong(parameterIndex, parameterAsNum.longValue());

      break;
    case 7:
      setFloat(parameterIndex, parameterAsNum.floatValue());

      break;
    case 6:
    case 8:
      setDouble(parameterIndex, parameterAsNum.doubleValue());

      break;
    case 2:
    case 3:
      if ((parameterAsNum instanceof BigDecimal)) {
        BigDecimal scaledBigDecimal = null;
        try
        {
          scaledBigDecimal = ((BigDecimal)parameterAsNum).setScale(scale);
        }
        catch (ArithmeticException ex) {
          try {
            scaledBigDecimal = ((BigDecimal)parameterAsNum).setScale(scale, 4);
          }
          catch (ArithmeticException arEx)
          {
            throw SQLError.createSQLException("Can't set scale of '" + scale + "' for DECIMAL argument '" + parameterAsNum + "'", "S1009");
          }

        }

        setBigDecimal(parameterIndex, scaledBigDecimal);
      } else if ((parameterAsNum instanceof BigInteger)) {
        setBigDecimal(parameterIndex, new BigDecimal((BigInteger)parameterAsNum, scale));
      }
      else
      {
        setBigDecimal(parameterIndex, new BigDecimal(parameterAsNum.doubleValue()));
      }
      break;
    case -4:
    case -3:
    case -2:
    case -1:
    case 0:
    case 1:
    }
  }

  public void setObject(int parameterIndex, Object parameterObj)
    throws SQLException
  {
    if (parameterObj == null) {
      setNull(parameterIndex, 1111);
    }
    else if ((parameterObj instanceof Byte))
      setInt(parameterIndex, ((Byte)parameterObj).intValue());
    else if ((parameterObj instanceof String))
      setString(parameterIndex, (String)parameterObj);
    else if ((parameterObj instanceof BigDecimal))
      setBigDecimal(parameterIndex, (BigDecimal)parameterObj);
    else if ((parameterObj instanceof Short))
      setShort(parameterIndex, ((Short)parameterObj).shortValue());
    else if ((parameterObj instanceof Integer))
      setInt(parameterIndex, ((Integer)parameterObj).intValue());
    else if ((parameterObj instanceof Long))
      setLong(parameterIndex, ((Long)parameterObj).longValue());
    else if ((parameterObj instanceof Float))
      setFloat(parameterIndex, ((Float)parameterObj).floatValue());
    else if ((parameterObj instanceof Double))
      setDouble(parameterIndex, ((Double)parameterObj).doubleValue());
    else if ((parameterObj instanceof byte[]))
      setBytes(parameterIndex, (byte[])parameterObj);
    else if ((parameterObj instanceof java.sql.Date))
      setDate(parameterIndex, (java.sql.Date)parameterObj);
    else if ((parameterObj instanceof Time))
      setTime(parameterIndex, (Time)parameterObj);
    else if ((parameterObj instanceof Timestamp))
      setTimestamp(parameterIndex, (Timestamp)parameterObj);
    else if ((parameterObj instanceof Boolean)) {
      setBoolean(parameterIndex, ((Boolean)parameterObj).booleanValue());
    }
    else if ((parameterObj instanceof InputStream))
      setBinaryStream(parameterIndex, (InputStream)parameterObj, -1);
    else if ((parameterObj instanceof Blob))
      setBlob(parameterIndex, (Blob)parameterObj);
    else if ((parameterObj instanceof Clob))
      setClob(parameterIndex, (Clob)parameterObj);
    else if ((this.connection.getTreatUtilDateAsTimestamp()) && ((parameterObj instanceof java.util.Date)))
    {
      setTimestamp(parameterIndex, new Timestamp(((java.util.Date)parameterObj).getTime()));
    }
    else if ((parameterObj instanceof BigInteger))
      setString(parameterIndex, parameterObj.toString());
    else
      setSerializableObject(parameterIndex, parameterObj);
  }

  public void setObject(int parameterIndex, Object parameterObj, int targetSqlType)
    throws SQLException
  {
    if (!(parameterObj instanceof BigDecimal))
      setObject(parameterIndex, parameterObj, targetSqlType, 0);
    else
      setObject(parameterIndex, parameterObj, targetSqlType, ((BigDecimal)parameterObj).scale());
  }

  public void setObject(int parameterIndex, Object parameterObj, int targetSqlType, int scale)
    throws SQLException
  {
    if (parameterObj == null)
      setNull(parameterIndex, 1111);
    else
      try {
        switch (targetSqlType)
        {
        case 16:
          if ((parameterObj instanceof Boolean)) {
            setBoolean(parameterIndex, ((Boolean)parameterObj).booleanValue());
          }
          else if ((parameterObj instanceof String)) {
            setBoolean(parameterIndex, ("true".equalsIgnoreCase((String)parameterObj)) || (!"0".equalsIgnoreCase((String)parameterObj)));
          }
          else if ((parameterObj instanceof Number)) {
            int intValue = ((Number)parameterObj).intValue();

            setBoolean(parameterIndex, intValue != 0);
          }
          else
          {
            throw SQLError.createSQLException("No conversion from " + parameterObj.getClass().getName() + " to Types.BOOLEAN possible.", "S1009");
          }

          break;
        case -7:
        case -6:
        case -5:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
          setNumericObject(parameterIndex, parameterObj, targetSqlType, scale);

          break;
        case -1:
        case 1:
        case 12:
          if ((parameterObj instanceof BigDecimal)) {
            setString(parameterIndex, StringUtils.fixDecimalExponent(StringUtils.consistentToString((BigDecimal)parameterObj)));
          }
          else
          {
            setString(parameterIndex, parameterObj.toString());
          }

          break;
        case 2005:
          if ((parameterObj instanceof Clob))
            setClob(parameterIndex, (Clob)parameterObj);
          else {
            setString(parameterIndex, parameterObj.toString());
          }

          break;
        case -4:
        case -3:
        case -2:
        case 2004:
          if ((parameterObj instanceof byte[]))
            setBytes(parameterIndex, (byte[])parameterObj);
          else if ((parameterObj instanceof Blob))
            setBlob(parameterIndex, (Blob)parameterObj);
          else {
            setBytes(parameterIndex, StringUtils.getBytes(parameterObj.toString(), this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode()));
          }

          break;
        case 91:
        case 93:
          java.util.Date parameterAsDate;
          java.util.Date parameterAsDate;
          if ((parameterObj instanceof String)) {
            ParsePosition pp = new ParsePosition(0);
            DateFormat sdf = new SimpleDateFormat(getDateTimePattern((String)parameterObj, false), Locale.US);

            parameterAsDate = sdf.parse((String)parameterObj, pp);
          } else {
            parameterAsDate = (java.util.Date)parameterObj;
          }

          switch (targetSqlType)
          {
          case 91:
            if ((parameterAsDate instanceof java.sql.Date)) {
              setDate(parameterIndex, (java.sql.Date)parameterAsDate);
            }
            else {
              setDate(parameterIndex, new java.sql.Date(parameterAsDate.getTime()));
            }

            break;
          case 93:
            if ((parameterAsDate instanceof Timestamp)) {
              setTimestamp(parameterIndex, (Timestamp)parameterAsDate);
            }
            else {
              setTimestamp(parameterIndex, new Timestamp(parameterAsDate.getTime()));
            }

            break;
          }

          break;
        case 92:
          if ((parameterObj instanceof String)) {
            DateFormat sdf = new SimpleDateFormat(getDateTimePattern((String)parameterObj, true), Locale.US);

            setTime(parameterIndex, new Time(sdf.parse((String)parameterObj).getTime()));
          }
          else if ((parameterObj instanceof Timestamp)) {
            Timestamp xT = (Timestamp)parameterObj;
            setTime(parameterIndex, new Time(xT.getTime()));
          } else {
            setTime(parameterIndex, (Time)parameterObj);
          }

          break;
        case 1111:
          setSerializableObject(parameterIndex, parameterObj);

          break;
        default:
          throw SQLError.createSQLException(Messages.getString("PreparedStatement.16"), "S1000");
        }
      }
      catch (Exception ex)
      {
        if ((ex instanceof SQLException)) {
          throw ((SQLException)ex);
        }

        throw SQLError.createSQLException(Messages.getString("PreparedStatement.17") + parameterObj.getClass().toString() + Messages.getString("PreparedStatement.18") + ex.getClass().getName() + Messages.getString("PreparedStatement.19") + ex.getMessage(), "S1000");
      }
  }

  protected int setOneBatchedParameterSet(java.sql.PreparedStatement batchedStatement, int batchedParamIndex, Object paramSet)
    throws SQLException
  {
    BatchParams paramArg = (BatchParams)paramSet;

    boolean[] isNullBatch = paramArg.isNull;
    boolean[] isStreamBatch = paramArg.isStream;

    for (int j = 0; j < isNullBatch.length; j++) {
      if (isNullBatch[j] != 0) {
        batchedStatement.setNull(batchedParamIndex++, 0);
      }
      else if (isStreamBatch[j] != 0) {
        batchedStatement.setBinaryStream(batchedParamIndex++, paramArg.parameterStreams[j], paramArg.streamLengths[j]);
      }
      else
      {
        ((PreparedStatement)batchedStatement).setBytesNoEscapeNoQuotes(batchedParamIndex++, paramArg.parameterStrings[j]);
      }

    }

    return batchedParamIndex;
  }

  public void setRef(int i, Ref x)
    throws SQLException
  {
    throw new NotImplemented();
  }

  void setResultSetConcurrency(int concurrencyFlag)
  {
    this.resultSetConcurrency = concurrencyFlag;
  }

  void setResultSetType(int typeFlag)
  {
    this.resultSetType = typeFlag;
  }

  protected void setRetrieveGeneratedKeys(boolean retrieveGeneratedKeys)
  {
    this.retrieveGeneratedKeys = retrieveGeneratedKeys;
  }

  private final void setSerializableObject(int parameterIndex, Object parameterObj)
    throws SQLException
  {
    try
    {
      ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
      ObjectOutputStream objectOut = new ObjectOutputStream(bytesOut);
      objectOut.writeObject(parameterObj);
      objectOut.flush();
      objectOut.close();
      bytesOut.flush();
      bytesOut.close();

      byte[] buf = bytesOut.toByteArray();
      ByteArrayInputStream bytesIn = new ByteArrayInputStream(buf);
      setBinaryStream(parameterIndex, bytesIn, buf.length);
    } catch (Exception ex) {
      throw SQLError.createSQLException(Messages.getString("PreparedStatement.54") + ex.getClass().getName(), "S1009");
    }
  }

  public void setShort(int parameterIndex, short x)
    throws SQLException
  {
    setInternal(parameterIndex, String.valueOf(x));
  }

  public void setString(int parameterIndex, String x)
    throws SQLException
  {
    if (x == null) {
      setNull(parameterIndex, 1);
    } else {
      checkClosed();

      int stringLength = x.length();

      if (this.connection.isNoBackslashEscapesSet())
      {
        boolean needsHexEscape = false;

        for (int i = 0; i < stringLength; i++) {
          char c = x.charAt(i);

          switch (c)
          {
          case '\000':
            needsHexEscape = true;
            break;
          case '\n':
            needsHexEscape = true;

            break;
          case '\r':
            needsHexEscape = true;
            break;
          case '\\':
            needsHexEscape = true;

            break;
          case '\'':
            needsHexEscape = true;

            break;
          case '"':
            needsHexEscape = true;

            break;
          case '\032':
            needsHexEscape = true;
          }

          if (needsHexEscape)
          {
            break;
          }

        }

        if (!needsHexEscape) {
          byte[] parameterAsBytes = null;

          StringBuffer quotedString = new StringBuffer(x.length() + 2);
          quotedString.append('\'');
          quotedString.append(x);
          quotedString.append('\'');

          if (!this.isLoadDataQuery) {
            parameterAsBytes = StringUtils.getBytes(quotedString.toString(), this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
          }
          else
          {
            parameterAsBytes = quotedString.toString().getBytes();
          }

          setInternal(parameterIndex, parameterAsBytes);
        } else {
          byte[] parameterAsBytes = null;

          if (!this.isLoadDataQuery) {
            parameterAsBytes = StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
          }
          else
          {
            parameterAsBytes = x.getBytes();
          }

          setBytes(parameterIndex, parameterAsBytes);
        }

        return;
      }

      StringBuffer buf = new StringBuffer((int)(x.length() * 1.1D));
      buf.append('\'');

      for (int i = 0; i < stringLength; i++) {
        char c = x.charAt(i);

        switch (c) {
        case '\000':
          buf.append('\\');
          buf.append('0');

          break;
        case '\n':
          buf.append('\\');
          buf.append('n');

          break;
        case '\r':
          buf.append('\\');
          buf.append('r');

          break;
        case '\\':
          buf.append('\\');
          buf.append('\\');

          break;
        case '\'':
          buf.append('\\');
          buf.append('\'');

          break;
        case '"':
          if (this.usingAnsiMode) {
            buf.append('\\');
          }

          buf.append('"');

          break;
        case '\032':
          buf.append('\\');
          buf.append('Z');

          break;
        default:
          buf.append(c);
        }
      }

      buf.append('\'');

      String parameterAsString = buf.toString();

      byte[] parameterAsBytes = null;

      if (!this.isLoadDataQuery) {
        parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
      }
      else
      {
        parameterAsBytes = parameterAsString.getBytes();
      }

      setInternal(parameterIndex, parameterAsBytes);
    }
  }

  public void setTime(int parameterIndex, Time x, Calendar cal)
    throws SQLException
  {
    setTimeInternal(parameterIndex, x, cal, cal.getTimeZone(), true);
  }

  public void setTime(int parameterIndex, Time x)
    throws SQLException
  {
    setTimeInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false);
  }

  private void setTimeInternal(int parameterIndex, Time x, Calendar targetCalendar, TimeZone tz, boolean rollForward)
    throws SQLException
  {
    if (x == null) {
      setNull(parameterIndex, 92);
    } else {
      checkClosed();

      Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();

      synchronized (sessionCalendar) {
        x = TimeUtil.changeTimezone(this.connection, sessionCalendar, targetCalendar, x, tz, this.connection.getServerTimezoneTZ(), rollForward);
      }

      setInternal(parameterIndex, "'" + x.toString() + "'");
    }
  }

  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
    throws SQLException
  {
    setTimestampInternal(parameterIndex, x, cal, cal.getTimeZone(), true);
  }

<

你可能感兴趣的:(Java基础知识)