OSDN Git Service

The patch does the following:
authorBarry Lind <barry@xythos.com>
Tue, 11 Jun 2002 02:55:16 +0000 (02:55 +0000)
committerBarry Lind <barry@xythos.com>
Tue, 11 Jun 2002 02:55:16 +0000 (02:55 +0000)
  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
----------------------------------------------------------------------

src/interfaces/jdbc/org/postgresql/Connection.java
src/interfaces/jdbc/org/postgresql/Driver.java.in
src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
src/interfaces/jdbc/org/postgresql/util/Serialize.java

index 96b85c7..7951ddd 100644 (file)
-package org.postgresql;\r
-\r
-import java.io.*;\r
-import java.net.*;\r
-import java.sql.*;\r
-import java.util.*;\r
-import org.postgresql.Driver;\r
-import org.postgresql.Field;\r
-import org.postgresql.fastpath.*;\r
-import org.postgresql.largeobject.*;\r
-import org.postgresql.util.*;\r
-import org.postgresql.core.*;\r
-\r
-/*\r
- * $Id: Connection.java,v 1.47 2002/05/17 01:19:19 tgl Exp $\r
- *\r
- * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or\r
- * JDBC2 versions of the Connection class.\r
- *\r
- */\r
-public abstract class Connection\r
-{\r
-        // This is the network stream associated with this connection\r
-        public PG_Stream pg_stream;\r
-\r
-        private String PG_HOST;\r
-        private int PG_PORT;\r
-        private String PG_USER;\r
-        private String PG_DATABASE;\r
-        private boolean PG_STATUS;\r
-        private String compatible;\r
-\r
-        /*\r
-         The encoding to use for this connection.\r
-         */\r
-        private Encoding encoding = Encoding.defaultEncoding();\r
-\r
-        private String dbVersionNumber;\r
-\r
-        public boolean CONNECTION_OK = true;\r
-        public boolean CONNECTION_BAD = false;\r
-\r
-        public boolean autoCommit = true;\r
-        public boolean readOnly = false;\r
-\r
-        public Driver this_driver;\r
-        private String this_url;\r
-        private String cursor = null;  // The positioned update cursor name\r
-\r
-        // These are new for v6.3, they determine the current protocol versions\r
-        // supported by this version of the driver. They are defined in\r
-        // src/include/libpq/pqcomm.h\r
-        protected static final int PG_PROTOCOL_LATEST_MAJOR = 2;\r
-        protected static final int PG_PROTOCOL_LATEST_MINOR = 0;\r
-\r
-        private static final int AUTH_REQ_OK = 0;\r
-        private static final int AUTH_REQ_KRB4 = 1;\r
-        private static final int AUTH_REQ_KRB5 = 2;\r
-        private static final int AUTH_REQ_PASSWORD = 3;\r
-        private static final int AUTH_REQ_CRYPT = 4;\r
-        private static final int AUTH_REQ_MD5 = 5;\r
-\r
-\r
-        // These are used to cache oids, PGTypes and SQLTypes\r
-        private static Hashtable sqlTypeCache = new Hashtable();  // oid -> SQLType\r
-        private static Hashtable pgTypeCache = new Hashtable();  // oid -> PGType\r
-        private static Hashtable typeOidCache = new Hashtable();  //PGType -> oid\r
-\r
-        // Now handle notices as warnings, so things like "show" now work\r
-        public SQLWarning firstWarning = null;\r
-\r
-        /*\r
-         * Cache of the current isolation level\r
-         */\r
-        private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;\r
-\r
-        // The PID an cancellation key we get from the backend process\r
-        public int pid;\r
-        public int ckey;\r
-\r
-        /*\r
-         * This is called by Class.forName() from within org.postgresql.Driver\r
-         */\r
-        public Connection()\r
-        {}\r
-\r
-        public void cancelQuery() throws SQLException\r
-        {\r
-                PG_Stream cancelStream = null;\r
-                try {\r
-                        cancelStream = new PG_Stream(PG_HOST, PG_PORT);\r
-                } catch (ConnectException cex) {\r
-                        // Added by Peter Mount <peter@retep.org.uk>\r
-                        // ConnectException is thrown when the connection cannot be made.\r
-                        // we trap this an return a more meaningful message for the end user\r
-                        throw new PSQLException ("postgresql.con.refused");\r
-                } catch (IOException e) {\r
-                        throw new PSQLException ("postgresql.con.failed",e);\r
-                }\r
-\r
-                // Now we need to construct and send a cancel packet\r
-                try {\r
-                        cancelStream.SendInteger(16, 4);\r
-                        cancelStream.SendInteger(80877102, 4);\r
-                        cancelStream.SendInteger(pid, 4);\r
-                        cancelStream.SendInteger(ckey, 4);\r
-                        cancelStream.flush();\r
-                }\r
-                catch(IOException e) {\r
-                        throw new PSQLException("postgresql.con.failed",e);\r
-                }\r
-                finally {\r
-                        try {\r
-                                if(cancelStream != null)\r
-                                        cancelStream.close();\r
-                        }\r
-                        catch(IOException e) {} // Ignore\r
-                }\r
-        }\r
-\r
-        /*\r
-         * This method actually opens the connection. It is called by Driver.\r
-         *\r
-         * @param host the hostname of the database back end\r
-         * @param port the port number of the postmaster process\r
-         * @param info a Properties[] thing of the user and password\r
-         * @param database the database to connect to\r
-         * @param u the URL of the connection\r
-         * @param d the Driver instantation of the connection\r
-         * @return a valid connection profile\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException\r
-        {\r
-                firstWarning = null;\r
-\r
-                // Throw an exception if the user or password properties are missing\r
-                // This occasionally occurs when the client uses the properties version\r
-                // of getConnection(), and is a common question on the email lists\r
-                if (info.getProperty("user") == null)\r
-                        throw new PSQLException("postgresql.con.user");\r
-\r
-                this_driver = d;\r
-                this_url = url;\r
-\r
-                PG_DATABASE = database;\r
-                PG_USER = info.getProperty("user");\r
-\r
-                String password = info.getProperty("password", "");\r
-                PG_PORT = port;\r
-\r
-                PG_HOST = host;\r
-                PG_STATUS = CONNECTION_BAD;\r
-\r
-                if (info.getProperty("compatible") == null)\r
-                {\r
-                        compatible = d.getMajorVersion() + "." + d.getMinorVersion();\r
-                }\r
-                else\r
-                {\r
-                        compatible = info.getProperty("compatible");\r
-                }\r
-\r
-                // Now make the initial connection\r
-                try\r
-                {\r
-                        pg_stream = new PG_Stream(host, port);\r
-                }\r
-                catch (ConnectException cex)\r
-                {\r
-                        // Added by Peter Mount <peter@retep.org.uk>\r
-                        // ConnectException is thrown when the connection cannot be made.\r
-                        // we trap this an return a more meaningful message for the end user\r
-                        throw new PSQLException ("postgresql.con.refused");\r
-                }\r
-                catch (IOException e)\r
-                {\r
-                        throw new PSQLException ("postgresql.con.failed", e);\r
-                }\r
-\r
-                // Now we need to construct and send a startup packet\r
-                try\r
-                {\r
-                        new StartupPacket(PG_PROTOCOL_LATEST_MAJOR,\r
-                                                PG_PROTOCOL_LATEST_MINOR,\r
-                                                PG_USER,\r
-                                                database).writeTo(pg_stream);\r
-\r
-                        // now flush the startup packets to the backend\r
-                        pg_stream.flush();\r
-\r
-                        // Now get the response from the backend, either an error message\r
-                        // or an authentication request\r
-                        int areq = -1; // must have a value here\r
-                        do\r
-                        {\r
-                                int beresp = pg_stream.ReceiveChar();\r
-                                String salt = null;\r
-                                switch (beresp)\r
-                                {\r
-                                        case 'E':\r
-                                                // An error occured, so pass the error message to the\r
-                                                // user.\r
-                                                //\r
-                                                // The most common one to be thrown here is:\r
-                                                // "User authentication failed"\r
-                                                //\r
-                                                throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding));\r
-\r
-                                        case 'R':\r
-                                                // Get the type of request\r
-                                                areq = pg_stream.ReceiveIntegerR(4);\r
-                                                // Get the crypt password salt if there is one\r
-                                                if (areq == AUTH_REQ_CRYPT)\r
-                                                {\r
-                                                        byte[] rst = new byte[2];\r
-                                                        rst[0] = (byte)pg_stream.ReceiveChar();\r
-                                                        rst[1] = (byte)pg_stream.ReceiveChar();\r
-                                                        salt = new String(rst, 0, 2);\r
-                                                        Driver.debug("Crypt salt=" + salt);\r
-                                                }\r
-\r
-                                                // Or get the md5 password salt if there is one\r
-                                                if (areq == AUTH_REQ_MD5)\r
-                                                {\r
-                                                        byte[] rst = new byte[4];\r
-                                                        rst[0] = (byte)pg_stream.ReceiveChar();\r
-                                                        rst[1] = (byte)pg_stream.ReceiveChar();\r
-                                                        rst[2] = (byte)pg_stream.ReceiveChar();\r
-                                                        rst[3] = (byte)pg_stream.ReceiveChar();\r
-                                                        salt = new String(rst, 0, 4);\r
-                                                        Driver.debug("MD5 salt=" + salt);\r
-                                                }\r
-\r
-                                                // now send the auth packet\r
-                                                switch (areq)\r
-                                                {\r
-                                                        case AUTH_REQ_OK:\r
-                                                                break;\r
-\r
-                                                        case AUTH_REQ_KRB4:\r
-                                                                Driver.debug("postgresql: KRB4");\r
-                                                                throw new PSQLException("postgresql.con.kerb4");\r
-\r
-                                                        case AUTH_REQ_KRB5:\r
-                                                                Driver.debug("postgresql: KRB5");\r
-                                                                throw new PSQLException("postgresql.con.kerb5");\r
-\r
-                                                        case AUTH_REQ_PASSWORD:\r
-                                                                Driver.debug("postgresql: PASSWORD");\r
-                                                                pg_stream.SendInteger(5 + password.length(), 4);\r
-                                                                pg_stream.Send(password.getBytes());\r
-                                                                pg_stream.SendInteger(0, 1);\r
-                                                                pg_stream.flush();\r
-                                                                break;\r
-\r
-                                                        case AUTH_REQ_CRYPT:\r
-                                                                Driver.debug("postgresql: CRYPT");\r
-                                                                String crypted = UnixCrypt.crypt(salt, password);\r
-                                                                pg_stream.SendInteger(5 + crypted.length(), 4);\r
-                                                                pg_stream.Send(crypted.getBytes());\r
-                                                                pg_stream.SendInteger(0, 1);\r
-                                                                pg_stream.flush();\r
-                                                                break;\r
-\r
-                                                        case AUTH_REQ_MD5:\r
-                                                                Driver.debug("postgresql: MD5");\r
-                                                                byte[] digest = MD5Digest.encode(PG_USER, password, salt);\r
-                                                                pg_stream.SendInteger(5 + digest.length, 4);\r
-                                                                pg_stream.Send(digest);\r
-                                                                pg_stream.SendInteger(0, 1);\r
-                                                                pg_stream.flush();\r
-                                                                break;\r
-\r
-                                                        default:\r
-                                                                throw new PSQLException("postgresql.con.auth", new Integer(areq));\r
-                                                }\r
-                                                break;\r
-\r
-                                        default:\r
-                                                throw new PSQLException("postgresql.con.authfail");\r
-                                }\r
-                        }\r
-                        while (areq != AUTH_REQ_OK);\r
-\r
-                }\r
-                catch (IOException e)\r
-                {\r
-                        throw new PSQLException("postgresql.con.failed", e);\r
-                }\r
-\r
-\r
-                // As of protocol version 2.0, we should now receive the cancellation key and the pid\r
-                int beresp;\r
-                do {\r
-                    beresp = pg_stream.ReceiveChar();\r
-                    switch (beresp)\r
-                    {\r
-                        case 'K':\r
-                                pid = pg_stream.ReceiveIntegerR(4);\r
-                                ckey = pg_stream.ReceiveIntegerR(4);\r
-                                break;\r
-                        case 'E':\r
-                                throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));\r
-                        case 'N':\r
-                                addWarning(pg_stream.ReceiveString(encoding));\r
-                                break;\r
-                        default:\r
-                                throw new PSQLException("postgresql.con.setup");\r
-                    }\r
-                } while (beresp == 'N');\r
-\r
-                // Expect ReadyForQuery packet\r
-                do {\r
-                    beresp = pg_stream.ReceiveChar();\r
-                    switch (beresp)\r
-                    {\r
-                        case 'Z':\r
-                                break;\r
-                        case 'N':\r
-                                addWarning(pg_stream.ReceiveString(encoding));\r
-                                break;\r
-                        case 'E':\r
-                                throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding));\r
-                        default:\r
-                                throw new PSQLException("postgresql.con.setup");\r
-                    }\r
-                } while (beresp == 'N');\r
-                // "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte,\r
-                // otherwise it's hardcoded to 'SQL_ASCII'.\r
-                // If the backend doesn't know about multibyte we can't assume anything about the encoding\r
-                // used, so we denote this with 'UNKNOWN'.\r
-                //Note: begining with 7.2 we should be using pg_client_encoding() which\r
-                //is new in 7.2.  However it isn't easy to conditionally call this new\r
-                //function, since we don't yet have the information as to what server\r
-                //version we are talking to.  Thus we will continue to call\r
-                //getdatabaseencoding() until we drop support for 7.1 and older versions\r
-                //or until someone comes up with a conditional way to run one or\r
-                //the other function depending on server version that doesn't require\r
-                //two round trips to the server per connection\r
-\r
-                final String encodingQuery =\r
-                        "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";\r
-\r
-                // Set datestyle and fetch db encoding in a single call, to avoid making\r
-                // more than one round trip to the backend during connection startup.\r
-\r
-                java.sql.ResultSet resultSet =\r
-                        ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");\r
-\r
-                if (! resultSet.next())\r
-                {\r
-                        throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");\r
-                }\r
-                String version = resultSet.getString(1);\r
-                dbVersionNumber = extractVersionNumber(version);\r
-\r
-                String dbEncoding = resultSet.getString(2);\r
-                encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));\r
-\r
-                // Initialise object handling\r
-                initObjectTypes();\r
-\r
-                // Mark the connection as ok, and cleanup\r
-                PG_STATUS = CONNECTION_OK;\r
-        }\r
-\r
-        // These methods used to be in the main Connection implementation. As they\r
-        // are common to all implementations (JDBC1 or 2), they are placed here.\r
-        // This should make it easy to maintain the two specifications.\r
-\r
-        /*\r
-         * This adds a warning to the warning chain.\r
-         * @param msg message to add\r
-         */\r
-        public void addWarning(String msg)\r
-        {\r
-                // Add the warning to the chain\r
-                if (firstWarning != null)\r
-                        firstWarning.setNextWarning(new SQLWarning(msg));\r
-                else\r
-                        firstWarning = new SQLWarning(msg);\r
-\r
-                // Now check for some specific messages\r
-\r
-                // This is obsolete in 6.5, but I've left it in here so if we need to use this\r
-                // technique again, we'll know where to place it.\r
-                //\r
-                // This is generated by the SQL "show datestyle"\r
-                //if (msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {\r
-                //// 13 is the length off "DateStyle is "\r
-                //msg = msg.substring(msg.indexOf("DateStyle is ")+13);\r
-                //\r
-                //for(int i=0;i<dateStyles.length;i+=2)\r
-                //if (msg.startsWith(dateStyles[i]))\r
-                //currentDateStyle=i+1; // this is the index of the format\r
-                //}\r
-        }\r
-\r
-        /*\r
-         * Send a query to the backend.  Returns one of the ResultSet\r
-         * objects.\r
-         *\r
-         * <B>Note:</B> there does not seem to be any method currently\r
-         * in existance to return the update count.\r
-         *\r
-         * @param sql the SQL statement to be executed\r
-         * @return a ResultSet holding the results\r
-         * @exception SQLException if a database error occurs\r
-         */\r
-        public java.sql.ResultSet ExecSQL(String sql) throws SQLException\r
-        {\r
-                return ExecSQL(sql, null);\r
-        }\r
-\r
-        /*\r
-         * Send a query to the backend.  Returns one of the ResultSet\r
-         * objects.\r
-         *\r
-         * <B>Note:</B> there does not seem to be any method currently\r
-         * in existance to return the update count.\r
-         *\r
-         * @param sql the SQL statement to be executed\r
-         * @param stat The Statement associated with this query (may be null)\r
-         * @return a ResultSet holding the results\r
-         * @exception SQLException if a database error occurs\r
-         */\r
-        public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException\r
-        {\r
-                return new QueryExecutor(sql, stat, pg_stream, this).execute();\r
-        }\r
-\r
-        /*\r
-         * In SQL, a result table can be retrieved through a cursor that\r
-         * is named.  The current row of a result can be updated or deleted\r
-         * using a positioned update/delete statement that references the\r
-         * cursor name.\r
-         *\r
-         * We support one cursor per connection.\r
-         *\r
-         * setCursorName sets the cursor name.\r
-         *\r
-         * @param cursor the cursor name\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void setCursorName(String cursor) throws SQLException\r
-        {\r
-                this.cursor = cursor;\r
-        }\r
-\r
-        /*\r
-         * getCursorName gets the cursor name.\r
-         *\r
-         * @return the current cursor name\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public String getCursorName() throws SQLException\r
-        {\r
-                return cursor;\r
-        }\r
-\r
-        /*\r
-         * We are required to bring back certain information by\r
-         * the DatabaseMetaData class. These functions do that.\r
-         *\r
-         * Method getURL() brings back the URL (good job we saved it)\r
-         *\r
-         * @return the url\r
-         * @exception SQLException just in case...\r
-         */\r
-        public String getURL() throws SQLException\r
-        {\r
-                return this_url;\r
-        }\r
-\r
-        /*\r
-         * Method getUserName() brings back the User Name (again, we\r
-         * saved it)\r
-         *\r
-         * @return the user name\r
-         * @exception SQLException just in case...\r
-         */\r
-            int lastMessage = 0;\r
-        public String getUserName() throws SQLException\r
-        {\r
-                return PG_USER;\r
-        }\r
-\r
-        /*\r
-         * Get the character encoding to use for this connection.\r
-         */\r
-        public Encoding getEncoding() throws SQLException\r
-        {\r
-                return encoding;\r
-        }\r
-\r
-        /*\r
-         * This returns the Fastpath API for the current connection.\r
-         *\r
-         * <p><b>NOTE:</b> This is not part of JDBC, but allows access to\r
-         * functions on the org.postgresql backend itself.\r
-         *\r
-         * <p>It is primarily used by the LargeObject API\r
-         *\r
-         * <p>The best way to use this is as follows:\r
-         *\r
-         * <p><pre>\r
-         * import org.postgresql.fastpath.*;\r
-         * ...\r
-         * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();\r
-         * </pre>\r
-         *\r
-         * <p>where myconn is an open Connection to org.postgresql.\r
-         *\r
-         * @return Fastpath object allowing access to functions on the org.postgresql\r
-         * backend.\r
-         * @exception SQLException by Fastpath when initialising for first time\r
-         */\r
-        public Fastpath getFastpathAPI() throws SQLException\r
-        {\r
-                if (fastpath == null)\r
-                        fastpath = new Fastpath(this, pg_stream);\r
-                return fastpath;\r
-        }\r
-\r
-        // This holds a reference to the Fastpath API if already open\r
-        private Fastpath fastpath = null;\r
-\r
-        /*\r
-         * This returns the LargeObject API for the current connection.\r
-         *\r
-         * <p><b>NOTE:</b> This is not part of JDBC, but allows access to\r
-         * functions on the org.postgresql backend itself.\r
-         *\r
-         * <p>The best way to use this is as follows:\r
-         *\r
-         * <p><pre>\r
-         * import org.postgresql.largeobject.*;\r
-         * ...\r
-         * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();\r
-         * </pre>\r
-         *\r
-         * <p>where myconn is an open Connection to org.postgresql.\r
-         *\r
-         * @return LargeObject object that implements the API\r
-         * @exception SQLException by LargeObject when initialising for first time\r
-         */\r
-        public LargeObjectManager getLargeObjectAPI() throws SQLException\r
-        {\r
-                if (largeobject == null)\r
-                        largeobject = new LargeObjectManager(this);\r
-                return largeobject;\r
-        }\r
-\r
-        // This holds a reference to the LargeObject API if already open\r
-        private LargeObjectManager largeobject = null;\r
-\r
-        /*\r
-         * This method is used internally to return an object based around\r
-         * org.postgresql's more unique data types.\r
-         *\r
-         * <p>It uses an internal Hashtable to get the handling class. If the\r
-         * type is not supported, then an instance of org.postgresql.util.PGobject\r
-         * is returned.\r
-         *\r
-         * You can use the getValue() or setValue() methods to handle the returned\r
-         * object. Custom objects can have their own methods.\r
-         *\r
-         * In 6.4, this is extended to use the org.postgresql.util.Serialize class to\r
-         * allow the Serialization of Java Objects into the database without using\r
-         * Blobs. Refer to that class for details on how this new feature works.\r
-         *\r
-         * @return PGobject for this type, and set to value\r
-         * @exception SQLException if value is not correct for this type\r
-         * @see org.postgresql.util.Serialize\r
-         */\r
-        public Object getObject(String type, String value) throws SQLException\r
-        {\r
-                try\r
-                {\r
-                        Object o = objectTypes.get(type);\r
-\r
-                        // If o is null, then the type is unknown, so check to see if type\r
-                        // is an actual table name. If it does, see if a Class is known that\r
-                        // can handle it\r
-                        if (o == null)\r
-                        {\r
-                                Serialize ser = new Serialize(this, type);\r
-                                objectTypes.put(type, ser);\r
-                                return ser.fetch(Integer.parseInt(value));\r
-                        }\r
-\r
-                        // If o is not null, and it is a String, then its a class name that\r
-                        // extends PGobject.\r
-                        //\r
-                        // This is used to implement the org.postgresql unique types (like lseg,\r
-                        // point, etc).\r
-                        if (o instanceof String)\r
-                        {\r
-                                // 6.3 style extending PG_Object\r
-                                PGobject obj = null;\r
-                                obj = (PGobject)(Class.forName((String)o).newInstance());\r
-                                obj.setType(type);\r
-                                obj.setValue(value);\r
-                                return (Object)obj;\r
-                        }\r
-                        else\r
-                        {\r
-                                // If it's an object, it should be an instance of our Serialize class\r
-                                // If so, then call it's fetch method.\r
-                                if (o instanceof Serialize)\r
-                                        return ((Serialize)o).fetch(Integer.parseInt(value));\r
-                        }\r
-                }\r
-                catch (SQLException sx)\r
-                {\r
-                        // rethrow the exception. Done because we capture any others next\r
-                        sx.fillInStackTrace();\r
-                        throw sx;\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                        throw new PSQLException("postgresql.con.creobj", type, ex);\r
-                }\r
-\r
-                // should never be reached\r
-                return null;\r
-        }\r
-\r
-        /*\r
-         * This stores an object into the database.  This method was\r
-         * deprecated in 7.2 bacause an OID can be larger than the java signed\r
-         * int returned by this method.\r
-         * @deprecated Replaced by storeObject() in 7.2\r
-         */\r
-        public int putObject(Object o) throws SQLException\r
-        {\r
-            return (int) storeObject(o);\r
-        }\r
-\r
-        /*\r
-         * This stores an object into the database.\r
-         * @param o Object to store\r
-         * @return OID of the new rectord\r
-         * @exception SQLException if value is not correct for this type\r
-         * @see org.postgresql.util.Serialize\r
-         * @since 7.2\r
-         */\r
-        public long storeObject(Object o) throws SQLException\r
-        {\r
-                try\r
-                {\r
-                        String type = o.getClass().getName();\r
-                        Object x = objectTypes.get(type);\r
-\r
-                        // If x is null, then the type is unknown, so check to see if type\r
-                        // is an actual table name. If it does, see if a Class is known that\r
-                        // can handle it\r
-                        if (x == null)\r
-                        {\r
-                                Serialize ser = new Serialize(this, type);\r
-                                objectTypes.put(type, ser);\r
-                                return ser.storeObject(o);\r
-                        }\r
-\r
-                        // If it's an object, it should be an instance of our Serialize class\r
-                        // If so, then call it's fetch method.\r
-                        if (x instanceof Serialize)\r
-                                return ((Serialize)x).storeObject(o);\r
-\r
-                        // Thow an exception because the type is unknown\r
-                        throw new PSQLException("postgresql.con.strobj");\r
-\r
-                }\r
-                catch (SQLException sx)\r
-                {\r
-                        // rethrow the exception. Done because we capture any others next\r
-                        sx.fillInStackTrace();\r
-                        throw sx;\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                        throw new PSQLException("postgresql.con.strobjex", ex);\r
-                }\r
-        }\r
-\r
-        /*\r
-         * This allows client code to add a handler for one of org.postgresql's\r
-         * more unique data types.\r
-         *\r
-         * <p><b>NOTE:</b> This is not part of JDBC, but an extension.\r
-         *\r
-         * <p>The best way to use this is as follows:\r
-         *\r
-         * <p><pre>\r
-         * ...\r
-         * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");\r
-         * ...\r
-         * </pre>\r
-         *\r
-         * <p>where myconn is an open Connection to org.postgresql.\r
-         *\r
-         * <p>The handling class must extend org.postgresql.util.PGobject\r
-         *\r
-         * @see org.postgresql.util.PGobject\r
-         */\r
-        public void addDataType(String type, String name)\r
-        {\r
-                objectTypes.put(type, name);\r
-        }\r
-\r
-        // This holds the available types\r
-        private Hashtable objectTypes = new Hashtable();\r
-\r
-        // This array contains the types that are supported as standard.\r
-        //\r
-        // The first entry is the types name on the database, the second\r
-        // the full class name of the handling class.\r
-        //\r
-        private static final String defaultObjectTypes[][] = {\r
-                                {"box", "org.postgresql.geometric.PGbox"},\r
-                                {"circle", "org.postgresql.geometric.PGcircle"},\r
-                                {"line", "org.postgresql.geometric.PGline"},\r
-                                {"lseg", "org.postgresql.geometric.PGlseg"},\r
-                                {"path", "org.postgresql.geometric.PGpath"},\r
-                                {"point", "org.postgresql.geometric.PGpoint"},\r
-                                {"polygon", "org.postgresql.geometric.PGpolygon"},\r
-                                {"money", "org.postgresql.util.PGmoney"}\r
-                        };\r
-\r
-        // This initialises the objectTypes hashtable\r
-        private void initObjectTypes()\r
-        {\r
-                for (int i = 0;i < defaultObjectTypes.length;i++)\r
-                        objectTypes.put(defaultObjectTypes[i][0], defaultObjectTypes[i][1]);\r
-        }\r
-\r
-        // These are required by other common classes\r
-        public abstract java.sql.Statement createStatement() throws SQLException;\r
-\r
-        /*\r
-         * This returns a resultset. It must be overridden, so that the correct\r
-         * version (from jdbc1 or jdbc2) are returned.\r
-         */\r
-        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;\r
-\r
-        /*\r
-         * In some cases, it is desirable to immediately release a Connection's\r
-         * database and JDBC resources instead of waiting for them to be\r
-         * automatically released (cant think why off the top of my head)\r
-         *\r
-         * <B>Note:</B> A Connection is automatically closed when it is\r
-         * garbage collected.  Certain fatal errors also result in a closed\r
-         * connection.\r
-         *\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void close() throws SQLException\r
-        {\r
-                if (pg_stream != null)\r
-                {\r
-                        try\r
-                        {\r
-                                pg_stream.SendChar('X');\r
-                                pg_stream.flush();\r
-                                pg_stream.close();\r
-                        }\r
-                        catch (IOException e)\r
-                        {}\r
-                        pg_stream = null;\r
-                }\r
-        }\r
-\r
-        /*\r
-         * A driver may convert the JDBC sql grammar into its system's\r
-         * native SQL grammar prior to sending it; nativeSQL returns the\r
-         * native form of the statement that the driver would have sent.\r
-         *\r
-         * @param sql a SQL statement that may contain one or more '?'\r
-         *     parameter placeholders\r
-         * @return the native form of this statement\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public String nativeSQL(String sql) throws SQLException\r
-        {\r
-                return sql;\r
-        }\r
-\r
-        /*\r
-         * The first warning reported by calls on this Connection is\r
-         * returned.\r
-         *\r
-         * <B>Note:</B> Sebsequent warnings will be changed to this\r
-         * SQLWarning\r
-         *\r
-         * @return the first SQLWarning or null\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public SQLWarning getWarnings() throws SQLException\r
-        {\r
-                return firstWarning;\r
-        }\r
-\r
-        /*\r
-         * After this call, getWarnings returns null until a new warning\r
-         * is reported for this connection.\r
-         *\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void clearWarnings() throws SQLException\r
-        {\r
-                firstWarning = null;\r
-        }\r
-\r
-\r
-        /*\r
-         * You can put a connection in read-only mode as a hunt to enable\r
-         * database optimizations\r
-         *\r
-         * <B>Note:</B> setReadOnly cannot be called while in the middle\r
-         * of a transaction\r
-         *\r
-         * @param readOnly - true enables read-only mode; false disables it\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void setReadOnly(boolean readOnly) throws SQLException\r
-        {\r
-                this.readOnly = readOnly;\r
-        }\r
-\r
-        /*\r
-         * Tests to see if the connection is in Read Only Mode.  Note that\r
-         * we cannot really put the database in read only mode, but we pretend\r
-         * we can by returning the value of the readOnly flag\r
-         *\r
-         * @return true if the connection is read only\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public boolean isReadOnly() throws SQLException\r
-        {\r
-                return readOnly;\r
-        }\r
-\r
-        /*\r
-         * If a connection is in auto-commit mode, than all its SQL\r
-         * statements will be executed and committed as individual\r
-         * transactions.  Otherwise, its SQL statements are grouped\r
-         * into transactions that are terminated by either commit()\r
-         * or rollback().  By default, new connections are in auto-\r
-         * commit mode.  The commit occurs when the statement completes\r
-         * or the next execute occurs, whichever comes first.  In the\r
-         * case of statements returning a ResultSet, the statement\r
-         * completes when the last row of the ResultSet has been retrieved\r
-         * or the ResultSet has been closed.  In advanced cases, a single\r
-         * statement may return multiple results as well as output parameter\r
-         * values.     Here the commit occurs when all results and output param\r
-         * values have been retrieved.\r
-         *\r
-         * @param autoCommit - true enables auto-commit; false disables it\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void setAutoCommit(boolean autoCommit) throws SQLException\r
-        {\r
-                if (this.autoCommit == autoCommit)\r
-                        return;\r
-                if (autoCommit)\r
-                        ExecSQL("end");\r
-                else\r
-                {\r
-                        if (haveMinimumServerVersion("7.1"))\r
-                        {\r
-                                ExecSQL("begin;" + getIsolationLevelSQL());\r
-                        }\r
-                        else\r
-                        {\r
-                                ExecSQL("begin");\r
-                                ExecSQL(getIsolationLevelSQL());\r
-                        }\r
-                }\r
-                this.autoCommit = autoCommit;\r
-        }\r
-\r
-        /*\r
-         * gets the current auto-commit state\r
-         *\r
-         * @return Current state of the auto-commit mode\r
-         * @exception SQLException (why?)\r
-         * @see setAutoCommit\r
-         */\r
-        public boolean getAutoCommit() throws SQLException\r
-        {\r
-                return this.autoCommit;\r
-        }\r
-\r
-        /*\r
-         * The method commit() makes all changes made since the previous\r
-         * commit/rollback permanent and releases any database locks currently\r
-         * held by the Connection.     This method should only be used when\r
-         * auto-commit has been disabled.  (If autoCommit == true, then we\r
-         * just return anyhow)\r
-         *\r
-         * @exception SQLException if a database access error occurs\r
-         * @see setAutoCommit\r
-         */\r
-        public void commit() throws SQLException\r
-        {\r
-                if (autoCommit)\r
-                        return;\r
-                if (haveMinimumServerVersion("7.1"))\r
-                {\r
-                        ExecSQL("commit;begin;" + getIsolationLevelSQL());\r
-                }\r
-                else\r
-                {\r
-                        ExecSQL("commit");\r
-                        ExecSQL("begin");\r
-                        ExecSQL(getIsolationLevelSQL());\r
-                }\r
-        }\r
-\r
-        /*\r
-         * The method rollback() drops all changes made since the previous\r
-         * commit/rollback and releases any database locks currently held by\r
-         * the Connection.\r
-         *\r
-         * @exception SQLException if a database access error occurs\r
-         * @see commit\r
-         */\r
-        public void rollback() throws SQLException\r
-        {\r
-                if (autoCommit)\r
-                        return;\r
-                if (haveMinimumServerVersion("7.1"))\r
-                {\r
-                        ExecSQL("rollback; begin;" + getIsolationLevelSQL());\r
-                }\r
-                else\r
-                {\r
-                        ExecSQL("rollback");\r
-                        ExecSQL("begin");\r
-                        ExecSQL(getIsolationLevelSQL());\r
-                }\r
-        }\r
-\r
-        /*\r
-         * Get this Connection's current transaction isolation mode.\r
-         *\r
-         * @return the current TRANSACTION_* mode value\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public int getTransactionIsolation() throws SQLException\r
-        {\r
-                clearWarnings();\r
-                ExecSQL("show transaction isolation level");\r
-\r
-                SQLWarning warning = getWarnings();\r
-                if (warning != null)\r
-                {\r
-                        String message = warning.getMessage();\r
-                        clearWarnings();\r
-                        if (message.indexOf("READ COMMITTED") != -1)\r
-                                return java.sql.Connection.TRANSACTION_READ_COMMITTED;\r
-                        else if (message.indexOf("READ UNCOMMITTED") != -1)\r
-                                return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;\r
-                        else if (message.indexOf("REPEATABLE READ") != -1)\r
-                                return java.sql.Connection.TRANSACTION_REPEATABLE_READ;\r
-                        else if (message.indexOf("SERIALIZABLE") != -1)\r
-                                return java.sql.Connection.TRANSACTION_SERIALIZABLE;\r
-                }\r
-                return java.sql.Connection.TRANSACTION_READ_COMMITTED;\r
-        }\r
-\r
-        /*\r
-         * You can call this method to try to change the transaction\r
-         * isolation level using one of the TRANSACTION_* values.\r
-         *\r
-         * <B>Note:</B> setTransactionIsolation cannot be called while\r
-         * in the middle of a transaction\r
-         *\r
-         * @param level one of the TRANSACTION_* isolation values with\r
-         *     the exception of TRANSACTION_NONE; some databases may\r
-         *     not support other values\r
-         * @exception SQLException if a database access error occurs\r
-         * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel\r
-         */\r
-        public void setTransactionIsolation(int level) throws SQLException\r
-        {\r
-                //In 7.1 and later versions of the server it is possible using\r
-                //the "set session" command to set this once for all future txns\r
-                //however in 7.0 and prior versions it is necessary to set it in\r
-                //each transaction, thus adding complexity below.\r
-                //When we decide to drop support for servers older than 7.1\r
-                //this can be simplified\r
-                isolationLevel = level;\r
-                String isolationLevelSQL;\r
-\r
-                if (!haveMinimumServerVersion("7.1"))\r
-                {\r
-                        isolationLevelSQL = getIsolationLevelSQL();\r
-                }\r
-                else\r
-                {\r
-                        isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ";\r
-                        switch (isolationLevel)\r
-                        {\r
-                                case java.sql.Connection.TRANSACTION_READ_COMMITTED:\r
-                                        isolationLevelSQL += "READ COMMITTED";\r
-                                        break;\r
-                                case java.sql.Connection.TRANSACTION_SERIALIZABLE:\r
-                                        isolationLevelSQL += "SERIALIZABLE";\r
-                                        break;\r
-                                default:\r
-                                        throw new PSQLException("postgresql.con.isolevel",\r
-                                                                                        new Integer(isolationLevel));\r
-                        }\r
-                }\r
-                ExecSQL(isolationLevelSQL);\r
-        }\r
-\r
-        /*\r
-         * Helper method used by setTransactionIsolation(), commit(), rollback()\r
-         * and setAutoCommit(). This returns the SQL string needed to\r
-         * set the isolation level for a transaction.  In 7.1 and later it\r
-         * is possible to set a default isolation level that applies to all\r
-         * future transactions, this method is only necesary for 7.0 and older\r
-         * servers, and should be removed when support for these older\r
-         * servers are dropped\r
-         */\r
-        protected String getIsolationLevelSQL() throws SQLException\r
-        {\r
-                //7.1 and higher servers have a default specified so\r
-                //no additional SQL is required to set the isolation level\r
-                if (haveMinimumServerVersion("7.1"))\r
-                {\r
-                        return "";\r
-                }\r
-                StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL");\r
-\r
-                switch (isolationLevel)\r
-                {\r
-                        case java.sql.Connection.TRANSACTION_READ_COMMITTED:\r
-                                sb.append(" READ COMMITTED");\r
-                                break;\r
-\r
-                        case java.sql.Connection.TRANSACTION_SERIALIZABLE:\r
-                                sb.append(" SERIALIZABLE");\r
-                                break;\r
-\r
-                        default:\r
-                                throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel));\r
-                }\r
-                return sb.toString();\r
-        }\r
-\r
-        /*\r
-         * A sub-space of this Connection's database may be selected by\r
-         * setting a catalog name.     If the driver does not support catalogs,\r
-         * it will silently ignore this request\r
-         *\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public void setCatalog(String catalog) throws SQLException\r
-        {\r
-                //no-op\r
-        }\r
-\r
-        /*\r
-         * Return the connections current catalog name, or null if no\r
-         * catalog name is set, or we dont support catalogs.\r
-         *\r
-         * @return the current catalog name or null\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public String getCatalog() throws SQLException\r
-        {\r
-                return PG_DATABASE;\r
-        }\r
-\r
-        /*\r
-         * Overides finalize(). If called, it closes the connection.\r
-         *\r
-         * This was done at the request of Rachel Greenham\r
-         * <rachel@enlarion.demon.co.uk> who hit a problem where multiple\r
-         * clients didn't close the connection, and once a fortnight enough\r
-         * clients were open to kill the org.postgres server.\r
-         */\r
-        public void finalize() throws Throwable\r
-        {\r
-                close();\r
-        }\r
-\r
-        private static String extractVersionNumber(String fullVersionString)\r
-        {\r
-                StringTokenizer versionParts = new StringTokenizer(fullVersionString);\r
-                versionParts.nextToken(); /* "PostgreSQL" */\r
-                return versionParts.nextToken(); /* "X.Y.Z" */\r
-        }\r
-\r
-        /*\r
-         * Get server version number\r
-         */\r
-        public String getDBVersionNumber()\r
-        {\r
-                return dbVersionNumber;\r
-        }\r
-\r
-        public boolean haveMinimumServerVersion(String ver) throws SQLException\r
-        {\r
-                return (getDBVersionNumber().compareTo(ver) >= 0);\r
-        }\r
-\r
-        /*\r
-         * This method returns true if the compatible level set in the connection\r
-         * (which can be passed into the connection or specified in the URL)\r
-         * is at least the value passed to this method.  This is used to toggle\r
-         * between different functionality as it changes across different releases\r
-         * of the jdbc driver code.  The values here are versions of the jdbc client\r
-         * and not server versions.  For example in 7.1 get/setBytes worked on\r
-         * LargeObject values, in 7.2 these methods were changed to work on bytea\r
-         * values.     This change in functionality could be disabled by setting the\r
-         * "compatible" level to be 7.1, in which case the driver will revert to\r
-         * the 7.1 functionality.\r
-         */\r
-        public boolean haveMinimumCompatibleVersion(String ver) throws SQLException\r
-        {\r
-                return (compatible.compareTo(ver) >= 0);\r
-        }\r
-\r
-\r
-        /*\r
-         * This returns the java.sql.Types type for a PG type oid\r
-         *\r
-         * @param oid PostgreSQL type oid\r
-         * @return the java.sql.Types type\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public int getSQLType(int oid) throws SQLException\r
-        {\r
-                Integer sqlType = (Integer)sqlTypeCache.get(new Integer(oid));\r
-\r
-                // it's not in the cache, so perform a query, and add the result to the cache\r
-                if (sqlType == null)\r
-                {\r
-                        ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);\r
-                        if (result.getColumnCount() != 1 || result.getTupleCount() != 1)\r
-                                throw new PSQLException("postgresql.unexpected");\r
-                        result.next();\r
-                        String pgType = result.getString(1);\r
-                        Integer iOid = new Integer(oid);\r
-                        sqlType = new Integer(getSQLType(result.getString(1)));\r
-                        sqlTypeCache.put(iOid, sqlType);\r
-                        pgTypeCache.put(iOid, pgType);\r
-                        result.close();\r
-                }\r
-\r
-                return sqlType.intValue();\r
-        }\r
-\r
-        /*\r
-         * This returns the java.sql.Types type for a PG type\r
-         *\r
-         * @param pgTypeName PostgreSQL type name\r
-         * @return the java.sql.Types type\r
-         */\r
-        public abstract int getSQLType(String pgTypeName);\r
-\r
-        /*\r
-         * This returns the oid for a given PG data type\r
-         * @param typeName PostgreSQL type name\r
-         * @return PostgreSQL oid value for a field of this type\r
-         */\r
-        public int getOID(String typeName) throws SQLException\r
-        {\r
-                int oid = -1;\r
-                if (typeName != null)\r
-                {\r
-                        Integer oidValue = (Integer) typeOidCache.get(typeName);\r
-                        if (oidValue != null)\r
-                        {\r
-                                oid = oidValue.intValue();\r
-                        }\r
-                        else\r
-                        {\r
-                                // it's not in the cache, so perform a query, and add the result to the cache\r
-                                ResultSet result = (org.postgresql.ResultSet)ExecSQL("select oid from pg_type where typname='"\r
-                                                                   + typeName + "'");\r
-                                if (result.getColumnCount() != 1 || result.getTupleCount() != 1)\r
-                                        throw new PSQLException("postgresql.unexpected");\r
-                                result.next();\r
-                                oid = Integer.parseInt(result.getString(1));\r
-                                typeOidCache.put(typeName, new Integer(oid));\r
-                                result.close();\r
-                        }\r
-                }\r
-                return oid;\r
-        }\r
-\r
-        /*\r
-         * We also need to get the PG type name as returned by the back end.\r
-         *\r
-         * @return the String representation of the type of this field\r
-         * @exception SQLException if a database access error occurs\r
-         */\r
-        public String getPGType(int oid) throws SQLException\r
-        {\r
-                String pgType = (String) pgTypeCache.get(new Integer(oid));\r
-                if (pgType == null)\r
-                {\r
-                        getSQLType(oid);\r
-                        pgType = (String) pgTypeCache.get(new Integer(oid));\r
-                }\r
-                return pgType;\r
-        }\r
-}\r
-\r
+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);
+           }
+       }
+
+}
+
index bc1925e..a199fe2 100644 (file)
@@ -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;
+
 }
index a746450..20f5a6f 100644 (file)
@@ -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);
         }
 
index 29f641e..3c447a8 100644 (file)
@@ -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);
index 0d62c74..86b1a4f 100644 (file)
@@ -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));
+           }
+       }
 
 }
 
index 2eb2b07..a613072 100644 (file)
@@ -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);
index dec1de5..e529618 100644 (file)
@@ -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");
        }
 
        /*
index 59d9c03..80d10bc 100644 (file)
@@ -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());
        }