aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Lind <barry@xythos.com>2002-06-11 02:55:16 +0000
committerBarry Lind <barry@xythos.com>2002-06-11 02:55:16 +0000
commitb465f5307f9f5506beb1edbcc0fb56eed7c29c12 (patch)
tree8b9c3b3635d22ac8e0983c28ba761ca231469c05 /src
parent8d1c1d40ec25424d08539cdd358cfcc437adeb63 (diff)
downloadpostgresql-b465f5307f9f5506beb1edbcc0fb56eed7c29c12.tar.gz
postgresql-b465f5307f9f5506beb1edbcc0fb56eed7c29c12.zip
The patch does the following:
Allows you to set the loglevel at runtime by adding ?loglevel=X to the connection URL, where 1 = INFO and 2 = DEBUG. Automatically turns on logging by calling DriverManager.setPrintWriter(new PrintWriter(System.out)) if one is not already set. Adds a Driver.info() message that prints out the version number Adds member variables logDebug and logInfo that can be checked before making logging methods calls Adds a build number to the version number string. This build number will need to be manually incremented when we see fit. ---------------------------------------------------------------------- Modified Files: org/postgresql/Connection.java org/postgresql/Driver.java.in org/postgresql/fastpath/Fastpath.java org/postgresql/jdbc1/DatabaseMetaData.java org/postgresql/jdbc2/Connection.java org/postgresql/jdbc2/DatabaseMetaData.java org/postgresql/largeobject/LargeObjectManager.java org/postgresql/util/PSQLException.java org/postgresql/util/Serialize.java ----------------------------------------------------------------------
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/jdbc/org/postgresql/Connection.java2461
-rw-r--r--src/interfaces/jdbc/org/postgresql/Driver.java.in124
-rw-r--r--src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java4
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java5
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java10
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java160
-rw-r--r--src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java3
-rw-r--r--src/interfaces/jdbc/org/postgresql/util/Serialize.java23
8 files changed, 1378 insertions, 1412 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/Connection.java
index 96b85c78ce7..7951ddd1ecb 100644
--- a/src/interfaces/jdbc/org/postgresql/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/Connection.java
@@ -1,1215 +1,1246 @@
-package org.postgresql;
-
-import java.io.*;
-import java.net.*;
-import java.sql.*;
-import java.util.*;
-import org.postgresql.Driver;
-import org.postgresql.Field;
-import org.postgresql.fastpath.*;
-import org.postgresql.largeobject.*;
-import org.postgresql.util.*;
-import org.postgresql.core.*;
-
-/*
- * $Id: Connection.java,v 1.47 2002/05/17 01:19:19 tgl Exp $
- *
- * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
- * JDBC2 versions of the Connection class.
- *
- */
-public abstract class Connection
-{
- // This is the network stream associated with this connection
- public PG_Stream pg_stream;
-
- private String PG_HOST;
- private int PG_PORT;
- private String PG_USER;
- private String PG_DATABASE;
- private boolean PG_STATUS;
- private String compatible;
-
- /*
- The encoding to use for this connection.
- */
- private Encoding encoding = Encoding.defaultEncoding();
-
- private String dbVersionNumber;
-
- public boolean CONNECTION_OK = true;
- public boolean CONNECTION_BAD = false;
-
- public boolean autoCommit = true;
- public boolean readOnly = false;
-
- public Driver this_driver;
- private String this_url;
- private String cursor = null; // The positioned update cursor name
-
- // These are new for v6.3, they determine the current protocol versions
- // supported by this version of the driver. They are defined in
- // src/include/libpq/pqcomm.h
- protected static final int PG_PROTOCOL_LATEST_MAJOR = 2;
- protected static final int PG_PROTOCOL_LATEST_MINOR = 0;
-
- private static final int AUTH_REQ_OK = 0;
- private static final int AUTH_REQ_KRB4 = 1;
- private static final int AUTH_REQ_KRB5 = 2;
- private static final int AUTH_REQ_PASSWORD = 3;
- private static final int AUTH_REQ_CRYPT = 4;
- private static final int AUTH_REQ_MD5 = 5;
-
-
- // These are used to cache oids, PGTypes and SQLTypes
- private static Hashtable sqlTypeCache = new Hashtable(); // oid -> SQLType
- private static Hashtable pgTypeCache = new Hashtable(); // oid -> PGType
- private static Hashtable typeOidCache = new Hashtable(); //PGType -> oid
-
- // Now handle notices as warnings, so things like "show" now work
- public SQLWarning firstWarning = null;
-
- /*
- * Cache of the current isolation level
- */
- private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
-
- // The PID an cancellation key we get from the backend process
- public int pid;
- public int ckey;
-
- /*
- * This is called by Class.forName() from within org.postgresql.Driver
- */
- public Connection()
- {}
-
- public void cancelQuery() throws SQLException
- {
- PG_Stream cancelStream = null;
- try {
- cancelStream = new PG_Stream(PG_HOST, PG_PORT);
- } catch (ConnectException cex) {
- // Added by Peter Mount <peter@retep.org.uk>
- // ConnectException is thrown when the connection cannot be made.
- // we trap this an return a more meaningful message for the end user
- throw new PSQLException ("postgresql.con.refused");
- } catch (IOException e) {
- throw new PSQLException ("postgresql.con.failed",e);
- }
-
- // Now we need to construct and send a cancel packet
- try {
- cancelStream.SendInteger(16, 4);
- cancelStream.SendInteger(80877102, 4);
- cancelStream.SendInteger(pid, 4);
- cancelStream.SendInteger(ckey, 4);
- cancelStream.flush();
- }
- catch(IOException e) {
- throw new PSQLException("postgresql.con.failed",e);
- }
- finally {
- try {
- if(cancelStream != null)
- cancelStream.close();
- }
- catch(IOException e) {} // Ignore
- }
- }
-
- /*
- * This method actually opens the connection. It is called by Driver.
- *
- * @param host the hostname of the database back end
- * @param port the port number of the postmaster process
- * @param info a Properties[] thing of the user and password
- * @param database the database to connect to
- * @param u the URL of the connection
- * @param d the Driver instantation of the connection
- * @return a valid connection profile
- * @exception SQLException if a database access error occurs
- */
- protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
- {
- firstWarning = null;
-
- // Throw an exception if the user or password properties are missing
- // This occasionally occurs when the client uses the properties version
- // of getConnection(), and is a common question on the email lists
- if (info.getProperty("user") == null)
- throw new PSQLException("postgresql.con.user");
-
- this_driver = d;
- this_url = url;
-
- PG_DATABASE = database;
- PG_USER = info.getProperty("user");
-
- String password = info.getProperty("password", "");
- PG_PORT = port;
-
- PG_HOST = host;
- PG_STATUS = CONNECTION_BAD;
-
- if (info.getProperty("compatible") == null)
- {
- compatible = d.getMajorVersion() + "." + d.getMinorVersion();
- }
- else
- {
- compatible = info.getProperty("compatible");
- }
-
- // Now make the initial connection
- try
- {
- pg_stream = new PG_Stream(host, port);
- }
- catch (ConnectException cex)
- {
- // Added by Peter Mount <peter@retep.org.uk>
- // ConnectException is thrown when the connection cannot be made.
- // we trap this an return a more meaningful message for the end user
- throw new PSQLException ("postgresql.con.refused");
- }
- catch (IOException e)
- {
- throw new PSQLException ("postgresql.con.failed", e);
- }
-
- // Now we need to construct and send a startup packet
- try
- {
- new StartupPacket(PG_PROTOCOL_LATEST_MAJOR,
- PG_PROTOCOL_LATEST_MINOR,
- PG_USER,
- database).writeTo(pg_stream);
-
- // now flush the startup packets to the backend
- pg_stream.flush();
-
- // Now get the response from the backend, either an error message
- // or an authentication request
- int areq = -1; // must have a value here
- do
- {
- int beresp = pg_stream.ReceiveChar();
- String salt = null;
- switch (beresp)
- {
- case 'E':
- // An error occured, so pass the error message to the
- // user.
- //
- // The most common one to be thrown here is:
- // "User authentication failed"
- //
- throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding));
-
- case 'R':
- // Get the type of request
- areq = pg_stream.ReceiveIntegerR(4);
- // Get the crypt password salt if there is one
- if (areq == AUTH_REQ_CRYPT)
- {
- byte[] rst = new byte[2];
- rst[0] = (byte)pg_stream.ReceiveChar();
- rst[1] = (byte)pg_stream.ReceiveChar();
- salt = new String(rst, 0, 2);
- Driver.debug("Crypt salt=" + salt);
- }
-
- // Or get the md5 password salt if there is one
- if (areq == AUTH_REQ_MD5)
- {
- byte[] rst = new byte[4];
- rst[0] = (byte)pg_stream.ReceiveChar();
- rst[1] = (byte)pg_stream.ReceiveChar();
- rst[2] = (byte)pg_stream.ReceiveChar();
- rst[3] = (byte)pg_stream.ReceiveChar();
- salt = new String(rst, 0, 4);
- Driver.debug("MD5 salt=" + salt);
- }
-
- // now send the auth packet
- switch (areq)
- {
- case AUTH_REQ_OK:
- break;
-
- case AUTH_REQ_KRB4:
- Driver.debug("postgresql: KRB4");
- throw new PSQLException("postgresql.con.kerb4");
-
- case AUTH_REQ_KRB5:
- Driver.debug("postgresql: KRB5");
- throw new PSQLException("postgresql.con.kerb5");
-
- case AUTH_REQ_PASSWORD:
- Driver.debug("postgresql: PASSWORD");
- pg_stream.SendInteger(5 + password.length(), 4);
- pg_stream.Send(password.getBytes());
- pg_stream.SendInteger(0, 1);
- pg_stream.flush();
- break;
-
- case AUTH_REQ_CRYPT:
- Driver.debug("postgresql: CRYPT");
- String crypted = UnixCrypt.crypt(salt, password);
- pg_stream.SendInteger(5 + crypted.length(), 4);
- pg_stream.Send(crypted.getBytes());
- pg_stream.SendInteger(0, 1);
- pg_stream.flush();
- break;
-
- case AUTH_REQ_MD5:
- Driver.debug("postgresql: MD5");
- byte[] digest = MD5Digest.encode(PG_USER, password, salt);
- pg_stream.SendInteger(5 + digest.length, 4);
- pg_stream.Send(digest);
- pg_stream.SendInteger(0, 1);
- pg_stream.flush();
- break;
-
- default:
- throw new PSQLException("postgresql.con.auth", new Integer(areq));
- }
- break;
-
- default:
- throw new PSQLException("postgresql.con.authfail");
- }
- }
- while (areq != AUTH_REQ_OK);
-
- }
- catch (IOException e)
- {
- throw new PSQLException("postgresql.con.failed", e);
- }
-
-
- // As of protocol version 2.0, we should now receive the cancellation key and the pid
- int beresp;
- do {
- beresp = pg_stream.ReceiveChar();
- switch (beresp)
- {
- case 'K':
- pid = pg_stream.ReceiveIntegerR(4);
- ckey = pg_stream.ReceiveIntegerR(4);
- break;
- case 'E':
- throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));
- case 'N':
- addWarning(pg_stream.ReceiveString(encoding));
- break;
- default:
- throw new PSQLException("postgresql.con.setup");
- }
- } while (beresp == 'N');
-
- // Expect ReadyForQuery packet
- do {
- beresp = pg_stream.ReceiveChar();
- switch (beresp)
- {
- case 'Z':
- break;
- case 'N':
- addWarning(pg_stream.ReceiveString(encoding));
- break;
- case 'E':
- throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));
- default:
- throw new PSQLException("postgresql.con.setup");
- }
- } while (beresp == 'N');
- // "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte,
- // otherwise it's hardcoded to 'SQL_ASCII'.
- // If the backend doesn't know about multibyte we can't assume anything about the encoding
- // used, so we denote this with 'UNKNOWN'.
- //Note: begining with 7.2 we should be using pg_client_encoding() which
- //is new in 7.2. However it isn't easy to conditionally call this new
- //function, since we don't yet have the information as to what server
- //version we are talking to. Thus we will continue to call
- //getdatabaseencoding() until we drop support for 7.1 and older versions
- //or until someone comes up with a conditional way to run one or
- //the other function depending on server version that doesn't require
- //two round trips to the server per connection
-
- final String encodingQuery =
- "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
-
- // Set datestyle and fetch db encoding in a single call, to avoid making
- // more than one round trip to the backend during connection startup.
-
- java.sql.ResultSet resultSet =
- ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
-
- if (! resultSet.next())
- {
- throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
- }
- String version = resultSet.getString(1);
- dbVersionNumber = extractVersionNumber(version);
-
- String dbEncoding = resultSet.getString(2);
- encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
-
- // Initialise object handling
- initObjectTypes();
-
- // Mark the connection as ok, and cleanup
- PG_STATUS = CONNECTION_OK;
- }
-
- // These methods used to be in the main Connection implementation. As they
- // are common to all implementations (JDBC1 or 2), they are placed here.
- // This should make it easy to maintain the two specifications.
-
- /*
- * This adds a warning to the warning chain.
- * @param msg message to add
- */
- public void addWarning(String msg)
- {
- // Add the warning to the chain
- if (firstWarning != null)
- firstWarning.setNextWarning(new SQLWarning(msg));
- else
- firstWarning = new SQLWarning(msg);
-
- // Now check for some specific messages
-
- // This is obsolete in 6.5, but I've left it in here so if we need to use this
- // technique again, we'll know where to place it.
- //
- // This is generated by the SQL "show datestyle"
- //if (msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
- //// 13 is the length off "DateStyle is "
- //msg = msg.substring(msg.indexOf("DateStyle is ")+13);
- //
- //for(int i=0;i<dateStyles.length;i+=2)
- //if (msg.startsWith(dateStyles[i]))
- //currentDateStyle=i+1; // this is the index of the format
- //}
- }
-
- /*
- * Send a query to the backend. Returns one of the ResultSet
- * objects.
- *
- * <B>Note:</B> there does not seem to be any method currently
- * in existance to return the update count.
- *
- * @param sql the SQL statement to be executed
- * @return a ResultSet holding the results
- * @exception SQLException if a database error occurs
- */
- public java.sql.ResultSet ExecSQL(String sql) throws SQLException
- {
- return ExecSQL(sql, null);
- }
-
- /*
- * Send a query to the backend. Returns one of the ResultSet
- * objects.
- *
- * <B>Note:</B> there does not seem to be any method currently
- * in existance to return the update count.
- *
- * @param sql the SQL statement to be executed
- * @param stat The Statement associated with this query (may be null)
- * @return a ResultSet holding the results
- * @exception SQLException if a database error occurs
- */
- public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException
- {
- return new QueryExecutor(sql, stat, pg_stream, this).execute();
- }
-
- /*
- * In SQL, a result table can be retrieved through a cursor that
- * is named. The current row of a result can be updated or deleted
- * using a positioned update/delete statement that references the
- * cursor name.
- *
- * We support one cursor per connection.
- *
- * setCursorName sets the cursor name.
- *
- * @param cursor the cursor name
- * @exception SQLException if a database access error occurs
- */
- public void setCursorName(String cursor) throws SQLException
- {
- this.cursor = cursor;
- }
-
- /*
- * getCursorName gets the cursor name.
- *
- * @return the current cursor name
- * @exception SQLException if a database access error occurs
- */
- public String getCursorName() throws SQLException
- {
- return cursor;
- }
-
- /*
- * We are required to bring back certain information by
- * the DatabaseMetaData class. These functions do that.
- *
- * Method getURL() brings back the URL (good job we saved it)
- *
- * @return the url
- * @exception SQLException just in case...
- */
- public String getURL() throws SQLException
- {
- return this_url;
- }
-
- /*
- * Method getUserName() brings back the User Name (again, we
- * saved it)
- *
- * @return the user name
- * @exception SQLException just in case...
- */
- int lastMessage = 0;
- public String getUserName() throws SQLException
- {
- return PG_USER;
- }
-
- /*
- * Get the character encoding to use for this connection.
- */
- public Encoding getEncoding() throws SQLException
- {
- return encoding;
- }
-
- /*
- * This returns the Fastpath API for the current connection.
- *
- * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
- * functions on the org.postgresql backend itself.
- *
- * <p>It is primarily used by the LargeObject API
- *
- * <p>The best way to use this is as follows:
- *
- * <p><pre>
- * import org.postgresql.fastpath.*;
- * ...
- * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();
- * </pre>
- *
- * <p>where myconn is an open Connection to org.postgresql.
- *
- * @return Fastpath object allowing access to functions on the org.postgresql
- * backend.
- * @exception SQLException by Fastpath when initialising for first time
- */
- public Fastpath getFastpathAPI() throws SQLException
- {
- if (fastpath == null)
- fastpath = new Fastpath(this, pg_stream);
- return fastpath;
- }
-
- // This holds a reference to the Fastpath API if already open
- private Fastpath fastpath = null;
-
- /*
- * This returns the LargeObject API for the current connection.
- *
- * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
- * functions on the org.postgresql backend itself.
- *
- * <p>The best way to use this is as follows:
- *
- * <p><pre>
- * import org.postgresql.largeobject.*;
- * ...
- * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();
- * </pre>
- *
- * <p>where myconn is an open Connection to org.postgresql.
- *
- * @return LargeObject object that implements the API
- * @exception SQLException by LargeObject when initialising for first time
- */
- public LargeObjectManager getLargeObjectAPI() throws SQLException
- {
- if (largeobject == null)
- largeobject = new LargeObjectManager(this);
- return largeobject;
- }
-
- // This holds a reference to the LargeObject API if already open
- private LargeObjectManager largeobject = null;
-
- /*
- * This method is used internally to return an object based around
- * org.postgresql's more unique data types.
- *
- * <p>It uses an internal Hashtable to get the handling class. If the
- * type is not supported, then an instance of org.postgresql.util.PGobject
- * is returned.
- *
- * You can use the getValue() or setValue() methods to handle the returned
- * object. Custom objects can have their own methods.
- *
- * In 6.4, this is extended to use the org.postgresql.util.Serialize class to
- * allow the Serialization of Java Objects into the database without using
- * Blobs. Refer to that class for details on how this new feature works.
- *
- * @return PGobject for this type, and set to value
- * @exception SQLException if value is not correct for this type
- * @see org.postgresql.util.Serialize
- */
- public Object getObject(String type, String value) throws SQLException
- {
- try
- {
- Object o = objectTypes.get(type);
-
- // If o is null, then the type is unknown, so check to see if type
- // is an actual table name. If it does, see if a Class is known that
- // can handle it
- if (o == null)
- {
- Serialize ser = new Serialize(this, type);
- objectTypes.put(type, ser);
- return ser.fetch(Integer.parseInt(value));
- }
-
- // If o is not null, and it is a String, then its a class name that
- // extends PGobject.
- //
- // This is used to implement the org.postgresql unique types (like lseg,
- // point, etc).
- if (o instanceof String)
- {
- // 6.3 style extending PG_Object
- PGobject obj = null;
- obj = (PGobject)(Class.forName((String)o).newInstance());
- obj.setType(type);
- obj.setValue(value);
- return (Object)obj;
- }
- else
- {
- // If it's an object, it should be an instance of our Serialize class
- // If so, then call it's fetch method.
- if (o instanceof Serialize)
- return ((Serialize)o).fetch(Integer.parseInt(value));
- }
- }
- catch (SQLException sx)
- {
- // rethrow the exception. Done because we capture any others next
- sx.fillInStackTrace();
- throw sx;
- }
- catch (Exception ex)
- {
- throw new PSQLException("postgresql.con.creobj", type, ex);
- }
-
- // should never be reached
- return null;
- }
-
- /*
- * This stores an object into the database. This method was
- * deprecated in 7.2 bacause an OID can be larger than the java signed
- * int returned by this method.
- * @deprecated Replaced by storeObject() in 7.2
- */
- public int putObject(Object o) throws SQLException
- {
- return (int) storeObject(o);
- }
-
- /*
- * This stores an object into the database.
- * @param o Object to store
- * @return OID of the new rectord
- * @exception SQLException if value is not correct for this type
- * @see org.postgresql.util.Serialize
- * @since 7.2
- */
- public long storeObject(Object o) throws SQLException
- {
- try
- {
- String type = o.getClass().getName();
- Object x = objectTypes.get(type);
-
- // If x is null, then the type is unknown, so check to see if type
- // is an actual table name. If it does, see if a Class is known that
- // can handle it
- if (x == null)
- {
- Serialize ser = new Serialize(this, type);
- objectTypes.put(type, ser);
- return ser.storeObject(o);
- }
-
- // If it's an object, it should be an instance of our Serialize class
- // If so, then call it's fetch method.
- if (x instanceof Serialize)
- return ((Serialize)x).storeObject(o);
-
- // Thow an exception because the type is unknown
- throw new PSQLException("postgresql.con.strobj");
-
- }
- catch (SQLException sx)
- {
- // rethrow the exception. Done because we capture any others next
- sx.fillInStackTrace();
- throw sx;
- }
- catch (Exception ex)
- {
- throw new PSQLException("postgresql.con.strobjex", ex);
- }
- }
-
- /*
- * This allows client code to add a handler for one of org.postgresql's
- * more unique data types.
- *
- * <p><b>NOTE:</b> This is not part of JDBC, but an extension.
- *
- * <p>The best way to use this is as follows:
- *
- * <p><pre>
- * ...
- * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");
- * ...
- * </pre>
- *
- * <p>where myconn is an open Connection to org.postgresql.
- *
- * <p>The handling class must extend org.postgresql.util.PGobject
- *
- * @see org.postgresql.util.PGobject
- */
- public void addDataType(String type, String name)
- {
- objectTypes.put(type, name);
- }
-
- // This holds the available types
- private Hashtable objectTypes = new Hashtable();
-
- // This array contains the types that are supported as standard.
- //
- // The first entry is the types name on the database, the second
- // the full class name of the handling class.
- //
- private static final String defaultObjectTypes[][] = {
- {"box", "org.postgresql.geometric.PGbox"},
- {"circle", "org.postgresql.geometric.PGcircle"},
- {"line", "org.postgresql.geometric.PGline"},
- {"lseg", "org.postgresql.geometric.PGlseg"},
- {"path", "org.postgresql.geometric.PGpath"},
- {"point", "org.postgresql.geometric.PGpoint"},
- {"polygon", "org.postgresql.geometric.PGpolygon"},
- {"money", "org.postgresql.util.PGmoney"}
- };
-
- // This initialises the objectTypes hashtable
- private void initObjectTypes()
- {
- for (int i = 0;i < defaultObjectTypes.length;i++)
- objectTypes.put(defaultObjectTypes[i][0], defaultObjectTypes[i][1]);
- }
-
- // These are required by other common classes
- public abstract java.sql.Statement createStatement() throws SQLException;
-
- /*
- * This returns a resultset. It must be overridden, so that the correct
- * version (from jdbc1 or jdbc2) are returned.
- */
- public abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
-
- /*
- * 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 SQLException if a database access error occurs
- */
- public void close() throws SQLException
- {
- if (pg_stream != null)
- {
- try
- {
- pg_stream.SendChar('X');
- pg_stream.flush();
- pg_stream.close();
- }
- catch (IOException e)
- {}
- pg_stream = null;
- }
- }
-
- /*
- * 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 SQLException if a database access error occurs
- */
- public String nativeSQL(String sql) throws SQLException
- {
- return sql;
- }
-
- /*
- * The first warning reported by calls on this Connection is
- * returned.
- *
- * <B>Note:</B> Sebsequent warnings will be changed to this
- * SQLWarning
- *
- * @return the first SQLWarning or null
- * @exception SQLException if a database access error occurs
- */
- public SQLWarning getWarnings() throws SQLException
- {
- return firstWarning;
- }
-
- /*
- * After this call, getWarnings returns null until a new warning
- * is reported for this connection.
- *
- * @exception SQLException if a database access error occurs
- */
- public void clearWarnings() throws SQLException
- {
- firstWarning = null;
- }
-
-
- /*
- * You can put a connection in read-only mode as a hunt 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 SQLException if a database access error occurs
- */
- public void setReadOnly(boolean readOnly) throws SQLException
- {
- 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 SQLException if a database access error occurs
- */
- public boolean isReadOnly() throws SQLException
- {
- return readOnly;
- }
-
- /*
- * 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.
- *
- * @param autoCommit - true enables auto-commit; false disables it
- * @exception SQLException if a database access error occurs
- */
- public void setAutoCommit(boolean autoCommit) throws SQLException
- {
- if (this.autoCommit == autoCommit)
- return;
- if (autoCommit)
- ExecSQL("end");
- else
- {
- if (haveMinimumServerVersion("7.1"))
- {
- ExecSQL("begin;" + getIsolationLevelSQL());
- }
- else
- {
- ExecSQL("begin");
- ExecSQL(getIsolationLevelSQL());
- }
- }
- this.autoCommit = autoCommit;
- }
-
- /*
- * gets the current auto-commit state
- *
- * @return Current state of the auto-commit mode
- * @exception SQLException (why?)
- * @see setAutoCommit
- */
- public boolean getAutoCommit() throws SQLException
- {
- return this.autoCommit;
- }
-
- /*
- * 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. (If autoCommit == true, then we
- * just return anyhow)
- *
- * @exception SQLException if a database access error occurs
- * @see setAutoCommit
- */
- public void commit() throws SQLException
- {
- if (autoCommit)
- return;
- if (haveMinimumServerVersion("7.1"))
- {
- ExecSQL("commit;begin;" + getIsolationLevelSQL());
- }
- else
- {
- ExecSQL("commit");
- ExecSQL("begin");
- ExecSQL(getIsolationLevelSQL());
- }
- }
-
- /*
- * The method rollback() drops all changes made since the previous
- * commit/rollback and releases any database locks currently held by
- * the Connection.
- *
- * @exception SQLException if a database access error occurs
- * @see commit
- */
- public void rollback() throws SQLException
- {
- if (autoCommit)
- return;
- if (haveMinimumServerVersion("7.1"))
- {
- ExecSQL("rollback; begin;" + getIsolationLevelSQL());
- }
- else
- {
- ExecSQL("rollback");
- ExecSQL("begin");
- ExecSQL(getIsolationLevelSQL());
- }
- }
-
- /*
- * Get this Connection's current transaction isolation mode.
- *
- * @return the current TRANSACTION_* mode value
- * @exception SQLException if a database access error occurs
- */
- public int getTransactionIsolation() throws SQLException
- {
- clearWarnings();
- ExecSQL("show transaction isolation level");
-
- SQLWarning warning = getWarnings();
- if (warning != null)
- {
- String message = warning.getMessage();
- clearWarnings();
- if (message.indexOf("READ COMMITTED") != -1)
- return java.sql.Connection.TRANSACTION_READ_COMMITTED;
- else if (message.indexOf("READ UNCOMMITTED") != -1)
- return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
- else if (message.indexOf("REPEATABLE READ") != -1)
- return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
- else if (message.indexOf("SERIALIZABLE") != -1)
- return java.sql.Connection.TRANSACTION_SERIALIZABLE;
- }
- return java.sql.Connection.TRANSACTION_READ_COMMITTED;
- }
-
- /*
- * You can call this method to try to change the transaction
- * isolation level using one of the TRANSACTION_* values.
- *
- * <B>Note:</B> setTransactionIsolation cannot be called while
- * in the middle of a transaction
- *
- * @param level one of the TRANSACTION_* isolation values with
- * the exception of TRANSACTION_NONE; some databases may
- * not support other values
- * @exception SQLException if a database access error occurs
- * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
- */
- public void setTransactionIsolation(int level) throws SQLException
- {
- //In 7.1 and later versions of the server it is possible using
- //the "set session" command to set this once for all future txns
- //however in 7.0 and prior versions it is necessary to set it in
- //each transaction, thus adding complexity below.
- //When we decide to drop support for servers older than 7.1
- //this can be simplified
- isolationLevel = level;
- String isolationLevelSQL;
-
- if (!haveMinimumServerVersion("7.1"))
- {
- isolationLevelSQL = getIsolationLevelSQL();
- }
- else
- {
- isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ";
- switch (isolationLevel)
- {
- case java.sql.Connection.TRANSACTION_READ_COMMITTED:
- isolationLevelSQL += "READ COMMITTED";
- break;
- case java.sql.Connection.TRANSACTION_SERIALIZABLE:
- isolationLevelSQL += "SERIALIZABLE";
- break;
- default:
- throw new PSQLException("postgresql.con.isolevel",
- new Integer(isolationLevel));
- }
- }
- ExecSQL(isolationLevelSQL);
- }
-
- /*
- * Helper method used by setTransactionIsolation(), commit(), rollback()
- * and setAutoCommit(). This returns the SQL string needed to
- * set the isolation level for a transaction. In 7.1 and later it
- * is possible to set a default isolation level that applies to all
- * future transactions, this method is only necesary for 7.0 and older
- * servers, and should be removed when support for these older
- * servers are dropped
- */
- protected String getIsolationLevelSQL() throws SQLException
- {
- //7.1 and higher servers have a default specified so
- //no additional SQL is required to set the isolation level
- if (haveMinimumServerVersion("7.1"))
- {
- return "";
- }
- StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL");
-
- switch (isolationLevel)
- {
- case java.sql.Connection.TRANSACTION_READ_COMMITTED:
- sb.append(" READ COMMITTED");
- break;
-
- case java.sql.Connection.TRANSACTION_SERIALIZABLE:
- sb.append(" SERIALIZABLE");
- break;
-
- default:
- throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel));
- }
- return sb.toString();
- }
-
- /*
- * 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
- *
- * @exception SQLException if a database access error occurs
- */
- public void setCatalog(String catalog) throws SQLException
- {
- //no-op
- }
-
- /*
- * Return the connections current catalog name, or null if no
- * catalog name is set, or we dont support catalogs.
- *
- * @return the current catalog name or null
- * @exception SQLException if a database access error occurs
- */
- public String getCatalog() throws SQLException
- {
- return PG_DATABASE;
- }
-
- /*
- * Overides finalize(). If called, it closes the connection.
- *
- * This was done at the request of Rachel Greenham
- * <rachel@enlarion.demon.co.uk> who hit a problem where multiple
- * clients didn't close the connection, and once a fortnight enough
- * clients were open to kill the org.postgres server.
- */
- public void finalize() throws Throwable
- {
- close();
- }
-
- private static String extractVersionNumber(String fullVersionString)
- {
- StringTokenizer versionParts = new StringTokenizer(fullVersionString);
- versionParts.nextToken(); /* "PostgreSQL" */
- return versionParts.nextToken(); /* "X.Y.Z" */
- }
-
- /*
- * Get server version number
- */
- public String getDBVersionNumber()
- {
- return dbVersionNumber;
- }
-
- public boolean haveMinimumServerVersion(String ver) throws SQLException
- {
- return (getDBVersionNumber().compareTo(ver) >= 0);
- }
-
- /*
- * This method returns true if the compatible level set in the connection
- * (which can be passed into the connection or specified in the URL)
- * is at least the value passed to this method. This is used to toggle
- * between different functionality as it changes across different releases
- * of the jdbc driver code. The values here are versions of the jdbc client
- * and not server versions. For example in 7.1 get/setBytes worked on
- * LargeObject values, in 7.2 these methods were changed to work on bytea
- * values. This change in functionality could be disabled by setting the
- * "compatible" level to be 7.1, in which case the driver will revert to
- * the 7.1 functionality.
- */
- public boolean haveMinimumCompatibleVersion(String ver) throws SQLException
- {
- return (compatible.compareTo(ver) >= 0);
- }
-
-
- /*
- * This returns the java.sql.Types type for a PG type oid
- *
- * @param oid PostgreSQL type oid
- * @return the java.sql.Types type
- * @exception SQLException if a database access error occurs
- */
- public int getSQLType(int oid) throws SQLException
- {
- Integer sqlType = (Integer)sqlTypeCache.get(new Integer(oid));
-
- // it's not in the cache, so perform a query, and add the result to the cache
- if (sqlType == null)
- {
- ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
- if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
- throw new PSQLException("postgresql.unexpected");
- result.next();
- String pgType = result.getString(1);
- Integer iOid = new Integer(oid);
- sqlType = new Integer(getSQLType(result.getString(1)));
- sqlTypeCache.put(iOid, sqlType);
- pgTypeCache.put(iOid, pgType);
- result.close();
- }
-
- return sqlType.intValue();
- }
-
- /*
- * This returns the java.sql.Types type for a PG type
- *
- * @param pgTypeName PostgreSQL type name
- * @return the java.sql.Types type
- */
- public abstract int getSQLType(String pgTypeName);
-
- /*
- * This returns the oid for a given PG data type
- * @param typeName PostgreSQL type name
- * @return PostgreSQL oid value for a field of this type
- */
- public int getOID(String typeName) throws SQLException
- {
- int oid = -1;
- if (typeName != null)
- {
- Integer oidValue = (Integer) typeOidCache.get(typeName);
- if (oidValue != null)
- {
- oid = oidValue.intValue();
- }
- else
- {
- // it's not in the cache, so perform a query, and add the result to the cache
- ResultSet result = (org.postgresql.ResultSet)ExecSQL("select oid from pg_type where typname='"
- + typeName + "'");
- if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
- throw new PSQLException("postgresql.unexpected");
- result.next();
- oid = Integer.parseInt(result.getString(1));
- typeOidCache.put(typeName, new Integer(oid));
- result.close();
- }
- }
- return oid;
- }
-
- /*
- * We also need to get the PG type name as returned by the back end.
- *
- * @return the String representation of the type of this field
- * @exception SQLException if a database access error occurs
- */
- public String getPGType(int oid) throws SQLException
- {
- String pgType = (String) pgTypeCache.get(new Integer(oid));
- if (pgType == null)
- {
- getSQLType(oid);
- pgType = (String) pgTypeCache.get(new Integer(oid));
- }
- return pgType;
- }
-}
-
+package org.postgresql;
+
+import java.io.*;
+import java.net.*;
+import java.sql.*;
+import java.util.*;
+import org.postgresql.Driver;
+import org.postgresql.Field;
+import org.postgresql.fastpath.*;
+import org.postgresql.largeobject.*;
+import org.postgresql.util.*;
+import org.postgresql.core.*;
+
+/*
+ * $Id: Connection.java,v 1.48 2002/06/11 02:55:15 barry Exp $
+ *
+ * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
+ * JDBC2 versions of the Connection class.
+ *
+ */
+public abstract class Connection
+{
+ // This is the network stream associated with this connection
+ public PG_Stream pg_stream;
+
+ private String PG_HOST;
+ private int PG_PORT;
+ private String PG_USER;
+ private String PG_DATABASE;
+ private boolean PG_STATUS;
+ private String compatible;
+
+ /*
+ The encoding to use for this connection.
+ */
+ private Encoding encoding = Encoding.defaultEncoding();
+
+ private String dbVersionNumber;
+
+ public boolean CONNECTION_OK = true;
+ public boolean CONNECTION_BAD = false;
+
+ public boolean autoCommit = true;
+ public boolean readOnly = false;
+
+ public Driver this_driver;
+ private String this_url;
+ private String cursor = null; // The positioned update cursor name
+
+ // These are new for v6.3, they determine the current protocol versions
+ // supported by this version of the driver. They are defined in
+ // src/include/libpq/pqcomm.h
+ protected static final int PG_PROTOCOL_LATEST_MAJOR = 2;
+ protected static final int PG_PROTOCOL_LATEST_MINOR = 0;
+
+ private static final int AUTH_REQ_OK = 0;
+ private static final int AUTH_REQ_KRB4 = 1;
+ private static final int AUTH_REQ_KRB5 = 2;
+ private static final int AUTH_REQ_PASSWORD = 3;
+ private static final int AUTH_REQ_CRYPT = 4;
+ private static final int AUTH_REQ_MD5 = 5;
+
+
+ // These are used to cache oids, PGTypes and SQLTypes
+ private static Hashtable sqlTypeCache = new Hashtable(); // oid -> SQLType
+ private static Hashtable pgTypeCache = new Hashtable(); // oid -> PGType
+ private static Hashtable typeOidCache = new Hashtable(); //PGType -> oid
+
+ // Now handle notices as warnings, so things like "show" now work
+ public SQLWarning firstWarning = null;
+
+ /*
+ * Cache of the current isolation level
+ */
+ private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
+
+ // The PID an cancellation key we get from the backend process
+ public int pid;
+ public int ckey;
+
+ /*
+ * This is called by Class.forName() from within org.postgresql.Driver
+ */
+ public Connection()
+ {}
+
+ public void cancelQuery() throws SQLException
+ {
+ PG_Stream cancelStream = null;
+ try {
+ cancelStream = new PG_Stream(PG_HOST, PG_PORT);
+ } catch (ConnectException cex) {
+ // Added by Peter Mount <peter@retep.org.uk>
+ // ConnectException is thrown when the connection cannot be made.
+ // we trap this an return a more meaningful message for the end user
+ throw new PSQLException ("postgresql.con.refused");
+ } catch (IOException e) {
+ throw new PSQLException ("postgresql.con.failed",e);
+ }
+
+ // Now we need to construct and send a cancel packet
+ try {
+ cancelStream.SendInteger(16, 4);
+ cancelStream.SendInteger(80877102, 4);
+ cancelStream.SendInteger(pid, 4);
+ cancelStream.SendInteger(ckey, 4);
+ cancelStream.flush();
+ }
+ catch(IOException e) {
+ throw new PSQLException("postgresql.con.failed",e);
+ }
+ finally {
+ try {
+ if(cancelStream != null)
+ cancelStream.close();
+ }
+ catch(IOException e) {} // Ignore
+ }
+ }
+
+ /*
+ * This method actually opens the connection. It is called by Driver.
+ *
+ * @param host the hostname of the database back end
+ * @param port the port number of the postmaster process
+ * @param info a Properties[] thing of the user and password
+ * @param database the database to connect to
+ * @param u the URL of the connection
+ * @param d the Driver instantation of the connection
+ * @return a valid connection profile
+ * @exception SQLException if a database access error occurs
+ */
+ protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
+ {
+ firstWarning = null;
+
+ // Throw an exception if the user or password properties are missing
+ // This occasionally occurs when the client uses the properties version
+ // of getConnection(), and is a common question on the email lists
+ if (info.getProperty("user") == null)
+ throw new PSQLException("postgresql.con.user");
+
+ this_driver = d;
+ this_url = url;
+
+ PG_DATABASE = database;
+ PG_USER = info.getProperty("user");
+
+ String password = info.getProperty("password", "");
+ PG_PORT = port;
+
+ PG_HOST = host;
+ PG_STATUS = CONNECTION_BAD;
+
+ if (info.getProperty("compatible") == null)
+ {
+ compatible = d.getMajorVersion() + "." + d.getMinorVersion();
+ }
+ else
+ {
+ compatible = info.getProperty("compatible");
+ }
+
+ //Read loglevel arg and set the loglevel based on this value
+ //in addition to setting the log level enable output to
+ //standard out if no other printwriter is set
+ String l_logLevelProp = info.getProperty("loglevel","0");
+ int l_logLevel = 0;
+ try {
+ l_logLevel = Integer.parseInt(l_logLevelProp);
+ if (l_logLevel > Driver.DEBUG || l_logLevel < Driver.INFO) {
+ l_logLevel = 0;
+ }
+ } catch (Exception l_e) {
+ //invalid value for loglevel ignore
+ }
+ if (l_logLevel > 0) {
+ Driver.setLogLevel(l_logLevel);
+ enableDriverManagerLogging();
+ }
+
+ //Print out the driver version number
+ if (Driver.logInfo) Driver.info(Driver.getVersion());
+
+ // Now make the initial connection
+ try
+ {
+ pg_stream = new PG_Stream(host, port);
+ }
+ catch (ConnectException cex)
+ {
+ // Added by Peter Mount <peter@retep.org.uk>
+ // ConnectException is thrown when the connection cannot be made.
+ // we trap this an return a more meaningful message for the end user
+ throw new PSQLException ("postgresql.con.refused");
+ }
+ catch (IOException e)
+ {
+ throw new PSQLException ("postgresql.con.failed", e);
+ }
+
+ // Now we need to construct and send a startup packet
+ try
+ {
+ new StartupPacket(PG_PROTOCOL_LATEST_MAJOR,
+ PG_PROTOCOL_LATEST_MINOR,
+ PG_USER,
+ database).writeTo(pg_stream);
+
+ // now flush the startup packets to the backend
+ pg_stream.flush();
+
+ // Now get the response from the backend, either an error message
+ // or an authentication request
+ int areq = -1; // must have a value here
+ do
+ {
+ int beresp = pg_stream.ReceiveChar();
+ String salt = null;
+ switch (beresp)
+ {
+ case 'E':
+ // An error occured, so pass the error message to the
+ // user.
+ //
+ // The most common one to be thrown here is:
+ // "User authentication failed"
+ //
+ throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding));
+
+ case 'R':
+ // Get the type of request
+ areq = pg_stream.ReceiveIntegerR(4);
+ // Get the crypt password salt if there is one
+ if (areq == AUTH_REQ_CRYPT)
+ {
+ byte[] rst = new byte[2];
+ rst[0] = (byte)pg_stream.ReceiveChar();
+ rst[1] = (byte)pg_stream.ReceiveChar();
+ salt = new String(rst, 0, 2);
+ if (Driver.logDebug) Driver.debug("Crypt salt=" + salt);
+ }
+
+ // Or get the md5 password salt if there is one
+ if (areq == AUTH_REQ_MD5)
+ {
+ byte[] rst = new byte[4];
+ rst[0] = (byte)pg_stream.ReceiveChar();
+ rst[1] = (byte)pg_stream.ReceiveChar();
+ rst[2] = (byte)pg_stream.ReceiveChar();
+ rst[3] = (byte)pg_stream.ReceiveChar();
+ salt = new String(rst, 0, 4);
+ if (Driver.logDebug) Driver.debug("MD5 salt=" + salt);
+ }
+
+ // now send the auth packet
+ switch (areq)
+ {
+ case AUTH_REQ_OK:
+ break;
+
+ case AUTH_REQ_KRB4:
+ if (Driver.logDebug) Driver.debug("postgresql: KRB4");
+ throw new PSQLException("postgresql.con.kerb4");
+
+ case AUTH_REQ_KRB5:
+ if (Driver.logDebug) Driver.debug("postgresql: KRB5");
+ throw new PSQLException("postgresql.con.kerb5");
+
+ case AUTH_REQ_PASSWORD:
+ if (Driver.logDebug) Driver.debug("postgresql: PASSWORD");
+ pg_stream.SendInteger(5 + password.length(), 4);
+ pg_stream.Send(password.getBytes());
+ pg_stream.SendInteger(0, 1);
+ pg_stream.flush();
+ break;
+
+ case AUTH_REQ_CRYPT:
+ if (Driver.logDebug) Driver.debug("postgresql: CRYPT");
+ String crypted = UnixCrypt.crypt(salt, password);
+ pg_stream.SendInteger(5 + crypted.length(), 4);
+ pg_stream.Send(crypted.getBytes());
+ pg_stream.SendInteger(0, 1);
+ pg_stream.flush();
+ break;
+
+ case AUTH_REQ_MD5:
+ if (Driver.logDebug) Driver.debug("postgresql: MD5");
+ byte[] digest = MD5Digest.encode(PG_USER, password, salt);
+ pg_stream.SendInteger(5 + digest.length, 4);
+ pg_stream.Send(digest);
+ pg_stream.SendInteger(0, 1);
+ pg_stream.flush();
+ break;
+
+ default:
+ throw new PSQLException("postgresql.con.auth", new Integer(areq));
+ }
+ break;
+
+ default:
+ throw new PSQLException("postgresql.con.authfail");
+ }
+ }
+ while (areq != AUTH_REQ_OK);
+
+ }
+ catch (IOException e)
+ {
+ throw new PSQLException("postgresql.con.failed", e);
+ }
+
+
+ // As of protocol version 2.0, we should now receive the cancellation key and the pid
+ int beresp;
+ do {
+ beresp = pg_stream.ReceiveChar();
+ switch (beresp)
+ {
+ case 'K':
+ pid = pg_stream.ReceiveIntegerR(4);
+ ckey = pg_stream.ReceiveIntegerR(4);
+ break;
+ case 'E':
+ throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));
+ case 'N':
+ addWarning(pg_stream.ReceiveString(encoding));
+ break;
+ default:
+ throw new PSQLException("postgresql.con.setup");
+ }
+ } while (beresp == 'N');
+
+ // Expect ReadyForQuery packet
+ do {
+ beresp = pg_stream.ReceiveChar();
+ switch (beresp)
+ {
+ case 'Z':
+ break;
+ case 'N':
+ addWarning(pg_stream.ReceiveString(encoding));
+ break;
+ case 'E':
+ throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));
+ default:
+ throw new PSQLException("postgresql.con.setup");
+ }
+ } while (beresp == 'N');
+ // "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte,
+ // otherwise it's hardcoded to 'SQL_ASCII'.
+ // If the backend doesn't know about multibyte we can't assume anything about the encoding
+ // used, so we denote this with 'UNKNOWN'.
+ //Note: begining with 7.2 we should be using pg_client_encoding() which
+ //is new in 7.2. However it isn't easy to conditionally call this new
+ //function, since we don't yet have the information as to what server
+ //version we are talking to. Thus we will continue to call
+ //getdatabaseencoding() until we drop support for 7.1 and older versions
+ //or until someone comes up with a conditional way to run one or
+ //the other function depending on server version that doesn't require
+ //two round trips to the server per connection
+
+ final String encodingQuery =
+ "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
+
+ // Set datestyle and fetch db encoding in a single call, to avoid making
+ // more than one round trip to the backend during connection startup.
+
+ java.sql.ResultSet resultSet =
+ ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
+
+ if (! resultSet.next())
+ {
+ throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
+ }
+ String version = resultSet.getString(1);
+ dbVersionNumber = extractVersionNumber(version);
+
+ String dbEncoding = resultSet.getString(2);
+ encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
+
+ // Initialise object handling
+ initObjectTypes();
+
+ // Mark the connection as ok, and cleanup
+ PG_STATUS = CONNECTION_OK;
+ }
+
+ // These methods used to be in the main Connection implementation. As they
+ // are common to all implementations (JDBC1 or 2), they are placed here.
+ // This should make it easy to maintain the two specifications.
+
+ /*
+ * This adds a warning to the warning chain.
+ * @param msg message to add
+ */
+ public void addWarning(String msg)
+ {
+ // Add the warning to the chain
+ if (firstWarning != null)
+ firstWarning.setNextWarning(new SQLWarning(msg));
+ else
+ firstWarning = new SQLWarning(msg);
+
+ // Now check for some specific messages
+
+ // This is obsolete in 6.5, but I've left it in here so if we need to use this
+ // technique again, we'll know where to place it.
+ //
+ // This is generated by the SQL "show datestyle"
+ //if (msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
+ //// 13 is the length off "DateStyle is "
+ //msg = msg.substring(msg.indexOf("DateStyle is ")+13);
+ //
+ //for(int i=0;i<dateStyles.length;i+=2)
+ //if (msg.startsWith(dateStyles[i]))
+ //currentDateStyle=i+1; // this is the index of the format
+ //}
+ }
+
+ /*
+ * Send a query to the backend. Returns one of the ResultSet
+ * objects.
+ *
+ * <B>Note:</B> there does not seem to be any method currently
+ * in existance to return the update count.
+ *
+ * @param sql the SQL statement to be executed
+ * @return a ResultSet holding the results
+ * @exception SQLException if a database error occurs
+ */
+ public java.sql.ResultSet ExecSQL(String sql) throws SQLException
+ {
+ return ExecSQL(sql, null);
+ }
+
+ /*
+ * Send a query to the backend. Returns one of the ResultSet
+ * objects.
+ *
+ * <B>Note:</B> there does not seem to be any method currently
+ * in existance to return the update count.
+ *
+ * @param sql the SQL statement to be executed
+ * @param stat The Statement associated with this query (may be null)
+ * @return a ResultSet holding the results
+ * @exception SQLException if a database error occurs
+ */
+ public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException
+ {
+ return new QueryExecutor(sql, stat, pg_stream, this).execute();
+ }
+
+ /*
+ * In SQL, a result table can be retrieved through a cursor that
+ * is named. The current row of a result can be updated or deleted
+ * using a positioned update/delete statement that references the
+ * cursor name.
+ *
+ * We support one cursor per connection.
+ *
+ * setCursorName sets the cursor name.
+ *
+ * @param cursor the cursor name
+ * @exception SQLException if a database access error occurs
+ */
+ public void setCursorName(String cursor) throws SQLException
+ {
+ this.cursor = cursor;
+ }
+
+ /*
+ * getCursorName gets the cursor name.
+ *
+ * @return the current cursor name
+ * @exception SQLException if a database access error occurs
+ */
+ public String getCursorName() throws SQLException
+ {
+ return cursor;
+ }
+
+ /*
+ * We are required to bring back certain information by
+ * the DatabaseMetaData class. These functions do that.
+ *
+ * Method getURL() brings back the URL (good job we saved it)
+ *
+ * @return the url
+ * @exception SQLException just in case...
+ */
+ public String getURL() throws SQLException
+ {
+ return this_url;
+ }
+
+ /*
+ * Method getUserName() brings back the User Name (again, we
+ * saved it)
+ *
+ * @return the user name
+ * @exception SQLException just in case...
+ */
+ int lastMessage = 0;
+ public String getUserName() throws SQLException
+ {
+ return PG_USER;
+ }
+
+ /*
+ * Get the character encoding to use for this connection.
+ */
+ public Encoding getEncoding() throws SQLException
+ {
+ return encoding;
+ }
+
+ /*
+ * This returns the Fastpath API for the current connection.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
+ * functions on the org.postgresql backend itself.
+ *
+ * <p>It is primarily used by the LargeObject API
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * import org.postgresql.fastpath.*;
+ * ...
+ * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to org.postgresql.
+ *
+ * @return Fastpath object allowing access to functions on the org.postgresql
+ * backend.
+ * @exception SQLException by Fastpath when initialising for first time
+ */
+ public Fastpath getFastpathAPI() throws SQLException
+ {
+ if (fastpath == null)
+ fastpath = new Fastpath(this, pg_stream);
+ return fastpath;
+ }
+
+ // This holds a reference to the Fastpath API if already open
+ private Fastpath fastpath = null;
+
+ /*
+ * This returns the LargeObject API for the current connection.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
+ * functions on the org.postgresql backend itself.
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * import org.postgresql.largeobject.*;
+ * ...
+ * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to org.postgresql.
+ *
+ * @return LargeObject object that implements the API
+ * @exception SQLException by LargeObject when initialising for first time
+ */
+ public LargeObjectManager getLargeObjectAPI() throws SQLException
+ {
+ if (largeobject == null)
+ largeobject = new LargeObjectManager(this);
+ return largeobject;
+ }
+
+ // This holds a reference to the LargeObject API if already open
+ private LargeObjectManager largeobject = null;
+
+ /*
+ * This method is used internally to return an object based around
+ * org.postgresql's more unique data types.
+ *
+ * <p>It uses an internal Hashtable to get the handling class. If the
+ * type is not supported, then an instance of org.postgresql.util.PGobject
+ * is returned.
+ *
+ * You can use the getValue() or setValue() methods to handle the returned
+ * object. Custom objects can have their own methods.
+ *
+ * In 6.4, this is extended to use the org.postgresql.util.Serialize class to
+ * allow the Serialization of Java Objects into the database without using
+ * Blobs. Refer to that class for details on how this new feature works.
+ *
+ * @return PGobject for this type, and set to value
+ * @exception SQLException if value is not correct for this type
+ * @see org.postgresql.util.Serialize
+ */
+ public Object getObject(String type, String value) throws SQLException
+ {
+ try
+ {
+ Object o = objectTypes.get(type);
+
+ // If o is null, then the type is unknown, so check to see if type
+ // is an actual table name. If it does, see if a Class is known that
+ // can handle it
+ if (o == null)
+ {
+ Serialize ser = new Serialize(this, type);
+ objectTypes.put(type, ser);
+ return ser.fetch(Integer.parseInt(value));
+ }
+
+ // If o is not null, and it is a String, then its a class name that
+ // extends PGobject.
+ //
+ // This is used to implement the org.postgresql unique types (like lseg,
+ // point, etc).
+ if (o instanceof String)
+ {
+ // 6.3 style extending PG_Object
+ PGobject obj = null;
+ obj = (PGobject)(Class.forName((String)o).newInstance());
+ obj.setType(type);
+ obj.setValue(value);
+ return (Object)obj;
+ }
+ else
+ {
+ // If it's an object, it should be an instance of our Serialize class
+ // If so, then call it's fetch method.
+ if (o instanceof Serialize)
+ return ((Serialize)o).fetch(Integer.parseInt(value));
+ }
+ }
+ catch (SQLException sx)
+ {
+ // rethrow the exception. Done because we capture any others next
+ sx.fillInStackTrace();
+ throw sx;
+ }
+ catch (Exception ex)
+ {
+ throw new PSQLException("postgresql.con.creobj", type, ex);
+ }
+
+ // should never be reached
+ return null;
+ }
+
+ /*
+ * This stores an object into the database. This method was
+ * deprecated in 7.2 bacause an OID can be larger than the java signed
+ * int returned by this method.
+ * @deprecated Replaced by storeObject() in 7.2
+ */
+ public int putObject(Object o) throws SQLException
+ {
+ return (int) storeObject(o);
+ }
+
+ /*
+ * This stores an object into the database.
+ * @param o Object to store
+ * @return OID of the new rectord
+ * @exception SQLException if value is not correct for this type
+ * @see org.postgresql.util.Serialize
+ * @since 7.2
+ */
+ public long storeObject(Object o) throws SQLException
+ {
+ try
+ {
+ String type = o.getClass().getName();
+ Object x = objectTypes.get(type);
+
+ // If x is null, then the type is unknown, so check to see if type
+ // is an actual table name. If it does, see if a Class is known that
+ // can handle it
+ if (x == null)
+ {
+ Serialize ser = new Serialize(this, type);
+ objectTypes.put(type, ser);
+ return ser.storeObject(o);
+ }
+
+ // If it's an object, it should be an instance of our Serialize class
+ // If so, then call it's fetch method.
+ if (x instanceof Serialize)
+ return ((Serialize)x).storeObject(o);
+
+ // Thow an exception because the type is unknown
+ throw new PSQLException("postgresql.con.strobj");
+
+ }
+ catch (SQLException sx)
+ {
+ // rethrow the exception. Done because we capture any others next
+ sx.fillInStackTrace();
+ throw sx;
+ }
+ catch (Exception ex)
+ {
+ throw new PSQLException("postgresql.con.strobjex", ex);
+ }
+ }
+
+ /*
+ * This allows client code to add a handler for one of org.postgresql's
+ * more unique data types.
+ *
+ * <p><b>NOTE:</b> This is not part of JDBC, but an extension.
+ *
+ * <p>The best way to use this is as follows:
+ *
+ * <p><pre>
+ * ...
+ * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");
+ * ...
+ * </pre>
+ *
+ * <p>where myconn is an open Connection to org.postgresql.
+ *
+ * <p>The handling class must extend org.postgresql.util.PGobject
+ *
+ * @see org.postgresql.util.PGobject
+ */
+ public void addDataType(String type, String name)
+ {
+ objectTypes.put(type, name);
+ }
+
+ // This holds the available types
+ private Hashtable objectTypes = new Hashtable();
+
+ // This array contains the types that are supported as standard.
+ //
+ // The first entry is the types name on the database, the second
+ // the full class name of the handling class.
+ //
+ private static final String defaultObjectTypes[][] = {
+ {"box", "org.postgresql.geometric.PGbox"},
+ {"circle", "org.postgresql.geometric.PGcircle"},
+ {"line", "org.postgresql.geometric.PGline"},
+ {"lseg", "org.postgresql.geometric.PGlseg"},
+ {"path", "org.postgresql.geometric.PGpath"},
+ {"point", "org.postgresql.geometric.PGpoint"},
+ {"polygon", "org.postgresql.geometric.PGpolygon"},
+ {"money", "org.postgresql.util.PGmoney"}
+ };
+
+ // This initialises the objectTypes hashtable
+ private void initObjectTypes()
+ {
+ for (int i = 0;i < defaultObjectTypes.length;i++)
+ objectTypes.put(defaultObjectTypes[i][0], defaultObjectTypes[i][1]);
+ }
+
+ // These are required by other common classes
+ public abstract java.sql.Statement createStatement() throws SQLException;
+
+ /*
+ * This returns a resultset. It must be overridden, so that the correct
+ * version (from jdbc1 or jdbc2) are returned.
+ */
+ public abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
+
+ /*
+ * 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 SQLException if a database access error occurs
+ */
+ public void close() throws SQLException
+ {
+ if (pg_stream != null)
+ {
+ try
+ {
+ pg_stream.SendChar('X');
+ pg_stream.flush();
+ pg_stream.close();
+ }
+ catch (IOException e)
+ {}
+ pg_stream = null;
+ }
+ }
+
+ /*
+ * 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 SQLException if a database access error occurs
+ */
+ public String nativeSQL(String sql) throws SQLException
+ {
+ return sql;
+ }
+
+ /*
+ * The first warning reported by calls on this Connection is
+ * returned.
+ *
+ * <B>Note:</B> Sebsequent warnings will be changed to this
+ * SQLWarning
+ *
+ * @return the first SQLWarning or null
+ * @exception SQLException if a database access error occurs
+ */
+ public SQLWarning getWarnings() throws SQLException
+ {
+ return firstWarning;
+ }
+
+ /*
+ * After this call, getWarnings returns null until a new warning
+ * is reported for this connection.
+ *
+ * @exception SQLException if a database access error occurs
+ */
+ public void clearWarnings() throws SQLException
+ {
+ firstWarning = null;
+ }
+
+
+ /*
+ * You can put a connection in read-only mode as a hunt 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 SQLException if a database access error occurs
+ */
+ public void setReadOnly(boolean readOnly) throws SQLException
+ {
+ 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 SQLException if a database access error occurs
+ */
+ public boolean isReadOnly() throws SQLException
+ {
+ return readOnly;
+ }
+
+ /*
+ * 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.
+ *
+ * @param autoCommit - true enables auto-commit; false disables it
+ * @exception SQLException if a database access error occurs
+ */
+ public void setAutoCommit(boolean autoCommit) throws SQLException
+ {
+ if (this.autoCommit == autoCommit)
+ return;
+ if (autoCommit)
+ ExecSQL("end");
+ else
+ {
+ if (haveMinimumServerVersion("7.1"))
+ {
+ ExecSQL("begin;" + getIsolationLevelSQL());
+ }
+ else
+ {
+ ExecSQL("begin");
+ ExecSQL(getIsolationLevelSQL());
+ }
+ }
+ this.autoCommit = autoCommit;
+ }
+
+ /*
+ * gets the current auto-commit state
+ *
+ * @return Current state of the auto-commit mode
+ * @exception SQLException (why?)
+ * @see setAutoCommit
+ */
+ public boolean getAutoCommit() throws SQLException
+ {
+ return this.autoCommit;
+ }
+
+ /*
+ * 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. (If autoCommit == true, then we
+ * just return anyhow)
+ *
+ * @exception SQLException if a database access error occurs
+ * @see setAutoCommit
+ */
+ public void commit() throws SQLException
+ {
+ if (autoCommit)
+ return;
+ if (haveMinimumServerVersion("7.1"))
+ {
+ ExecSQL("commit;begin;" + getIsolationLevelSQL());
+ }
+ else
+ {
+ ExecSQL("commit");
+ ExecSQL("begin");
+ ExecSQL(getIsolationLevelSQL());
+ }
+ }
+
+ /*
+ * The method rollback() drops all changes made since the previous
+ * commit/rollback and releases any database locks currently held by
+ * the Connection.
+ *
+ * @exception SQLException if a database access error occurs
+ * @see commit
+ */
+ public void rollback() throws SQLException
+ {
+ if (autoCommit)
+ return;
+ if (haveMinimumServerVersion("7.1"))
+ {
+ ExecSQL("rollback; begin;" + getIsolationLevelSQL());
+ }
+ else
+ {
+ ExecSQL("rollback");
+ ExecSQL("begin");
+ ExecSQL(getIsolationLevelSQL());
+ }
+ }
+
+ /*
+ * Get this Connection's current transaction isolation mode.
+ *
+ * @return the current TRANSACTION_* mode value
+ * @exception SQLException if a database access error occurs
+ */
+ public int getTransactionIsolation() throws SQLException
+ {
+ clearWarnings();
+ ExecSQL("show transaction isolation level");
+
+ SQLWarning warning = getWarnings();
+ if (warning != null)
+ {
+ String message = warning.getMessage();
+ clearWarnings();
+ if (message.indexOf("READ COMMITTED") != -1)
+ return java.sql.Connection.TRANSACTION_READ_COMMITTED;
+ else if (message.indexOf("READ UNCOMMITTED") != -1)
+ return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
+ else if (message.indexOf("REPEATABLE READ") != -1)
+ return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
+ else if (message.indexOf("SERIALIZABLE") != -1)
+ return java.sql.Connection.TRANSACTION_SERIALIZABLE;
+ }
+ return java.sql.Connection.TRANSACTION_READ_COMMITTED;
+ }
+
+ /*
+ * You can call this method to try to change the transaction
+ * isolation level using one of the TRANSACTION_* values.
+ *
+ * <B>Note:</B> setTransactionIsolation cannot be called while
+ * in the middle of a transaction
+ *
+ * @param level one of the TRANSACTION_* isolation values with
+ * the exception of TRANSACTION_NONE; some databases may
+ * not support other values
+ * @exception SQLException if a database access error occurs
+ * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
+ */
+ public void setTransactionIsolation(int level) throws SQLException
+ {
+ //In 7.1 and later versions of the server it is possible using
+ //the "set session" command to set this once for all future txns
+ //however in 7.0 and prior versions it is necessary to set it in
+ //each transaction, thus adding complexity below.
+ //When we decide to drop support for servers older than 7.1
+ //this can be simplified
+ isolationLevel = level;
+ String isolationLevelSQL;
+
+ if (!haveMinimumServerVersion("7.1"))
+ {
+ isolationLevelSQL = getIsolationLevelSQL();
+ }
+ else
+ {
+ isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ";
+ switch (isolationLevel)
+ {
+ case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+ isolationLevelSQL += "READ COMMITTED";
+ break;
+ case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+ isolationLevelSQL += "SERIALIZABLE";
+ break;
+ default:
+ throw new PSQLException("postgresql.con.isolevel",
+ new Integer(isolationLevel));
+ }
+ }
+ ExecSQL(isolationLevelSQL);
+ }
+
+ /*
+ * Helper method used by setTransactionIsolation(), commit(), rollback()
+ * and setAutoCommit(). This returns the SQL string needed to
+ * set the isolation level for a transaction. In 7.1 and later it
+ * is possible to set a default isolation level that applies to all
+ * future transactions, this method is only necesary for 7.0 and older
+ * servers, and should be removed when support for these older
+ * servers are dropped
+ */
+ protected String getIsolationLevelSQL() throws SQLException
+ {
+ //7.1 and higher servers have a default specified so
+ //no additional SQL is required to set the isolation level
+ if (haveMinimumServerVersion("7.1"))
+ {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL");
+
+ switch (isolationLevel)
+ {
+ case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+ sb.append(" READ COMMITTED");
+ break;
+
+ case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+ sb.append(" SERIALIZABLE");
+ break;
+
+ default:
+ throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel));
+ }
+ return sb.toString();
+ }
+
+ /*
+ * 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
+ *
+ * @exception SQLException if a database access error occurs
+ */
+ public void setCatalog(String catalog) throws SQLException
+ {
+ //no-op
+ }
+
+ /*
+ * Return the connections current catalog name, or null if no
+ * catalog name is set, or we dont support catalogs.
+ *
+ * @return the current catalog name or null
+ * @exception SQLException if a database access error occurs
+ */
+ public String getCatalog() throws SQLException
+ {
+ return PG_DATABASE;
+ }
+
+ /*
+ * Overides finalize(). If called, it closes the connection.
+ *
+ * This was done at the request of Rachel Greenham
+ * <rachel@enlarion.demon.co.uk> who hit a problem where multiple
+ * clients didn't close the connection, and once a fortnight enough
+ * clients were open to kill the org.postgres server.
+ */
+ public void finalize() throws Throwable
+ {
+ close();
+ }
+
+ private static String extractVersionNumber(String fullVersionString)
+ {
+ StringTokenizer versionParts = new StringTokenizer(fullVersionString);
+ versionParts.nextToken(); /* "PostgreSQL" */
+ return versionParts.nextToken(); /* "X.Y.Z" */
+ }
+
+ /*
+ * Get server version number
+ */
+ public String getDBVersionNumber()
+ {
+ return dbVersionNumber;
+ }
+
+ public boolean haveMinimumServerVersion(String ver) throws SQLException
+ {
+ return (getDBVersionNumber().compareTo(ver) >= 0);
+ }
+
+ /*
+ * This method returns true if the compatible level set in the connection
+ * (which can be passed into the connection or specified in the URL)
+ * is at least the value passed to this method. This is used to toggle
+ * between different functionality as it changes across different releases
+ * of the jdbc driver code. The values here are versions of the jdbc client
+ * and not server versions. For example in 7.1 get/setBytes worked on
+ * LargeObject values, in 7.2 these methods were changed to work on bytea
+ * values. This change in functionality could be disabled by setting the
+ * "compatible" level to be 7.1, in which case the driver will revert to
+ * the 7.1 functionality.
+ */
+ public boolean haveMinimumCompatibleVersion(String ver) throws SQLException
+ {
+ return (compatible.compareTo(ver) >= 0);
+ }
+
+
+ /*
+ * This returns the java.sql.Types type for a PG type oid
+ *
+ * @param oid PostgreSQL type oid
+ * @return the java.sql.Types type
+ * @exception SQLException if a database access error occurs
+ */
+ public int getSQLType(int oid) throws SQLException
+ {
+ Integer sqlType = (Integer)sqlTypeCache.get(new Integer(oid));
+
+ // it's not in the cache, so perform a query, and add the result to the cache
+ if (sqlType == null)
+ {
+ ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
+ if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ throw new PSQLException("postgresql.unexpected");
+ result.next();
+ String pgType = result.getString(1);
+ Integer iOid = new Integer(oid);
+ sqlType = new Integer(getSQLType(result.getString(1)));
+ sqlTypeCache.put(iOid, sqlType);
+ pgTypeCache.put(iOid, pgType);
+ result.close();
+ }
+
+ return sqlType.intValue();
+ }
+
+ /*
+ * This returns the java.sql.Types type for a PG type
+ *
+ * @param pgTypeName PostgreSQL type name
+ * @return the java.sql.Types type
+ */
+ public abstract int getSQLType(String pgTypeName);
+
+ /*
+ * This returns the oid for a given PG data type
+ * @param typeName PostgreSQL type name
+ * @return PostgreSQL oid value for a field of this type
+ */
+ public int getOID(String typeName) throws SQLException
+ {
+ int oid = -1;
+ if (typeName != null)
+ {
+ Integer oidValue = (Integer) typeOidCache.get(typeName);
+ if (oidValue != null)
+ {
+ oid = oidValue.intValue();
+ }
+ else
+ {
+ // it's not in the cache, so perform a query, and add the result to the cache
+ ResultSet result = (org.postgresql.ResultSet)ExecSQL("select oid from pg_type where typname='"
+ + typeName + "'");
+ if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ throw new PSQLException("postgresql.unexpected");
+ result.next();
+ oid = Integer.parseInt(result.getString(1));
+ typeOidCache.put(typeName, new Integer(oid));
+ result.close();
+ }
+ }
+ return oid;
+ }
+
+ /*
+ * We also need to get the PG type name as returned by the back end.
+ *
+ * @return the String representation of the type of this field
+ * @exception SQLException if a database access error occurs
+ */
+ public String getPGType(int oid) throws SQLException
+ {
+ String pgType = (String) pgTypeCache.get(new Integer(oid));
+ if (pgType == null)
+ {
+ getSQLType(oid);
+ pgType = (String) pgTypeCache.get(new Integer(oid));
+ }
+ return pgType;
+ }
+
+ //Because the get/setLogStream methods are deprecated in JDBC2
+ //we use them for JDBC1 here and override this method in the jdbc2
+ //version of this class
+ protected void enableDriverManagerLogging() {
+ if (DriverManager.getLogStream() == null) {
+ DriverManager.setLogStream(System.out);
+ }
+ }
+
+}
+
diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in
index bc1925efe56..a199fe2bc7a 100644
--- a/src/interfaces/jdbc/org/postgresql/Driver.java.in
+++ b/src/interfaces/jdbc/org/postgresql/Driver.java.in
@@ -29,13 +29,10 @@ public class Driver implements java.sql.Driver
// make these public so they can be used in setLogLevel below
- public static final int DEBUG = 0;
+ public static final int DEBUG = 2;
public static final int INFO = 1;
- public static final int WARN = 2;
- public static final int ERROR = 3;
- public static final int FATAL = 4;
-
- private static int logLevel = FATAL;
+ public static boolean logDebug = false;
+ public static boolean logInfo = false;
static
{
@@ -46,7 +43,6 @@ public class Driver implements java.sql.Driver
// 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)
{
@@ -106,7 +102,12 @@ public class Driver implements java.sql.Driver
* to/from the database to unicode. If multibyte is enabled on the
* server then the character set of the database is used as the default,
* otherwise the jvm character encoding is used as the default.
- * compatible - This is used to toggle
+ * loglevel - (optional) Enable logging of messages from the driver.
+ * The value is an integer from 1 to 2 where:
+ * INFO = 1, DEBUG = 2
+ * The output is sent to DriverManager.getPrintWriter() if set,
+ * otherwise it is sent to System.out.
+ * compatible - (optional) This is used to toggle
* between different functionality as it changes across different releases
* of the jdbc driver code. The values here are versions of the jdbc
* client and not server versions. For example in 7.1 get/setBytes
@@ -140,12 +141,12 @@ public class Driver implements java.sql.Driver
{
if ((props = parseURL(url, info)) == null)
{
- Driver.debug("Error in url" + url);
+ if (Driver.logDebug) Driver.debug("Error in url" + url);
return null;
}
try
{
- Driver.debug("connect " + url);
+ if (Driver.logDebug) Driver.debug("connect " + url);
org.postgresql.Connection con = (org.postgresql.Connection)(Class.forName("@JDBCCONNECTCLASS@").newInstance());
con.openConnection (host(), port(), props, database(), url, this);
@@ -153,7 +154,7 @@ public class Driver implements java.sql.Driver
}
catch (ClassNotFoundException ex)
{
- Driver.debug("error", ex);
+ if (Driver.logDebug) Driver.debug("error", ex);
throw new PSQLException("postgresql.jvm.version", ex);
}
catch (PSQLException ex1)
@@ -164,7 +165,7 @@ public class Driver implements java.sql.Driver
}
catch (Exception ex2)
{
- Driver.debug("error", ex2);
+ if (Driver.logDebug) Driver.debug("error", ex2);
throw new PSQLException("postgresql.unusual", ex2);
}
}
@@ -251,7 +252,7 @@ public class Driver implements java.sql.Driver
*/
public static String getVersion()
{
- return "@VERSION@";
+ return "@VERSION@ jdbc driver build " + m_buildNumber;
}
/*
@@ -293,12 +294,6 @@ public class Driver implements java.sql.Driver
{
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)
{
@@ -379,7 +374,6 @@ public class Driver implements java.sql.Driver
else if (state == -5)
{
value = token;
- //DriverManager.println("put("+key+","+value+")");
urlProps.put(key, value);
state = -2;
}
@@ -387,13 +381,6 @@ public class Driver implements java.sql.Driver
}
}
- // PM June 29 1997
- // This now outputs the properties only if we are logging
- // PM Sep 13 1999 Commented out, as it throws a Deprecation warning
- // when compiled under JDK1.2.
- //if (DriverManager.getLogStream() != null)
- // urlProps.list(DriverManager.getLogStream());
-
return urlProps;
}
@@ -446,12 +433,13 @@ public class Driver implements java.sql.Driver
* used to turn logging on to a certain level, can be called
* by specifying fully qualified class ie org.postgresql.Driver.setLogLevel()
* @param int logLevel sets the level which logging will respond to
- * FATAL being almost no messages
+ * INFO being almost no messages
* DEBUG most verbose
*/
public static void setLogLevel(int logLevel)
{
- Driver.logLevel = logLevel;
+ logDebug = (logLevel >= DEBUG) ? true : false;
+ logInfo = (logLevel >= INFO) ? true : false;
}
/*
* logging message at the debug level
@@ -459,7 +447,7 @@ public class Driver implements java.sql.Driver
*/
public static void debug(String msg)
{
- if (logLevel <= DEBUG)
+ if (logDebug)
{
DriverManager.println(msg);
}
@@ -470,7 +458,7 @@ public class Driver implements java.sql.Driver
*/
public static void debug(String msg, Exception ex)
{
- if (logLevel <= DEBUG)
+ if (logDebug)
{
DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
}
@@ -481,7 +469,7 @@ public class Driver implements java.sql.Driver
*/
public static void info(String msg)
{
- if (logLevel <= INFO)
+ if (logInfo)
{
DriverManager.println(msg);
}
@@ -492,75 +480,13 @@ public class Driver implements java.sql.Driver
*/
public static void info(String msg, Exception ex)
{
- if (logLevel <= INFO)
- {
- DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
- }
- }
- /*
- * logging message at warn level
- * messages will be printed if the logging level is less or equal to WARN
- */
- public static void warn(String msg)
- {
- if (logLevel <= WARN)
- {
- DriverManager.println(msg);
- }
- }
- /*
- * logging message at warn level
- * messages will be printed if the logging level is less or equal to WARN
- */
- public static void warn(String msg, Exception ex)
- {
- if (logLevel <= WARN)
- {
- DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
- }
- }
- /*
- * logging message at error level
- * messages will be printed if the logging level is less or equal to ERROR
- */
- public static void error(String msg)
- {
- if (logLevel <= ERROR)
- {
- DriverManager.println(msg);
- }
- }
- /*
- * logging message at error level
- * messages will be printed if the logging level is less or equal to ERROR
- */
- public static void error(String msg, Exception ex)
- {
- if (logLevel <= ERROR)
- {
- DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
- }
- }
- /*
- * logging message at fatal level
- * messages will be printed if the logging level is less or equal to FATAL
- */
- public static void fatal(String msg)
- {
- if (logLevel <= FATAL)
- {
- DriverManager.println(msg);
- }
- }
- /*
- * logging message at fatal level
- * messages will be printed if the logging level is less or equal to FATAL
- */
- public static void fatal(String msg, Exception ex)
- {
- if (logLevel <= FATAL)
+ if (logInfo)
{
DriverManager.println(msg + ex != null ? ex.getMessage() : "null Exception");
}
}
+
+ //The build number should be incremented for every new build
+ private static int m_buildNumber = 100;
+
}
diff --git a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
index a74645015a8..20f5a6f3e26 100644
--- a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
+++ b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
@@ -1,5 +1,6 @@
package org.postgresql.fastpath;
+import org.postgresql.Driver;
import java.io.*;
import java.lang.*;
import java.net.*;
@@ -44,7 +45,6 @@ public class Fastpath
{
this.conn = conn;
this.stream = stream;
- //DriverManager.println("Fastpath initialised");
}
/*
@@ -174,7 +174,7 @@ public class Fastpath
*/
public Object fastpath(String name, boolean resulttype, FastpathArg[] args) throws SQLException
{
- //DriverManager.println("Fastpath: calling "+name);
+ if (Driver.logDebug) Driver.debug("Fastpath: calling "+name);
return fastpath(getID(name), resulttype, args);
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
index 29f641e02fe..3c447a88b4b 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
/*
* This class provides information about the database as a whole.
*
- * $Id: DatabaseMetaData.java,v 1.45 2002/06/06 14:47:52 davec Exp $
+ * $Id: DatabaseMetaData.java,v 1.46 2002/06/11 02:55:16 barry Exp $
*
* <p>Many of the methods here return lists of information in ResultSets. You
* can use the normal ResultSet methods such as getString and getInt to
@@ -1731,7 +1731,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
String relKind;
switch (r.getBytes(3)[0])
{
- case (byte) 'r':
+ case (byte) 'r':
if ( r.getString(1).startsWith("pg_") )
{
relKind = "SYSTEM TABLE";
@@ -2108,7 +2108,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
byte[][] tuple = new byte[8][0];
tuple[0] = tuple[1] = "".getBytes();
- DriverManager.println("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\"");
// For now, don't add to the result as relacl needs to be processed.
//v.addElement(tuple);
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
index 0d62c74c9ad..86b1a4fc79c 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.*;
/*
- * $Id: Connection.java,v 1.18 2002/03/26 05:52:50 barry Exp $
+ * $Id: Connection.java,v 1.19 2002/06/11 02:55:16 barry Exp $
*
* A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are
@@ -318,6 +318,14 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
Types.ARRAY
};
+ //Because the get/setLogStream methods are deprecated in JDBC2
+ //we use the get/setLogWriter methods here for JDBC2 by overriding
+ //the base version of this method
+ protected void enableDriverManagerLogging() {
+ if (DriverManager.getLogWriter() == null) {
+ DriverManager.setLogWriter(new PrintWriter(System.out));
+ }
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
index 2eb2b07087b..a6130720ddb 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
@@ -15,7 +15,7 @@ import org.postgresql.util.PSQLException;
/*
* This class provides information about the database as a whole.
*
- * $Id: DatabaseMetaData.java,v 1.54 2002/06/06 14:47:52 davec Exp $
+ * $Id: DatabaseMetaData.java,v 1.55 2002/06/11 02:55:16 barry Exp $
*
* <p>Many of the methods here return lists of information in ResultSets. You
* can use the normal ResultSet methods such as getString and getInt to
@@ -62,7 +62,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean allProceduresAreCallable() throws SQLException
{
- Driver.debug("allProceduresAreCallable");
+ if (Driver.logDebug) Driver.debug("allProceduresAreCallable");
return true; // For now...
}
@@ -75,7 +75,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean allTablesAreSelectable() throws SQLException
{
- Driver.debug("allTablesAreSelectable");
+ if (Driver.logDebug) Driver.debug("allTablesAreSelectable");
return true; // For now...
}
@@ -88,7 +88,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public String getURL() throws SQLException
{
String url = connection.getURL();
- Driver.debug("getURL " + url);
+ if (Driver.logDebug) Driver.debug("getURL " + url);
return url;
}
@@ -101,7 +101,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public String getUserName() throws SQLException
{
String userName = connection.getUserName();
- Driver.debug("getUserName " + userName);
+ if (Driver.logDebug) Driver.debug("getUserName " + userName);
return userName;
}
@@ -114,7 +114,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean isReadOnly() throws SQLException
{
boolean isReadOnly = connection.isReadOnly();
- Driver.debug("isReadOnly " + isReadOnly);
+ if (Driver.logDebug) Driver.debug("isReadOnly " + isReadOnly);
return isReadOnly;
}
@@ -127,7 +127,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean nullsAreSortedHigh() throws SQLException
{
boolean nullSortedHigh = connection.haveMinimumServerVersion("7.2");
- Driver.debug("nullsAreSortedHigh " + nullSortedHigh);
+ if (Driver.logDebug) Driver.debug("nullsAreSortedHigh " + nullSortedHigh);
return nullSortedHigh;
}
@@ -139,7 +139,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean nullsAreSortedLow() throws SQLException
{
- Driver.debug("nullsAreSortedLow false");
+ if (Driver.logDebug) Driver.debug("nullsAreSortedLow false");
return false;
}
@@ -151,7 +151,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean nullsAreSortedAtStart() throws SQLException
{
- Driver.debug("nullsAreSortedAtStart false");
+ if (Driver.logDebug) Driver.debug("nullsAreSortedAtStart false");
return false;
}
@@ -164,7 +164,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean nullsAreSortedAtEnd() throws SQLException
{
boolean nullsAreSortedAtEnd = ! connection.haveMinimumServerVersion("7.2");
- Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd);
+ if (Driver.logDebug) Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd);
return nullsAreSortedAtEnd;
}
@@ -177,7 +177,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getDatabaseProductName() throws SQLException
{
- Driver.debug("getDatabaseProductName PostgresSQL");
+ if (Driver.logDebug) Driver.debug("getDatabaseProductName PostgresSQL");
return "PostgreSQL";
}
@@ -190,7 +190,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public String getDatabaseProductVersion() throws SQLException
{
String versionNumber = connection.getDBVersionNumber();
- Driver.debug("getDatabaseProductVersion " + versionNumber);
+ if (Driver.logDebug) Driver.debug("getDatabaseProductVersion " + versionNumber);
return versionNumber;
}
@@ -204,7 +204,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public String getDriverName() throws SQLException
{
String driverName = "PostgreSQL Native Driver";
- Driver.debug("getDriverName" + driverName);
+ if (Driver.logDebug) Driver.debug("getDriverName" + driverName);
return driverName;
}
@@ -218,7 +218,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public String getDriverVersion() throws SQLException
{
String driverVersion = connection.this_driver.getVersion();
- Driver.debug("getDriverVersion " + driverVersion);
+ if (Driver.logDebug) Driver.debug("getDriverVersion " + driverVersion);
return driverVersion;
}
@@ -230,7 +230,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public int getDriverMajorVersion()
{
int majorVersion = connection.this_driver.getMajorVersion();
- Driver.debug("getMajorVersion " + majorVersion);
+ if (Driver.logDebug) Driver.debug("getMajorVersion " + majorVersion);
return majorVersion;
}
@@ -242,7 +242,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public int getDriverMinorVersion()
{
int minorVersion = connection.this_driver.getMinorVersion();
- Driver.debug("getMinorVersion " + minorVersion);
+ if (Driver.logDebug) Driver.debug("getMinorVersion " + minorVersion);
return minorVersion;
}
@@ -255,7 +255,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean usesLocalFiles() throws SQLException
{
- Driver.debug("usesLocalFiles " + false);
+ if (Driver.logDebug) Driver.debug("usesLocalFiles " + false);
return false;
}
@@ -268,7 +268,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean usesLocalFilePerTable() throws SQLException
{
- Driver.debug("usesLocalFilePerTable " + false);
+ if (Driver.logDebug) Driver.debug("usesLocalFilePerTable " + false);
return false;
}
@@ -286,7 +286,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsMixedCaseIdentifiers() throws SQLException
{
- Driver.debug("supportsMixedCaseIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("supportsMixedCaseIdentifiers " + false);
return false;
}
@@ -298,7 +298,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesUpperCaseIdentifiers() throws SQLException
{
- Driver.debug("storesUpperCaseIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("storesUpperCaseIdentifiers " + false);
return false;
}
@@ -310,7 +310,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesLowerCaseIdentifiers() throws SQLException
{
- Driver.debug("storesLowerCaseIdentifiers " + true);
+ if (Driver.logDebug) Driver.debug("storesLowerCaseIdentifiers " + true);
return true;
}
@@ -322,7 +322,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesMixedCaseIdentifiers() throws SQLException
{
- Driver.debug("storesMixedCaseIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("storesMixedCaseIdentifiers " + false);
return false;
}
@@ -336,7 +336,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException
{
- Driver.debug("supportsMixedCaseQuotedIdentifiers " + true);
+ if (Driver.logDebug) Driver.debug("supportsMixedCaseQuotedIdentifiers " + true);
return true;
}
@@ -348,7 +348,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException
{
- Driver.debug("storesUpperCaseQuotedIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("storesUpperCaseQuotedIdentifiers " + false);
return false;
}
@@ -360,7 +360,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException
{
- Driver.debug("storesLowerCaseQuotedIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("storesLowerCaseQuotedIdentifiers " + false);
return false;
}
@@ -372,7 +372,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException
{
- Driver.debug("storesMixedCaseQuotedIdentifiers " + false);
+ if (Driver.logDebug) Driver.debug("storesMixedCaseQuotedIdentifiers " + false);
return false;
}
@@ -386,7 +386,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getIdentifierQuoteString() throws SQLException
{
- Driver.debug("getIdentifierQuoteString \"" );
+ if (Driver.logDebug) Driver.debug("getIdentifierQuoteString \"" );
return "\"";
}
@@ -408,35 +408,35 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getSQLKeywords() throws SQLException
{
- Driver.debug("getSQLKeyWords");
+ if (Driver.logDebug) Driver.debug("getSQLKeyWords");
return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version";
}
public String getNumericFunctions() throws SQLException
{
// XXX-Not Implemented
- Driver.debug("getNumericFunctions");
+ if (Driver.logDebug) Driver.debug("getNumericFunctions");
return "";
}
public String getStringFunctions() throws SQLException
{
// XXX-Not Implemented
- Driver.debug("getStringFunctions");
+ if (Driver.logDebug) Driver.debug("getStringFunctions");
return "";
}
public String getSystemFunctions() throws SQLException
{
// XXX-Not Implemented
- Driver.debug("getSystemFunctions");
+ if (Driver.logDebug) Driver.debug("getSystemFunctions");
return "";
}
public String getTimeDateFunctions() throws SQLException
{
// XXX-Not Implemented
- Driver.debug("getTimeDateFunctions");
+ if (Driver.logDebug) Driver.debug("getTimeDateFunctions");
return "";
}
@@ -449,7 +449,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getSearchStringEscape() throws SQLException
{
- Driver.debug("getSearchStringEscape");
+ if (Driver.logDebug) Driver.debug("getSearchStringEscape");
return "\\";
}
@@ -466,7 +466,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getExtraNameCharacters() throws SQLException
{
- Driver.debug("getExtraNameCharacters");
+ if (Driver.logDebug) Driver.debug("getExtraNameCharacters");
return "";
}
@@ -479,7 +479,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsAlterTableWithAddColumn() throws SQLException
{
- Driver.debug("supportsAlterTableWithAddColumn " + true);
+ if (Driver.logDebug) Driver.debug("supportsAlterTableWithAddColumn " + true);
return true;
}
@@ -492,7 +492,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsAlterTableWithDropColumn() throws SQLException
{
- Driver.debug("supportsAlterTableWithDropColumn " + false);
+ if (Driver.logDebug) Driver.debug("supportsAlterTableWithDropColumn " + false);
return false;
}
@@ -516,7 +516,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsColumnAliasing() throws SQLException
{
- Driver.debug("supportsColumnAliasing " + true);
+ if (Driver.logDebug) Driver.debug("supportsColumnAliasing " + true);
return true;
}
@@ -529,21 +529,21 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean nullPlusNonNullIsNull() throws SQLException
{
- Driver.debug("nullPlusNonNullIsNull " + true);
+ if (Driver.logDebug) Driver.debug("nullPlusNonNullIsNull " + true);
return true;
}
public boolean supportsConvert() throws SQLException
{
// XXX-Not Implemented
- Driver.debug("supportsConvert " + false);
+ if (Driver.logDebug) Driver.debug("supportsConvert " + false);
return false;
}
public boolean supportsConvert(int fromType, int toType) throws SQLException
{
// XXX-Not Implemented
- Driver.debug("supportsConvert " + false);
+ if (Driver.logDebug) Driver.debug("supportsConvert " + false);
return false;
}
@@ -556,7 +556,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsTableCorrelationNames() throws SQLException
{
- Driver.debug("supportsTableCorrelationNames " + true);
+ if (Driver.logDebug) Driver.debug("supportsTableCorrelationNames " + true);
return true;
}
@@ -569,7 +569,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsDifferentTableCorrelationNames() throws SQLException
{
- Driver.debug("supportsDifferentTableCorrelationNames " + false);
+ if (Driver.logDebug) Driver.debug("supportsDifferentTableCorrelationNames " + false);
return false;
}
@@ -583,7 +583,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsExpressionsInOrderBy() throws SQLException
{
- Driver.debug("supportsExpressionsInOrderBy " + true);
+ if (Driver.logDebug) Driver.debug("supportsExpressionsInOrderBy " + true);
return true;
}
@@ -596,7 +596,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsOrderByUnrelated() throws SQLException
{
boolean supportsOrderByUnrelated = connection.haveMinimumServerVersion("6.4");
- Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated);
+ if (Driver.logDebug) Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated);
return supportsOrderByUnrelated;
}
@@ -609,7 +609,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsGroupBy() throws SQLException
{
- Driver.debug("supportsGroupBy " + true);
+ if (Driver.logDebug) Driver.debug("supportsGroupBy " + true);
return true;
}
@@ -622,7 +622,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsGroupByUnrelated() throws SQLException
{
boolean supportsGroupByUnrelated = connection.haveMinimumServerVersion("6.4");
- Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated);
+ if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated);
return supportsGroupByUnrelated;
}
@@ -639,7 +639,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsGroupByBeyondSelect() throws SQLException
{
boolean supportsGroupByBeyondSelect = connection.haveMinimumServerVersion("6.4");
- Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect);
+ if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect);
return supportsGroupByBeyondSelect;
}
@@ -653,7 +653,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsLikeEscapeClause() throws SQLException
{
boolean supportsLikeEscapeClause = connection.haveMinimumServerVersion("7.1");
- Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause);
+ if (Driver.logDebug) Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause);
return supportsLikeEscapeClause;
}
@@ -667,7 +667,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsMultipleResultSets() throws SQLException
{
- Driver.debug("supportsMultipleResultSets " + false);
+ if (Driver.logDebug) Driver.debug("supportsMultipleResultSets " + false);
return false;
}
@@ -681,7 +681,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsMultipleTransactions() throws SQLException
{
- Driver.debug("supportsMultipleTransactions " + true);
+ if (Driver.logDebug) Driver.debug("supportsMultipleTransactions " + true);
return true;
}
@@ -697,7 +697,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsNonNullableColumns() throws SQLException
{
- Driver.debug("supportsNonNullableColumns true");
+ if (Driver.logDebug) Driver.debug("supportsNonNullableColumns true");
return true;
}
@@ -715,7 +715,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsMinimumSQLGrammar() throws SQLException
{
- Driver.debug("supportsMinimumSQLGrammar TRUE");
+ if (Driver.logDebug) Driver.debug("supportsMinimumSQLGrammar TRUE");
return true;
}
@@ -728,7 +728,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCoreSQLGrammar() throws SQLException
{
- Driver.debug("supportsCoreSQLGrammar FALSE ");
+ if (Driver.logDebug) Driver.debug("supportsCoreSQLGrammar FALSE ");
return false;
}
@@ -742,7 +742,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsExtendedSQLGrammar() throws SQLException
{
- Driver.debug("supportsExtendedSQLGrammar FALSE");
+ if (Driver.logDebug) Driver.debug("supportsExtendedSQLGrammar FALSE");
return false;
}
@@ -761,7 +761,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsANSI92EntryLevelSQL() throws SQLException
{
boolean schemas = connection.haveMinimumServerVersion("7.3");
- Driver.debug("supportsANSI92EntryLevelSQL " + schemas);
+ if (Driver.logDebug) Driver.debug("supportsANSI92EntryLevelSQL " + schemas);
return schemas;
}
@@ -775,7 +775,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsANSI92IntermediateSQL() throws SQLException
{
- Driver.debug("supportsANSI92IntermediateSQL false ");
+ if (Driver.logDebug) Driver.debug("supportsANSI92IntermediateSQL false ");
return false;
}
@@ -787,7 +787,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsANSI92FullSQL() throws SQLException
{
- Driver.debug("supportsANSI92FullSQL false ");
+ if (Driver.logDebug) Driver.debug("supportsANSI92FullSQL false ");
return false;
}
@@ -800,7 +800,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsIntegrityEnhancementFacility() throws SQLException
{
- Driver.debug("supportsIntegrityEnhancementFacility false ");
+ if (Driver.logDebug) Driver.debug("supportsIntegrityEnhancementFacility false ");
return false;
}
@@ -813,7 +813,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsOuterJoins() throws SQLException
{
boolean supportsOuterJoins = connection.haveMinimumServerVersion("7.1");
- Driver.debug("supportsOuterJoins " + supportsOuterJoins);
+ if (Driver.logDebug) Driver.debug("supportsOuterJoins " + supportsOuterJoins);
return supportsOuterJoins;
}
@@ -826,7 +826,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsFullOuterJoins() throws SQLException
{
boolean supportsFullOuterJoins = connection.haveMinimumServerVersion("7.1");
- Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins);
+ if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins);
return supportsFullOuterJoins;
}
@@ -839,7 +839,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
public boolean supportsLimitedOuterJoins() throws SQLException
{
boolean supportsLimitedOuterJoins = connection.haveMinimumServerVersion("7.1");
- Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins);
+ if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins);
return supportsLimitedOuterJoins;
}
@@ -853,7 +853,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getSchemaTerm() throws SQLException
{
- Driver.debug("getSchemaTerm schema");
+ if (Driver.logDebug) Driver.debug("getSchemaTerm schema");
return "schema";
}
@@ -866,7 +866,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getProcedureTerm() throws SQLException
{
- Driver.debug("getProcedureTerm function ");
+ if (Driver.logDebug) Driver.debug("getProcedureTerm function ");
return "function";
}
@@ -878,7 +878,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public String getCatalogTerm() throws SQLException
{
- Driver.debug("getCatalogTerm database ");
+ if (Driver.logDebug) Driver.debug("getCatalogTerm database ");
return "database";
}
@@ -893,7 +893,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
// return true here; we return false for every other catalog function
// so it won't matter what we return here D.C.
- Driver.debug("isCatalogAtStart not implemented");
+ if (Driver.logDebug) Driver.debug("isCatalogAtStart not implemented");
return true;
}
@@ -907,7 +907,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
// Give them something to work with here
// everything else returns false so it won't matter what we return here D.C.
- Driver.debug("getCatalogSeparator not implemented ");
+ if (Driver.logDebug) Driver.debug("getCatalogSeparator not implemented ");
return ".";
}
@@ -919,7 +919,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsSchemasInDataManipulation() throws SQLException
{
- Driver.debug("supportsSchemasInDataManipulation false");
+ if (Driver.logDebug) Driver.debug("supportsSchemasInDataManipulation false");
return false;
}
@@ -931,7 +931,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsSchemasInProcedureCalls() throws SQLException
{
- Driver.debug("supportsSchemasInProcedureCalls false");
+ if (Driver.logDebug) Driver.debug("supportsSchemasInProcedureCalls false");
return false;
}
@@ -945,7 +945,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
boolean schemas = connection.haveMinimumServerVersion("7.3");
- Driver.debug("supportsSchemasInTableDefinitions " + schemas);
+ if (Driver.logDebug) Driver.debug("supportsSchemasInTableDefinitions " + schemas);
return schemas;
}
@@ -957,7 +957,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsSchemasInIndexDefinitions() throws SQLException
{
- Driver.debug("supportsSchemasInIndexDefinitions false");
+ if (Driver.logDebug) Driver.debug("supportsSchemasInIndexDefinitions false");
return false;
}
@@ -969,7 +969,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException
{
- Driver.debug("supportsSchemasInPrivilegeDefinitions false");
+ if (Driver.logDebug) Driver.debug("supportsSchemasInPrivilegeDefinitions false");
return false;
}
@@ -981,7 +981,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCatalogsInDataManipulation() throws SQLException
{
- Driver.debug("supportsCatalogsInDataManipulation false");
+ if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false");
return false;
}
@@ -993,7 +993,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCatalogsInProcedureCalls() throws SQLException
{
- Driver.debug("supportsCatalogsInDataManipulation false");
+ if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false");
return false;
}
@@ -1005,7 +1005,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCatalogsInTableDefinitions() throws SQLException
{
- Driver.debug("supportsCatalogsInTableDefinitions false");
+ if (Driver.logDebug) Driver.debug("supportsCatalogsInTableDefinitions false");
return false;
}
@@ -1017,7 +1017,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCatalogsInIndexDefinitions() throws SQLException
{
- Driver.debug("supportsCatalogsInIndexDefinitions false");
+ if (Driver.logDebug) Driver.debug("supportsCatalogsInIndexDefinitions false");
return false;
}
@@ -1029,7 +1029,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException
{
- Driver.debug("supportsCatalogsInPrivilegeDefinitions false");
+ if (Driver.logDebug) Driver.debug("supportsCatalogsInPrivilegeDefinitions false");
return false;
}
@@ -1042,7 +1042,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsPositionedDelete() throws SQLException
{
- Driver.debug("supportsPositionedDelete false");
+ if (Driver.logDebug) Driver.debug("supportsPositionedDelete false");
return false; // For now...
}
@@ -1054,7 +1054,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
*/
public boolean supportsPositionedUpdate() throws SQLException
{
- Driver.debug("supportsPositionedUpdate false");
+ if (Driver.logDebug) Driver.debug("supportsPositionedUpdate false");
return false; // For now...
}
@@ -2212,7 +2212,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
byte[][] tuple = new byte[8][0];
tuple[0] = tuple[1] = "".getBytes();
- DriverManager.println("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\"");
+ if (Driver.logDebug) Driver.debug("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\"");
// For now, don't add to the result as relacl needs to be processed.
//v.addElement(tuple);
@@ -2275,7 +2275,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
{
byte[][] tuple = new byte[8][0];
tuple[0] = tuple[1] = "".getBytes();
- DriverManager.println("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\"");
+ if (Driver.logDebug) Driver.debug("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\"");
// For now, don't add to the result as relacl needs to be processed.
//v.addElement(tuple);
diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
index dec1de55f0a..e5296189cdc 100644
--- a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
+++ b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
@@ -1,5 +1,6 @@
package org.postgresql.largeobject;
+import org.postgresql.Driver;
import java.io.*;
import java.lang.*;
import java.net.*;
@@ -117,7 +118,7 @@ public class LargeObjectManager
fp.addFunctions(res);
res.close();
- DriverManager.println("Large Object initialised");
+ if (Driver.logDebug) Driver.debug("Large Object initialised");
}
/*
diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
index 59d9c03206e..80d10bc5410 100644
--- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java
+++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
@@ -1,5 +1,6 @@
package org.postgresql.util;
+import org.postgresql.Driver;
import java.io.*;
import java.lang.*;
import java.lang.reflect.*;
@@ -128,14 +129,14 @@ public class Serialize
try
{
conn = c;
- DriverManager.println("Serialize: initializing instance for type: " + type);
+ if (Driver.logDebug) Driver.debug("Serialize: initializing instance for type: " + type);
tableName = toPostgreSQL(type);
className = type;
ourClass = Class.forName(className);
}
catch (ClassNotFoundException cnfe)
{
- DriverManager.println("Serialize: " + className + " java class not found");
+ if (Driver.logDebug) Driver.debug("Serialize: " + className + " java class not found");
throw new PSQLException("postgresql.serial.noclass", type);
}
@@ -147,14 +148,14 @@ public class Serialize
if (rs.next())
{
status = true;
- DriverManager.println("Serialize: " + tableName + " table found");
+ if (Driver.logDebug) Driver.debug("Serialize: " + tableName + " table found");
}
rs.close();
}
// This should never occur, as org.postgresql has it's own internal checks
if (!status)
{
- DriverManager.println("Serialize: " + tableName + " table not found");
+ if (Driver.logDebug) Driver.debug("Serialize: " + tableName + " table not found");
throw new PSQLException("postgresql.serial.table", type);
}
// Finally cache the fields within the table
@@ -186,9 +187,9 @@ public class Serialize
{
try
{
- DriverManager.println("Serialize.fetch: " + "attempting to instantiate object of type: " + ourClass.getName() );
+ if (Driver.logDebug) Driver.debug("Serialize.fetch: " + "attempting to instantiate object of type: " + ourClass.getName() );
Object obj = ourClass.newInstance();
- DriverManager.println("Serialize.fetch: " + "instantiated object of type: " + ourClass.getName() );
+ if (Driver.logDebug) Driver.debug("Serialize.fetch: " + "instantiated object of type: " + ourClass.getName() );
// NB: we use java.lang.reflect here to prevent confusion with
// the org.postgresql.Field
@@ -219,7 +220,7 @@ public class Serialize
sb.append(" where oid=");
sb.append(oid);
- DriverManager.println("Serialize.fetch: " + sb.toString());
+ if (Driver.logDebug) Driver.debug("Serialize.fetch: " + sb.toString());
ResultSet rs = conn.ExecSQL(sb.toString());
if (rs != null)
@@ -388,7 +389,7 @@ public class Serialize
sb.append(')');
}
- DriverManager.println("Serialize.store: " + sb.toString() );
+ if (Driver.logDebug) Driver.debug("Serialize.store: " + sb.toString() );
org.postgresql.ResultSet rs = (org.postgresql.ResultSet) conn.ExecSQL(sb.toString());
// fetch the OID for returning
@@ -495,13 +496,13 @@ public class Serialize
ResultSet rs = con.ExecSQL("select relname from pg_class where relname = '" + tableName + "'");
if ( rs.next() )
{
- DriverManager.println("Serialize.create: table " + tableName + " exists, skipping");
+ if (Driver.logDebug) Driver.debug("Serialize.create: table " + tableName + " exists, skipping");
rs.close();
return;
}
// else table not found, so create it
- DriverManager.println("Serialize.create: table " + tableName + " not found, creating" );
+ if (Driver.logDebug) Driver.debug("Serialize.create: table " + tableName + " not found, creating" );
// No entries returned, so the table doesn't exist
StringBuffer sb = new StringBuffer("create table ");
@@ -547,7 +548,7 @@ public class Serialize
sb.append(")");
// Now create the table
- DriverManager.println("Serialize.create: " + sb );
+ if (Driver.logDebug) Driver.debug("Serialize.create: " + sb );
con.ExecSQL(sb.toString());
}