📄 serverpreparedstatement.java
字号:
this.outByteBuffer.clear(); int originalPosition = this.outByteBuffer.getPosition(); storeBinding(this.outByteBuffer, bindValue, this.connection.getIO()); int newPosition = this.outByteBuffer.getPosition(); int length = newPosition - originalPosition; byte[] valueAsBytes = new byte[length]; System.arraycopy(this.outByteBuffer.getByteBuffer(), originalPosition, valueAsBytes, 0, length); return valueAsBytes; } } /** * @see com.mysql.jdbc.PreparedStatement#isNull(int) */ boolean isNull(int paramIndex) { throw new IllegalArgumentException(Messages.getString( "ServerPreparedStatement.7")); //$NON-NLS-1$ } private BindValue getBinding(int parameterIndex, boolean forLongData) throws SQLException { if (this.parameterBindings.length == 0) { throw new SQLException(Messages.getString( "ServerPreparedStatement.8"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } parameterIndex--; if ((parameterIndex < 0) || (parameterIndex >= this.parameterBindings.length)) { throw new SQLException(Messages.getString( "ServerPreparedStatement.9") //$NON-NLS-1$ +(parameterIndex + 1) + Messages.getString("ServerPreparedStatement.10") //$NON-NLS-1$ +this.parameterBindings.length, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } if (this.parameterBindings[parameterIndex] == null) { this.parameterBindings[parameterIndex] = new BindValue(); } else { if (this.parameterBindings[parameterIndex].isLongData && !forLongData) { this.detectedLongParameterSwitch = true; } } this.parameterBindings[parameterIndex].isSet = true; return this.parameterBindings[parameterIndex]; } private void setType(BindValue oldValue, int bufferType) { if (oldValue.bufferType != bufferType) { this.sendTypesToServer = true; } oldValue.bufferType = bufferType; } private void clearParametersInternal(boolean clearServerParameters) throws SQLException { boolean hadLongData = false; if (this.parameterBindings != null) { for (int i = 0; i < this.parameterCount; i++) { if ((this.parameterBindings[i] != null) && this.parameterBindings[i].isLongData) { hadLongData = true; } this.parameterBindings[i].reset(); } } if (clearServerParameters && hadLongData) { serverResetStatement(); this.detectedLongParameterSwitch = false; } } /** * Tells the server to execute this prepared statement with the current * parameter bindings. * <pre> * * - Server gets the command 'COM_EXECUTE' to execute the * previously prepared query. If there is any param markers; * then client will send the data in the following format: * * [COM_EXECUTE:1] * [STMT_ID:4] * [NULL_BITS:(param_count+7)/8)] * [TYPES_SUPPLIED_BY_CLIENT(0/1):1] * [[length]data] * [[length]data] .. [[length]data]. * * (Note: Except for string/binary types; all other types will not be * supplied with length field) * * </pre> * * @param maxRowsToRetrieve DOCUMENT ME! * @param createStreamingResultSet DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SQLException */ private com.mysql.jdbc.ResultSet serverExecute(int maxRowsToRetrieve, boolean createStreamingResultSet) throws SQLException { synchronized (this.connection.getMutex()) { if (this.detectedLongParameterSwitch) { throw new SQLException(Messages.getString( "ServerPreparedStatement.11") //$NON-NLS-1$ +Messages.getString("ServerPreparedStatement.12"), //$NON-NLS-1$ SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); } // Check bindings for (int i = 0; i < this.parameterCount; i++) { if (!this.parameterBindings[i].isSet) { throw new SQLException(Messages.getString( "ServerPreparedStatement.13") + (i + 1) //$NON-NLS-1$ +Messages.getString("ServerPreparedStatement.14"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } MysqlIO mysql = this.connection.getIO(); Buffer packet = mysql.getSharedSendPacket(); packet.clear(); packet.writeByte((byte) MysqlDefs.COM_EXECUTE); packet.writeLong(this.serverStatementId); if (this.connection.versionMeetsMinimum(4, 1, 2)) { packet.writeByte((byte) 0); // placeholder for flags packet.writeLong(1); // placeholder for parameter iterations } /* Reserve place for null-marker bytes */ int nullCount = (this.parameterCount + 7) / 8; //if (mysql.versionMeetsMinimum(4, 1, 2)) { // nullCount = (this.parameterCount + 9) / 8; //} int nullBitsPosition = packet.getPosition(); for (int i = 0; i < nullCount; i++) { packet.writeByte((byte) 0); } byte[] nullBitsBuffer = new byte[nullCount]; /* In case if buffers (type) altered, indicate to server */ packet.writeByte(this.sendTypesToServer ? (byte) 1 : (byte) 0); if (this.sendTypesToServer) { /* Store types of parameters in first in first package that is sent to the server. */ for (int i = 0; i < this.parameterCount; i++) { packet.writeInt(this.parameterBindings[i].bufferType); } } // // store the parameter values // for (int i = 0; i < this.parameterCount; i++) { if (!this.parameterBindings[i].isLongData) { if (!this.parameterBindings[i].isNull) { storeBinding(packet, this.parameterBindings[i], mysql); } else { nullBitsBuffer[i / 8] |= (1 << (i & 7)); } } } // // Go back and write the NULL flags // to the beginning of the packet // int endPosition = packet.getPosition(); packet.setPosition(nullBitsPosition); packet.writeBytesNoNull(nullBitsBuffer); packet.setPosition(endPosition); long begin = 0; if (this.connection.getProfileSql() || this.connection.getLogSlowQueries() || this.connection.getGatherPerformanceMetrics()) { begin = System.currentTimeMillis(); } Buffer resultPacket = mysql.sendCommand(MysqlDefs.COM_EXECUTE, null, packet, false, null); if (this.connection.getLogSlowQueries() || this.connection.getGatherPerformanceMetrics()) { long elapsedTime = System.currentTimeMillis() - begin; if (this.connection.getLogSlowQueries() && (elapsedTime > this.connection.getSlowQueryThresholdMillis())) { StringBuffer mesgBuf = new StringBuffer(48 + this.originalSql.length()); mesgBuf.append(Messages.getString( "ServerPreparedStatement.15")); //$NON-NLS-1$ mesgBuf.append(this.connection.getSlowQueryThresholdMillis()); mesgBuf.append(Messages.getString( "ServerPreparedStatement.16")); //$NON-NLS-1$ mesgBuf.append(this.originalSql); this.connection.getLog().logWarn(mesgBuf.toString()); if (this.connection.getExplainSlowQueries()) { String queryAsString = asSql(); mysql.explainSlowQuery(queryAsString.getBytes(), queryAsString); } } if (this.connection.getGatherPerformanceMetrics()) { this.connection.registerQueryExecutionTime(elapsedTime); } } this.connection.incrementNumberOfPreparedExecutes(); if (this.connection.getProfileSql()) { this.eventSink = ProfileEventSink.getInstance(this.connection); this.eventSink.consumeEvent(new ProfilerEvent( ProfilerEvent.TYPE_EXECUTE, "", this.currentCatalog, //$NON-NLS-1$ this.connection.getId(), this.statementId, -1, System.currentTimeMillis(), (int) (System.currentTimeMillis() - begin), null, new Throwable(), null)); } com.mysql.jdbc.ResultSet rs = mysql.readAllResults(this, maxRowsToRetrieve, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, resultPacket, true, this.fieldCount, true); if (!createStreamingResultSet) { serverResetStatement(); // clear any long data... } this.sendTypesToServer = false; this.results = rs; return rs; } } /** * Sends stream-type data parameters to the server. * <pre> * Long data handling: * * - Server gets the long data in pieces with command type 'COM_LONG_DATA'. * - The packet recieved will have the format as: * [COM_LONG_DATA: 1][STMT_ID:4][parameter_number:2][type:2][data] * - Checks if the type is specified by client, and if yes reads the type, * and stores the data in that format. * - It's up to the client to check for read data ended. The server doesn't * care; and also server doesn't notify to the client that it got the * data or not; if there is any error; then during execute; the error * will be returned * </pre> * * @param parameterIndex DOCUMENT ME! * @param longData DOCUMENT ME! * * @throws SQLException if an error occurs. */ private void serverLongData(int parameterIndex, BindValue longData) throws SQLException { synchronized (this.connection.getMutex()) { MysqlIO mysql = this.connection.getIO(); Buffer packet = mysql.getSharedSendPacket(); packet.clear(); packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); packet.writeLong(this.serverStatementId); packet.writeInt((parameterIndex - 1)); Object value = longData.value; if (value instanceof byte[]) { packet.writeBytesNoNull((byte[]) longData.value); } else if (value instanceof InputStream) { storeStream(packet, (InputStream) value); } else if (value instanceof java.sql.Blob) { storeStream(packet, ((java.sql.Blob) value).getBinaryStream()); } else if (value instanceof Reader) { storeReader(packet, (Reader) value); } else { throw new SQLException(Messages.getString( "ServerPreparedStatement.18") //$NON-NLS-1$ +value.getClass().getName() + "'", //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, null); } } private void serverPrepare(String sql) throws SQLException { synchronized (this.connection.getMutex()) { MysqlIO mysql = this.connection.getIO(); try { long begin = 0; if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) { //$NON-NLS-1$ this.isLoadDataQuery = true; } else { this.isLoadDataQuery = false; } if (this.connection.getProfileSql()) { begin = System.currentTimeMillis(); } String characterEncoding = null; String connectionEncoding = this.connection.getEncoding(); if (!this.isLoadDataQuery && this.connection.getUseUnicode() && (connectionEncoding != null)) { characterEncoding = connectionEncoding; } Buffer prepareResultPacket = mysql.sendCommand(MysqlDefs.COM_PREPARE, sql, null, false, characterEncoding); if (this.connection.versionMeetsMinimum(4, 1, 1)) { // 4.1.1 and newer use the first byte // as an 'ok' or 'error' flag, so move // the buffer pointer past it to // start reading the statement id. prepareResultPacket.setPosition(1); } else { // 4.1.0 doesn't use the first byte as an // 'ok' or 'error' flag prepareResultPacket.setPosition(0); } this.serverStatementId = prepareResultPacket.readLong(); this.fieldCount = prepareResultPacket.readInt(); this.parameterCount = prepareResultPacket.readInt(); this.parameterBindings = new BindValue[this.parameterCount]; for (int i = 0; i < this.parameterCount; i++) { this.parameterBindings[i] = new BindValue(); } this.connection.incrementNumberOfPrepares(); if (this.connection.getProfileSql()) { this.eventSink = ProfileEventSink.getInstance(this.connection);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -