📄 connection.java
字号:
/*
Copyright (C) 2002 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Clob;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.Ref;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
/**
* A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are
* returned.
*
* <P>
* A Connection's database is able to provide information describing its
* tables, its supported SQL grammar, its stored procedures, the capabilities
* of this connection, etc. This information is obtained with the getMetaData
* method.
* </p>
*
* @author Mark Matthews
* @version $Id: Connection.java,v 1.31.2.55 2004/02/13 22:33:50 mmatthew Exp $
*
* @see java.sql.Connection
*/
public class Connection implements java.sql.Connection {
// The command used to "ping" the database.
// Newer versions of MySQL server have a ping() command,
// but this works for everything
private static final String PING_COMMAND = "SELECT 1";
/**
* Map mysql transaction isolation level name to
* java.sql.Connection.TRANSACTION_XXX
*/
private static Map mapTransIsolationName2Value = null;
/**
* The mapping between MySQL charset names and Java charset names.
* Initialized by loadCharacterSetMapping()
*/
private static Map charsetMap;
/** Table of multi-byte charsets. Initialized by loadCharacterSetMapping() */
private static Map multibyteCharsetsMap;
/** Default socket factory classname */
private static final String DEFAULT_SOCKET_FACTORY = StandardSocketFactory.class
.getName();
static {
loadCharacterSetMapping();
mapTransIsolationName2Value = new HashMap(8);
mapTransIsolationName2Value.put("READ-UNCOMMITED",
new Integer(TRANSACTION_READ_UNCOMMITTED));
mapTransIsolationName2Value.put("READ-UNCOMMITTED",
new Integer(TRANSACTION_READ_UNCOMMITTED));
mapTransIsolationName2Value.put("READ-COMMITTED",
new Integer(TRANSACTION_READ_COMMITTED));
mapTransIsolationName2Value.put("REPEATABLE-READ",
new Integer(TRANSACTION_REPEATABLE_READ));
mapTransIsolationName2Value.put("SERIALIZABLE",
new Integer(TRANSACTION_SERIALIZABLE));
}
/**
* Marker for character set converter not being available (not written,
* multibyte, etc) Used to prevent multiple instantiation requests.
*/
private final static Object CHARSET_CONVERTER_NOT_AVAILABLE_MARKER = new Object();
/** Internal DBMD to use for various database-version specific features */
private DatabaseMetaData dbmd = null;
/** The list of host(s) to try and connect to */
private List hostList = null;
/** A map of SQL to parsed prepared statement parameters. */
private Map cachedPreparedStatementParams;
/**
* Holds cached mappings to charset converters to avoid static
* synchronization and at the same time save memory (each charset
* converter takes approx 65K of static data).
*/
private Map charsetConverterMap = new HashMap(CharsetMapping.JAVA_TO_MYSQL_CHARSET_MAP
.size());
/** A map of statements that have had setMaxRows() called on them */
private Map statementsUsingMaxRows;
/**
* The type map for UDTs (not implemented, but used by some third-party
* vendors, most notably IBM WebSphere)
*/
private Map typeMap;
/** The I/O abstraction interface (network conn to MySQL server */
private MysqlIO io = null;
/** Mutex */
private final Object mutex = new Object();
/** The map of server variables that we retrieve at connection init. */
private Map serverVariables = null;
/** The driver instance that created us */
private NonRegisteringDriver myDriver;
/** Properties for this connection specified by user */
private Properties props = null;
/** The database we're currently using (called Catalog in JDBC terms). */
private String database = null;
/** If we're doing unicode character conversions, what encoding do we use? */
private String encoding = null;
/** The hostname we're connected to */
private String host = null;
/** The JDBC URL we're using */
private String myURL = null;
/** What does MySQL call this encoding? */
private String mysqlEncodingName = null;
private String negativeInfinityRep = MysqlDefs.MIN_DOUBLE_VAL_STRING;
private String notANumberRep = MysqlDefs.NAN_VAL_STRING;
/** The password we used */
private String password = null;
private String positiveInfinityRep = MysqlDefs.MAX_DOUBLE_VAL_STRING;
/** Classname for socket factory */
private String socketFactoryClassName = null;
/** The user we're connected as */
private String user = null;
/** Where was the connection _explicitly_ closed by the application? */
private Throwable explicitCloseLocation;
/** If the connection was forced closed, why was it forced closed? */
private Throwable forcedCloseReason;
private TimeZone defaultTimeZone;
/** The timezone of the server */
private TimeZone serverTimezone = null;
/** Allow LOAD LOCAL INFILE (defaults to true) */
private boolean allowLoadLocalInfile = true;
/** Should we clear the input stream each query? */
private boolean alwaysClearStream = false;
/** Are we in autoCommit mode? */
private boolean autoCommit = true;
/** SHould we cache the parsing of prepared statements? */
private boolean cachePreparedStatements = false;
/** Should we capitalize mysql types */
private boolean capitalizeDBMDTypes = false;
/** Should we clobber streaming results on new queries, or issue an error? */
private boolean clobberStreamingResults = false;
/**
* Should we continue processing batch commands if one fails. The JDBC spec
* allows either way, so we let the user choose
*/
private boolean continueBatchOnError = true;
/** Should we do unicode character conversions? */
private boolean doUnicode = false;
/** Are we failed-over to a non-master host */
private boolean failedOver = false;
/** Does the server suuport isolation levels? */
private boolean hasIsolationLevels = false;
/** Does this version of MySQL support quoted identifiers? */
private boolean hasQuotedIdentifiers = false;
//
// This is for the high availability :) routines
//
private boolean highAvailability = false;
/** Ignore non-transactional table warning for rollback? */
private boolean ignoreNonTxTables = false;
/** Has this connection been closed? */
private boolean isClosed = true;
/** Should we tell MySQL that we're an interactive client? */
private boolean isInteractiveClient = false;
/** Is the server configured to use lower-case table names only? */
private boolean lowerCaseTableNames = false;
/** Has the max-rows setting been changed from the default? */
private boolean maxRowsChanged = false;
private boolean negativeInfinityRepIsClipped = true;
private boolean notANumberRepIsClipped = true;
/** Do we expose sensitive information in exception and error messages? */
private boolean paranoid = false;
/** Should we do 'extra' sanity checks? */
private boolean pedantic = false;
private boolean positiveInfinityRepIsClipped = true;
/** Should we retrieve 'info' messages from the server? */
private boolean readInfoMsg = false;
/** Are we in read-only mode? */
private boolean readOnly = false;
/**
* If autoReconnect == true, should we attempt to reconnect at transaction
* boundaries?
*/
private boolean reconnectAtTxEnd = false;
/** Do we relax the autoCommit semantics? (For enhydra, for example) */
private boolean relaxAutoCommit = false;
/** Do we need to correct endpoint rounding errors */
private boolean strictFloatingPoint = false;
/** Do we check all keys for updatable result sets? */
private boolean strictUpdates = true;
/** Are transactions supported by the MySQL server we are connected to? */
private boolean transactionsSupported = false;
/** Has ANSI_QUOTES been enabled on the server? */
private boolean useAnsiQuotes = false;
/** Should we use compression? */
private boolean useCompression = false;
/** Can we use the "ping" command rather than a query? */
private boolean useFastPing = false;
/** Should we tack on hostname in DBMD.getTable/ColumnPrivileges()? */
private boolean useHostsInPrivileges = true;
/** Should we use SSL? */
private boolean useSSL = false;
/**
* Should we use stream lengths in prepared statements? (true by default ==
* JDBC compliant)
*/
private boolean useStreamLengthsInPrepStmts = true;
/** Should we use timezone information? */
private boolean useTimezone = false;
/** Should we return PreparedStatements for UltraDev's stupid bug? */
private boolean useUltraDevWorkAround = false;
private boolean useUnbufferedInput = true;
private double initialTimeout = 2.0D;
/** How many hosts are in the host list? */
private int hostListSize = 0;
/** isolation level */
private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
/**
* The largest packet we can send (changed once we know what the server
* supports, we get this at connection init).
*/
private int maxAllowedPacket = 65536;
private int maxReconnects = 3;
/**
* The max rows that a result set can contain. Defaults to -1, which
* according to the JDBC spec means "all".
*/
private int maxRows = -1;
private int netBufferLength = 16384;
/** The port number we're connected to (defaults to 3306) */
private int port = 3306;
/**
* If prepared statement caching is enabled, what should the threshold
* length of the SQL to prepare should be in order to _not_ cache?
*/
private int preparedStatementCacheMaxSqlSize = 256;
/** If prepared statement caching is enabled, how many should we cache? */
private int preparedStatementCacheSize = 25;
/**
* How many queries should we wait before we try to re-connect to the
* master, when we are failing over to replicated hosts Defaults to 50
*/
private int queriesBeforeRetryMaster = 50;
/** What should we set the socket timeout to? */
private int socketTimeout = 0; // infinite
/** When did the last query finish? */
private long lastQueryFinishedTime = 0;
/** When did the master fail? */
private long masterFailTimeMillis = 0L;
/** Number of queries we've issued since the master failed */
private long queriesIssuedFailedOver = 0;
/**
* How many seconds should we wait before retrying to connect to the master
* if failed over? We fall back when either queriesBeforeRetryMaster or
* secondsBeforeRetryMaster is reached.
*/
private long secondsBeforeRetryMaster = 30L;
/**
* Creates a connection to a MySQL Server.
*
* @param host the hostname of the database server
* @param port the port number the server is listening on
* @param info a Properties[] list holding the user and password
* @param database the database to connect to
* @param url the URL of the connection
* @param d the Driver instantation of the connection
*
* @exception java.sql.SQLException if a database access error occurs
* @throws SQLException DOCUMENT ME!
*/
Connection(String host, int port, Properties info, String database,
String url, NonRegisteringDriver d) throws java.sql.SQLException {
if (Driver.TRACE) {
Object[] args = { host, new Integer(port), info, database, url, d };
Debug.methodCall(this, "constructor", args);
}
this.defaultTimeZone = TimeZone.getDefault();
this.serverVariables = new HashMap();
if (host == null) {
this.host = "localhost";
hostList = new ArrayList();
hostList.add(this.host);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -