NonRegisteringDriver.java
上传用户:tanyanyong
上传日期:2013-06-23
资源大小:1355k
文件大小:28k
源码类别:
电子政务应用
开发平台:
MultiPlatform
- /*
- 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
- */
- public boolean acceptsURL(String url) throws java.sql.SQLException {
- return (parseURL(url, null) != null);
- }
- /**
- * Try to make a database connection to the given URL. The driver should
- * return "null" if it realizes it is the wrong kind of driver to connect
- * to the given URL. This will be common, as when the JDBC driverManager
- * is asked to connect to a given URL, it passes the URL to each loaded
- * driver in turn.
- *
- * <p>
- * The driver should raise an java.sql.SQLException if it is the right
- * driver to connect to the given URL, but has trouble connecting to the
- * database.
- * </p>
- *
- * <p>
- * The java.util.Properties argument can be used to pass arbitrary string
- * tag/value pairs as connection arguments.
- * </p>
- *
- * <p>
- * My protocol takes the form:
- * <PRE>
- * jdbc:mysql://host:port/database
- * </PRE>
- * </p>
- *
- * @param url the URL of the database to connect to
- * @param info a list of arbitrary tag/value pairs as connection arguments
- *
- * @return a connection to the URL or null if it isnt us
- *
- * @exception java.sql.SQLException if a database access error occurs
- * @throws SQLException DOCUMENT ME!
- *
- * @see java.sql.Driver#connect
- */
- public java.sql.Connection connect(String url, Properties info)
- throws java.sql.SQLException {
- Properties props = null;
- if ((props = parseURL(url, info)) == null) {
- return null;
- } else {
- try {
- Connection newConn = new com.mysql.jdbc.Connection(host(props),
- port(props), props, database(props), url, this);
- return (java.sql.Connection) newConn;
- } catch (SQLException sqlEx) {
- // Don't wrap SQLExceptions, throw
- // them un-changed.
- throw sqlEx;
- } catch (Exception ex) {
- throw new SQLException(
- "Cannot load connection class because of underlying exception: '"
- + ex.toString() + "'.",
- SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
- }
- }
- }
- //
- // return the database name property
- //
- /**
- * Returns the database property from <code>props</code>
- *
- * @param props the Properties to look for the database property.
- *
- * @return the database name.
- */
- public String database(Properties props) {
- return props.getProperty("DBNAME");
- }
- /**
- * Returns the hostname property
- *
- * @param props the java.util.Properties instance to retrieve the hostname
- * from.
- *
- * @return the hostname
- */
- public String host(Properties props) {
- return props.getProperty("HOST", "localhost");
- }
- /**
- * Report whether the driver is a genuine JDBC compliant driver. A driver
- * may only report "true" here if it passes the JDBC compliance tests,
- * otherwise it is required to return false. JDBC compliance requires
- * full support for the JDBC API and full support for SQL 92 Entry Level.
- *
- * <p>
- * MySQL is not SQL92 compliant
- * </p>
- *
- * @return is this driver JDBC compliant?
- */
- public boolean jdbcCompliant() {
- return false;
- }
- /**
- * Returns the port number property
- *
- * @param props the properties to get the port number from
- *
- * @return the port number
- */
- public int port(Properties props) {
- return Integer.parseInt(props.getProperty("PORT", "3306"));
- }
- //
- // return the value of any property this driver knows about
- //
- /**
- * Returns the given property from <code>props</code>
- *
- * @param name the property name
- * @param props the property instance to look in
- *
- * @return the property value, or null if not found.
- */
- public String property(String name, Properties props) {
- return props.getProperty(name);
- }
- /**
- * Gets the drivers major version number
- *
- * @return the drivers major version number
- */
- static int getMajorVersionInternal() {
- return safeIntParse("3");
- }
- /**
- * Get the drivers minor version number
- *
- * @return the drivers minor version number
- */
- static int getMinorVersionInternal() {
- return safeIntParse("0");
- }
- /**
- * Constructs a new DriverURL, splitting the specified URL into its
- * component parts
- *
- * @param url JDBC URL to parse
- * @param defaults Default properties
- *
- * @return Properties with elements added from the url
- *
- * @exception java.sql.SQLException
- */
- //
- // This is a new URL-parser. This file no longer contains any
- // Postgresql code.
- //
- Properties parseURL(String url, Properties defaults)
- throws java.sql.SQLException {
- Properties urlProps = new Properties(defaults);
- if (url == null) {
- return null;
- } else {
- /*
- * Parse parameters after the ? in the URL and remove
- * them from the original URL.
- */
- int index = url.indexOf("?");
- if (index != -1) {
- String paramString = url.substring(index + 1, url.length());
- url = url.substring(0, index);
- StringTokenizer queryParams = new StringTokenizer(paramString,
- "&");
- while (queryParams.hasMoreTokens()) {
- StringTokenizer vp = new StringTokenizer(queryParams
- .nextToken(), "=");
- String param = "";
- if (vp.hasMoreTokens()) {
- param = vp.nextToken();
- }
- String value = "";
- if (vp.hasMoreTokens()) {
- value = vp.nextToken();
- }
- if ((value.length() > 0) && (param.length() > 0)) {
- urlProps.put(param, value);
- }
- }
- }
- StringTokenizer st = new StringTokenizer(url, ":/", true);
- if (st.hasMoreTokens()) {
- String protocol = st.nextToken();
- if (protocol != null) {
- if (!protocol.equalsIgnoreCase("jdbc")) {
- return null;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- // Look for the colon following 'jdbc'
- if (st.hasMoreTokens()) {
- String colon = st.nextToken();
- if (colon != null) {
- if (!colon.equals(":")) {
- return null;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- // Look for sub-protocol to be mysql
- if (st.hasMoreTokens()) {
- String subProto = st.nextToken();
- if (subProto != null) {
- if (!subProto.equalsIgnoreCase("mysql")) {
- return null;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- // Look for the colon following 'mysql'
- if (st.hasMoreTokens()) {
- String colon = st.nextToken();
- if (colon != null) {
- if (!colon.equals(":")) {
- return null;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- // Look for the "//" of the URL
- if (st.hasMoreTokens()) {
- String slash = st.nextToken();
- String slash2 = "";
- if (st.hasMoreTokens()) {
- slash2 = st.nextToken();
- }
- if ((slash != null) && (slash2 != null)) {
- if (!slash.equals("/") && !slash2.equals("/")) {
- return null;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- // Okay the next one is a candidate for many things
- if (st.hasMoreTokens()) {
- String token = st.nextToken();
- if (token != null) {
- if (!token.equals(":") && !token.equals("/")) {
- // Must be hostname
- urlProps.put("HOST", token);
- if (st.hasMoreTokens()) {
- token = st.nextToken();
- } else {
- return null;
- }
- }
- // Check for Port spec
- if (token.equals(":")) {
- if (st.hasMoreTokens()) {
- token = st.nextToken();
- urlProps.put("PORT", token);
- if (st.hasMoreTokens()) {
- token = st.nextToken();
- }
- }
- }
- if (token.equals("/")) {
- if (st.hasMoreTokens()) {
- token = st.nextToken();
- urlProps.put("DBNAME", token);
- // We're done
- return urlProps;
- } else {
- urlProps.put("DBNAME", "");
- return urlProps;
- }
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
- return urlProps;
- }
- private static int safeIntParse(String intAsString) {
- try {
- return Integer.parseInt(intAsString);
- } catch (NumberFormatException nfe) {
- return 0;
- }
- }
- }