diff options
Diffstat (limited to 'src/interfaces/jdbc/postgresql/Driver.java')
-rw-r--r-- | src/interfaces/jdbc/postgresql/Driver.java | 500 |
1 files changed, 264 insertions, 236 deletions
diff --git a/src/interfaces/jdbc/postgresql/Driver.java b/src/interfaces/jdbc/postgresql/Driver.java index 055a65601aa..674c96fc66d 100644 --- a/src/interfaces/jdbc/postgresql/Driver.java +++ b/src/interfaces/jdbc/postgresql/Driver.java @@ -2,12 +2,8 @@ package postgresql; import java.sql.*; import java.util.*; -import postgresql.*; /** - * @version 1.0 15-APR-1997 - * @author <A HREF="mailto:[email protected]">Adrian Hall</A> - * * The Java SQL framework allows for multiple database drivers. Each * driver should supply a class that implements the Driver interface * @@ -28,242 +24,274 @@ import postgresql.*; */ public class Driver implements java.sql.Driver { - - static - { - try - { - new Driver(); - } catch (SQLException e) { - e.printStackTrace(); - } + // These should be in sync with the backend that the driver was + // distributed with + static final int MAJORVERSION = 6; + static final int MINORVERSION = 2; + + static + { + try { + // moved the registerDriver from the constructor to here + // because some clients call the driver themselves (I know, as + // my early jdbc work did - and that was based on other examples). + // Placing it here, means that the driver is registered once only. + java.sql.DriverManager.registerDriver(new Driver()); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Construct a new driver and register it with DriverManager + * + * @exception SQLException for who knows what! + */ + public Driver() throws SQLException + { + } + + /** + * 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. + * + * The driver should raise an SQLException if it is the right driver + * to connect to the given URL, but has trouble connecting to the + * database. + * + * The java.util.Properties argument can be used to pass arbitrary + * string tag/value pairs as connection arguments. Normally, at least + * "user" and "password" properties should be included in the + * properties. + * + * Our protocol takes the form: + * <PRE> + * jdbc:postgresql://host:port/database + * </PRE> + * + * @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 SQLException if a database access error occurs + * @see java.sql.Driver#connect + */ + public java.sql.Connection connect(String url, Properties info) throws SQLException + { + if((props = parseURL(url,info))==null) + return null; + + return new Connection (host(), port(), props, database(), url, this); + } + + /** + * Returns true if the driver thinks it can open a connection to the + * given URL. Typically, drivers will return true if they understand + * the subprotocol specified in the URL and false if they don't. Our + * protocols start with jdbc:postgresql: + * + * @see java.sql.Driver#acceptsURL + * @param url the URL of the driver + * @return true if this driver accepts the given URL + * @exception SQLException if a database-access error occurs + * (Dont know why it would *shrug*) + */ + public boolean acceptsURL(String url) throws SQLException + { + if(parseURL(url,null)==null) + return false; + return true; + } + + /** + * 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. + * 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 + * + * @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 SQLException if a database-access error occurs + * @see java.sql.Driver#getPropertyInfo + */ + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException + { + return null; // We don't need anything except + // the username, which is a default + } + + /** + * Gets the drivers major version number + * + * @return the drivers major version number + */ + public int getMajorVersion() + { + return MAJORVERSION; + } + + /** + * Get the drivers minor version number + * + * @return the drivers minor version number + */ + public int getMinorVersion() + { + return MINORVERSION; + } + + /** + * 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. + */ + public boolean jdbcCompliant() + { + return false; + } + + private Properties props; + + static private String[] protocols = { "jdbc","postgresql" }; + + /** + * Constructs a new DriverURL, splitting the specified URL into its + * component parts + */ + Properties parseURL(String url,Properties defaults) throws SQLException + { + int state = -1; + Properties urlProps = new Properties(defaults); + String key = new String(); + String value = new String(); + + StringTokenizer st = new StringTokenizer(url, ":/;=&?", true); + for (int count = 0; (st.hasMoreTokens()); count++) { + String token = st.nextToken(); + + // PM June 29 1997 + // Added this, to help me understand how this works. + // Unless you want each token to be processed, leave this commented out + // but don't delete it. + //DriverManager.println("wellFormedURL: state="+state+" count="+count+" token='"+token+"'"); + + // PM Aug 2 1997 - Modified to allow multiple backends + if (count <= 3) { + if ((count % 2) == 1 && token.equals(":")) + ; + else if((count % 2) == 0) { + boolean found=(count==0)?true:false; + for(int tmp=0;tmp<protocols.length;tmp++) { + if(token.equals(protocols[tmp])) { + // PM June 29 1997 Added this property to enable the driver + // to handle multiple backend protocols. + if(count == 2 && tmp > 0) { + urlProps.put("Protocol",token); + found=true; + } + } + } + + if(found == false) + return null; + } else return null; + } + else if (count > 3) { + if (count == 4 && token.equals("/")) state = 0; + else if (count == 4) { + urlProps.put("PGDBNAME", token); + state = -2; } - - /** - * Construct a new driver and register it with DriverManager - * - * @exception SQLException for who knows what! - */ - public Driver() throws SQLException - { - java.sql.DriverManager.registerDriver(this); + else if (count == 5 && state == 0 && token.equals("/")) + state = 1; + else if (count == 5 && state == 0) + return null; + else if (count == 6 && state == 1) + urlProps.put("PGHOST", token); + else if (count == 7 && token.equals(":")) state = 2; + else if (count == 8 && state == 2) { + try { + Integer portNumber = Integer.decode(token); + urlProps.put("PGPORT", portNumber.toString()); + } catch (Exception e) { + return 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. - * - * The driver should raise an SQLException if it is the right driver - * to connect to the given URL, but has trouble connecting to the - * database. - * - * The java.util.Properties argument can be used to pass arbitrary - * string tag/value pairs as connection arguments. Normally, at least - * "user" and "password" properties should be included in the - * properties. - * - * Our protocol takes the form: - * <PRE> - * jdbc:postgresql://host:port/database - * </PRE> - * - * @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 SQLException if a database access error occurs - * @see java.sql.Driver#connect - */ - public java.sql.Connection connect(String url, Properties info) throws SQLException - { - DriverURL dr = new DriverURL(url); - int port; - - if (!(dr.protocol().equals("jdbc"))) - return null; - if (!(dr.subprotocol().equals("postgresql"))) - return null; - if (dr.host().equals("unknown")) - return null; - port = dr.port(); - if (port == -1) - port = 5432; // Default PostgreSQL port - return new Connection (dr.host(), port, info, dr.database(), url, this); + else if ((count == 7 || count == 9) && + (state == 1 || state == 2) && token.equals("/")) + state = -1; + else if (state == -1) { + urlProps.put("PGDBNAME", token); + state = -2; } - - /** - * Returns true if the driver thinks it can open a connection to the - * given URL. Typically, drivers will return true if they understand - * the subprotocol specified in the URL and false if they don't. Our - * protocols start with jdbc:postgresql: - * - * @see java.sql.Driver#acceptsURL - * @param url the URL of the driver - * @return true if this driver accepts the given URL - * @exception SQLException if a database-access error occurs - * (Dont know why it would *shrug*) - */ - public boolean acceptsURL(String url) throws SQLException - { - DriverURL dr = new DriverURL(url); - - if (dr.protocol().equals("jdbc")) - if (dr.subprotocol().equals("postgresql")) - return true; - return false; + else if (state <= -2 && (count % 2) == 1) { + // PM Aug 2 1997 - added tests for ? and & + if (token.equals(";") || token.equals("?") || token.equals("&") ) state = -3; + else if (token.equals("=")) state = -5; } - - /** - * 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. - * 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 - * - * @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 SQLException if a database-access error occurs - * @see java.sql.Driver#getPropertyInfo - */ - public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException - { - return null; // We don't need anything except - // the username, which is a default - } - - /** - * Gets the drivers major version number - * - * @return the drivers major version number - */ - public int getMajorVersion() - { - return 1; - } - - /** - * Get the drivers minor version number - * - * @return the drivers minor version number - */ - public int getMinorVersion() - { - return 0; - } - - /** - * 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. - */ - public boolean jdbcCompliant() - { - return false; + else if (state <= -2 && (count % 2) == 0) { + if (state == -3) key = token; + else if (state == -5) { + value = token; + //DriverManager.println("put("+key+","+value+")"); + urlProps.put(key, value); + state = -2; + } } + } + } + + // PM June 29 1997 + // This now outputs the properties only if we are logging + if(DriverManager.getLogStream() != null) + urlProps.list(DriverManager.getLogStream()); + + return urlProps; + + } + + /** + * Returns the hostname portion of the URL + */ + public String host() + { + return props.getProperty("PGHOST","localhost"); + } + + /** + * Returns the port number portion of the URL + * or -1 if no port was specified + */ + public int port() + { + return Integer.parseInt(props.getProperty("PGPORT","5432")); + } + + /** + * Returns the database name of the URL + */ + public String database() + { + return props.getProperty("PGDBNAME"); + } + + /** + * Returns any property + */ + public String property(String name) + { + return props.getProperty(name); + } } -/** - * The DriverURL class splits a JDBC URL into its subcomponents - * - * protocol:subprotocol:/[/host[:port]/][database] - */ -class DriverURL -{ - private String protocol, subprotocol, host, database; - private int port = -1; - - /** - * Constructs a new DriverURL, splitting the specified URL into its - * component parts - */ - public DriverURL(String url) throws SQLException - { - int a, b, c; - String tmp, hostport, dbportion; - - a = url.indexOf(':'); - if (a == -1) - throw new SQLException("Bad URL Protocol specifier"); - b = url.indexOf(':', a+1); - if (b == -1) - throw new SQLException("Bad URL Subprotocol specifier"); - protocol = new String(url.substring(0, a)); - subprotocol = new String(url.substring(a+1, b)); - tmp = new String(url.substring(b+1, url.length())); - if (tmp.length() < 2) - throw new SQLException("Bad URL Database specifier"); - if (!tmp.substring(0, 2).equals("//")) - { - host = new String("unknown"); - port = -1; - database = new String(tmp.substring(1, tmp.length())); - return; - } - dbportion = new String(tmp.substring(2, tmp.length())); - c = dbportion.indexOf('/'); - if (c == -1) - throw new SQLException("Bad URL Database specifier"); - a = dbportion.indexOf(':'); - if (a == -1) - { - host = new String(dbportion.substring(0, c)); - port = -1; - database = new String(dbportion.substring(c+1, dbportion.length())); - } else { - host = new String(dbportion.substring(0, a)); - port = Integer.valueOf(dbportion.substring(a+1, c)).intValue(); - database = new String(dbportion.substring(c+1, dbportion.length())); - } - } - - /** - * Returns the protocol name of the DriverURL - */ - public String protocol() - { - return protocol; - } - - /** - * Returns the subprotocol name of the DriverURL - */ - public String subprotocol() - { - return subprotocol; - } - - /** - * Returns the hostname portion of the URL - */ - public String host() - { - return host; - } - - /** - * Returns the port number portion of the URL - * or -1 if no port was specified - */ - public int port() - { - return port; - } - - /** - * Returns the database name of the URL - */ - public String database() - { - return database; - } -} |