Connection.java
资源名称:bookshop.zip [点击查看]
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:130k
源码类别:
数据库编程
开发平台:
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);
- } else if (host.indexOf(",") != -1) {
- // multiple hosts separated by commas (failover)
- hostList = StringUtils.split(host, ",", true);
- } else {
- this.host = host;
- hostList = new ArrayList();
- hostList.add(this.host);
- }
- hostListSize = hostList.size();
- this.port = port;
- if (database == null) {
- throw new SQLException("Malformed URL '" + url + "'.",
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- this.database = database;
- this.myURL = url;
- this.myDriver = d;
- this.user = info.getProperty("user");
- this.password = info.getProperty("password");
- if ((this.user == null) || this.user.equals("")) {
- this.user = "nobody";
- }
- if (this.password == null) {
- this.password = "";
- }
- this.props = info;
- initializeDriverProperties(info);
- if (Driver.DEBUG) {
- System.out.println("Connect: " + this.user + " to " + this.database);
- }
- try {
- createNewIO(false);
- this.dbmd = new DatabaseMetaData(this, this.database);
- } catch (java.sql.SQLException ex) {
- cleanup(ex);
- // don't clobber SQL exceptions
- throw ex;
- } catch (Exception ex) {
- cleanup(ex);
- StringBuffer mesg = new StringBuffer();
- if (!useParanoidErrorMessages()) {
- mesg.append("Cannot connect to MySQL server on ");
- mesg.append(this.host);
- mesg.append(":");
- mesg.append(this.port);
- mesg.append(".nn");
- mesg.append("Make sure that there is a MySQL server ");
- mesg.append("running on the machine/port you are trying ");
- mesg.append(
- "to connect to and that the machine this software is "
- + "running on ");
- mesg.append("is able to connect to this host/port "
- + "(i.e. not firewalled). ");
- mesg.append(
- "Also make sure that the server has not been started "
- + "with the --skip-networking ");
- mesg.append("flag.nn");
- } else {
- mesg.append("Unable to connect to database.");
- }
- mesg.append("Underlying exception: nn");
- mesg.append(ex.getClass().getName());
- throw new java.sql.SQLException(mesg.toString(),
- SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE);
- }
- }
- /**
- * If a connection is in auto-commit mode, than all its SQL statements will
- * be executed and committed as individual transactions. Otherwise, its
- * SQL statements are grouped into transactions that are terminated by
- * either commit() or rollback(). By default, new connections are in
- * auto- commit mode. The commit occurs when the statement completes or
- * the next execute occurs, whichever comes first. In the case of
- * statements returning a ResultSet, the statement completes when the last
- * row of the ResultSet has been retrieved or the ResultSet has been
- * closed. In advanced cases, a single statement may return multiple
- * results as well as output parameter values. Here the commit occurs
- * when all results and output param values have been retrieved.
- *
- * <p>
- * <b>Note:</b> MySQL does not support transactions, so this method is a
- * no-op.
- * </p>
- *
- * @param autoCommit - true enables auto-commit; false disables it
- *
- * @exception java.sql.SQLException if a database access error occurs
- * @throws SQLException DOCUMENT ME!
- */
- public void setAutoCommit(boolean autoCommit) throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = { new Boolean(autoCommit) };
- Debug.methodCall(this, "setAutoCommit", args);
- }
- checkClosed();
- if (this.transactionsSupported) {
- // this internal value must be set first as failover depends on it
- // being set to true to fail over (which is done by most
- // app servers and connection pools at the end of
- // a transaction), and the driver issues an implicit set
- // based on this value when it (re)-connects to a server
- // so the value holds across connections
- //
- this.autoCommit = autoCommit;
- //
- // This is to catch the 'edge' case of
- // autoCommit going from true -> false
- //
- if ((this.highAvailability || this.failedOver) && !this.autoCommit) {
- pingAndReconnect(true);
- }
- String sql = "SET autocommit=" + (autoCommit ? "1" : "0");
- execSQL(sql, -1, this.database);
- } else {
- if ((autoCommit == false) && (this.relaxAutoCommit == false)) {
- throw new SQLException("MySQL Versions Older than 3.23.15 "
- + "do not support transactions",
- SQLError.SQL_STATE_DRIVER_NOT_CAPABLE);
- } else {
- this.autoCommit = autoCommit;
- }
- }
- return;
- }
- /**
- * gets the current auto-commit state
- *
- * @return Current state of the auto-commit mode
- *
- * @exception java.sql.SQLException (why?)
- *
- * @see setAutoCommit
- */
- public boolean getAutoCommit() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "getAutoCommit", args);
- Debug.returnValue(this, "getAutoCommit",
- new Boolean(this.autoCommit));
- }
- return this.autoCommit;
- }
- /**
- * A sub-space of this Connection's database may be selected by setting a
- * catalog name. If the driver does not support catalogs, it will
- * silently ignore this request
- *
- * <p>
- * <b>Note:</b> MySQL's notion of catalogs are individual databases.
- * </p>
- *
- * @param catalog the database for this connection to use
- *
- * @throws java.sql.SQLException if a database access error occurs
- */
- public void setCatalog(String catalog) throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = { catalog };
- Debug.methodCall(this, "setCatalog", args);
- }
- checkClosed();
- String quotedId = this.dbmd.getIdentifierQuoteString();
- if ((quotedId == null) || quotedId.equals(" ")) {
- quotedId = "";
- }
- StringBuffer query = new StringBuffer("USE ");
- query.append(quotedId);
- query.append(catalog);
- query.append(quotedId);
- execSQL(query.toString(), -1, catalog);
- this.database = catalog;
- }
- /**
- * Return the connections current catalog name, or null if no catalog name
- * is set, or we dont support catalogs.
- *
- * <p>
- * <b>Note:</b> MySQL's notion of catalogs are individual databases.
- * </p>
- *
- * @return the current catalog name or null
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public String getCatalog() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "getCatalog", args);
- Debug.returnValue(this, "getCatalog", this.database);
- }
- return this.database;
- }
- /**
- * Returns whether we clobber streaming results on new queries, or issue an
- * error?
- *
- * @return true if we should implicitly close streaming result sets upon
- * receiving a new query
- */
- public boolean getClobberStreamingResults() {
- return this.clobberStreamingResults;
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean isClosed() {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "isClosed", args);
- Debug.returnValue(this, "isClosed", new Boolean(this.isClosed));
- }
- return this.isClosed;
- }
- /**
- * Returns the character encoding for this Connection
- *
- * @return the character encoding for this connection.
- */
- public String getEncoding() {
- return this.encoding;
- }
- /**
- * @see Connection#setHoldability(int)
- */
- public void setHoldability(int arg0) throws SQLException {
- // do nothing
- }
- /**
- * @see Connection#getHoldability()
- */
- public int getHoldability() throws SQLException {
- return ResultSet.CLOSE_CURSORS_AT_COMMIT;
- }
- /**
- * NOT JDBC-Compliant, but clients can use this method to determine how
- * long this connection has been idle. This time (reported in
- * milliseconds) is updated once a query has completed.
- *
- * @return number of ms that this connection has been idle, 0 if the driver
- * is busy retrieving results.
- */
- public long getIdleFor() {
- if (this.lastQueryFinishedTime == 0) {
- return 0;
- } else {
- long now = System.currentTimeMillis();
- long idleTime = now - this.lastQueryFinishedTime;
- return idleTime;
- }
- }
- /**
- * Should we tell MySQL that we're an interactive client
- *
- * @return true if isInteractiveClient was set to true.
- */
- public boolean isInteractiveClient() {
- return isInteractiveClient;
- }
- /**
- * 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 made
- * available through a DatabaseMetaData object.
- *
- * @return a DatabaseMetaData object for this connection
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public java.sql.DatabaseMetaData getMetaData() throws java.sql.SQLException {
- checkClosed();
- return new DatabaseMetaData(this, this.database);
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public String getNegativeInfinityRep() {
- return negativeInfinityRep;
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public boolean isNegativeInfinityRepIsClipped() {
- return negativeInfinityRepIsClipped;
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public String getNotANumberRep() {
- return notANumberRep;
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public boolean isNotANumberRepIsClipped() {
- return notANumberRepIsClipped;
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public String getPositiveInfinityRep() {
- return positiveInfinityRep;
- }
- /**
- * DOCUMENT ME!
- *
- * @return
- */
- public boolean isPositiveInfinityRepIsClipped() {
- return positiveInfinityRepIsClipped;
- }
- /**
- * Should the driver do profiling?
- *
- * @param flag set to true to enable profiling.
- *
- * @throws SQLException if the connection is closed.
- */
- public void setProfileSql(boolean flag) throws SQLException {
- // For re-connection
- this.props.setProperty("profileSql", String.valueOf(flag));
- getIO().setProfileSql(flag);
- }
- /**
- * You can put a connection in read-only mode as a hint to enable database
- * optimizations <B>Note:</B> setReadOnly cannot be called while in the
- * middle of a transaction
- *
- * @param readOnly - true enables read-only mode; false disables it
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public void setReadOnly(boolean readOnly) throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = { new Boolean(readOnly) };
- Debug.methodCall(this, "setReadOnly", args);
- Debug.returnValue(this, "setReadOnly", new Boolean(readOnly));
- }
- checkClosed();
- this.readOnly = readOnly;
- }
- /**
- * Tests to see if the connection is in Read Only Mode. Note that we
- * cannot really put the database in read only mode, but we pretend we can
- * by returning the value of the readOnly flag
- *
- * @return true if the connection is read only
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public boolean isReadOnly() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "isReadOnly", args);
- Debug.returnValue(this, "isReadOnly", new Boolean(this.readOnly));
- }
- return this.readOnly;
- }
- /**
- * @see Connection#setSavepoint()
- */
- public java.sql.Savepoint setSavepoint() throws SQLException {
- throw new NotImplemented();
- }
- /**
- * @see Connection#setSavepoint(String)
- */
- public java.sql.Savepoint setSavepoint(String arg0)
- throws SQLException {
- throw new NotImplemented();
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public TimeZone getServerTimezone() {
- return this.serverTimezone;
- }
- /**
- * DOCUMENT ME!
- *
- * @param level DOCUMENT ME!
- *
- * @throws java.sql.SQLException DOCUMENT ME!
- * @throws SQLException DOCUMENT ME!
- */
- public void setTransactionIsolation(int level) throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = { new Integer(level) };
- Debug.methodCall(this, "setTransactionIsolation", args);
- }
- checkClosed();
- if (this.hasIsolationLevels) {
- StringBuffer sql = new StringBuffer(
- "SET SESSION TRANSACTION ISOLATION LEVEL ");
- switch (level) {
- case java.sql.Connection.TRANSACTION_NONE:
- throw new SQLException("Transaction isolation level "
- + "NONE not supported by MySQL");
- case java.sql.Connection.TRANSACTION_READ_COMMITTED:
- sql.append("READ COMMITTED");
- break;
- case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
- sql.append("READ UNCOMMITTED");
- break;
- case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
- sql.append("REPEATABLE READ");
- break;
- case java.sql.Connection.TRANSACTION_SERIALIZABLE:
- sql.append("SERIALIZABLE");
- break;
- default:
- throw new SQLException("Unsupported transaction "
- + "isolation level '" + level + "'", "S1C00");
- }
- execSQL(sql.toString(), -1, this.database);
- isolationLevel = level;
- } else {
- throw new java.sql.SQLException("Transaction Isolation Levels are "
- + "not supported on MySQL versions older than 3.23.36.", "S1C00");
- }
- }
- /**
- * Get this Connection's current transaction isolation mode.
- *
- * @return the current TRANSACTION_ mode value
- *
- * @exception java.sql.SQLException if a database access error occurs
- * @throws SQLException DOCUMENT ME!
- */
- public int getTransactionIsolation() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "getTransactionIsolation", args);
- Debug.returnValue(this, "getTransactionIsolation",
- new Integer(isolationLevel));
- }
- if (this.hasIsolationLevels) {
- java.sql.Statement stmt = null;
- java.sql.ResultSet rs = null;
- try {
- stmt = this.createStatement();
- if (stmt.getMaxRows() != 0) {
- stmt.setMaxRows(0);
- }
- String query = null;
- if (this.io.versionMeetsMinimum(4, 0, 3)) {
- query = "SHOW VARIABLES LIKE 'tx_isolation'";
- } else {
- query = "SHOW VARIABLES LIKE 'transaction_isolation'";
- }
- rs = stmt.executeQuery(query);
- if (rs.next()) {
- String s = rs.getString(2);
- if (s != null) {
- Integer intTI = (Integer) mapTransIsolationName2Value
- .get(s);
- if (intTI != null) {
- return intTI.intValue();
- }
- }
- throw new SQLException(
- "Could not map transaction isolation '" + s
- + " to a valid JDBC level.",
- SQLError.SQL_STATE_GENERAL_ERROR);
- } else {
- throw new SQLException("Could not retrieve transaction isolation level from server",
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (Exception ex) {
- // ignore
- }
- rs = null;
- }
- if (stmt != null) {
- try {
- stmt.close();
- } catch (Exception ex) {
- // ignore
- }
- stmt = null;
- }
- }
- }
- return isolationLevel;
- }
- /**
- * JDBC 2.0 Install a type-map object as the default type-map for this
- * connection
- *
- * @param map the type mapping
- *
- * @throws SQLException if a database error occurs.
- */
- public void setTypeMap(java.util.Map map) throws SQLException {
- this.typeMap = map;
- }
- /**
- * JDBC 2.0 Get the type-map object associated with this connection. By
- * default, the map returned is empty.
- *
- * @return the type map
- *
- * @throws SQLException if a database error occurs
- */
- public synchronized java.util.Map getTypeMap() throws SQLException {
- if (this.typeMap == null) {
- this.typeMap = new HashMap();
- }
- return this.typeMap;
- }
- /**
- * The first warning reported by calls on this Connection is returned.
- * <B>Note:</B> Sebsequent warnings will be changed to this
- * java.sql.SQLWarning
- *
- * @return the first java.sql.SQLWarning or null
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public java.sql.SQLWarning getWarnings() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "getWarnings", args);
- Debug.returnValue(this, "getWarnings", null);
- }
- return null;
- }
- /**
- * Allow use of LOAD LOCAL INFILE?
- *
- * @return true if allowLoadLocalInfile was set to true.
- */
- public boolean allowLoadLocalInfile() {
- return this.allowLoadLocalInfile;
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean capitalizeDBMDTypes() {
- return this.capitalizeDBMDTypes;
- }
- /**
- * After this call, getWarnings returns null until a new warning is
- * reported for this connection.
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public void clearWarnings() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "clearWarnings", args);
- }
- // firstWarning = null;
- }
- /**
- * In some cases, it is desirable to immediately release a Connection's
- * database and JDBC resources instead of waiting for them to be
- * automatically released (cant think why off the top of my head)
- * <B>Note:</B> A Connection is automatically closed when it is garbage
- * collected. Certain fatal errors also result in a closed connection.
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public void close() throws java.sql.SQLException {
- if (this.explicitCloseLocation == null) {
- this.explicitCloseLocation = new Throwable();
- }
- realClose(true, true);
- }
- /**
- * The method commit() makes all changes made since the previous
- * commit/rollback permanent and releases any database locks currently
- * held by the Connection. This method should only be used when
- * auto-commit has been disabled.
- *
- * <p>
- * <b>Note:</b> MySQL does not support transactions, so this method is a
- * no-op.
- * </p>
- *
- * @exception java.sql.SQLException if a database access error occurs
- * @throws SQLException DOCUMENT ME!
- *
- * @see setAutoCommit
- */
- public void commit() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "commit", args);
- }
- checkClosed();
- try {
- // no-op if _relaxAutoCommit == true
- if (this.autoCommit && !this.relaxAutoCommit) {
- throw new SQLException("Can't call commit when autocommit=true",
- SQLError.SQL_STATE_GENERAL_ERROR);
- } else if (this.transactionsSupported) {
- execSQL("commit", -1, this.database);
- }
- } finally {
- if (this.reconnectAtTxEnd) {
- pingAndReconnect(true);
- }
- }
- return;
- }
- //--------------------------JDBC 2.0-----------------------------
- /**
- * JDBC 2.0 Same as createStatement() above, but allows the default result
- * set type and result set concurrency type to be overridden.
- *
- * @param resultSetType a result set type, see ResultSet.TYPE_XXX
- * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
- *
- * @return a new Statement object
- *
- * @exception SQLException if a database-access error occurs.
- */
- public java.sql.Statement createStatement(int resultSetType,
- int resultSetConcurrency) throws SQLException {
- checkClosed();
- Statement stmt = new com.mysql.jdbc.Statement(this, this.database);
- stmt.setResultSetType(resultSetType);
- stmt.setResultSetConcurrency(resultSetConcurrency);
- return stmt;
- }
- /**
- * SQL statements without parameters are normally executed using Statement
- * objects. If the same SQL statement is executed many times, it is more
- * efficient to use a PreparedStatement
- *
- * @return a new Statement object
- *
- * @throws SQLException passed through from the constructor
- */
- public java.sql.Statement createStatement() throws SQLException {
- return createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
- java.sql.ResultSet.CONCUR_READ_ONLY);
- }
- /**
- * @see Connection#createStatement(int, int, int)
- */
- public java.sql.Statement createStatement(int resultSetType,
- int resultSetConcurrency, int resultSetHoldability)
- throws SQLException {
- if (this.pedantic) {
- if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
- throw new SQLException("HOLD_CUSRORS_OVER_COMMIT is only supported holdability level",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
- return createStatement(resultSetType, resultSetConcurrency);
- }
- /**
- * DOCUMENT ME!
- *
- * @throws Throwable DOCUMENT ME!
- */
- public void finalize() throws Throwable {
- cleanup(null);
- }
- /**
- * Is the server configured to use lower-case table names only?
- *
- * @return true if lower_case_table_names is 'on'
- */
- public boolean lowerCaseTableNames() {
- return this.lowerCaseTableNames;
- }
- /**
- * A driver may convert the JDBC sql grammar into its system's native SQL
- * grammar prior to sending it; nativeSQL returns the native form of the
- * statement that the driver would have sent.
- *
- * @param sql a SQL statement that may contain one or more '?' parameter
- * placeholders
- *
- * @return the native form of this statement
- *
- * @exception java.sql.SQLException if a database access error occurs
- */
- public String nativeSQL(String sql) throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = { sql };
- Debug.methodCall(this, "nativeSQL", args);
- Debug.returnValue(this, "nativeSQL", sql);
- }
- return EscapeProcessor.escapeSQL(sql,
- getIO().versionMeetsMinimum(4, 0, 2));
- }
- /**
- * DOCUMENT ME!
- *
- * @param sql DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws java.sql.SQLException DOCUMENT ME!
- */
- public java.sql.CallableStatement prepareCall(String sql)
- throws java.sql.SQLException {
- if (this.getUseUltraDevWorkAround()) {
- return new UltraDevWorkAround(prepareStatement(sql));
- } else {
- throw new java.sql.SQLException("Callable statments not "
- + "supported.", "S1C00");
- }
- }
- /**
- * JDBC 2.0 Same as prepareCall() above, but allows the default result set
- * type and result set concurrency type to be overridden.
- *
- * @param sql the SQL representing the callable statement
- * @param resultSetType a result set type, see ResultSet.TYPE_XXX
- * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
- *
- * @return a new CallableStatement object containing the pre-compiled SQL
- * statement
- *
- * @exception SQLException if a database-access error occurs.
- */
- public java.sql.CallableStatement prepareCall(String sql,
- int resultSetType, int resultSetConcurrency) throws SQLException {
- return prepareCall(sql);
- }
- /**
- * @see Connection#prepareCall(String, int, int, int)
- */
- public java.sql.CallableStatement prepareCall(String sql,
- int resultSetType, int resultSetConcurrency, int resultSetHoldability)
- throws SQLException {
- if (this.pedantic) {
- if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
- throw new SQLException("HOLD_CUSRORS_OVER_COMMIT is only supported holdability level",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
- throw new NotImplemented();
- }
- /**
- * A SQL statement with or without IN parameters can be pre-compiled and
- * stored in a PreparedStatement object. This object can then be used to
- * efficiently execute this statement multiple times.
- *
- * <p>
- * <B>Note:</B> This method is optimized for handling parametric SQL
- * statements that benefit from precompilation if the driver supports
- * precompilation. In this case, the statement is not sent to the database
- * until the PreparedStatement is executed. This has no direct effect on
- * users; however it does affect which method throws certain
- * java.sql.SQLExceptions
- * </p>
- *
- * <p>
- * MySQL does not support precompilation of statements, so they are handled
- * by the driver.
- * </p>
- *
- * @param sql a SQL statement that may contain one or more '?' IN parameter
- * placeholders
- *
- * @return a new PreparedStatement object containing the pre-compiled
- * statement.
- *
- * @exception java.sql.SQLException if a database access error occurs.
- */
- public java.sql.PreparedStatement prepareStatement(String sql)
- throws java.sql.SQLException {
- return prepareStatement(sql, java.sql.ResultSet.TYPE_FORWARD_ONLY,
- java.sql.ResultSet.CONCUR_READ_ONLY);
- }
- /**
- * JDBC 2.0 Same as prepareStatement() above, but allows the default result
- * set type and result set concurrency type to be overridden.
- *
- * @param sql the SQL query containing place holders
- * @param resultSetType a result set type, see ResultSet.TYPE_XXX
- * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
- *
- * @return a new PreparedStatement object containing the pre-compiled SQL
- * statement
- *
- * @exception SQLException if a database-access error occurs.
- */
- public synchronized java.sql.PreparedStatement prepareStatement(
- String sql, int resultSetType, int resultSetConcurrency)
- throws SQLException {
- checkClosed();
- PreparedStatement pStmt = null;
- if (this.cachePreparedStatements) {
- PreparedStatement.ParseInfo pStmtInfo = (PreparedStatement.ParseInfo) cachedPreparedStatementParams
- .get(sql);
- if (pStmtInfo == null) {
- pStmt = new com.mysql.jdbc.PreparedStatement(this, sql,
- this.database);
- PreparedStatement.ParseInfo parseInfo = pStmt.getParseInfo();
- if (parseInfo.statementLength < this.preparedStatementCacheMaxSqlSize) {
- if (this.cachedPreparedStatementParams.size() >= 25) {
- Iterator oldestIter = this.cachedPreparedStatementParams.keySet()
- .iterator();
- long lruTime = Long.MAX_VALUE;
- String oldestSql = null;
- while (oldestIter.hasNext()) {
- String sqlKey = (String) oldestIter.next();
- PreparedStatement.ParseInfo lruInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams
- .get(sqlKey);
- if (lruInfo.lastUsed < lruTime) {
- lruTime = lruInfo.lastUsed;
- oldestSql = sqlKey;
- }
- }
- if (oldestSql != null) {
- this.cachedPreparedStatementParams.remove(oldestSql);
- }
- }
- cachedPreparedStatementParams.put(sql, pStmt.getParseInfo());
- }
- } else {
- pStmtInfo.lastUsed = System.currentTimeMillis();
- pStmt = new com.mysql.jdbc.PreparedStatement(this, sql,
- this.database, pStmtInfo);
- }
- } else {
- pStmt = new com.mysql.jdbc.PreparedStatement(this, sql,
- this.database);
- }
- //
- // FIXME: Create warnings if can't create results of the given
- // type or concurrency
- //
- pStmt.setResultSetType(resultSetType);
- pStmt.setResultSetConcurrency(resultSetConcurrency);
- return pStmt;
- }
- /**
- * @see Connection#prepareStatement(String, int, int, int)
- */
- public java.sql.PreparedStatement prepareStatement(String sql,
- int resultSetType, int resultSetConcurrency, int resultSetHoldability)
- throws SQLException {
- if (this.pedantic) {
- if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
- throw new SQLException("HOLD_CUSRORS_OVER_COMMIT is only supported holdability level",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
- return prepareStatement(sql, resultSetType, resultSetConcurrency);
- }
- /**
- * @see Connection#prepareStatement(String, int)
- */
- public java.sql.PreparedStatement prepareStatement(String sql,
- int autoGenKeyIndex) throws SQLException {
- java.sql.PreparedStatement pStmt = prepareStatement(sql);
- ((com.mysql.jdbc.PreparedStatement) pStmt).setRetrieveGeneratedKeys(autoGenKeyIndex == Statement.RETURN_GENERATED_KEYS);
- return pStmt;
- }
- /**
- * @see Connection#prepareStatement(String, int[])
- */
- public java.sql.PreparedStatement prepareStatement(String sql,
- int[] autoGenKeyIndexes) throws SQLException {
- java.sql.PreparedStatement pStmt = prepareStatement(sql);
- ((com.mysql.jdbc.PreparedStatement) pStmt).setRetrieveGeneratedKeys((autoGenKeyIndexes != null)
- && (autoGenKeyIndexes.length > 0));
- return pStmt;
- }
- /**
- * @see Connection#prepareStatement(String, String[])
- */
- public java.sql.PreparedStatement prepareStatement(String sql,
- String[] autoGenKeyColNames) throws SQLException {
- java.sql.PreparedStatement pStmt = prepareStatement(sql);
- ((com.mysql.jdbc.PreparedStatement) pStmt).setRetrieveGeneratedKeys((autoGenKeyColNames != null)
- && (autoGenKeyColNames.length > 0));
- return pStmt;
- }
- /**
- * @see Connection#releaseSavepoint(Savepoint)
- */
- public void releaseSavepoint(Savepoint arg0) throws SQLException {
- throw new NotImplemented();
- }
- /**
- * The method rollback() drops all changes made since the previous
- * commit/rollback and releases any database locks currently held by the
- * Connection.
- *
- * @exception java.sql.SQLException if a database access error occurs
- * @throws SQLException DOCUMENT ME!
- *
- * @see commit
- */
- public void rollback() throws java.sql.SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[0];
- Debug.methodCall(this, "rollback", args);
- }
- checkClosed();
- try {
- // no-op if _relaxAutoCommit == true
- if (this.autoCommit && !this.relaxAutoCommit) {
- throw new SQLException("Can't call rollback when autocommit=true",
- SQLError.SQL_STATE_GENERAL_ERROR);
- } else if (this.transactionsSupported) {
- try {
- rollbackNoChecks();
- } catch (SQLException sqlEx) {
- // We ignore non-transactional tables if told to do so
- if (this.ignoreNonTxTables
- && (sqlEx.getErrorCode() != MysqlDefs.ER_WARNING_NOT_COMPLETE_ROLLBACK)) {
- throw sqlEx;
- }
- }
- }
- } finally {
- if (this.reconnectAtTxEnd) {
- pingAndReconnect(true);
- }
- }
- }
- /**
- * @see Connection#rollback(Savepoint)
- */
- public void rollback(Savepoint arg0) throws SQLException {
- throw new NotImplemented();
- }
- /**
- * Used by MiniAdmin to shutdown a MySQL server
- *
- * @throws SQLException if the command can not be issued.
- */
- public void shutdownServer() throws SQLException {
- try {
- this.io.sendCommand(MysqlDefs.SHUTDOWN, null, null);
- } catch (Exception ex) {
- throw new SQLException("Unhandled exception '" + ex.toString()
- + "'", SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean supportsIsolationLevel() {
- return this.hasIsolationLevels;
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean supportsQuotedIdentifiers() {
- return this.hasQuotedIdentifiers;
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean supportsTransactions() {
- return this.transactionsSupported;
- }
- /**
- * Should we use compression?
- *
- * @return should we use compression to communicate with the server?
- */
- public boolean useCompression() {
- return this.useCompression;
- }
- /**
- * Returns the paranoidErrorMessages.
- *
- * @return boolean if we should be paranoid about error messages.
- */
- public boolean useParanoidErrorMessages() {
- return paranoid;
- }
- /**
- * Should we use SSL?
- *
- * @return should we use SSL to communicate with the server?
- */
- public boolean useSSL() {
- return this.useSSL;
- }
- /**
- * Should we enable work-arounds for floating point rounding errors in the
- * server?
- *
- * @return should we use floating point work-arounds?
- */
- public boolean useStrictFloatingPoint() {
- return this.strictFloatingPoint;
- }
- /**
- * Returns the strictUpdates value.
- *
- * @return boolean
- */
- public boolean useStrictUpdates() {
- return strictUpdates;
- }
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean useTimezone() {
- return this.useTimezone;
- }
- /**
- * Should unicode character mapping be used ?
- *
- * @return should we use Unicode character mapping?
- */
- public boolean useUnicode() {
- return this.doUnicode;
- }
- /**
- * DOCUMENT ME!
- *
- * @return Returns the defaultTimeZone.
- */
- protected TimeZone getDefaultTimeZone() {
- return defaultTimeZone;
- }
- /**
- * Returns the IO channel to the server
- *
- * @return the IO channel to the server
- *
- * @throws SQLException if the connection is closed.
- */
- protected MysqlIO getIO() throws SQLException {
- if ((this.io == null) || this.isClosed) {
- throw new SQLException("Operation not allowed on closed connection",
- "08003");
- }
- return this.io;
- }
- protected int getNetWriteTimeout() {
- String netWriteTimeoutStr = (String) this.serverVariables.get(
- "net_write_timeout");
- if (netWriteTimeoutStr != null) {
- try {
- return Integer.parseInt(netWriteTimeoutStr);
- } catch (NumberFormatException nfe) {
- return Integer.MAX_VALUE;
- }
- } else {
- return Integer.MAX_VALUE;
- }
- }
- /**
- * Is this connection using unbuffered input?
- *
- * @return whether or not to use buffered input streams
- */
- protected boolean isUsingUnbufferedInput() {
- return this.useUnbufferedInput;
- }
- /**
- * Creates an IO channel to the server
- *
- * @param isForReconnect is this request for a re-connect
- *
- * @return a new MysqlIO instance connected to a server
- *
- * @throws SQLException if a database access error occurs
- */
- protected com.mysql.jdbc.MysqlIO createNewIO(boolean isForReconnect)
- throws SQLException {
- MysqlIO newIo = null;
- if (!highAvailability && !this.failedOver) {
- for (int hostIndex = 0; hostIndex < hostListSize; hostIndex++) {
- try {
- this.io = new MysqlIO(this.hostList.get(hostIndex).toString(),
- this.port, this.socketFactoryClassName, this.props,
- this, this.socketTimeout);
- this.io.doHandshake(this.user, this.password, this.database);
- this.isClosed = false;
- if (this.database.length() != 0) {
- this.io.sendCommand(MysqlDefs.INIT_DB, this.database,
- null);
- }
- // save state from old connection
- boolean autoCommit = getAutoCommit();
- int oldIsolationLevel = getTransactionIsolation();
- boolean oldReadOnly = isReadOnly();
- String oldCatalog = getCatalog();
- // Server properties might be different
- // from previous connection, so initialize
- // again...
- initializePropsFromServer(this.props);
- if (isForReconnect) {
- // Restore state from old connection
- setAutoCommit(autoCommit);
- if (this.hasIsolationLevels) {
- setTransactionIsolation(oldIsolationLevel);
- }
- setCatalog(oldCatalog);
- }
- if (hostIndex != 0) {
- setFailedOverState();
- } else {
- this.failedOver = false;
- if (hostListSize > 1) {
- setReadOnly(false);
- } else {
- setReadOnly(oldReadOnly);
- }
- }
- break; // low-level connection succeeded
- } catch (SQLException sqlEx) {
- if (this.io != null) {
- this.io.forceClose();
- }
- String sqlState = sqlEx.getSQLState();
- if ((sqlState == null)
- || !sqlState.equals(
- SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) {
- throw sqlEx;
- }
- if ((hostListSize - 1) == hostIndex) {
- throw sqlEx;
- }
- } catch (Exception unknownException) {
- if (this.io != null) {
- this.io.forceClose();
- }
- if ((hostListSize - 1) == hostIndex) {
- throw new SQLException(
- "Unable to connect to any hosts due to exception: "
- + unknownException.toString(),
- SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE);
- }
- }
- }
- } else {
- double timeout = this.initialTimeout;
- boolean connectionGood = false;
- Exception connectionException = null;
- for (int hostIndex = 0;
- (hostIndex < hostListSize) && !connectionGood;
- hostIndex++) {
- for (int attemptCount = 0;
- !connectionGood && (attemptCount < this.maxReconnects);
- attemptCount++) {
- try {
- if (this.io != null) {
- this.io.forceClose();
- }
- this.io = new MysqlIO(this.hostList.get(hostIndex)
- .toString(),
- this.port, this.socketFactoryClassName,
- this.props, this, this.socketTimeout);
- this.io.doHandshake(this.user, this.password,
- this.database);
- if (this.database.length() != 0) {
- this.io.sendCommand(MysqlDefs.INIT_DB,
- this.database, null);
- }
- ping();
- this.isClosed = false;
- // save state from old connection
- boolean autoCommit = getAutoCommit();
- int oldIsolationLevel = getTransactionIsolation();
- boolean oldReadOnly = isReadOnly();
- String oldCatalog = getCatalog();
- // Server properties might be different
- // from previous connection, so initialize
- // again...
- initializePropsFromServer(this.props);
- if (isForReconnect) {
- // Restore state from old connection
- setAutoCommit(autoCommit);
- if (this.hasIsolationLevels) {
- setTransactionIsolation(oldIsolationLevel);
- }
- setCatalog(oldCatalog);
- }
- connectionGood = true;
- if (hostIndex != 0) {
- setFailedOverState();
- } else {
- this.failedOver = false;
- if (hostListSize > 1) {
- setReadOnly(false);
- } else {
- setReadOnly(oldReadOnly);
- }
- }
- break;
- } catch (Exception EEE) {
- connectionException = EEE;
- connectionGood = false;
- }
- if (!connectionGood) {
- try {
- Thread.sleep((long) timeout * 1000);
- timeout = timeout * 2;
- } catch (InterruptedException IE) {
- ;
- }
- }
- }
- if (!connectionGood) {
- // We've really failed!
- throw new SQLException(
- "Server connection failure during transaction. Due to underlying exception: '"
- + connectionException + "'.nAttempted reconnect "
- + this.maxReconnects + " times. Giving up.",
- SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
- }
- }
- }
- if (paranoid && !highAvailability && (hostListSize <= 1)) {
- password = null;
- user = null;
- }
- return newIo;
- }
- /**
- * Closes connection and frees resources.
- *
- * @param calledExplicitly is this being called from close()
- * @param issueRollback should a rollback() be issued?
- *
- * @throws SQLException if an error occurs
- */
- protected void realClose(boolean calledExplicitly, boolean issueRollback)
- throws SQLException {
- if (Driver.TRACE) {
- Object[] args = new Object[] {
- new Boolean(calledExplicitly), new Boolean(issueRollback)
- };
- Debug.methodCall(this, "realClose", args);
- }
- SQLException sqlEx = null;
- if (!isClosed() && !getAutoCommit() && issueRollback) {
- try {
- rollback();
- } catch (SQLException ex) {
- sqlEx = ex;
- }
- }
- if (this.io != null) {
- try {
- this.io.quit();
- } catch (Exception e) {
- ;
- }
- this.io = null;
- }
- if (this.cachedPreparedStatementParams != null) {
- this.cachedPreparedStatementParams.clear();
- this.cachedPreparedStatementParams = null;
- }
- this.isClosed = true;
- if (sqlEx != null) {
- throw sqlEx;
- }
- }
- /**
- * Returns the locally mapped instance of a charset converter (to avoid
- * overhead of static synchronization).
- *
- * @param javaEncodingName the encoding name to retrieve
- *
- * @return a character converter, or null if one couldn't be mapped.
- */
- synchronized SingleByteCharsetConverter getCharsetConverter(
- String javaEncodingName) {
- SingleByteCharsetConverter converter = (SingleByteCharsetConverter) this.charsetConverterMap
- .get(javaEncodingName);
- if (converter == CHARSET_CONVERTER_NOT_AVAILABLE_MARKER) {
- return null;
- }
- if (converter == null) {
- try {
- converter = SingleByteCharsetConverter.getInstance(javaEncodingName);
- if (converter == null) {
- this.charsetConverterMap.put(javaEncodingName,
- CHARSET_CONVERTER_NOT_AVAILABLE_MARKER);
- }
- this.charsetConverterMap.put(javaEncodingName, converter);
- } catch (UnsupportedEncodingException unsupEncEx) {
- this.charsetConverterMap.put(javaEncodingName,
- CHARSET_CONVERTER_NOT_AVAILABLE_MARKER);
- converter = null;
- }
- }
- return converter;
- }
- /**
- * Returns the maximum packet size the MySQL server will accept
- *
- * @return DOCUMENT ME!
- */
- int getMaxAllowedPacket() {
- return this.maxAllowedPacket;
- }
- /**
- * DOCUMENT ME!
- *
- * @return the max rows to return for statements (by default)
- */
- int getMaxRows() {
- return this.maxRows;
- }
- /**
- * Returns the Mutex all queries are locked against
- *
- * @return DOCUMENT ME!
- *
- * @throws SQLException DOCUMENT ME!
- */
- Object getMutex() throws SQLException {
- if (this.io == null) {
- throw new SQLException("Connection.close() has already been called. Invalid operation in this state.",
- "08003");
- }
- return this.mutex;
- }
- /**
- * Returns the packet buffer size the MySQL server reported upon connection