/*
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.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* The Java SQL framework allows for multiple database drivers. Each driver
* should supply a class that implements the Driver interface
*
* <p>
* The DriverManager will try to load as many drivers as it can find and then
* for any given connection request, it will ask each driver in turn to try to
* connect to the target URL.
* </p>
*
* <p>
* It is strongly recommended that each Driver class should be small and
* standalone so that the Driver class can be loaded and queried without
* bringing in vast quantities of supporting code.
* </p>
*
* <p>
* When a Driver class is loaded, it should create an instance of itself and
* register it with the DriverManager. This means that a user can load and
* register a driver by doing Class.forName("foo.bah.Driver")
* </p>
*
* @author Mark Matthews
* @version $Id: NonRegisteringDriver.java,v 1.1.2.10 2004/02/13 22:31:53 mmatthew Exp $
*
* @see org.gjt.mm.mysql.Connection
* @see java.sql.Driver
*/
public class NonRegisteringDriver implements java.sql.Driver {
/** Should the driver generate debugging output? */
public static final boolean DEBUG = false;
/** Should the driver generate method-call traces? */
public static final boolean TRACE = false;
/**
* Construct a new driver and register it with DriverManager
*
* @throws java.sql.SQLException if a database error occurs.
*/
public NonRegisteringDriver() throws java.sql.SQLException {
// Required for Class.forName().newInstance()
}
/**
* Gets the drivers major version number
*
* @return the drivers major version number
*/
public int getMajorVersion() {
return getMajorVersionInternal();
}
/**
* Get the drivers minor version number
*
* @return the drivers minor version number
*/
public int getMinorVersion() {
return getMinorVersionInternal();
}
/**
* The getPropertyInfo method is intended to allow a generic GUI tool to
* discover what properties it should prompt a human for in order to get
* enough information to connect to a database.
*
* <p>
* Note that depending on the values the human has supplied so far,
* additional values may become necessary, so it may be necessary to
* iterate through several calls to getPropertyInfo
* </p>
*
* @param url the Url of the database to connect to
* @param info a proposed list of tag/value pairs that will be sent on
* connect open.
*
* @return An array of DriverPropertyInfo objects describing possible
* properties. This array may be an empty array if no properties
* are required
*
* @exception java.sql.SQLException if a database-access error occurs
*
* @see java.sql.Driver#getPropertyInfo
*/
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws java.sql.SQLException {
if (info == null) {
info = new Properties();
}
if ((url != null) && url.startsWith("jdbc:mysql://")) {
info = parseURL(url, info);
}
DriverPropertyInfo hostProp = new DriverPropertyInfo("HOST",
info.getProperty("HOST"));
hostProp.required = true;
hostProp.description = "Hostname of MySQL Server";
DriverPropertyInfo portProp = new DriverPropertyInfo("PORT",
info.getProperty("PORT", "3306"));
portProp.required = false;
portProp.description = "Port number of MySQL Server";
DriverPropertyInfo dbProp = new DriverPropertyInfo("DBNAME",
info.getProperty("DBNAME"));
dbProp.required = false;
dbProp.description = "Database name";
DriverPropertyInfo userProp = new DriverPropertyInfo("user",
info.getProperty("user"));
userProp.required = true;
userProp.description = "Username to authenticate as";
DriverPropertyInfo passwordProp = new DriverPropertyInfo("password",
info.getProperty("password"));
passwordProp.required = true;
passwordProp.description = "Password to use for authentication";
DriverPropertyInfo autoReconnect = new DriverPropertyInfo("autoReconnect",
info.getProperty("autoReconnect", "false"));
autoReconnect.required = false;
autoReconnect.choices = new String[] { "true", "false" };
autoReconnect.description = "Should the driver try to re-establish bad connections?";
DriverPropertyInfo maxReconnects = new DriverPropertyInfo("maxReconnects",
info.getProperty("maxReconnects", "3"));
maxReconnects.required = false;
maxReconnects.description = "Maximum number of reconnects to attempt if autoReconnect is true";
;
DriverPropertyInfo initialTimeout = new DriverPropertyInfo("initialTimeout",
info.getProperty("initialTimeout", "2"));
initialTimeout.required = false;
initialTimeout.description = "Initial timeout (seconds) to wait between failed connections";
DriverPropertyInfo profileSql = new DriverPropertyInfo("profileSql",
info.getProperty("profileSql", "false"));
profileSql.required = false;
profileSql.choices = new String[] { "true", "false" };
profileSql.description = "Trace queries and their execution/fetch times on STDERR (true/false) defaults to false";
;
DriverPropertyInfo socketTimeout = new DriverPropertyInfo("socketTimeout",
info.getProperty("socketTimeout", "0"));
socketTimeout.required = false;
socketTimeout.description = "Timeout on network socket operations (0 means no timeout)";
;
DriverPropertyInfo useSSL = new DriverPropertyInfo("useSSL",
info.getProperty("useSSL", "false"));
useSSL.required = false;
useSSL.choices = new String[] { "true", "false" };
useSSL.description = "Use SSL when communicating with the server?";
;
DriverPropertyInfo useCompression = new DriverPropertyInfo("useCompression",
info.getProperty("useCompression", "false"));
useCompression.required = false;
useCompression.choices = new String[] { "true", "false" };
useCompression.description = "Use zlib compression when communicating with the server?";
;
DriverPropertyInfo paranoid = new DriverPropertyInfo("paranoid",
info.getProperty("paranoid", "false"));
paranoid.required = false;
paranoid.choices = new String[] { "true", "false" };
paranoid.description = "Expose sensitive information in error messages and clear "
+ "data structures holding sensitiven data when possible?";
;
DriverPropertyInfo useHostsInPrivileges = new DriverPropertyInfo("useHostsInPrivileges",
info.getProperty("useHostsInPrivileges", "true"));
useHostsInPrivileges.required = false;
useHostsInPrivileges.choices = new String[] { "true", "false" };
useHostsInPrivileges.description = "Add '@hostname' to users in DatabaseMetaData.getColumn/TablePrivileges()";
;
DriverPropertyInfo interactiveClient = new DriverPropertyInfo("interactiveClient",
info.getProperty("interactiveClient", "false"));
interactiveClient.required = false;
interactiveClient.choices = new String[] { "true", "false" };
interactiveClient.description = "Set the CLIENT_INTERACTIVE flag, which tells MySQL "
+ "to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT";
;
DriverPropertyInfo useTimezone = new DriverPropertyInfo("useTimezone",
info.getProperty("useTimezone", "false"));
useTimezone.required = false;
useTimezone.choices = new String[] { "true", "false" };
useTimezone.description = "Convert time/date types between client and server timezones";
DriverPropertyInfo serverTimezone = new DriverPropertyInfo("serverTimezone",
info.getProperty("serverTimezone", ""));
serverTimezone.required = false;
serverTimezone.description = "Override detection/mapping of timezone. Used when timezone from server doesn't map to Java timezone";
DriverPropertyInfo connectTimeout = new DriverPropertyInfo("connectTimeout",
info.getProperty("connectTimeout", "0"));
connectTimeout.required = false;
connectTimeout.description = "Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'.";
DriverPropertyInfo queriesBeforeRetryMaster = new DriverPropertyInfo("queriesBeforeRetryMaster",
info.getProperty("queriesBeforeRetryMaster", "50"));
queriesBeforeRetryMaster.required = false;
queriesBeforeRetryMaster.description = "Number of queries to issue before falling back to master when failed over "
+ "(when using multi-host failover). Whichever condition is met first, "
+ "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an "
+ "attempt to be made to reconnect to the master. Defaults to 50.";
;
DriverPropertyInfo secondsBeforeRetryMaster = new DriverPropertyInfo("secondsBeforeRetryMaster",
info.getProperty("secondsBeforeRetryMaster", "30"));
secondsBeforeRetryMaster.required = false;
secondsBeforeRetryMaster.description = "How long should the driver wait, when failed over, before attempting "
+ "to reconnect to the master server? Whichever condition is met first, "
+ "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an "
+ "attempt to be made to reconnect to the master. Time in seconds, defaults to 30";
DriverPropertyInfo useStreamLengthsInPrepStmts = new DriverPropertyInfo("useStreamLengthsInPrepStmts",
info.getProperty("useStreamLengthsInPrepStmts", "true"));
useStreamLengthsInPrepStmts.required = false;
useStreamLengthsInPrepStmts.choices = new String[] { "true", "false" };
useStreamLengthsInPrepStmts.description = "Honor stream length parameter in "
+ "PreparedStatement/ResultSet.setXXXStream() method calls (defaults to 'true')";
DriverPropertyInfo continueBatchOnError = new DriverPropertyInfo("continueBatchOnError",
info.getProperty("continueBatchOnError", "true"));
continueBatchOnError.required = false;
continueBatchOnError.choices = new String[] { "true", "false" };
continueBatchOnError.description = "Should the driver continue processing batch commands if "
+ "one statement fails. The JDBC spec allows either way (defaults to 'true').";
DriverPropertyInfo allowLoadLocalInfile = new DriverPropertyInfo("allowLoadLocalInfile",
info.getProperty("allowLoadLocalInfile", "true"));
allowLoadLocalInfile.required = false;
allowLoadLocalInfile.choices = new String[] { "true", "false" };
allowLoadLocalInfile.description = "Should the driver allow use of 'LOAD DATA LOCAL INFILE...' (defaults to 'true').";
DriverPropertyInfo strictUpdates = new DriverPropertyInfo("strictUpdates",
info.getProperty("strictUpdates", "true"));
strictUpdates.required = false;
strictUpdates.choices = new String[] { "true", "false" };
strictUpdates.description = "Should the driver do strict checking (all primary keys selected) of updatable result sets?...' (defaults to 'true').";
DriverPropertyInfo ignoreNonTxTables = new DriverPropertyInfo("ignoreNonTxTables",
info.getProperty("ignoreNonTxTables", "false"));
ignoreNonTxTables.required = false;
ignoreNonTxTables.choices = new String[] { "true", "false" };
ignoreNonTxTables.description = "Ignore non-transactional table warning for rollback? (defaults to 'false').";
DriverPropertyInfo clobberStreamingResults = new DriverPropertyInfo("clobberStreamingResults",
info.getProperty("clobberStreamingResults", "false"));
clobberStreamingResults.required = false;
clobberStreamingResults.choices = new String[] { "true", "false" };
clobberStreamingResults.description = "This will cause a 'streaming' ResultSet to be automatically closed, "
+ "and any oustanding data still streaming from the server to be discarded if another query is executed "
+ "before all the data has been read from the server.";
DriverPropertyInfo reconnectAtTxEnd = new DriverPropertyInfo("reconnectAtTxEnd",
info.getProperty("reconnectAtTxEnd", "false"));
reconnectAtTxEnd.required = false;
reconnectAtTxEnd.choices = new String[] { "true", "false" };
reconnectAtTxEnd.description = "If autoReconnect is set to true, should the driver attempt reconnections"
+ "at the end of every transaction? (true/false, defaults to false)";
DriverPropertyInfo alwaysClearStream = new DriverPropertyInfo("alwaysClearStream",
info.getProperty("alwaysClearStream", "false"));
alwaysClearStream.required = false;
alwaysClearStream.choices = new String[] { "true", "false" };
alwaysClearStream.description = "Should the driver clear any remaining data from the input stream before issuing"
+ " a query? Normally not needed (approx 1-2% perf. penalty, true/false, defaults to false)";
DriverPropertyInfo cachePrepStmts = new DriverPropertyInfo("cachePrepStmts",
info.getProperty("cachePrepStmts", "false"));
cachePrepStmts.required = false;
cachePrepStmts.choices = new String[] { "true", "false" };
cachePrepStmts.description = "Should the driver cache the parsing stage of PreparedStatements (true/false, default is 'false')";
DriverPropertyInfo prepStmtCacheSize = new DriverPropertyInfo("prepStmtCacheSize",
info.getProperty("prepStmtCacheSize", "25"));
prepStmtCacheSize.required = false;
prepStmtCacheSize.description = "If prepared statement caching is enabled, "
+ "how many prepared statements should be cached? (default is '25')";
DriverPropertyInfo prepStmtCacheSqlLimit = new DriverPropertyInfo("prepStmtCacheSqlLimit",
info.getProperty("prepStmtCacheSqlLimit", "256"));
prepStmtCacheSqlLimit.required = false;
prepStmtCacheSqlLimit.description = "If prepared statement caching is enabled, "
+ "what's the largest SQL the driver will cache the parsing for? (in chars, default is '256')";
DriverPropertyInfo useUnbufferedInput = new DriverPropertyInfo("useUnbufferedInput",
info.getProperty("useUnbufferedInput", "true"));
useUnbufferedInput.required = false;
useUnbufferedInput.description = "Don't use BufferedInputStream for reading data from the server true/false (default is 'true')";
DriverPropertyInfo[] dpi = {
hostProp, portProp, dbProp, userProp, passwordProp, autoReconnect,
maxReconnects, initialTimeout, profileSql, socketTimeout, useSSL,
paranoid, useHostsInPrivileges, interactiveClient, useCompression,
useTimezone, serverTimezone, connectTimeout,
secondsBeforeRetryMaster, queriesBeforeRetryMaster,
useStreamLengthsInPrepStmts, continueBatchOnError,
allowLoadLocalInfile, strictUpdates, ignoreNonTxTables,
reconnectAtTxEnd, alwaysClearStream, cachePrepStmts,
prepStmtCacheSize, prepStmtCacheSqlLimit, useUnbufferedInput
};
return dpi;
}
/**
* Typically, drivers will return true if they understand the subprotocol
* specified in the URL and false if they don't. This driver's protocols
* start with jdbc:mysql:
*
* @param url the URL of the driver
*
* @return true if this driver accepts the given URL
*
* @exception java.sql.SQLException if a database-access error occurs
*
* @see java.sql.Driver#acceptsURL
*/