?? mysqlio.java
字號:
/* Copyright (C) 2002-2004 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 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.net.Socket;import java.security.NoSuchAlgorithmException;import java.sql.SQLException;import java.sql.SQLWarning;import java.util.ArrayList;import java.util.Properties;import java.util.zip.Deflater;import java.util.zip.Inflater;/** * This class is used by Connection for communicating with the MySQL server. * * @author Mark Matthews * @version $Id: MysqlIO.java,v 1.32.2.61 2004/08/27 21:50:12 mmatthew Exp $ * * @see java.sql.Connection */public class MysqlIO { static final int NULL_LENGTH = ~0; static final int COMP_HEADER_LENGTH = 3; static final int MIN_COMPRESS_LEN = 50; static final int HEADER_LENGTH = 4; private static int maxBufferSize = 65535; private static final int CLIENT_COMPRESS = 32; /* Can use compression protcol */ private static final int CLIENT_CONNECT_WITH_DB = 8; private static final int CLIENT_FOUND_ROWS = 2; private static final int CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */ 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; private static final int CLIENT_SSL = 2048; private static final int CLIENT_RESERVED = 16384; // for 4.1.0 only private static final int CLIENT_SECURE_CONNECTION = 32768; private static final String FALSE_SCRAMBLE = "xxxxxxxx"; /** * We store the platform 'encoding' here, only used to avoid munging * filenames for LOAD DATA LOCAL INFILE... */ private static String jvmPlatformCharset = null; 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 } } } // // 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 */ //private DataOutputStream _Mysql_Output = null; private BufferedOutputStream mysqlOutput = null; private com.mysql.jdbc.Connection connection; private Deflater deflater = null; private Inflater inflater = null; /** Buffered data from the server */ //private BufferedInputStream _Mysql_Buf_Input = null; /** Buffered data to the server */ //private BufferedOutputStream _Mysql_Buf_Output = null; /** Data from the server */ //private DataInputStream _Mysql_Input = null; private InputStream mysqlInput = null; private RowData streamingData = null; // // For SQL Warnings // private SQLWarning warningChain = null; /** The connection to the server */ private 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; private String host = null; private String seed; private String serverVersion = null; private String socketFactoryClassName = null; private byte[] packetHeaderBuf = new byte[4]; private boolean clearStreamBeforeEachQuery = false; private boolean colDecimalNeedsBump = false; // do we need to increment the colDecimal flag? private boolean has41NewNewProt = false; /** Does the server support long column info? */ private boolean hasLongColumnInfo = false; private boolean isInteractiveClient = false; /** * Does the character set of this connection match the character set of the * platform */ private boolean platformDbCharsetMatches = true; private boolean profileSql = 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 protocolVersion = 0; private int clientParam = 0; // changed once we've connected. private int maxAllowedPacket = 1024 * 1024; private int maxThreeBytes = 255 * 255 * 255; private int port = 3306; private int serverCapabilities; private int serverMajorVersion = 0; private int serverMinorVersion = 0; private int serverSubMinorVersion = 0; protected int serverCharsetIndex; private static final int MAX_QUERY_LENGTH_TO_LOG = 4 * 1024; // 4K /** * 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 socketFactoryClassName the socket factory to use * @param props the Properties from DriverManager.getConnection() * @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 java.sql.SQLException if a database access error occurs. */ protected MysqlIO(String host, int port, String socketFactoryClassName, Properties props, com.mysql.jdbc.Connection conn, int socketTimeout) throws IOException, java.sql.SQLException { this.connection = conn; this.reusablePacket = new Buffer(this.connection.getNetBufferLength()); this.port = port; this.host = host; this.socketFactoryClassName = socketFactoryClassName; this.socketFactory = createSocketFactory(); this.mysqlConnection = socketFactory.connect(this.host, this.port, props); this.clearStreamBeforeEachQuery = this.connection.alwaysClearStream(); 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.isUsingUnbufferedInput()) { this.mysqlInput = new BufferedInputStream(this.mysqlConnection .getInputStream(), 16384); } else { this.mysqlInput = this.mysqlConnection.getInputStream(); } this.mysqlOutput = new BufferedOutputStream(this.mysqlConnection .getOutputStream(), 16384); this.isInteractiveClient = this.connection.isInteractiveClient(); } /** * Should the driver generate SQL statement profiles? * * @param flag should the driver enable profiling? */ protected void setProfileSql(boolean flag) { this.profileSql = flag; } /** * Build a result set. Delegates to buildResultSetWithRows() to build a * JDBC-version-specific ResultSet, given rows as byte data, and field * information. * * @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 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 * * @return a result set * * @throws Exception if a database access error occurs */ protected ResultSet getResultSet(long columnCount, int maxRows, int resultSetType, boolean streamResults, String catalog) throws Exception { Buffer packet; // The packet from the server Field[] fields = new Field[(int) columnCount]; // Read in the column information for (int i = 0; i < columnCount; i++) { packet = readPacket(); fields[i] = unpackField(packet, false); } packet = reuseAndReadPacket(this.reusablePacket); RowData rowData = null; if (!streamResults) { ArrayList rows = new ArrayList(); // Now read the data byte[][] rowBytes = nextRow((int) columnCount); int rowCount = 0; if (rowBytes != null) { rows.add(rowBytes); rowCount = 1; } while ((rowBytes != null) && (rowCount < maxRows)) { rowBytes = nextRow((int) columnCount); if (rowBytes != null) { rows.add(rowBytes); rowCount++; } else { if (Driver.TRACE) { Debug.msg(this, "* NULL Row *"); } } } // // Clear any outstanding data left on the wire // when we've artifically limited the number of // rows we retrieve (fix for BUG#1695) // if (rowCount <= maxRows) { clearInputStream(); } if (Driver.TRACE) { Debug.msg(this, "* Fetched " + rows.size() + " rows from server *"); } rowData = new RowDataStatic(rows); reclaimLargeReusablePacket(); } else { rowData = new RowDataDynamic(this, (int) columnCount); this.streamingData = rowData; } return buildResultSetWithRows(catalog, fields, rowData, resultSetType); } /** * Forcibly closes the underlying socket to MySQL. */ protected final void forceClose() { try { if (this.mysqlInput != null) { this.mysqlInput.close(); } } catch (IOException ioEx) { // we can't do anything constructive about this // Let the JVM clean it up later this.mysqlInput = null; } try { if (this.mysqlOutput != null) { this.mysqlOutput.close(); } } catch (IOException ioEx) { // we can't do anything constructive about this // Let the JVM clean it up later this.mysqlOutput = null; } try { if (this.mysqlConnection != null) { this.mysqlConnection.close(); } } catch (IOException ioEx) { // we can't do anything constructive about this // Let the JVM clean it up later this.mysqlConnection = null; } } /** * Re-authenticates as the given user and password * * @param userName DOCUMENT ME!
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -