📄 mysqlio.java
字号:
this.clientParam &= ~CLIENT_LONG_PASSWORD; } // // 4.1 has some differences in the protocol // if (versionMeetsMinimum(4, 1, 0)) { if (versionMeetsMinimum(4, 1, 1)) { this.clientParam |= CLIENT_PROTOCOL_41; this.has41NewNewProt = true; // Need this to get server status values this.clientParam |= CLIENT_TRANSACTIONS; // We always allow multiple result sets this.clientParam |= CLIENT_MULTI_RESULTS; // We allow the user to configure whether // or not they want to support multiple queries // (by default, this is disabled). if (this.connection.getAllowMultiQueries()) { this.clientParam |= CLIENT_MULTI_QUERIES; } } else { this.clientParam |= CLIENT_RESERVED; this.has41NewNewProt = false; } this.use41Extensions = true; } int passwordLength = 16; int userLength = 0; int databaseLength = 0; if (user != null) { userLength = user.length(); } if (database != null) { databaseLength = database.length(); } int packLength = (userLength + passwordLength + databaseLength) + 7 + HEADER_LENGTH; Buffer packet = null; if (!this.connection.getUseSSL()) { if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { this.clientParam |= CLIENT_SECURE_CONNECTION; if (versionMeetsMinimum(4, 1, 1)) { secureAuth411(null, packLength, user, password, database, true); } else { secureAuth(null, packLength, user, password, database, true); } } else { // Passwords can be 16 chars long packet = Buffer.allocateNew(packLength, this.useNewIo); if ((this.clientParam & CLIENT_RESERVED) != 0) { if (versionMeetsMinimum(4, 1, 1)) { packet.writeLong(this.clientParam); packet.writeLong(this.maxThreeBytes); // charset, JDBC will connect as 'latin1', // and use 'SET NAMES' to change to the desired // charset after the connection is established. packet.writeByte((byte) 8); // Set of bytes reserved for future use. packet.writeBytesNoNull(new byte[23]); } else { packet.writeLong(this.clientParam); packet.writeLong(this.maxThreeBytes); } } else { packet.writeInt((int) this.clientParam); packet.writeLongInt(this.maxThreeBytes); } // User/Password data packet.writeString(user); if (this.protocolVersion > 9) { packet.writeString(Util.newCrypt(password, this.seed)); } else { packet.writeString(Util.oldCrypt(password, this.seed)); } if (((this.serverCapabilities & CLIENT_CONNECT_WITH_DB) != 0) && (database != null) && (database.length() > 0)) { packet.writeString(database); } send(packet); } } else { negotiateSSLConnection(user, password, database, packLength); } // Check for errors, not for 4.1.1 or newer, // as the new auth protocol doesn't work that way // (see secureAuth411() for more details...) if (!versionMeetsMinimum(4, 1, 1)) { checkErrorPacket(); } // // Can't enable compression until after handshake // if (((this.serverCapabilities & CLIENT_COMPRESS) != 0) && this.connection.getUseCompression()) { // The following matches with ZLIB's // compress() this.deflater = new Deflater(); this.useCompression = true; this.mysqlInput = new CompressedInputStream(this.connection, this.mysqlInput); } if (((this.serverCapabilities & CLIENT_CONNECT_WITH_DB) == 0) && (database != null) && (database.length() > 0)) { try { sendCommand(MysqlDefs.INIT_DB, database, null, false, null); } catch (Exception ex) { throw new CommunicationsException(this.connection, this.lastPacketSentTimeMs, ex); } } } /** * Retrieve one row from the MySQL server. Note: this method is not * thread-safe, but it is only called from methods that are guarded by * synchronizing on this object. * * @param fields DOCUMENT ME! * @param columnCount DOCUMENT ME! * @param isBinaryEncoded DOCUMENT ME! * @param resultSetConcurrency DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SQLException DOCUMENT ME! */ final Object[] nextRow(Field[] fields, int columnCount, boolean isBinaryEncoded, int resultSetConcurrency) throws SQLException { // Get the next incoming packet, re-using the packet because // all the data we need gets copied out of it. Buffer rowPacket = checkErrorPacket(); if (!isBinaryEncoded) { // // Didn't read an error, so re-position to beginning // of packet in order to read result set data // rowPacket.setPosition(rowPacket.getPosition() - 1); if (!rowPacket.isLastDataPacket()) { byte[][] rowData = new byte[columnCount][]; int offset = 0; for (int i = 0; i < columnCount; i++) { rowData[i] = rowPacket.readLenByteArray(offset); } return rowData; } readServerStatusForResultSets(rowPacket); return null; } // // Handle binary-encoded data for server-side // PreparedStatements... // if (!rowPacket.isLastDataPacket()) { return unpackBinaryResultSetRow(fields, rowPacket, resultSetConcurrency); } readServerStatusForResultSets(rowPacket); return null; } /** * Log-off of the MySQL server and close the socket. * * @throws SQLException DOCUMENT ME! */ final void quit() throws SQLException { Buffer packet = Buffer.allocateNew(6, this.useNewIo); this.packetSequence = -1; packet.writeByte((byte) MysqlDefs.QUIT); send(packet); forceClose(); } /** * Returns the packet used for sending data (used by PreparedStatement) * Guarded by external synchronization on a mutex. * * @return A packet to send data with */ Buffer getSharedSendPacket() { if (this.sharedSendPacket == null) { if (this.useNewIo) { this.sharedSendPacket = Buffer.allocateDirect(this.connection.getNetBufferLength(), true); } else { this.sharedSendPacket = Buffer.allocateNew(this.connection.getNetBufferLength(), false); } } return this.sharedSendPacket; } void closeStreamer(RowData streamer) throws SQLException { if (this.streamingData == null) { throw new SQLException(Messages.getString("MysqlIO.17") //$NON-NLS-1$ +streamer + Messages.getString("MysqlIO.18")); //$NON-NLS-1$ } if (streamer != this.streamingData) { throw new SQLException(Messages.getString("MysqlIO.19") //$NON-NLS-1$ +streamer + Messages.getString("MysqlIO.20") //$NON-NLS-1$ +Messages.getString("MysqlIO.21") //$NON-NLS-1$ +Messages.getString("MysqlIO.22")); //$NON-NLS-1$ } this.streamingData = null; } ResultSet readAllResults(Statement callingStatement, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Buffer resultPacket, boolean isBinaryEncoded, long preSentColumnCount, boolean unpackFieldInfo) throws SQLException { resultPacket.setPosition(resultPacket.getPosition() - 1); ResultSet topLevelResultSet = readResultsForQueryOrUpdate(callingStatement, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, resultPacket, isBinaryEncoded, preSentColumnCount, unpackFieldInfo); ResultSet currentResultSet = topLevelResultSet; boolean checkForMoreResults = ((this.clientParam & CLIENT_MULTI_RESULTS) != 0); boolean serverHasMoreResults = (this.serverStatus & SERVER_MORE_RESULTS_EXISTS) != 0; // // TODO: We need to support streaming of multiple result sets // if (serverHasMoreResults && streamResults) { clearInputStream(); throw new SQLException(Messages.getString("MysqlIO.23"), //$NON-NLS-1$ SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); } boolean moreRowSetsExist = checkForMoreResults & serverHasMoreResults; while (moreRowSetsExist) { Buffer fieldPacket = readPacket(); if ((fieldPacket.readByte(0) == 0) && (fieldPacket.readByte(1) == 0) && (fieldPacket.readByte(2) == 0)) { break; } ResultSet newResultSet = readResultsForQueryOrUpdate(callingStatement, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, fieldPacket, isBinaryEncoded, preSentColumnCount, unpackFieldInfo); currentResultSet.setNextResultSet(newResultSet); currentResultSet = newResultSet; moreRowSetsExist = (this.serverStatus & SERVER_MORE_RESULTS_EXISTS) != 0; } if (!streamResults) { clearInputStream(); } reclaimLargeReusablePacket(); return topLevelResultSet; } /** * Sets the buffer size to max-buf */ void resetMaxBuf() { this.maxAllowedPacket = this.connection.getMaxAllowedPacket(); } /** * Send a command to the MySQL server If data is to be sent with command, * it should be put in extraData. * * Raw packets can be sent by setting queryPacket to something other * than null. * * @param command the MySQL protocol 'command' from MysqlDefs * @param extraData any 'string' data for the command * @param queryPacket a packet pre-loaded with data for the protocol (i.e. * from a client-side prepared statement). * @param skipCheck do not call checkErrorPacket() if true * @param extraDataCharEncoding the character encoding of the extraData * parameter. * * @return the response packet from the server * * @throws SQLException if an I/O error or SQL error occurs */ final Buffer sendCommand(int command, String extraData, Buffer queryPacket, boolean skipCheck, String extraDataCharEncoding) throws SQLException { // // We cache these locally, per-command, as the checks // for them are in very 'hot' sections of the I/O code // and we save 10-15% in overall performance by doing this... // this.enablePacketDebug = this.connection.getEnablePacketDebug(); this.traceProtocol = this.connection.getTraceProtocol(); this.readPacketSequence = 0; try { checkForOutstandingStreamingData(); // Clear serverStatus...this value is guarded by an // external mutex, as you can only ever be processing // one command at a time this.serverStatus = 0; this.hadWarnings = false; this.warningCount = 0; this.queryNoIndexUsed = false; this.queryBadIndexUsed = false; // // Compressed input stream needs cleared at beginning // of each command execution... // if (this.useCompression) { int bytesLeft = this.mysqlInput.available(); if (bytesLeft > 0) { this.mysqlInput.skip(bytesLeft); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -