📄 mysqlio.java
字号:
} } if (versionMeetsMinimum(4, 0, 8)) { this.maxThreeBytes = (256 * 256 * 256) - 1; this.useNewLargePackets = true; } else { this.maxThreeBytes = 255 * 255 * 255; this.useNewLargePackets = false; } this.colDecimalNeedsBump = versionMeetsMinimum(3, 23, 0); this.colDecimalNeedsBump = !versionMeetsMinimum(3, 23, 15); // guess? Not noted in changelog this.useNewUpdateCounts = versionMeetsMinimum(3, 22, 5); threadId = buf.readLong(); this.seed = buf.readString("ASCII"); this.serverCapabilities = 0; if (buf.getPosition() < buf.getBufLength()) { this.serverCapabilities = buf.readInt(); } if (versionMeetsMinimum(4, 1, 1)) { int position = buf.getPosition(); /* New protocol with 16 bytes to describe server characteristics */ this.serverCharsetIndex = buf.readByte() & 0xff; this.serverStatus = buf.readInt(); checkTransactionState(0); buf.setPosition(position + 16); String seedPart2 = buf.readString("ASCII"); StringBuffer newSeed = new StringBuffer(20); newSeed.append(this.seed); newSeed.append(seedPart2); this.seed = newSeed.toString(); } if (((this.serverCapabilities & CLIENT_COMPRESS) != 0) && this.connection.getUseCompression()) { this.clientParam |= CLIENT_COMPRESS; } this.useConnectWithDb = (database != null) && (database.length() > 0) && !this.connection.getCreateDatabaseIfNotExist(); if (this.useConnectWithDb) { this.clientParam |= CLIENT_CONNECT_WITH_DB; } if (((this.serverCapabilities & CLIENT_SSL) == 0) && this.connection.getUseSSL()) { if (this.connection.getRequireSSL()) { this.connection.close(); forceClose(); throw SQLError.createSQLException(Messages.getString("MysqlIO.15"), //$NON-NLS-1$ SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); } this.connection.setUseSSL(false); } if ((this.serverCapabilities & CLIENT_LONG_FLAG) != 0) { // We understand other column flags, as well this.clientParam |= CLIENT_LONG_FLAG; this.hasLongColumnInfo = true; } // return FOUND rows if (!this.connection.getUseAffectedRows()) { this.clientParam |= CLIENT_FOUND_ROWS; } if (this.connection.getAllowLoadLocalInfile()) { this.clientParam |= CLIENT_LOCAL_FILES; } if (this.isInteractiveClient) { this.clientParam |= CLIENT_INTERACTIVE; } // Authenticate if (this.protocolVersion > 9) { this.clientParam |= CLIENT_LONG_PASSWORD; // for long passwords } else { 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 = (user != null) ? user.length() : 0; int databaseLength = (database != null) ? database.length() : 0; int packLength = ((userLength + passwordLength + databaseLength) * 2) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; 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 = new Buffer(packLength); 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, CODE_PAGE_1252, this.connection); if (this.protocolVersion > 9) { packet.writeString(Util.newCrypt(password, this.seed), CODE_PAGE_1252, this.connection); } else { packet.writeString(Util.oldCrypt(password, this.seed), CODE_PAGE_1252, this.connection); } if (this.useConnectWithDb) { packet.writeString(database, CODE_PAGE_1252, this.connection); } send(packet, packet.getPosition()); } } 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.useConnectWithDb) { changeDatabaseTo(database); } try { this.mysqlConnection = this.socketFactory.afterHandshake(); } catch (IOException ioEx) { throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx); } } private void changeDatabaseTo(String database) throws SQLException { if (database == null || database.length() == 0) { return; } try { sendCommand(MysqlDefs.INIT_DB, database, null, false, null, 0); } catch (Exception ex) { if (this.connection.getCreateDatabaseIfNotExist()) { sendCommand(MysqlDefs.QUERY, "CREATE DATABASE IF NOT EXISTS " + database, null, false, null, 0); sendCommand(MysqlDefs.INIT_DB, database, null, false, null, 0); } else { throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, 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! * @param b * * @return DOCUMENT ME! * * @throws SQLException DOCUMENT ME! */ final ResultSetRow nextRow(Field[] fields, int columnCount, boolean isBinaryEncoded, int resultSetConcurrency, boolean useBufferRowIfPossible, boolean useBufferRowExplicit, boolean canReuseRowPacketForBufferRow, Buffer existingRowPacket) throws SQLException { if (this.useDirectRowUnpack && existingRowPacket == null && !isBinaryEncoded && !useBufferRowIfPossible && !useBufferRowExplicit) { return nextRowFast(fields, columnCount, isBinaryEncoded, resultSetConcurrency, useBufferRowIfPossible, useBufferRowExplicit, canReuseRowPacketForBufferRow); } Buffer rowPacket = null; if (existingRowPacket == null) { rowPacket = checkErrorPacket(); if (!useBufferRowExplicit && useBufferRowIfPossible) { if (rowPacket.getBufLength() > this.useBufferRowSizeThreshold) { useBufferRowExplicit = true; } } } else { // We attempted to do nextRowFast(), but the packet was a // multipacket, so we couldn't unpack it directly rowPacket = existingRowPacket; checkErrorPacket(existingRowPacket); } 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()) { if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE || (!useBufferRowIfPossible && !useBufferRowExplicit)) { byte[][] rowData = new byte[columnCount][]; for (int i = 0; i < columnCount; i++) { rowData[i] = rowPacket.readLenByteArray(0); } return new ByteArrayRow(rowData); } if (!canReuseRowPacketForBufferRow) { this.reusablePacket = new Buffer(rowPacket.getBufLength()); } return new BufferRow(rowPacket, fields, false); } readServerStatusForResultSets(rowPacket); return null; } // // Handle binary-encoded data for server-side // PreparedStatements... // if (!rowPacket.isLastDataPacket()) { if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE || (!useBufferRowIfPossible && !useBufferRowExplicit)) { return unpackBinaryResultSetRow(fields, rowPacket, resultSetConcurrency); } if (!canReuseRowPacketForBufferRow) { this.reusablePacket = new Buffer(rowPacket.getBufLength()); } return new BufferRow(rowPacket, fields, true); } rowPacket.setPosition(rowPacket.getPosition() - 1); readServerStatusForResultSets(rowPacket); return null; } final ResultSetRow nextRowFast(Field[] fields, int columnCount, boolean isBinaryEncoded, int resultSetConcurrency, boolean useBufferRowIfPossible, boolean useBufferRowExplicit, boolean canReuseRowPacket) throws SQLException { try { int lengthRead = readFully(this.mysqlInput, this.packetHeaderBuf, 0, 4); if (lengthRead < 4) { forceClose(); throw new RuntimeException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$ } int packetLength = (this.packetHeaderBuf[0] & 0xff) + ((this.packetHeaderBuf[1] & 0xff) << 8) + ((this.packetHeaderBuf[2] & 0xff) << 16); // Have we stumbled upon a multi-packet? if (packetLength == this.maxThreeBytes) { reuseAndReadPacket(this.reusablePacket, packetLength); // Go back to "old" way which uses packets return nextRow(fields, columnCount, isBinaryEncoded, resultSetConcurrency, useBufferRowIfPossible, useBufferRowExplicit, canReuseRowPacket, this.reusablePacket); } // Does this go over the threshold where we should use a BufferRow? if (packetLength > this.useBufferRowSizeThreshold) { reuseAndReadPacket(this.reusablePacket, packetLength); // Go back to "old" way which uses packets return nextRow(fields, columnCount, isBinaryEncoded, resultSetConcurrency, true, true, false, this.reusablePacket); } int remaining = packetLength; boolean firstTime = true; byte[][] rowData = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -