?? mysqlio.java
字號:
/* Copyright (C) 2002-2007 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. There are special exceptions to the terms and conditions of the GPL as it is applied to this software. View the full text of the exception in file EXCEPTIONS-CONNECTOR-J in the directory of this software distribution. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package com.mysql.jdbc;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream;import java.io.EOFException;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStreamWriter;import java.lang.ref.SoftReference;import java.math.BigInteger;import java.net.MalformedURLException;import java.net.Socket;import java.net.URL;import java.security.NoSuchAlgorithmException;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Types;import java.util.ArrayList;import java.util.Calendar;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Properties;import java.util.zip.Deflater;import com.mysql.jdbc.profiler.ProfileEventSink;import com.mysql.jdbc.profiler.ProfilerEvent;import com.mysql.jdbc.util.ReadAheadInputStream;import com.mysql.jdbc.util.ResultSetUtil;/** * This class is used by Connection for communicating with the MySQL server. * * @author Mark Matthews * @version $Id: MysqlIO.java 6613 2007-10-04 16:56:05Z mmatthews $ * * @see java.sql.Connection */class MysqlIO { private static final int UTF8_CHARSET_INDEX = 33; private static final String CODE_PAGE_1252 = "Cp1252"; protected static final int NULL_LENGTH = ~0; protected static final int COMP_HEADER_LENGTH = 3; protected static final int MIN_COMPRESS_LEN = 50; protected static final int HEADER_LENGTH = 4; protected static final int AUTH_411_OVERHEAD = 33; private static int maxBufferSize = 65535; private static final int CLIENT_COMPRESS = 32; /* Can use compression protcol */ protected static final int CLIENT_CONNECT_WITH_DB = 8; private static final int CLIENT_FOUND_ROWS = 2; private static final int CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ /* Found instead of affected rows */ private static final int CLIENT_LONG_FLAG = 4; /* Get all column flags */ private static final int CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */ private static final int CLIENT_PROTOCOL_41 = 512; // for > 4.1.1 private static final int CLIENT_INTERACTIVE = 1024; protected static final int CLIENT_SSL = 2048; private static final int CLIENT_TRANSACTIONS = 8192; // Client knows about transactions protected static final int CLIENT_RESERVED = 16384; // for 4.1.0 only protected static final int CLIENT_SECURE_CONNECTION = 32768; private static final int CLIENT_MULTI_QUERIES = 65536; // Enable/disable multiquery support private static final int CLIENT_MULTI_RESULTS = 131072; // Enable/disable multi-results private static final int SERVER_STATUS_IN_TRANS = 1; private static final int SERVER_STATUS_AUTOCOMMIT = 2; // Server in auto_commit mode private static final int SERVER_MORE_RESULTS_EXISTS = 8; // Multi query - next query exists private static final int SERVER_QUERY_NO_GOOD_INDEX_USED = 16; private static final int SERVER_QUERY_NO_INDEX_USED = 32; private static final int SERVER_STATUS_CURSOR_EXISTS = 64; private static final String FALSE_SCRAMBLE = "xxxxxxxx"; //$NON-NLS-1$ protected static final int MAX_QUERY_SIZE_TO_LOG = 1024; // truncate logging of queries at 1K protected static final int MAX_QUERY_SIZE_TO_EXPLAIN = 1024 * 1024; // don't explain queries above 1MB protected static final int INITIAL_PACKET_SIZE = 1024; /** * We store the platform 'encoding' here, only used to avoid munging * filenames for LOAD DATA LOCAL INFILE... */ private static String jvmPlatformCharset = null; /** * We need to have a 'marker' for all-zero datetimes so that ResultSet * can decide what to do based on connection setting */ protected final static String ZERO_DATE_VALUE_MARKER = "0000-00-00"; protected final static String ZERO_DATETIME_VALUE_MARKER = "0000-00-00 00:00:00"; static { OutputStreamWriter outWriter = null; // // Use the I/O system to get the encoding (if possible), to avoid // security restrictions on System.getProperty("file.encoding") in // applets (why is that restricted?) // try { outWriter = new OutputStreamWriter(new ByteArrayOutputStream()); jvmPlatformCharset = outWriter.getEncoding(); } finally { try { if (outWriter != null) { outWriter.close(); } } catch (IOException ioEx) { // ignore } } } /** Max number of bytes to dump when tracing the protocol */ private final static int MAX_PACKET_DUMP_LENGTH = 1024; private boolean packetSequenceReset = false; protected int serverCharsetIndex; // // Use this when reading in rows to avoid thousands of new() // calls, because the byte arrays just get copied out of the // packet anyway // private Buffer reusablePacket = null; private Buffer sendPacket = null; private Buffer sharedSendPacket = null; /** Data to the server */ protected BufferedOutputStream mysqlOutput = null; protected ConnectionImpl connection; private Deflater deflater = null; protected InputStream mysqlInput = null; private LinkedList packetDebugRingBuffer = null; private RowData streamingData = null; /** The connection to the server */ protected Socket mysqlConnection = null; private SocketFactory socketFactory = null; // // Packet used for 'LOAD DATA LOCAL INFILE' // // We use a SoftReference, so that we don't penalize intermittent // use of this feature // private SoftReference loadFileBufRef; // // Used to send large packets to the server versions 4+ // We use a SoftReference, so that we don't penalize intermittent // use of this feature // private SoftReference splitBufRef; protected String host = null; protected String seed; private String serverVersion = null; private String socketFactoryClassName = null; private byte[] packetHeaderBuf = new byte[4]; private boolean colDecimalNeedsBump = false; // do we need to increment the colDecimal flag? private boolean hadWarnings = false; private boolean has41NewNewProt = false; /** Does the server support long column info? */ private boolean hasLongColumnInfo = false; private boolean isInteractiveClient = false; private boolean logSlowQueries = false; /** * Does the character set of this connection match the character set of the * platform */ private boolean platformDbCharsetMatches = true; // changed once we've connected. private boolean profileSql = false; private boolean queryBadIndexUsed = false; private boolean queryNoIndexUsed = false; /** Should we use 4.1 protocol extensions? */ private boolean use41Extensions = false; private boolean useCompression = false; private boolean useNewLargePackets = false; private boolean useNewUpdateCounts = false; // should we use the new larger update counts? private byte packetSequence = 0; private byte readPacketSequence = -1; private boolean checkPacketSequence = false; private byte protocolVersion = 0; private int maxAllowedPacket = 1024 * 1024; protected int maxThreeBytes = 255 * 255 * 255; protected int port = 3306; protected int serverCapabilities; private int serverMajorVersion = 0; private int serverMinorVersion = 0; private int serverStatus = 0; private int serverSubMinorVersion = 0; private int warningCount = 0; protected long clientParam = 0; protected long lastPacketSentTimeMs = 0; private boolean traceProtocol = false; private boolean enablePacketDebug = false; private Calendar sessionCalendar; private boolean useConnectWithDb; private boolean needToGrabQueryFromPacket; private boolean autoGenerateTestcaseScript; private long threadId; private boolean useNanosForElapsedTime; private long slowQueryThreshold; private String queryTimingUnits; private List statementInterceptors; private boolean useDirectRowUnpack = true; private int useBufferRowSizeThreshold; /** * Constructor: Connect to the MySQL server and setup a stream connection. * * @param host the hostname to connect to * @param port the port number that the server is listening on * @param props the Properties from DriverManager.getConnection() * @param socketFactoryClassName the socket factory to use * @param conn the Connection that is creating us * @param socketTimeout the timeout to set for the socket (0 means no * timeout) * * @throws IOException if an IOException occurs during connect. * @throws SQLException if a database access error occurs. */ public MysqlIO(String host, int port, Properties props, String socketFactoryClassName, ConnectionImpl conn, int socketTimeout, int useBufferRowSizeThreshold) throws IOException, SQLException { this.connection = conn; if (this.connection.getEnablePacketDebug()) { this.packetDebugRingBuffer = new LinkedList(); } this.useAutoSlowLog = this.connection.getAutoSlowLog(); this.useBufferRowSizeThreshold = useBufferRowSizeThreshold; this.useDirectRowUnpack = this.connection.getUseDirectRowUnpack(); this.logSlowQueries = this.connection.getLogSlowQueries(); this.reusablePacket = new Buffer(INITIAL_PACKET_SIZE); this.sendPacket = new Buffer(INITIAL_PACKET_SIZE); this.port = port; this.host = host; this.socketFactoryClassName = socketFactoryClassName; this.socketFactory = createSocketFactory(); this.mysqlConnection = this.socketFactory.connect(this.host, this.port, props); if (socketTimeout != 0) { try { this.mysqlConnection.setSoTimeout(socketTimeout); } catch (Exception ex) { /* Ignore if the platform does not support it */ } } this.mysqlConnection = this.socketFactory.beforeHandshake(); if (this.connection.getUseReadAheadInput()) { this.mysqlInput = new ReadAheadInputStream(this.mysqlConnection.getInputStream(), 16384, this.connection.getTraceProtocol(), this.connection.getLog()); } else if (this.connection.useUnbufferedInput()) { this.mysqlInput = this.mysqlConnection.getInputStream(); } else { this.mysqlInput = new BufferedInputStream(this.mysqlConnection.getInputStream(), 16384); } this.mysqlOutput = new BufferedOutputStream(this.mysqlConnection.getOutputStream(), 16384); this.isInteractiveClient = this.connection.getInteractiveClient(); this.profileSql = this.connection.getProfileSql(); this.sessionCalendar = Calendar.getInstance(); this.autoGenerateTestcaseScript = this.connection.getAutoGenerateTestcaseScript(); this.needToGrabQueryFromPacket = (this.profileSql || this.logSlowQueries || this.autoGenerateTestcaseScript); if (this.connection.getUseNanosForElapsedTime() && Util.nanoTimeAvailable()) { this.useNanosForElapsedTime = true; this.queryTimingUnits = Messages.getString("Nanoseconds"); } else { this.queryTimingUnits = Messages.getString("Milliseconds"); } if (this.connection.getLogSlowQueries()) { calculateSlowQueryThreshold(); } } protected void initializeStatementInterceptors(String interceptorClasses, Properties props) throws SQLException { this.statementInterceptors = Util.loadExtensions(this.connection, props, interceptorClasses, "MysqlIo.BadStatementInterceptor"); } /** * Does the server send back extra column info? * * @return true if so */ public boolean hasLongColumnInfo() { return this.hasLongColumnInfo; } protected boolean isDataAvailable() throws SQLException { try { return this.mysqlInput.available() > 0; } catch (IOException ioEx) { throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, ioEx); } } /** * DOCUMENT ME! * * @return Returns the lastPacketSentTimeMs. */ protected long getLastPacketSentTimeMs() { return this.lastPacketSentTimeMs; } /** * Build a result set. Delegates to buildResultSetWithRows() to build a * JDBC-version-specific ResultSet, given rows as byte data, and field * information. * * @param callingStatement DOCUMENT ME! * @param columnCount the number of columns in the result set * @param maxRows the maximum number of rows to read (-1 means all rows) * @param resultSetType (TYPE_FORWARD_ONLY, TYPE_SCROLL_????) * @param resultSetConcurrency the type of result set (CONCUR_UPDATABLE or * READ_ONLY) * @param streamResults should the result set be read all at once, or * streamed? * @param catalog the database name in use when the result set was created * @param isBinaryEncoded is this result set in native encoding? * @param unpackFieldInfo should we read MYSQL_FIELD info (if available)? * * @return a result set * * @throws SQLException if a database access error occurs */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -