diff --git a/src/interfaces/jdbc/example/Unicode.java b/src/interfaces/jdbc/example/Unicode.java index 7303ee7bc2046844cd1daa52d12005c846d03ba8..f10e4544305e2b52137f7985fdb22da9f7497907 100644 --- a/src/interfaces/jdbc/example/Unicode.java +++ b/src/interfaces/jdbc/example/Unicode.java @@ -233,7 +233,7 @@ public class Unicode catch (ClassNotFoundException cnfe) { log("Unable to load driver", cnfe); - return; + return ; } try { diff --git a/src/interfaces/jdbc/example/basic.java b/src/interfaces/jdbc/example/basic.java index 5f07a56c3f52a423e6905765624f4faa61aaf26c..61ef493181dba2ac9c0f15a3c36353d4b23474bf 100644 --- a/src/interfaces/jdbc/example/basic.java +++ b/src/interfaces/jdbc/example/basic.java @@ -6,7 +6,7 @@ import java.text.*; /* * - * $Id: basic.java,v 1.12 2002/07/23 03:59:54 barry Exp $ + * $Id: basic.java,v 1.13 2002/09/06 21:23:05 momjian Exp $ * * This example tests the basic components of the JDBC driver, and shows * how even the simplest of queries can be implemented. @@ -137,6 +137,7 @@ public class basic // result if you don't know what column number a value is in + System.out.println("performing another query"); rs = st.executeQuery("select * from basic where b>1"); if (rs != null) @@ -164,6 +165,7 @@ public class basic // Now test maxrows by setting it to 3 rows + st.setMaxRows(3); System.out.println("performing a query limited to " + st.getMaxRows()); rs = st.executeQuery("select a, b from basic"); diff --git a/src/interfaces/jdbc/example/corba/StockClient.java b/src/interfaces/jdbc/example/corba/StockClient.java index 258d2df2f4e95c4c2172eefb594a5c02d91d4ccf..127e157c33cd92d305b7e50f16668a4e40f13d41 100644 --- a/src/interfaces/jdbc/example/corba/StockClient.java +++ b/src/interfaces/jdbc/example/corba/StockClient.java @@ -9,7 +9,7 @@ import org.omg.CosNaming.*; * * It has no GUI, just a text frontend to keep it simple. * - * $Id: StockClient.java,v 1.5 2001/11/19 23:19:20 momjian Exp $ + * $Id: StockClient.java,v 1.6 2002/09/06 21:23:05 momjian Exp $ */ public class StockClient { @@ -35,14 +35,14 @@ public class StockClient if (nameServiceObj == null) { System.err.println("nameServiceObj == null"); - return; + return ; } nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); if (nameService == null) { System.err.println("nameService == null"); - return; + return ; } // Resolve the dispenser @@ -53,7 +53,7 @@ public class StockClient if (dispenser == null) { System.err.println("dispenser == null"); - return; + return ; } // Now run the front end. diff --git a/src/interfaces/jdbc/example/corba/StockDispenserImpl.java b/src/interfaces/jdbc/example/corba/StockDispenserImpl.java index 15adfe559bca71aba32f12dbe3f38f13ca9602b4..7dc7f5c20329d51b34e6f44d33e23976da856c98 100644 --- a/src/interfaces/jdbc/example/corba/StockDispenserImpl.java +++ b/src/interfaces/jdbc/example/corba/StockDispenserImpl.java @@ -5,7 +5,7 @@ import org.omg.CosNaming.*; /* * This class implements the server side of the example. * - * $Id: StockDispenserImpl.java,v 1.4 2001/11/19 23:19:20 momjian Exp $ + * $Id: StockDispenserImpl.java,v 1.5 2002/09/06 21:23:05 momjian Exp $ */ public class StockDispenserImpl extends stock._StockDispenserImplBase { @@ -67,11 +67,11 @@ public class StockDispenserImpl extends stock._StockDispenserImplBase { stock[i].inUse = false; System.out.println("Releasing slot " + i); - return; + return ; } } System.out.println("Reserved object not a member of this dispenser"); - return; + return ; } /* diff --git a/src/interfaces/jdbc/example/corba/StockServer.java b/src/interfaces/jdbc/example/corba/StockServer.java index 43dcbc64facb307e98bcf9b0897484493c5e9428..76d3fffe08b2eb8a78a909136ba77bec83431d16 100644 --- a/src/interfaces/jdbc/example/corba/StockServer.java +++ b/src/interfaces/jdbc/example/corba/StockServer.java @@ -5,7 +5,7 @@ import org.omg.CosNaming.*; /* * This class implements the server side of the example. * - * $Id: StockServer.java,v 1.4 2001/11/19 23:19:20 momjian Exp $ + * $Id: StockServer.java,v 1.5 2002/09/06 21:23:05 momjian Exp $ */ public class StockServer { @@ -29,14 +29,14 @@ public class StockServer if (nameServiceObj == null) { System.err.println("nameServiceObj = null"); - return; + return ; } org.omg.CosNaming.NamingContext nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); if (nameService == null) { System.err.println("nameService = null"); - return; + return ; } // bind the dispenser into the naming service diff --git a/src/interfaces/jdbc/example/psql.java b/src/interfaces/jdbc/example/psql.java index 0593293727963fe939ea8db6c22a5f29ed6988f5..a5af214d57438c2a094d0750595d4990b6a3baf3 100644 --- a/src/interfaces/jdbc/example/psql.java +++ b/src/interfaces/jdbc/example/psql.java @@ -82,7 +82,7 @@ public class psql if (line.startsWith("\\")) { processSlashCommand(line); - return; + return ; } boolean type = st.execute(line); diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in index 7d2ad9f1007769e915153387867a82143e4ee488..019a78dbebcbefcdd2c9daf821bb351dfbe9daff 100644 --- a/src/interfaces/jdbc/org/postgresql/Driver.java.in +++ b/src/interfaces/jdbc/org/postgresql/Driver.java.in @@ -31,8 +31,8 @@ public class Driver implements java.sql.Driver public static final int DEBUG = 2; public static final int INFO = 1; - public static boolean logDebug = false; - public static boolean logInfo = false; + public static boolean logDebug = false; + public static boolean logInfo = false; static { @@ -70,11 +70,11 @@ 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. - * 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. + * 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 @@ -109,12 +109,14 @@ public class Driver implements java.sql.Driver { if ((props = parseURL(url, info)) == null) { - if (Driver.logDebug) Driver.debug("Error in url" + url); + if (Driver.logDebug) + Driver.debug("Error in url" + url); return null; } try { - if (Driver.logDebug) Driver.debug("connect " + url); + if (Driver.logDebug) + Driver.debug("connect " + url); @JDBCCONNECTCLASS@ con = (@JDBCCONNECTCLASS@)(Class.forName("@JDBCCONNECTCLASS@").newInstance()); con.openConnection (host(), port(), props, database(), url, this); @@ -122,7 +124,8 @@ public class Driver implements java.sql.Driver } catch (ClassNotFoundException ex) { - if (Driver.logDebug) Driver.debug("error", ex); + if (Driver.logDebug) + Driver.debug("error", ex); throw new PSQLException("postgresql.jvm.version", ex); } catch (PSQLException ex1) @@ -133,7 +136,8 @@ public class Driver implements java.sql.Driver } catch (Exception ex2) { - if (Driver.logDebug) Driver.debug("error", ex2); + if (Driver.logDebug) + Driver.debug("error", ex2); throw new PSQLException("postgresql.unusual", ex2); } } @@ -177,7 +181,7 @@ public class Driver implements java.sql.Driver */ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { - //This method isn't really implemented + //This method isn't really implemented Properties p = parseURL(url, info); return new DriverPropertyInfo[0]; } @@ -385,16 +389,16 @@ public class Driver implements java.sql.Driver } /** - * used to turn logging on to a certain level, can be called + * 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 - * INFO being almost no messages + * INFO being almost no messages * DEBUG most verbose */ public static void setLogLevel(int logLevel) { - logDebug = (logLevel >= DEBUG) ? true : false; - logInfo = (logLevel >= INFO) ? true : false; + logDebug = (logLevel >= DEBUG) ? true : false; + logInfo = (logLevel >= INFO) ? true : false; } /* * logging message at the debug level @@ -441,7 +445,7 @@ public class Driver implements java.sql.Driver } } - //The build number should be incremented for every new build - private static int m_buildNumber = 104; + //The build number should be incremented for every new build + private static int m_buildNumber = 104; } diff --git a/src/interfaces/jdbc/org/postgresql/PGConnection.java b/src/interfaces/jdbc/org/postgresql/PGConnection.java index 2d22a318b0a4dd4e767f1ec329ab91844cf7aa42..a45fddcb1cfad9404ca6d40efe03a2ccdb37c6ac 100644 --- a/src/interfaces/jdbc/org/postgresql/PGConnection.java +++ b/src/interfaces/jdbc/org/postgresql/PGConnection.java @@ -7,74 +7,74 @@ import org.postgresql.core.Encoding; import org.postgresql.fastpath.Fastpath; import org.postgresql.largeobject.LargeObjectManager; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGConnection.java,v 1.2 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGConnection.java,v 1.3 2002/09/06 21:23:05 momjian Exp $ * This interface defines PostgreSQL extentions to the java.sql.Connection interface. - * Any java.sql.Connection object returned by the driver will also implement this + * Any java.sql.Connection object returned by the driver will also implement this * interface */ public interface PGConnection { - /* - * Get the character encoding to use for this connection. - */ - public Encoding getEncoding() throws SQLException; + /* + * Get the character encoding to use for this connection. + */ + public Encoding getEncoding() throws SQLException; - /* - * This method returns the java.sql.Types type for a postgres datatype name - */ - public int getSQLType(String pgTypeName) throws SQLException; + /* + * This method returns the java.sql.Types type for a postgres datatype name + */ + public int getSQLType(String pgTypeName) throws SQLException; - /* - * This returns the java.sql.Types type for a postgres datatype OID - */ - public int getSQLType(int oid) throws SQLException; + /* + * This returns the java.sql.Types type for a postgres datatype OID + */ + public int getSQLType(int oid) throws SQLException; - /* - * This returns the postgres datatype name from the - * postgres datatype OID - */ - public String getPGType(int oid) throws SQLException; + /* + * This returns the postgres datatype name from the + * postgres datatype OID + */ + public String getPGType(int oid) throws SQLException; - /* - * This returns the postgres datatype OID from the - * postgres datatype name - */ - public int getPGType(String typeName) throws SQLException; + /* + * This returns the postgres datatype OID from the + * postgres datatype name + */ + public int getPGType(String typeName) throws SQLException; - /* - * This returns the LargeObject API for the current connection. - */ - public LargeObjectManager getLargeObjectAPI() throws SQLException; + /* + * This returns the LargeObject API for the current connection. + */ + public LargeObjectManager getLargeObjectAPI() throws SQLException; - /* - * This returns the Fastpath API for the current connection. - */ - public Fastpath getFastpathAPI() throws SQLException; + /* + * This returns the Fastpath API for the current connection. + */ + public Fastpath getFastpathAPI() throws SQLException; - /* - * This method is used internally to return an object based around - * org.postgresql's more unique data types. - * - *

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. - * - * @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; + /* + * This method is used internally to return an object based around + * org.postgresql's more unique data types. + * + *

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. + * + * @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; - /* - * This method returns any notifications that have been received - * since the last call to this method. - * Returns null if there have been no notifications. - */ - public PGNotification[] getNotifications(); + /* + * This method returns any notifications that have been received + * since the last call to this method. + * Returns null if there have been no notifications. + */ + public PGNotification[] getNotifications(); } diff --git a/src/interfaces/jdbc/org/postgresql/PGNotification.java b/src/interfaces/jdbc/org/postgresql/PGNotification.java index 0413e9b35097723705efc43472b0549a40f0dc7d..dbcd6fbe6a054a258dbc76caaa60b100c44bed9d 100644 --- a/src/interfaces/jdbc/org/postgresql/PGNotification.java +++ b/src/interfaces/jdbc/org/postgresql/PGNotification.java @@ -1,20 +1,20 @@ package org.postgresql; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGNotification.java,v 1.1 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGNotification.java,v 1.2 2002/09/06 21:23:05 momjian Exp $ * This interface defines PostgreSQL extention for Notifications */ public interface PGNotification { - /* - * Returns name of this notification - */ - public String getName(); + /* + * Returns name of this notification + */ + public String getName(); - /* - * Returns the process id of the backend process making this notification - */ - public int getPID(); + /* + * Returns the process id of the backend process making this notification + */ + public int getPID(); } diff --git a/src/interfaces/jdbc/org/postgresql/PGStatement.java b/src/interfaces/jdbc/org/postgresql/PGStatement.java index a226246a81d197d141275a71d1d222ad6f8aa894..13aff7cde4c8ec93df25538a378dd7513158c5a5 100644 --- a/src/interfaces/jdbc/org/postgresql/PGStatement.java +++ b/src/interfaces/jdbc/org/postgresql/PGStatement.java @@ -3,23 +3,23 @@ package org.postgresql; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGStatement.java,v 1.4 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGStatement.java,v 1.5 2002/09/06 21:23:05 momjian Exp $ * This interface defines PostgreSQL extentions to the java.sql.Statement interface. - * Any java.sql.Statement object returned by the driver will also implement this + * Any java.sql.Statement object returned by the driver will also implement this * interface */ public interface PGStatement { /* - * Returns the Last inserted/updated oid. + * Returns the Last inserted/updated oid. * @return OID of last insert - * @since 7.3 + * @since 7.3 */ - public long getLastOID() throws SQLException; + public long getLastOID() throws SQLException; - public void setUseServerPrepare(boolean flag); + public void setUseServerPrepare(boolean flag); - public boolean isUseServerPrepare(); + public boolean isUseServerPrepare(); } diff --git a/src/interfaces/jdbc/org/postgresql/core/Encoding.java b/src/interfaces/jdbc/org/postgresql/core/Encoding.java index 2c4b0d348060c9ed723bc90831878464556a897e..95d4af5781febc91e2f6e6239db1348a5eac96e9 100644 --- a/src/interfaces/jdbc/org/postgresql/core/Encoding.java +++ b/src/interfaces/jdbc/org/postgresql/core/Encoding.java @@ -8,7 +8,7 @@ import org.postgresql.util.*; /* * Converts to and from the character encoding used by the backend. * - * $Id: Encoding.java,v 1.5 2002/03/19 02:48:45 momjian Exp $ + * $Id: Encoding.java,v 1.6 2002/09/06 21:23:05 momjian Exp $ */ public class Encoding @@ -42,14 +42,14 @@ public class Encoding encodings.put("EUC_KR", new String[] { "EUC_KR" }); encodings.put("JOHAB", new String[] { "Johab" }); encodings.put("EUC_TW", new String[] { "EUC_TW" }); - encodings.put("SJIS", new String[] { "MS932","SJIS" }); - encodings.put("BIG5", new String[] { "Big5","MS950","Cp950" }); - encodings.put("GBK", new String[] { "GBK","MS936" }); - encodings.put("UHC", new String[] { "MS949","Cp949","Cp949C" }); + encodings.put("SJIS", new String[] { "MS932", "SJIS" }); + encodings.put("BIG5", new String[] { "Big5", "MS950", "Cp950" }); + encodings.put("GBK", new String[] { "GBK", "MS936" }); + encodings.put("UHC", new String[] { "MS949", "Cp949", "Cp949C" }); encodings.put("TCVN", new String[] { "Cp1258" }); encodings.put("WIN1256", new String[] { "Cp1256" }); encodings.put("WIN1250", new String[] { "Cp1250" }); - encodings.put("WIN874", new String[] { "MS874","Cp874" }); + encodings.put("WIN874", new String[] { "MS874", "Cp874" }); encodings.put("WIN", new String[] { "Cp1251" }); encodings.put("ALT", new String[] { "Cp866" }); // We prefer KOI8-U, since it is a superset of KOI8-R. diff --git a/src/interfaces/jdbc/org/postgresql/core/Notification.java b/src/interfaces/jdbc/org/postgresql/core/Notification.java index 9612df4f74fac9dd281613f6a5d348a6e81ddff8..464e167b8c84d2d9290b5a4e3fe31f7bd3851376 100644 --- a/src/interfaces/jdbc/org/postgresql/core/Notification.java +++ b/src/interfaces/jdbc/org/postgresql/core/Notification.java @@ -1,32 +1,35 @@ package org.postgresql.core; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/Notification.java,v 1.1 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/Notification.java,v 1.2 2002/09/06 21:23:05 momjian Exp $ * This is the implementation of the PGNotification interface */ public class Notification implements org.postgresql.PGNotification { - public Notification(String p_name, int p_pid) { - m_name = p_name; - m_pid = p_pid; - } + public Notification(String p_name, int p_pid) + { + m_name = p_name; + m_pid = p_pid; + } - /* - * Returns name of this notification - */ - public String getName() { - return m_name; - } + /* + * Returns name of this notification + */ + public String getName() + { + return m_name; + } - /* - * Returns the process id of the backend process making this notification - */ - public int getPID() { - return m_pid; - } + /* + * Returns the process id of the backend process making this notification + */ + public int getPID() + { + return m_pid; + } - private String m_name; - private int m_pid; + private String m_name; + private int m_pid; } diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java index 0a842c193cf2ec19a682061a2f47ce7deea2f920..a16bd73dde14f6f0d590859d6516be63b27a5026 100644 --- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java +++ b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java @@ -13,208 +13,209 @@ import org.postgresql.util.PSQLException; *

The lifetime of a QueryExecutor object is from sending the query * until the response has been received from the backend. * - * $Id: QueryExecutor.java,v 1.15 2002/09/02 03:07:36 barry Exp $ + * $Id: QueryExecutor.java,v 1.16 2002/09/06 21:23:05 momjian Exp $ */ public class QueryExecutor { - private final String[] m_sqlFrags; - private final Object[] m_binds; - private final java.sql.Statement statement; - private final PG_Stream pg_stream; - private final org.postgresql.jdbc1.AbstractJdbc1Connection connection; - - public QueryExecutor(String[] p_sqlFrags, Object[] p_binds, - java.sql.Statement statement, - PG_Stream pg_stream, - java.sql.Connection connection) - throws SQLException - { - this.m_sqlFrags = p_sqlFrags; - this.m_binds = p_binds; - this.statement = statement; - this.pg_stream = pg_stream; - this.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)connection; - - if (statement != null) - maxRows = statement.getMaxRows(); - else - maxRows = 0; - } - - private Field[] fields = null; - private Vector tuples = new Vector(); - private boolean binaryCursor = false; - private String status = null; - private int update_count = 1; - private long insert_oid = 0; - private int maxRows; - - /* - * Execute a query on the backend. - */ - public java.sql.ResultSet execute() throws SQLException - { - - StringBuffer errorMessage = null; - - synchronized (pg_stream) - { - - sendQuery(); - - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = pg_stream.ReceiveChar(); - - switch (c) - { - case 'A': // Asynchronous Notify - int pid = pg_stream.ReceiveInteger(4); - String msg = pg_stream.ReceiveString(connection.getEncoding()); + private final String[] m_sqlFrags; + private final Object[] m_binds; + private final java.sql.Statement statement; + private final PG_Stream pg_stream; + private final org.postgresql.jdbc1.AbstractJdbc1Connection connection; + + public QueryExecutor(String[] p_sqlFrags, Object[] p_binds, + java.sql.Statement statement, + PG_Stream pg_stream, + java.sql.Connection connection) + throws SQLException + { + this.m_sqlFrags = p_sqlFrags; + this.m_binds = p_binds; + this.statement = statement; + this.pg_stream = pg_stream; + this.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)connection; + + if (statement != null) + maxRows = statement.getMaxRows(); + else + maxRows = 0; + } + + private Field[] fields = null; + private Vector tuples = new Vector(); + private boolean binaryCursor = false; + private String status = null; + private int update_count = 1; + private long insert_oid = 0; + private int maxRows; + + /* + * Execute a query on the backend. + */ + public java.sql.ResultSet execute() throws SQLException + { + + StringBuffer errorMessage = null; + + synchronized (pg_stream) + { + + sendQuery(); + + int c; + boolean l_endQuery = false; + while (!l_endQuery) + { + c = pg_stream.ReceiveChar(); + + switch (c) + { + case 'A': // Asynchronous Notify + int pid = pg_stream.ReceiveInteger(4); + String msg = pg_stream.ReceiveString(connection.getEncoding()); connection.addNotification(new org.postgresql.core.Notification(msg, pid)); - break; - case 'B': // Binary Data Transfer - receiveTuple(true); - break; - case 'C': // Command Status - receiveCommandStatus(); - break; - case 'D': // Text Data Transfer - receiveTuple(false); - break; - case 'E': // Error Message - - // it's possible to get more than one error message for a query - // see libpq comments wrt backend closing a connection - // so, append messages to a string buffer and keep processing - // check at the bottom to see if we need to throw an exception - - if ( errorMessage == null ) - errorMessage = new StringBuffer(); - - errorMessage.append(pg_stream.ReceiveString(connection.getEncoding())); - // keep processing - break; - case 'I': // Empty Query - int t = pg_stream.ReceiveChar(); - break; - case 'N': // Error Notification - connection.addWarning(pg_stream.ReceiveString(connection.getEncoding())); - break; - case 'P': // Portal Name - String pname = pg_stream.ReceiveString(connection.getEncoding()); - break; - case 'T': // MetaData Field Description - receiveFields(); - break; - case 'Z': - l_endQuery = true; - break; - default: - throw new PSQLException("postgresql.con.type", - new Character((char) c)); - } - - } - - // did we get an error during this query? - if ( errorMessage != null ) - throw new SQLException( errorMessage.toString() ); - - return connection.getResultSet(statement, fields, tuples, status, update_count, insert_oid, binaryCursor); - } - } - - /* - * Send a query to the backend. - */ - private void sendQuery() throws SQLException - { - try - { - pg_stream.SendChar('Q'); - for (int i = 0 ; i < m_binds.length ; ++i) { - if (m_binds[i] == null) - throw new PSQLException("postgresql.prep.param", new Integer(i + 1)); - pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); - pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); - } - pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[m_binds.length])); - pg_stream.SendChar(0); - pg_stream.flush(); - - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.ioerror", e); - } - } - - /* - * Receive a tuple from the backend. - * - * @param isBinary set if the tuple should be treated as binary data - */ - private void receiveTuple(boolean isBinary) throws SQLException - { - if (fields == null) - throw new PSQLException("postgresql.con.tuple"); - Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); - if (isBinary) - binaryCursor = true; - if (maxRows == 0 || tuples.size() < maxRows) - tuples.addElement(tuple); - } - - /* - * Receive command status from the backend. - */ - private void receiveCommandStatus() throws SQLException - { - - status = pg_stream.ReceiveString(connection.getEncoding()); - - try - { - // Now handle the update count correctly. - if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) - { - update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' '))); - } - if (status.startsWith("INSERT")) - { - insert_oid = Long.parseLong(status.substring(1 + status.indexOf(' '), - status.lastIndexOf(' '))); - } - } - catch (NumberFormatException nfe) - { - throw new PSQLException("postgresql.con.fathom", status); - } - } - - /* - * Receive the field descriptions from the back end. - */ - private void receiveFields() throws SQLException - { - if (fields != null) - throw new PSQLException("postgresql.con.multres"); - - int size = pg_stream.ReceiveIntegerR(2); - fields = new Field[size]; - - for (int i = 0; i < fields.length; i++) - { - String typeName = pg_stream.ReceiveString(connection.getEncoding()); - int typeOid = pg_stream.ReceiveIntegerR(4); - int typeLength = pg_stream.ReceiveIntegerR(2); - int typeModifier = pg_stream.ReceiveIntegerR(4); - fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier); - } - } + break; + case 'B': // Binary Data Transfer + receiveTuple(true); + break; + case 'C': // Command Status + receiveCommandStatus(); + break; + case 'D': // Text Data Transfer + receiveTuple(false); + break; + case 'E': // Error Message + + // it's possible to get more than one error message for a query + // see libpq comments wrt backend closing a connection + // so, append messages to a string buffer and keep processing + // check at the bottom to see if we need to throw an exception + + if ( errorMessage == null ) + errorMessage = new StringBuffer(); + + errorMessage.append(pg_stream.ReceiveString(connection.getEncoding())); + // keep processing + break; + case 'I': // Empty Query + int t = pg_stream.ReceiveChar(); + break; + case 'N': // Error Notification + connection.addWarning(pg_stream.ReceiveString(connection.getEncoding())); + break; + case 'P': // Portal Name + String pname = pg_stream.ReceiveString(connection.getEncoding()); + break; + case 'T': // MetaData Field Description + receiveFields(); + break; + case 'Z': + l_endQuery = true; + break; + default: + throw new PSQLException("postgresql.con.type", + new Character((char) c)); + } + + } + + // did we get an error during this query? + if ( errorMessage != null ) + throw new SQLException( errorMessage.toString() ); + + return connection.getResultSet(statement, fields, tuples, status, update_count, insert_oid, binaryCursor); + } + } + + /* + * Send a query to the backend. + */ + private void sendQuery() throws SQLException + { + try + { + pg_stream.SendChar('Q'); + for (int i = 0 ; i < m_binds.length ; ++i) + { + if (m_binds[i] == null) + throw new PSQLException("postgresql.prep.param", new Integer(i + 1)); + pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); + pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); + } + pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[m_binds.length])); + pg_stream.SendChar(0); + pg_stream.flush(); + + } + catch (IOException e) + { + throw new PSQLException("postgresql.con.ioerror", e); + } + } + + /* + * Receive a tuple from the backend. + * + * @param isBinary set if the tuple should be treated as binary data + */ + private void receiveTuple(boolean isBinary) throws SQLException + { + if (fields == null) + throw new PSQLException("postgresql.con.tuple"); + Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); + if (isBinary) + binaryCursor = true; + if (maxRows == 0 || tuples.size() < maxRows) + tuples.addElement(tuple); + } + + /* + * Receive command status from the backend. + */ + private void receiveCommandStatus() throws SQLException + { + + status = pg_stream.ReceiveString(connection.getEncoding()); + + try + { + // Now handle the update count correctly. + if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) + { + update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' '))); + } + if (status.startsWith("INSERT")) + { + insert_oid = Long.parseLong(status.substring(1 + status.indexOf(' '), + status.lastIndexOf(' '))); + } + } + catch (NumberFormatException nfe) + { + throw new PSQLException("postgresql.con.fathom", status); + } + } + + /* + * Receive the field descriptions from the back end. + */ + private void receiveFields() throws SQLException + { + if (fields != null) + throw new PSQLException("postgresql.con.multres"); + + int size = pg_stream.ReceiveIntegerR(2); + fields = new Field[size]; + + for (int i = 0; i < fields.length; i++) + { + String typeName = pg_stream.ReceiveString(connection.getEncoding()); + int typeOid = pg_stream.ReceiveIntegerR(4); + int typeLength = pg_stream.ReceiveIntegerR(2); + int typeModifier = pg_stream.ReceiveIntegerR(4); + fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier); + } + } } diff --git a/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java b/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java index 223f16ebd47c3189a0953c8696fa0ac088ab4ed7..38ddc15f44c44168cf48417f0d57e4858a4f6356 100644 --- a/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java +++ b/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java @@ -6,7 +6,7 @@ import java.io.IOException; /** * Sent to the backend to initialize a newly created connection. * - * $Id: StartupPacket.java,v 1.1 2002/03/21 02:40:03 davec Exp $ + * $Id: StartupPacket.java,v 1.2 2002/09/06 21:23:05 momjian Exp $ */ public class StartupPacket @@ -22,15 +22,16 @@ public class StartupPacket private String user; private String database; - public StartupPacket(int protocolMajor, int protocolMinor, String user, String database) { + public StartupPacket(int protocolMajor, int protocolMinor, String user, String database) + { this.protocolMajor = protocolMajor; this.protocolMinor = protocolMinor; this.user = user; this.database = database; } - public void writeTo(PG_Stream stream) throws IOException - { + public void writeTo(PG_Stream stream) throws IOException + { stream.SendInteger(4 + 4 + SM_DATABASE + SM_USER + SM_OPTIONS + SM_UNUSED + SM_TTY, 4); stream.SendInteger(protocolMajor, 2); stream.SendInteger(protocolMinor, 2); diff --git a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java index d166b10f83b658f48f42801793464ded4efa6660..56676a40ecaa48300a3752ebee9f0ab8ec6a3df5 100644 --- a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java +++ b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java @@ -24,268 +24,272 @@ import org.postgresql.util.*; */ public class Fastpath { - // This maps the functions names to their id's (possible unique just - // to a connection). - protected Hashtable func = new Hashtable(); + // This maps the functions names to their id's (possible unique just + // to a connection). + protected Hashtable func = new Hashtable(); - protected org.postgresql.PGConnection conn; // our connection - protected org.postgresql.PG_Stream stream; // the network stream + protected org.postgresql.PGConnection conn; // our connection + protected org.postgresql.PG_Stream stream; // the network stream - /* - * Initialises the fastpath system - * - *

Important Notice - *
This is called from org.postgresql.Connection, and should not be called - * from client code. - * - * @param conn org.postgresql.Connection to attach to - * @param stream The network stream to the backend - */ - public Fastpath(org.postgresql.PGConnection conn, org.postgresql.PG_Stream stream) - { - this.conn = conn; - this.stream = stream; - } + /* + * Initialises the fastpath system + * + *

Important Notice + *
This is called from org.postgresql.Connection, and should not be called + * from client code. + * + * @param conn org.postgresql.Connection to attach to + * @param stream The network stream to the backend + */ + public Fastpath(org.postgresql.PGConnection conn, org.postgresql.PG_Stream stream) + { + this.conn = conn; + this.stream = stream; + } - /* - * Send a function call to the PostgreSQL backend - * - * @param fnid Function id - * @param resulttype True if the result is an integer, false for other results - * @param args FastpathArguments to pass to fastpath - * @return null if no data, Integer if an integer result, or byte[] otherwise - * @exception SQLException if a database-access error occurs. - */ - public Object fastpath(int fnid, boolean resulttype, FastpathArg[] args) throws SQLException - { - // added Oct 7 1998 to give us thread safety - synchronized (stream) - { - // send the function call - try - { - // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding - // that confuses the backend. The 0 terminates the command line. - stream.SendInteger(70, 1); - stream.SendInteger(0, 1); + /* + * Send a function call to the PostgreSQL backend + * + * @param fnid Function id + * @param resulttype True if the result is an integer, false for other results + * @param args FastpathArguments to pass to fastpath + * @return null if no data, Integer if an integer result, or byte[] otherwise + * @exception SQLException if a database-access error occurs. + */ + public Object fastpath(int fnid, boolean resulttype, FastpathArg[] args) throws SQLException + { + // added Oct 7 1998 to give us thread safety + synchronized (stream) + { + // send the function call + try + { + // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding + // that confuses the backend. The 0 terminates the command line. + stream.SendInteger(70, 1); + stream.SendInteger(0, 1); - stream.SendInteger(fnid, 4); - stream.SendInteger(args.length, 4); + stream.SendInteger(fnid, 4); + stream.SendInteger(args.length, 4); - for (int i = 0;i < args.length;i++) - args[i].send(stream); + for (int i = 0;i < args.length;i++) + args[i].send(stream); - // This is needed, otherwise data can be lost - stream.flush(); + // This is needed, otherwise data can be lost + stream.flush(); - } - catch (IOException ioe) - { - throw new PSQLException("postgresql.fp.send", new Integer(fnid), ioe); - } + } + catch (IOException ioe) + { + throw new PSQLException("postgresql.fp.send", new Integer(fnid), ioe); + } - // Now handle the result + // Now handle the result - // Now loop, reading the results - Object result = null; // our result - StringBuffer errorMessage = null; - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = stream.ReceiveChar(); + // Now loop, reading the results + Object result = null; // our result + StringBuffer errorMessage = null; + int c; + boolean l_endQuery = false; + while (!l_endQuery) + { + c = stream.ReceiveChar(); - switch (c) - { - case 'A': // Asynchronous Notify - int pid = stream.ReceiveInteger(4); - String msg = stream.ReceiveString(conn.getEncoding()); - break; + switch (c) + { + case 'A': // Asynchronous Notify + int pid = stream.ReceiveInteger(4); + String msg = stream.ReceiveString(conn.getEncoding()); + break; - //------------------------------ - // Error message returned - case 'E': - if ( errorMessage == null ) - errorMessage = new StringBuffer(); - errorMessage.append(stream.ReceiveString(conn.getEncoding())); - break; + //------------------------------ + // Error message returned + case 'E': + if ( errorMessage == null ) + errorMessage = new StringBuffer(); + errorMessage.append(stream.ReceiveString(conn.getEncoding())); + break; - //------------------------------ - // Notice from backend - case 'N': - ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).addWarning(stream.ReceiveString(conn.getEncoding())); - break; + //------------------------------ + // Notice from backend + case 'N': + ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).addWarning(stream.ReceiveString(conn.getEncoding())); + break; - case 'V': - int l_nextChar = stream.ReceiveChar(); - if (l_nextChar == 'G') { - int sz = stream.ReceiveIntegerR(4); - // Return an Integer if - if (resulttype) - result = new Integer(stream.ReceiveIntegerR(sz)); - else - { - byte buf[] = new byte[sz]; - stream.Receive(buf, 0, sz); - result = buf; - } - //There should be a trailing '0' - int l_endChar = stream.ReceiveChar(); - } else { - //it must have been a '0', thus no results - } - break; + case 'V': + int l_nextChar = stream.ReceiveChar(); + if (l_nextChar == 'G') + { + int sz = stream.ReceiveIntegerR(4); + // Return an Integer if + if (resulttype) + result = new Integer(stream.ReceiveIntegerR(sz)); + else + { + byte buf[] = new byte[sz]; + stream.Receive(buf, 0, sz); + result = buf; + } + //There should be a trailing '0' + int l_endChar = stream.ReceiveChar(); + } + else + { + //it must have been a '0', thus no results + } + break; - case 'Z': - l_endQuery = true; - break; + case 'Z': + l_endQuery = true; + break; - default: - throw new PSQLException("postgresql.fp.protocol", new Character((char)c)); - } - } + default: + throw new PSQLException("postgresql.fp.protocol", new Character((char)c)); + } + } - if ( errorMessage != null ) - throw new PSQLException("postgresql.fp.error", errorMessage.toString()); + if ( errorMessage != null ) + throw new PSQLException("postgresql.fp.error", errorMessage.toString()); - return result; - } - } + return result; + } + } - /* - * Send a function call to the PostgreSQL backend by name. - * - * Note: the mapping for the procedure name to function id needs to exist, - * usually to an earlier call to addfunction(). - * - * This is the prefered method to call, as function id's can/may change - * between versions of the backend. - * - * For an example of how this works, refer to org.postgresql.LargeObject - * - * @param name Function name - * @param resulttype True if the result is an integer, false for other - * results - * @param args FastpathArguments to pass to fastpath - * @return null if no data, Integer if an integer result, or byte[] otherwise - * @exception SQLException if name is unknown or if a database-access error - * occurs. - * @see org.postgresql.LargeObject - */ - public Object fastpath(String name, boolean resulttype, FastpathArg[] args) throws SQLException - { - if (Driver.logDebug) Driver.debug("Fastpath: calling "+name); - return fastpath(getID(name), resulttype, args); - } + /* + * Send a function call to the PostgreSQL backend by name. + * + * Note: the mapping for the procedure name to function id needs to exist, + * usually to an earlier call to addfunction(). + * + * This is the prefered method to call, as function id's can/may change + * between versions of the backend. + * + * For an example of how this works, refer to org.postgresql.LargeObject + * + * @param name Function name + * @param resulttype True if the result is an integer, false for other + * results + * @param args FastpathArguments to pass to fastpath + * @return null if no data, Integer if an integer result, or byte[] otherwise + * @exception SQLException if name is unknown or if a database-access error + * occurs. + * @see org.postgresql.LargeObject + */ + public Object fastpath(String name, boolean resulttype, FastpathArg[] args) throws SQLException + { + if (Driver.logDebug) + Driver.debug("Fastpath: calling " + name); + return fastpath(getID(name), resulttype, args); + } - /* - * This convenience method assumes that the return value is an Integer - * @param name Function name - * @param args Function arguments - * @return integer result - * @exception SQLException if a database-access error occurs or no result - */ - public int getInteger(String name, FastpathArg[] args) throws SQLException - { - Integer i = (Integer)fastpath(name, true, args); - if (i == null) - throw new PSQLException("postgresql.fp.expint", name); - return i.intValue(); - } + /* + * This convenience method assumes that the return value is an Integer + * @param name Function name + * @param args Function arguments + * @return integer result + * @exception SQLException if a database-access error occurs or no result + */ + public int getInteger(String name, FastpathArg[] args) throws SQLException + { + Integer i = (Integer)fastpath(name, true, args); + if (i == null) + throw new PSQLException("postgresql.fp.expint", name); + return i.intValue(); + } - /* - * This convenience method assumes that the return value is an Integer - * @param name Function name - * @param args Function arguments - * @return byte[] array containing result - * @exception SQLException if a database-access error occurs or no result - */ - public byte[] getData(String name, FastpathArg[] args) throws SQLException - { - return (byte[])fastpath(name, false, args); - } + /* + * This convenience method assumes that the return value is an Integer + * @param name Function name + * @param args Function arguments + * @return byte[] array containing result + * @exception SQLException if a database-access error occurs or no result + */ + public byte[] getData(String name, FastpathArg[] args) throws SQLException + { + return (byte[])fastpath(name, false, args); + } - /* - * This adds a function to our lookup table. - * - *

User code should use the addFunctions method, which is based upon a - * query, rather than hard coding the oid. The oid for a function is not - * guaranteed to remain static, even on different servers of the same - * version. - * - * @param name Function name - * @param fnid Function id - */ - public void addFunction(String name, int fnid) - { - func.put(name, new Integer(fnid)); - } + /* + * This adds a function to our lookup table. + * + *

User code should use the addFunctions method, which is based upon a + * query, rather than hard coding the oid. The oid for a function is not + * guaranteed to remain static, even on different servers of the same + * version. + * + * @param name Function name + * @param fnid Function id + */ + public void addFunction(String name, int fnid) + { + func.put(name, new Integer(fnid)); + } - /* - * This takes a ResultSet containing two columns. Column 1 contains the - * function name, Column 2 the oid. - * - *

It reads the entire ResultSet, loading the values into the function - * table. - * - *

REMEMBER to close() the resultset after calling this!! - * - *

Implementation note about function name lookups: - * - *

PostgreSQL stores the function id's and their corresponding names in - * the pg_proc table. To speed things up locally, instead of querying each - * function from that table when required, a Hashtable is used. Also, only - * the function's required are entered into this table, keeping connection - * times as fast as possible. - * - *

The org.postgresql.LargeObject class performs a query upon it's startup, - * and passes the returned ResultSet to the addFunctions() method here. - * - *

Once this has been done, the LargeObject api refers to the functions by - * name. - * - *

Dont think that manually converting them to the oid's will work. Ok, - * they will for now, but they can change during development (there was some - * discussion about this for V7.0), so this is implemented to prevent any - * unwarranted headaches in the future. - * - * @param rs ResultSet - * @exception SQLException if a database-access error occurs. - * @see org.postgresql.LargeObjectManager - */ - public void addFunctions(ResultSet rs) throws SQLException - { - while (rs.next()) - { - func.put(rs.getString(1), new Integer(rs.getInt(2))); - } - } + /* + * This takes a ResultSet containing two columns. Column 1 contains the + * function name, Column 2 the oid. + * + *

It reads the entire ResultSet, loading the values into the function + * table. + * + *

REMEMBER to close() the resultset after calling this!! + * + *

Implementation note about function name lookups: + * + *

PostgreSQL stores the function id's and their corresponding names in + * the pg_proc table. To speed things up locally, instead of querying each + * function from that table when required, a Hashtable is used. Also, only + * the function's required are entered into this table, keeping connection + * times as fast as possible. + * + *

The org.postgresql.LargeObject class performs a query upon it's startup, + * and passes the returned ResultSet to the addFunctions() method here. + * + *

Once this has been done, the LargeObject api refers to the functions by + * name. + * + *

Dont think that manually converting them to the oid's will work. Ok, + * they will for now, but they can change during development (there was some + * discussion about this for V7.0), so this is implemented to prevent any + * unwarranted headaches in the future. + * + * @param rs ResultSet + * @exception SQLException if a database-access error occurs. + * @see org.postgresql.LargeObjectManager + */ + public void addFunctions(ResultSet rs) throws SQLException + { + while (rs.next()) + { + func.put(rs.getString(1), new Integer(rs.getInt(2))); + } + } - /* - * This returns the function id associated by its name - * - *

If addFunction() or addFunctions() have not been called for this name, - * then an SQLException is thrown. - * - * @param name Function name to lookup - * @return Function ID for fastpath call - * @exception SQLException is function is unknown. - */ - public int getID(String name) throws SQLException - { - Integer id = (Integer)func.get(name); + /* + * This returns the function id associated by its name + * + *

If addFunction() or addFunctions() have not been called for this name, + * then an SQLException is thrown. + * + * @param name Function name to lookup + * @return Function ID for fastpath call + * @exception SQLException is function is unknown. + */ + public int getID(String name) throws SQLException + { + Integer id = (Integer)func.get(name); - // may be we could add a lookup to the database here, and store the result - // in our lookup table, throwing the exception if that fails. - // We must, however, ensure that if we do, any existing ResultSet is - // unaffected, otherwise we could break user code. - // - // so, until we know we can do this (needs testing, on the TODO list) - // for now, we throw the exception and do no lookups. - if (id == null) - throw new PSQLException("postgresql.fp.unknown", name); + // may be we could add a lookup to the database here, and store the result + // in our lookup table, throwing the exception if that fails. + // We must, however, ensure that if we do, any existing ResultSet is + // unaffected, otherwise we could break user code. + // + // so, until we know we can do this (needs testing, on the TODO list) + // for now, we throw the exception and do no lookups. + if (id == null) + throw new PSQLException("postgresql.fp.unknown", name); - return id.intValue(); - } + return id.intValue(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java index 4721acc4353f7210510bdbad1ade2e82ebd1f988..45160ba34fc6fecc5350ea56df0a524ecda5097a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java @@ -14,1218 +14,1237 @@ import org.postgresql.largeobject.LargeObjectManager; import org.postgresql.util.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.7 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.8 2002/09/06 21:23:05 momjian Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2 * methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection */ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnection { - // This is the network stream associated with this connection - public PG_Stream pg_stream; - - protected String PG_HOST; - protected int PG_PORT; - protected String PG_USER; - protected String PG_DATABASE; - protected boolean PG_STATUS; - protected String compatible; - - // The PID an cancellation key we get from the backend process - protected int pid; - protected int ckey; - - private Vector m_notifications; - - /* - 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 org.postgresql.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; - - - public abstract java.sql.Statement createStatement() throws SQLException; - - - /* - * 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 url the URL of the connection - * @param d the Driver instantation of the connection - * @exception SQLException if a database access error occurs - */ - public void openConnection(String host, int port, Properties info, String database, String url, org.postgresql.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 = (org.postgresql.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 > org.postgresql.Driver.DEBUG || l_logLevel < org.postgresql.Driver.INFO) { - l_logLevel = 0; - } - } catch (Exception l_e) { - //invalid value for loglevel ignore + // This is the network stream associated with this connection + public PG_Stream pg_stream; + + protected String PG_HOST; + protected int PG_PORT; + protected String PG_USER; + protected String PG_DATABASE; + protected boolean PG_STATUS; + protected String compatible; + + // The PID an cancellation key we get from the backend process + protected int pid; + protected int ckey; + + private Vector m_notifications; + + /* + 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 org.postgresql.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; + + + public abstract java.sql.Statement createStatement() throws SQLException; + + + /* + * 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 url the URL of the connection + * @param d the Driver instantation of the connection + * @exception SQLException if a database access error occurs + */ + public void openConnection(String host, int port, Properties info, String database, String url, org.postgresql.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 = (org.postgresql.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 > org.postgresql.Driver.DEBUG || l_logLevel < org.postgresql.Driver.INFO) + { + l_logLevel = 0; + } + } + catch (Exception l_e) + { + //invalid value for loglevel ignore + } + if (l_logLevel > 0) + { + org.postgresql.Driver.setLogLevel(l_logLevel); + enableDriverManagerLogging(); + } + + //Print out the driver version number + if (org.postgresql.Driver.logInfo) + org.postgresql.Driver.info(org.postgresql.Driver.getVersion()); + + // Now make the initial connection + try + { + pg_stream = new PG_Stream(host, port); + } + catch (ConnectException cex) + { + // Added by Peter Mount + // 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; + byte [] md5Salt = new byte[4]; + 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 (org.postgresql.Driver.logDebug) + org.postgresql.Driver.debug("Crypt salt=" + salt); + } + + // Or get the md5 password salt if there is one + if (areq == AUTH_REQ_MD5) + { + + md5Salt[0] = (byte)pg_stream.ReceiveChar(); + md5Salt[1] = (byte)pg_stream.ReceiveChar(); + md5Salt[2] = (byte)pg_stream.ReceiveChar(); + md5Salt[3] = (byte)pg_stream.ReceiveChar(); + salt = new String(md5Salt, 0, 4); + if (org.postgresql.Driver.logDebug) + org.postgresql.Driver.debug("MD5 salt=" + salt); + } + + // now send the auth packet + switch (areq) + { + case AUTH_REQ_OK: + break; + + case AUTH_REQ_KRB4: + if (org.postgresql.Driver.logDebug) + org.postgresql.Driver.debug("postgresql: KRB4"); + throw new PSQLException("postgresql.con.kerb4"); + + case AUTH_REQ_KRB5: + if (org.postgresql.Driver.logDebug) + org.postgresql.Driver.debug("postgresql: KRB5"); + throw new PSQLException("postgresql.con.kerb5"); + + case AUTH_REQ_PASSWORD: + if (org.postgresql.Driver.logDebug) + org.postgresql.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 (org.postgresql.Driver.logDebug) + org.postgresql.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 (org.postgresql.Driver.logDebug) + org.postgresql.Driver.debug("postgresql: MD5"); + byte[] digest = MD5Digest.encode(PG_USER, password, md5Salt); + 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; + } + + + /* + * Return the instance of org.postgresql.Driver + * that created this connection + */ + public org.postgresql.Driver getDriver() + { + return this_driver; + } + + // 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. + + public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; + + public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount) throws SQLException; + + /* + * 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;iNote: 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. + * + * Note: 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(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); + } + private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + + /* + * Send a query to the backend. Returns one of the ResultSet + * objects. + * + * Note: there does not seem to be any method currently + * in existance to return the update count. + * + * @param p_sqlFragmentss the SQL statement parts to be executed + * @param p_binds the SQL bind values + * @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[] p_sqlFragments, Object[] p_binds, java.sql.Statement stat) throws SQLException + { + return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)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. + * + *

NOTE: This is not part of JDBC, but allows access to + * functions on the org.postgresql backend itself. + * + *

It is primarily used by the LargeObject API + * + *

The best way to use this is as follows: + * + *

+	 * import org.postgresql.fastpath.*;
+	 * ...
+	 * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();
+	 * 
+ * + *

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. + * + *

NOTE: This is not part of JDBC, but allows access to + * functions on the org.postgresql backend itself. + * + *

The best way to use this is as follows: + * + *

+	 * import org.postgresql.largeobject.*;
+	 * ...
+	 * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();
+	 * 
+ * + *

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((java.sql.Connection)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. + * + *

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((java.sql.Connection)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((java.sql.Connection)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; } - if (l_logLevel > 0) { - org.postgresql.Driver.setLogLevel(l_logLevel); - enableDriverManagerLogging(); + catch (Exception ex) + { + throw new PSQLException("postgresql.con.strobjex", ex); } + } - //Print out the driver version number - if (org.postgresql.Driver.logInfo) org.postgresql.Driver.info(org.postgresql.Driver.getVersion()); - - // Now make the initial connection - try - { - pg_stream = new PG_Stream(host, port); - } - catch (ConnectException cex) - { - // Added by Peter Mount - // 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; - byte [] md5Salt = new byte[4]; - 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 (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("Crypt salt=" + salt); - } - - // Or get the md5 password salt if there is one - if (areq == AUTH_REQ_MD5) - { - - md5Salt[0] = (byte)pg_stream.ReceiveChar(); - md5Salt[1] = (byte)pg_stream.ReceiveChar(); - md5Salt[2] = (byte)pg_stream.ReceiveChar(); - md5Salt[3] = (byte)pg_stream.ReceiveChar(); - salt = new String(md5Salt, 0, 4); - if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("MD5 salt=" + salt); - } - - // now send the auth packet - switch (areq) - { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB4"); - throw new PSQLException("postgresql.con.kerb4"); - - case AUTH_REQ_KRB5: - if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB5"); - throw new PSQLException("postgresql.con.kerb5"); - - case AUTH_REQ_PASSWORD: - if (org.postgresql.Driver.logDebug) org.postgresql.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 (org.postgresql.Driver.logDebug) org.postgresql.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 (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: MD5"); - byte[] digest = MD5Digest.encode(PG_USER, password, md5Salt); - 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; - } - - - /* - * Return the instance of org.postgresql.Driver - * that created this connection - */ - public org.postgresql.Driver getDriver() - { - return this_driver; + /* + * This allows client code to add a handler for one of org.postgresql's + * more unique data types. + * + *

NOTE: This is not part of JDBC, but an extension. + * + *

The best way to use this is as follows: + * + *

+	 * ...
+	 * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");
+	 * ...
+	 * 
+ * + *

where myconn is an open Connection to org.postgresql. + * + *

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); } - // 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. - - public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; - - public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount) throws SQLException; - - /* - * 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;iNote: 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. - * - * Note: 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(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); - } - private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - - /* - * Send a query to the backend. Returns one of the ResultSet - * objects. - * - * Note: there does not seem to be any method currently - * in existance to return the update count. - * - * @param p_sqlFragmentss the SQL statement parts to be executed - * @param p_binds the SQL bind values - * @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[] p_sqlFragments, Object[] p_binds, java.sql.Statement stat) throws SQLException - { - return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)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. - * - *

NOTE: This is not part of JDBC, but allows access to - * functions on the org.postgresql backend itself. - * - *

It is primarily used by the LargeObject API - * - *

The best way to use this is as follows: - * - *

-         * import org.postgresql.fastpath.*;
-         * ...
-         * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();
-         * 
- * - *

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. - * - *

NOTE: This is not part of JDBC, but allows access to - * functions on the org.postgresql backend itself. - * - *

The best way to use this is as follows: - * - *

-         * import org.postgresql.largeobject.*;
-         * ...
-         * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();
-         * 
- * - *

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((java.sql.Connection)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. - * - *

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((java.sql.Connection)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((java.sql.Connection)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. - * - *

NOTE: This is not part of JDBC, but an extension. - * - *

The best way to use this is as follows: - * - *

-         * ...
-         * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");
-         * ...
-         * 
- * - *

where myconn is an open Connection to org.postgresql. - * - *

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]); - } - - /* - * 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) - * - * Note: 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) - {} + // 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]); + } + + /* + * 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) + * + * Note: 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) + {} finally { - pg_stream = null; + 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. - * - * Note: 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 - * - * Note: 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. - * - * Note: 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 - * 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 = ExecSQL("select typname from pg_type where oid = " + oid); - if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)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 oid for a given PG data type - * @param typeName PostgreSQL type name - * @return PostgreSQL oid value for a field of this type - */ - public int getPGType(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 = ExecSQL("select oid from pg_type where typname='" - + typeName + "'"); - if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)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); - } + } + } + + /* + * 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. + * + * Note: 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 + * + * Note: 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. + * + * Note: 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 + * 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 = ExecSQL("select typname from pg_type where oid = " + oid); + if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)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 oid for a given PG data type + * @param typeName PostgreSQL type name + * @return PostgreSQL oid value for a field of this type + */ + public int getPGType(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 = ExecSQL("select oid from pg_type where typname='" + + typeName + "'"); + if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)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); + } } // This is a cache of the DatabaseMetaData instance for this connection @@ -1312,22 +1331,25 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP }; - //Methods to support postgres notifications - public void addNotification(org.postgresql.PGNotification p_notification) { - if (m_notifications == null) - m_notifications = new Vector(); - m_notifications.addElement(p_notification); - } - - public PGNotification[] getNotifications() { - PGNotification[] l_return = null; - if (m_notifications != null) { - l_return = new PGNotification[m_notifications.size()]; - m_notifications.copyInto(l_return); + //Methods to support postgres notifications + public void addNotification(org.postgresql.PGNotification p_notification) + { + if (m_notifications == null) + m_notifications = new Vector(); + m_notifications.addElement(p_notification); + } + + public PGNotification[] getNotifications() + { + PGNotification[] l_return = null; + if (m_notifications != null) + { + l_return = new PGNotification[m_notifications.size()]; + m_notifications.copyInto(l_return); + } + m_notifications = null; + return l_return; } - m_notifications = null; - return l_return; - } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java index 0682737b8b76e185aa29cdc2fc337bdf0673bf31..82660a2ae36fbbde4a2bcd532b33c0c0437bd21f 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java @@ -10,14 +10,14 @@ import org.postgresql.Driver; public abstract class AbstractJdbc1DatabaseMetaData { - private static final String keywords = "abort,acl,add,aggregate,append,archive," + - "arch_store,backward,binary,change,cluster,"+ - "copy,database,delimiter,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"; + private static final String keywords = "abort,acl,add,aggregate,append,archive," + + "arch_store,backward,binary,change,cluster," + + "copy,database,delimiter,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"; protected AbstractJdbc1Connection connection; // The connection association @@ -30,7 +30,7 @@ public abstract class AbstractJdbc1DatabaseMetaData public AbstractJdbc1DatabaseMetaData(AbstractJdbc1Connection conn) { - this.connection = conn; + this.connection = conn; } /* @@ -42,8 +42,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean allProceduresAreCallable() throws SQLException { - if (Driver.logDebug) Driver.debug("allProceduresAreCallable"); - return true; // For now... + if (Driver.logDebug) + Driver.debug("allProceduresAreCallable"); + return true; // For now... } /* @@ -55,7 +56,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean allTablesAreSelectable() throws SQLException { - if (Driver.logDebug) Driver.debug("allTablesAreSelectable"); + if (Driver.logDebug) + Driver.debug("allTablesAreSelectable"); return true; // For now... } @@ -67,9 +69,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getURL() throws SQLException { - String url = connection.getURL(); - if (Driver.logDebug) Driver.debug("getURL " + url); - return url; + String url = connection.getURL(); + if (Driver.logDebug) + Driver.debug("getURL " + url); + return url; } /* @@ -80,9 +83,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getUserName() throws SQLException { - String userName = connection.getUserName(); - if (Driver.logDebug) Driver.debug("getUserName " + userName); - return userName; + String userName = connection.getUserName(); + if (Driver.logDebug) + Driver.debug("getUserName " + userName); + return userName; } /* @@ -93,9 +97,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean isReadOnly() throws SQLException { - boolean isReadOnly = connection.isReadOnly(); - if (Driver.logDebug) Driver.debug("isReadOnly " + isReadOnly); - return isReadOnly; + boolean isReadOnly = connection.isReadOnly(); + if (Driver.logDebug) + Driver.debug("isReadOnly " + isReadOnly); + return isReadOnly; } /* @@ -106,9 +111,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedHigh() throws SQLException { - boolean nullSortedHigh = connection.haveMinimumServerVersion("7.2"); - if (Driver.logDebug) Driver.debug("nullsAreSortedHigh " + nullSortedHigh); - return nullSortedHigh; + boolean nullSortedHigh = connection.haveMinimumServerVersion("7.2"); + if (Driver.logDebug) + Driver.debug("nullsAreSortedHigh " + nullSortedHigh); + return nullSortedHigh; } /* @@ -119,8 +125,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedLow() throws SQLException { - if (Driver.logDebug) Driver.debug("nullsAreSortedLow false"); - return false; + if (Driver.logDebug) + Driver.debug("nullsAreSortedLow false"); + return false; } /* @@ -131,8 +138,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedAtStart() throws SQLException { - if (Driver.logDebug) Driver.debug("nullsAreSortedAtStart false"); - return false; + if (Driver.logDebug) + Driver.debug("nullsAreSortedAtStart false"); + return false; } /* @@ -143,9 +151,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedAtEnd() throws SQLException { - boolean nullsAreSortedAtEnd = ! connection.haveMinimumServerVersion("7.2"); - if (Driver.logDebug) Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd); - return nullsAreSortedAtEnd; + boolean nullsAreSortedAtEnd = ! connection.haveMinimumServerVersion("7.2"); + if (Driver.logDebug) + Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd); + return nullsAreSortedAtEnd; } /* @@ -157,8 +166,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDatabaseProductName() throws SQLException { - if (Driver.logDebug) Driver.debug("getDatabaseProductName PostgresSQL"); - return "PostgreSQL"; + if (Driver.logDebug) + Driver.debug("getDatabaseProductName PostgresSQL"); + return "PostgreSQL"; } /* @@ -169,9 +179,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDatabaseProductVersion() throws SQLException { - String versionNumber = connection.getDBVersionNumber(); - if (Driver.logDebug) Driver.debug("getDatabaseProductVersion " + versionNumber); - return versionNumber; + String versionNumber = connection.getDBVersionNumber(); + if (Driver.logDebug) + Driver.debug("getDatabaseProductVersion " + versionNumber); + return versionNumber; } /* @@ -183,9 +194,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDriverName() throws SQLException { - String driverName = "PostgreSQL Native Driver"; - if (Driver.logDebug) Driver.debug("getDriverName" + driverName); - return driverName; + String driverName = "PostgreSQL Native Driver"; + if (Driver.logDebug) + Driver.debug("getDriverName" + driverName); + return driverName; } /* @@ -197,9 +209,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDriverVersion() throws SQLException { - String driverVersion = connection.this_driver.getVersion(); - if (Driver.logDebug) Driver.debug("getDriverVersion " + driverVersion); - return driverVersion; + String driverVersion = connection.this_driver.getVersion(); + if (Driver.logDebug) + Driver.debug("getDriverVersion " + driverVersion); + return driverVersion; } /* @@ -209,9 +222,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public int getDriverMajorVersion() { - int majorVersion = connection.this_driver.getMajorVersion(); - if (Driver.logDebug) Driver.debug("getMajorVersion " + majorVersion); - return majorVersion; + int majorVersion = connection.this_driver.getMajorVersion(); + if (Driver.logDebug) + Driver.debug("getMajorVersion " + majorVersion); + return majorVersion; } /* @@ -221,9 +235,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public int getDriverMinorVersion() { - int minorVersion = connection.this_driver.getMinorVersion(); - if (Driver.logDebug) Driver.debug("getMinorVersion " + minorVersion); - return minorVersion; + int minorVersion = connection.this_driver.getMinorVersion(); + if (Driver.logDebug) + Driver.debug("getMinorVersion " + minorVersion); + return minorVersion; } /* @@ -235,8 +250,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean usesLocalFiles() throws SQLException { - if (Driver.logDebug) Driver.debug("usesLocalFiles " + false); - return false; + if (Driver.logDebug) + Driver.debug("usesLocalFiles " + false); + return false; } /* @@ -248,8 +264,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean usesLocalFilePerTable() throws SQLException { - if (Driver.logDebug) Driver.debug("usesLocalFilePerTable " + false); - return false; + if (Driver.logDebug) + Driver.debug("usesLocalFilePerTable " + false); + return false; } /* @@ -266,8 +283,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMixedCaseIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsMixedCaseIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("supportsMixedCaseIdentifiers " + false); + return false; } /* @@ -278,8 +296,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesUpperCaseIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesUpperCaseIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("storesUpperCaseIdentifiers " + false); + return false; } /* @@ -290,8 +309,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesLowerCaseIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesLowerCaseIdentifiers " + true); - return true; + if (Driver.logDebug) + Driver.debug("storesLowerCaseIdentifiers " + true); + return true; } /* @@ -302,8 +322,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesMixedCaseIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesMixedCaseIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("storesMixedCaseIdentifiers " + false); + return false; } /* @@ -316,8 +337,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsMixedCaseQuotedIdentifiers " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsMixedCaseQuotedIdentifiers " + true); + return true; } /* @@ -328,8 +350,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesUpperCaseQuotedIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("storesUpperCaseQuotedIdentifiers " + false); + return false; } /* @@ -340,8 +363,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesLowerCaseQuotedIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("storesLowerCaseQuotedIdentifiers " + false); + return false; } /* @@ -352,8 +376,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { - if (Driver.logDebug) Driver.debug("storesMixedCaseQuotedIdentifiers " + false); - return false; + if (Driver.logDebug) + Driver.debug("storesMixedCaseQuotedIdentifiers " + false); + return false; } /* @@ -366,8 +391,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getIdentifierQuoteString() throws SQLException { - if (Driver.logDebug) Driver.debug("getIdentifierQuoteString \"" ); - return "\""; + if (Driver.logDebug) + Driver.debug("getIdentifierQuoteString \"" ); + return "\""; } /* @@ -393,26 +419,30 @@ public abstract class AbstractJdbc1DatabaseMetaData public String getNumericFunctions() throws SQLException { - if (Driver.logDebug) Driver.debug("getNumericFunctions"); - return ""; + if (Driver.logDebug) + Driver.debug("getNumericFunctions"); + return ""; } public String getStringFunctions() throws SQLException { - if (Driver.logDebug) Driver.debug("getStringFunctions"); - return ""; + if (Driver.logDebug) + Driver.debug("getStringFunctions"); + return ""; } public String getSystemFunctions() throws SQLException { - if (Driver.logDebug) Driver.debug("getSystemFunctions"); - return ""; + if (Driver.logDebug) + Driver.debug("getSystemFunctions"); + return ""; } public String getTimeDateFunctions() throws SQLException { - if (Driver.logDebug) Driver.debug("getTimeDateFunctions"); - return ""; + if (Driver.logDebug) + Driver.debug("getTimeDateFunctions"); + return ""; } /* @@ -424,8 +454,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getSearchStringEscape() throws SQLException { - if (Driver.logDebug) Driver.debug("getSearchStringEscape"); - return "\\"; + if (Driver.logDebug) + Driver.debug("getSearchStringEscape"); + return "\\"; } /* @@ -441,8 +472,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getExtraNameCharacters() throws SQLException { - if (Driver.logDebug) Driver.debug("getExtraNameCharacters"); - return ""; + if (Driver.logDebug) + Driver.debug("getExtraNameCharacters"); + return ""; } /* @@ -454,8 +486,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsAlterTableWithAddColumn() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsAlterTableWithAddColumn " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsAlterTableWithAddColumn " + true); + return true; } /* @@ -467,7 +500,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsAlterTableWithDropColumn() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsAlterTableWithDropColumn " + false); + if (Driver.logDebug) + Driver.debug("supportsAlterTableWithDropColumn " + false); return false; } @@ -491,8 +525,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsColumnAliasing() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsColumnAliasing " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsColumnAliasing " + true); + return true; } /* @@ -504,20 +539,23 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullPlusNonNullIsNull() throws SQLException { - if (Driver.logDebug) Driver.debug("nullPlusNonNullIsNull " + true); - return true; + if (Driver.logDebug) + Driver.debug("nullPlusNonNullIsNull " + true); + return true; } public boolean supportsConvert() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsConvert " + false); - return false; + if (Driver.logDebug) + Driver.debug("supportsConvert " + false); + return false; } public boolean supportsConvert(int fromType, int toType) throws SQLException { - if (Driver.logDebug) Driver.debug("supportsConvert " + false); - return false; + if (Driver.logDebug) + Driver.debug("supportsConvert " + false); + return false; } /* @@ -529,8 +567,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsTableCorrelationNames() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsTableCorrelationNames " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsTableCorrelationNames " + true); + return true; } /* @@ -542,8 +581,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsDifferentTableCorrelationNames() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsDifferentTableCorrelationNames " + false); - return false; + if (Driver.logDebug) + Driver.debug("supportsDifferentTableCorrelationNames " + false); + return false; } /* @@ -556,8 +596,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsExpressionsInOrderBy() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsExpressionsInOrderBy " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsExpressionsInOrderBy " + true); + return true; } /* @@ -568,9 +609,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsOrderByUnrelated() throws SQLException { - boolean supportsOrderByUnrelated = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated); - return supportsOrderByUnrelated; + boolean supportsOrderByUnrelated = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) + Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated); + return supportsOrderByUnrelated; } /* @@ -582,8 +624,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupBy() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsGroupBy " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsGroupBy " + true); + return true; } /* @@ -594,9 +637,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupByUnrelated() throws SQLException { - boolean supportsGroupByUnrelated = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated); - return supportsGroupByUnrelated; + boolean supportsGroupByUnrelated = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) + Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated); + return supportsGroupByUnrelated; } /* @@ -611,9 +655,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupByBeyondSelect() throws SQLException { - boolean supportsGroupByBeyondSelect = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect); - return supportsGroupByBeyondSelect; + boolean supportsGroupByBeyondSelect = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) + Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect); + return supportsGroupByBeyondSelect; } /* @@ -625,9 +670,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsLikeEscapeClause() throws SQLException { - boolean supportsLikeEscapeClause = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause); - return supportsLikeEscapeClause; + boolean supportsLikeEscapeClause = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) + Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause); + return supportsLikeEscapeClause; } /* @@ -640,8 +686,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMultipleResultSets() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsMultipleResultSets " + false); - return false; + if (Driver.logDebug) + Driver.debug("supportsMultipleResultSets " + false); + return false; } /* @@ -654,8 +701,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMultipleTransactions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsMultipleTransactions " + true); - return true; + if (Driver.logDebug) + Driver.debug("supportsMultipleTransactions " + true); + return true; } /* @@ -670,8 +718,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsNonNullableColumns() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsNonNullableColumns true"); - return true; + if (Driver.logDebug) + Driver.debug("supportsNonNullableColumns true"); + return true; } /* @@ -688,8 +737,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMinimumSQLGrammar() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsMinimumSQLGrammar TRUE"); - return true; + if (Driver.logDebug) + Driver.debug("supportsMinimumSQLGrammar TRUE"); + return true; } /* @@ -701,8 +751,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCoreSQLGrammar() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCoreSQLGrammar FALSE "); - return false; + if (Driver.logDebug) + Driver.debug("supportsCoreSQLGrammar FALSE "); + return false; } /* @@ -715,8 +766,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsExtendedSQLGrammar() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsExtendedSQLGrammar FALSE"); - return false; + if (Driver.logDebug) + Driver.debug("supportsExtendedSQLGrammar FALSE"); + return false; } /* @@ -733,9 +785,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92EntryLevelSQL() throws SQLException { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) Driver.debug("supportsANSI92EntryLevelSQL " + schemas); - return schemas; + boolean schemas = connection.haveMinimumServerVersion("7.3"); + if (Driver.logDebug) + Driver.debug("supportsANSI92EntryLevelSQL " + schemas); + return schemas; } /* @@ -747,8 +800,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92IntermediateSQL() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsANSI92IntermediateSQL false "); - return false; + if (Driver.logDebug) + Driver.debug("supportsANSI92IntermediateSQL false "); + return false; } /* @@ -759,8 +813,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92FullSQL() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsANSI92FullSQL false "); - return false; + if (Driver.logDebug) + Driver.debug("supportsANSI92FullSQL false "); + return false; } /* @@ -772,8 +827,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsIntegrityEnhancementFacility() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsIntegrityEnhancementFacility false "); - return false; + if (Driver.logDebug) + Driver.debug("supportsIntegrityEnhancementFacility false "); + return false; } /* @@ -784,9 +840,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsOuterJoins() throws SQLException { - boolean supportsOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) Driver.debug("supportsOuterJoins " + supportsOuterJoins); - return supportsOuterJoins; + boolean supportsOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) + Driver.debug("supportsOuterJoins " + supportsOuterJoins); + return supportsOuterJoins; } /* @@ -797,9 +854,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsFullOuterJoins() throws SQLException { - boolean supportsFullOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins); - return supportsFullOuterJoins; + boolean supportsFullOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) + Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins); + return supportsFullOuterJoins; } /* @@ -810,9 +868,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsLimitedOuterJoins() throws SQLException { - boolean supportsLimitedOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins); - return supportsLimitedOuterJoins; + boolean supportsLimitedOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) + Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins); + return supportsLimitedOuterJoins; } /* @@ -825,8 +884,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getSchemaTerm() throws SQLException { - if (Driver.logDebug) Driver.debug("getSchemaTerm schema"); - return "schema"; + if (Driver.logDebug) + Driver.debug("getSchemaTerm schema"); + return "schema"; } /* @@ -838,8 +898,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getProcedureTerm() throws SQLException { - if (Driver.logDebug) Driver.debug("getProcedureTerm function "); - return "function"; + if (Driver.logDebug) + Driver.debug("getProcedureTerm function "); + return "function"; } /* @@ -850,8 +911,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getCatalogTerm() throws SQLException { - if (Driver.logDebug) Driver.debug("getCatalogTerm database "); - return "database"; + if (Driver.logDebug) + Driver.debug("getCatalogTerm database "); + return "database"; } /* @@ -863,10 +925,11 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean isCatalogAtStart() throws SQLException { - // return true here; we return false for every other catalog function - // so it won't matter what we return here D.C. - if (Driver.logDebug) Driver.debug("isCatalogAtStart not implemented"); - return true; + // return true here; we return false for every other catalog function + // so it won't matter what we return here D.C. + if (Driver.logDebug) + Driver.debug("isCatalogAtStart not implemented"); + return true; } /* @@ -877,10 +940,11 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getCatalogSeparator() throws SQLException { - // Give them something to work with here - // everything else returns false so it won't matter what we return here D.C. - if (Driver.logDebug) Driver.debug("getCatalogSeparator not implemented "); - return "."; + // Give them something to work with here + // everything else returns false so it won't matter what we return here D.C. + if (Driver.logDebug) + Driver.debug("getCatalogSeparator not implemented "); + return "."; } /* @@ -891,8 +955,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInDataManipulation() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsSchemasInDataManipulation false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsSchemasInDataManipulation false"); + return false; } /* @@ -903,8 +968,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInProcedureCalls() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsSchemasInProcedureCalls false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsSchemasInProcedureCalls false"); + return false; } /* @@ -915,10 +981,11 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInTableDefinitions() throws SQLException { - boolean schemas = connection.haveMinimumServerVersion("7.3"); + boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) Driver.debug("supportsSchemasInTableDefinitions " + schemas); - return schemas; + if (Driver.logDebug) + Driver.debug("supportsSchemasInTableDefinitions " + schemas); + return schemas; } /* @@ -929,8 +996,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInIndexDefinitions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsSchemasInIndexDefinitions false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsSchemasInIndexDefinitions false"); + return false; } /* @@ -941,8 +1009,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsSchemasInPrivilegeDefinitions false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsSchemasInPrivilegeDefinitions false"); + return false; } /* @@ -953,8 +1022,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInDataManipulation() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsCatalogsInDataManipulation false"); + return false; } /* @@ -965,8 +1035,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInProcedureCalls() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsCatalogsInDataManipulation false"); + return false; } /* @@ -977,8 +1048,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInTableDefinitions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCatalogsInTableDefinitions false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsCatalogsInTableDefinitions false"); + return false; } /* @@ -989,8 +1061,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInIndexDefinitions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCatalogsInIndexDefinitions false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsCatalogsInIndexDefinitions false"); + return false; } /* @@ -1001,8 +1074,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsCatalogsInPrivilegeDefinitions false"); - return false; + if (Driver.logDebug) + Driver.debug("supportsCatalogsInPrivilegeDefinitions false"); + return false; } /* @@ -1014,8 +1088,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsPositionedDelete() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsPositionedDelete false"); - return false; // For now... + if (Driver.logDebug) + Driver.debug("supportsPositionedDelete false"); + return false; // For now... } /* @@ -1026,8 +1101,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsPositionedUpdate() throws SQLException { - if (Driver.logDebug) Driver.debug("supportsPositionedUpdate false"); - return false; // For now... + if (Driver.logDebug) + Driver.debug("supportsPositionedUpdate false"); + return false; // For now... } /* @@ -1038,7 +1114,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSelectForUpdate() throws SQLException { - return connection.haveMinimumServerVersion("6.5"); + return connection.haveMinimumServerVersion("6.5"); } /* @@ -1050,7 +1126,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsStoredProcedures() throws SQLException { - return false; + return false; } /* @@ -1809,14 +1885,14 @@ public abstract class AbstractJdbc1DatabaseMetaData { case (byte) 'r': if ( r.getString(1).startsWith("pg_") ) - { - relKind = "SYSTEM TABLE"; - } - else - { - relKind = "TABLE"; - } - break; + { + relKind = "SYSTEM TABLE"; + } + else + { + relKind = "TABLE"; + } + break; case (byte) 'i': relKind = "INDEX"; break; @@ -2100,7 +2176,7 @@ public abstract class AbstractJdbc1DatabaseMetaData // from the typmod value. if (typname.equals("numeric") || typname.equals("decimal")) { - int attypmod = r.getInt(8) - VARHDRSZ; + int attypmod = r.getInt(8) - VARHDRSZ; tuple[8] = Integer.toString(attypmod & 0xffff).getBytes(); tuple[9] = @@ -2184,7 +2260,8 @@ public abstract class AbstractJdbc1DatabaseMetaData { byte[][] tuple = new byte[8][0]; tuple[0] = tuple[1] = "".getBytes(); - if (Driver.logDebug) Driver.debug("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); @@ -2193,68 +2270,69 @@ public abstract class AbstractJdbc1DatabaseMetaData return connection.getResultSet(null, f, v, "OK", 1); } - /* - * Get a description of the access rights for each table available - * in a catalog. - * - * This method is currently unimplemented. - * - *

Only privileges matching the schema and table name - * criteria are returned. They are ordered by TABLE_SCHEM, - * TABLE_NAME, and PRIVILEGE. - * - *

Each privilige description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. COLUMN_NAME String => column name - *
  5. GRANTOR => grantor of access (may be null) - *
  6. GRANTEE String => grantee of access - *
  7. PRIVILEGE String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - *
  8. IS_GRANTABLE String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @return ResultSet each row is a table privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException - { - Field f[] = new Field[8]; - Vector v = new Vector(); - - if (tableNamePattern == null) - tableNamePattern = "%"; - - f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32); - f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32); - f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32); - f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32); - f[4] = new Field(connection, "GRANTOR", iVarcharOid, 32); - f[5] = new Field(connection, "GRANTEE", iVarcharOid, 32); - f[6] = new Field(connection, "PRIVILEGE", iVarcharOid, 32); - f[7] = new Field(connection, "IS_GRANTABLE", iVarcharOid, 32); - - // This is taken direct from the psql source - java.sql.ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '" + tableNamePattern.toLowerCase() + "' ORDER BY relname"); - while (r.next()) - { - byte[][] tuple = new byte[8][0]; - tuple[0] = tuple[1] = "".getBytes(); - 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); - } - - return connection.getResultSet(null, f, v, "OK", 1); - } + /* + * Get a description of the access rights for each table available + * in a catalog. + * + * This method is currently unimplemented. + * + *

Only privileges matching the schema and table name + * criteria are returned. They are ordered by TABLE_SCHEM, + * TABLE_NAME, and PRIVILEGE. + * + *

Each privilige description has the following columns: + *

    + *
  1. TABLE_CAT String => table catalog (may be null) + *
  2. TABLE_SCHEM String => table schema (may be null) + *
  3. TABLE_NAME String => table name + *
  4. COLUMN_NAME String => column name + *
  5. GRANTOR => grantor of access (may be null) + *
  6. GRANTEE String => grantee of access + *
  7. PRIVILEGE String => name of access (SELECT, + * INSERT, UPDATE, REFRENCES, ...) + *
  8. IS_GRANTABLE String => "YES" if grantee is permitted + * to grant to others; "NO" if not; null if unknown + *
+ * + * @param catalog a catalog name; "" retrieves those without a catalog + * @param schemaPattern a schema name pattern; "" retrieves those + * without a schema + * @param tableNamePattern a table name pattern + * @return ResultSet each row is a table privilege description + * @see #getSearchStringEscape + */ + public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException + { + Field f[] = new Field[8]; + Vector v = new Vector(); + + if (tableNamePattern == null) + tableNamePattern = "%"; + + f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32); + f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32); + f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32); + f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32); + f[4] = new Field(connection, "GRANTOR", iVarcharOid, 32); + f[5] = new Field(connection, "GRANTEE", iVarcharOid, 32); + f[6] = new Field(connection, "PRIVILEGE", iVarcharOid, 32); + f[7] = new Field(connection, "IS_GRANTABLE", iVarcharOid, 32); + + // This is taken direct from the psql source + java.sql.ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '" + tableNamePattern.toLowerCase() + "' ORDER BY relname"); + while (r.next()) + { + byte[][] tuple = new byte[8][0]; + tuple[0] = tuple[1] = "".getBytes(); + 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); + } + + return connection.getResultSet(null, f, v, "OK", 1); + } /* * Get a description of a table's optimal set of columns that @@ -2375,7 +2453,7 @@ public abstract class AbstractJdbc1DatabaseMetaData "a.attnum as KEY_SEQ," + "ic.relname as PK_NAME " + " FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a" + - " WHERE bc.relkind = 'r' " + // -- not indices + " WHERE bc.relkind = 'r' " + // -- not indices " and upper(bc.relname) = upper('" + table + "')" + " and i.indrelid = bc.oid" + " and i.indexrelid = ic.oid" + @@ -2385,274 +2463,275 @@ public abstract class AbstractJdbc1DatabaseMetaData ); } -/* - SELECT - c.relname as primary, - c2.relname as foreign, - t.tgconstrname, - ic.relname as fkeyname, - af.attnum as fkeyseq, - ipc.relname as pkeyname, - ap.attnum as pkeyseq, - t.tgdeferrable, - t.tginitdeferred, - t.tgnargs,t.tgargs, - p1.proname as updaterule, - p2.proname as deleterule -FROM - pg_trigger t, - pg_trigger t1, - pg_class c, - pg_class c2, - pg_class ic, - pg_class ipc, - pg_proc p1, - pg_proc p2, - pg_index if, - pg_index ip, - pg_attribute af, - pg_attribute ap -WHERE - (t.tgrelid=c.oid - AND t.tgisconstraint - AND t.tgconstrrelid=c2.oid - AND t.tgfoid=p1.oid - and p1.proname like '%%upd') - - and - (t1.tgrelid=c.oid - and t1.tgisconstraint - and t1.tgconstrrelid=c2.oid - AND t1.tgfoid=p2.oid - and p2.proname like '%%del') - - AND c2.relname='users' - - AND - (if.indrelid=c.oid - AND if.indexrelid=ic.oid - and ic.oid=af.attrelid - AND if.indisprimary) - - and - (ip.indrelid=c2.oid - and ip.indexrelid=ipc.oid - and ipc.oid=ap.attrelid - and ip.indisprimary) - -*/ -/** - * - * @param catalog - * @param schema - * @param primaryTable if provided will get the keys exported by this table - * @param foreignTable if provided will get the keys imported by this table - * @return ResultSet - * @throws SQLException - */ - - protected java.sql.ResultSet getImportedExportedKeys(String catalog, String schema, String primaryTable, String foreignTable) throws SQLException - { - Field f[] = new Field[14]; - - f[0] = new Field(connection, "PKTABLE_CAT", iVarcharOid, 32); - f[1] = new Field(connection, "PKTABLE_SCHEM", iVarcharOid, 32); - f[2] = new Field(connection, "PKTABLE_NAME", iVarcharOid, 32); - f[3] = new Field(connection, "PKCOLUMN_NAME", iVarcharOid, 32); - f[4] = new Field(connection, "FKTABLE_CAT", iVarcharOid, 32); - f[5] = new Field(connection, "FKTABLE_SCHEM", iVarcharOid, 32); - f[6] = new Field(connection, "FKTABLE_NAME", iVarcharOid, 32); - f[7] = new Field(connection, "FKCOLUMN_NAME", iVarcharOid, 32); - f[8] = new Field(connection, "KEY_SEQ", iInt2Oid, 2); - f[9] = new Field(connection, "UPDATE_RULE", iInt2Oid, 2); - f[10] = new Field(connection, "DELETE_RULE", iInt2Oid, 2); - f[11] = new Field(connection, "FK_NAME", iVarcharOid, 32); - f[12] = new Field(connection, "PK_NAME", iVarcharOid, 32); - f[13] = new Field(connection, "DEFERRABILITY", iInt2Oid, 2); - - java.sql.ResultSet rs = connection.ExecSQL( - "SELECT distinct " - + "c.relname as prelname, " - + "c2.relname as frelname, " - + "t.tgconstrname, " - + "a.attnum as keyseq, " - + "ic.relname as fkeyname, " - + "t.tgdeferrable, " - + "t.tginitdeferred, " - + "t.tgnargs,t.tgargs, " - + "p1.proname as updaterule, " - + "p2.proname as deleterule " - + "FROM " - + "pg_trigger t, " - + "pg_trigger t1, " - + "pg_class c, " - + "pg_class c2, " - + "pg_class ic, " - + "pg_proc p1, " - + "pg_proc p2, " - + "pg_index i, " - + "pg_attribute a " - + "WHERE " - // isolate the update rule - + "(t.tgrelid=c.oid " - + "AND t.tgisconstraint " - + "AND t.tgconstrrelid=c2.oid " - + "AND t.tgfoid=p1.oid " - + "and p1.proname like '%%upd') " - - + "and " - // isolate the delete rule - + "(t1.tgrelid=c.oid " - + "and t1.tgisconstraint " - + "and t1.tgconstrrelid=c2.oid " - + "AND t1.tgfoid=p2.oid " - + "and p2.proname like '%%del') " - - // if we are looking for exported keys then primary table will be used - + ((primaryTable != null) ? "AND c.relname='" + primaryTable + "' " : "") - - // if we are looking for imported keys then the foreign table will be used - + ((foreignTable != null) ? "AND c2.relname='" + foreignTable + "' " : "") - + "AND i.indrelid=c.oid " - + "AND i.indexrelid=ic.oid " - + "AND ic.oid=a.attrelid " - + "AND i.indisprimary " - + "ORDER BY " - - // orderby is as follows getExported, orders by FKTABLE, - // getImported orders by PKTABLE - // getCrossReference orders by FKTABLE, so this should work for both, - // since when getting crossreference, primaryTable will be defined - - + (primaryTable != null ? "frelname" : "prelname") + ",keyseq"); - -// returns the following columns -// and some example data with a table defined as follows - -// create table people ( id int primary key); -// create table policy ( id int primary key); -// create table users ( id int primary key, people_id int references people(id), policy_id int references policy(id)) - -// prelname | frelname | tgconstrname | keyseq | fkeyName | tgdeferrable | tginitdeferred -// 1 | 2 | 3 | 4 | 5 | 6 | 7 - -// people | users | | 1 | people_pkey | f | f - -// | tgnargs | tgargs | updaterule | deleterule -// | 8 | 9 | 10 | 11 -// | 6 | \000users\000people\000UNSPECIFIED\000people_id\000id\000 | RI_FKey_noaction_upd | RI_FKey_noaction_del - - Vector tuples = new Vector(); - - - while ( rs.next() ) - { - byte tuple[][] = new byte[14][]; - - tuple[2] = rs.getBytes(1); //PKTABLE_NAME - tuple[6] = rs.getBytes(2); //FKTABLE_NAME - String fKeyName = rs.getString(3); - String updateRule = rs.getString(10); - - if (updateRule != null ) - { - // Rules look like this RI_FKey_noaction_del so we want to pull out the part between the 'Key_' and the last '_' s - - String rule = updateRule.substring(8, updateRule.length() - 4); - - int action = java.sql.DatabaseMetaData.importedKeyNoAction; - - if ( rule == null || "noaction".equals(rule) ) - action = java.sql.DatabaseMetaData.importedKeyNoAction; - if ("cascade".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyCascade; - else if ("setnull".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetNull; - else if ("setdefault".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetDefault; - else if ("restrict".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyRestrict; - - tuple[9] = Integer.toString(action).getBytes(); - - } - - String deleteRule = rs.getString(11); - - if ( deleteRule != null ) - { - - String rule = updateRule.substring(8, updateRule.length() - 4); - - int action = java.sql.DatabaseMetaData.importedKeyNoAction; - if ("cascade".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyCascade; - else if ("setnull".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetNull; - else if ("setdefault".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetDefault; - tuple[10] = Integer.toString(action).getBytes(); - } - + /* + SELECT + c.relname as primary, + c2.relname as foreign, + t.tgconstrname, + ic.relname as fkeyname, + af.attnum as fkeyseq, + ipc.relname as pkeyname, + ap.attnum as pkeyseq, + t.tgdeferrable, + t.tginitdeferred, + t.tgnargs,t.tgargs, + p1.proname as updaterule, + p2.proname as deleterule + FROM + pg_trigger t, + pg_trigger t1, + pg_class c, + pg_class c2, + pg_class ic, + pg_class ipc, + pg_proc p1, + pg_proc p2, + pg_index if, + pg_index ip, + pg_attribute af, + pg_attribute ap + WHERE + (t.tgrelid=c.oid + AND t.tgisconstraint + AND t.tgconstrrelid=c2.oid + AND t.tgfoid=p1.oid + and p1.proname like '%%upd') + + and + (t1.tgrelid=c.oid + and t1.tgisconstraint + and t1.tgconstrrelid=c2.oid + AND t1.tgfoid=p2.oid + and p2.proname like '%%del') + + AND c2.relname='users' + + AND + (if.indrelid=c.oid + AND if.indexrelid=ic.oid + and ic.oid=af.attrelid + AND if.indisprimary) + + and + (ip.indrelid=c2.oid + and ip.indexrelid=ipc.oid + and ipc.oid=ap.attrelid + and ip.indisprimary) + + */ + /** + * + * @param catalog + * @param schema + * @param primaryTable if provided will get the keys exported by this table + * @param foreignTable if provided will get the keys imported by this table + * @return ResultSet + * @throws SQLException + */ + + protected java.sql.ResultSet getImportedExportedKeys(String catalog, String schema, String primaryTable, String foreignTable) throws SQLException + { + Field f[] = new Field[14]; + + f[0] = new Field(connection, "PKTABLE_CAT", iVarcharOid, 32); + f[1] = new Field(connection, "PKTABLE_SCHEM", iVarcharOid, 32); + f[2] = new Field(connection, "PKTABLE_NAME", iVarcharOid, 32); + f[3] = new Field(connection, "PKCOLUMN_NAME", iVarcharOid, 32); + f[4] = new Field(connection, "FKTABLE_CAT", iVarcharOid, 32); + f[5] = new Field(connection, "FKTABLE_SCHEM", iVarcharOid, 32); + f[6] = new Field(connection, "FKTABLE_NAME", iVarcharOid, 32); + f[7] = new Field(connection, "FKCOLUMN_NAME", iVarcharOid, 32); + f[8] = new Field(connection, "KEY_SEQ", iInt2Oid, 2); + f[9] = new Field(connection, "UPDATE_RULE", iInt2Oid, 2); + f[10] = new Field(connection, "DELETE_RULE", iInt2Oid, 2); + f[11] = new Field(connection, "FK_NAME", iVarcharOid, 32); + f[12] = new Field(connection, "PK_NAME", iVarcharOid, 32); + f[13] = new Field(connection, "DEFERRABILITY", iInt2Oid, 2); + + java.sql.ResultSet rs = connection.ExecSQL( + "SELECT distinct " + + "c.relname as prelname, " + + "c2.relname as frelname, " + + "t.tgconstrname, " + + "a.attnum as keyseq, " + + "ic.relname as fkeyname, " + + "t.tgdeferrable, " + + "t.tginitdeferred, " + + "t.tgnargs,t.tgargs, " + + "p1.proname as updaterule, " + + "p2.proname as deleterule " + + "FROM " + + "pg_trigger t, " + + "pg_trigger t1, " + + "pg_class c, " + + "pg_class c2, " + + "pg_class ic, " + + "pg_proc p1, " + + "pg_proc p2, " + + "pg_index i, " + + "pg_attribute a " + + "WHERE " + // isolate the update rule + + "(t.tgrelid=c.oid " + + "AND t.tgisconstraint " + + "AND t.tgconstrrelid=c2.oid " + + "AND t.tgfoid=p1.oid " + + "and p1.proname like '%%upd') " + + + "and " + // isolate the delete rule + + "(t1.tgrelid=c.oid " + + "and t1.tgisconstraint " + + "and t1.tgconstrrelid=c2.oid " + + "AND t1.tgfoid=p2.oid " + + "and p2.proname like '%%del') " + + // if we are looking for exported keys then primary table will be used + + ((primaryTable != null) ? "AND c.relname='" + primaryTable + "' " : "") + + // if we are looking for imported keys then the foreign table will be used + + ((foreignTable != null) ? "AND c2.relname='" + foreignTable + "' " : "") + + "AND i.indrelid=c.oid " + + "AND i.indexrelid=ic.oid " + + "AND ic.oid=a.attrelid " + + "AND i.indisprimary " + + "ORDER BY " + + // orderby is as follows getExported, orders by FKTABLE, + // getImported orders by PKTABLE + // getCrossReference orders by FKTABLE, so this should work for both, + // since when getting crossreference, primaryTable will be defined + + + (primaryTable != null ? "frelname" : "prelname") + ",keyseq"); + + // returns the following columns + // and some example data with a table defined as follows + + // create table people ( id int primary key); + // create table policy ( id int primary key); + // create table users ( id int primary key, people_id int references people(id), policy_id int references policy(id)) + + // prelname | frelname | tgconstrname | keyseq | fkeyName | tgdeferrable | tginitdeferred + // 1 | 2 | 3 | 4 | 5 | 6 | 7 + + // people | users | | 1 | people_pkey | f | f + + // | tgnargs | tgargs | updaterule | deleterule + // | 8 | 9 | 10 | 11 + // | 6 | \000users\000people\000UNSPECIFIED\000people_id\000id\000 | RI_FKey_noaction_upd | RI_FKey_noaction_del + + Vector tuples = new Vector(); + + + while ( rs.next() ) + { + byte tuple[][] = new byte[14][]; - // Parse the tgargs data - String fkeyColumn=""; - String pkeyColumn=""; + tuple[2] = rs.getBytes(1); //PKTABLE_NAME + tuple[6] = rs.getBytes(2); //FKTABLE_NAME + String fKeyName = rs.getString(3); + String updateRule = rs.getString(10); + if (updateRule != null ) + { + // Rules look like this RI_FKey_noaction_del so we want to pull out the part between the 'Key_' and the last '_' s - // Note, I am guessing at most of this, but it should be close - // if not, please correct - // the keys are in pairs and start after the first four arguments - // the arguments are seperated by \000 + String rule = updateRule.substring(8, updateRule.length() - 4); - int keySequence = rs.getInt(4); //KEY_SEQ + int action = java.sql.DatabaseMetaData.importedKeyNoAction; - // get the args - String targs = rs.getString(9); + if ( rule == null || "noaction".equals(rule) ) + action = java.sql.DatabaseMetaData.importedKeyNoAction; + if ("cascade".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyCascade; + else if ("setnull".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetNull; + else if ("setdefault".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetDefault; + else if ("restrict".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyRestrict; - // args look like this - //\000ww\000vv\000UNSPECIFIED\000m\000a\000n\000b\000 - // we are primarily interested in the column names which are the last items in the string + tuple[9] = Integer.toString(action).getBytes(); - StringTokenizer st = new StringTokenizer(targs, "\\000"); + } + + String deleteRule = rs.getString(11); + + if ( deleteRule != null ) + { + + String rule = updateRule.substring(8, updateRule.length() - 4); + + int action = java.sql.DatabaseMetaData.importedKeyNoAction; + if ("cascade".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyCascade; + else if ("setnull".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetNull; + else if ("setdefault".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetDefault; + tuple[10] = Integer.toString(action).getBytes(); + } + + + // Parse the tgargs data + String fkeyColumn = ""; + String pkeyColumn = ""; + + + // Note, I am guessing at most of this, but it should be close + // if not, please correct + // the keys are in pairs and start after the first four arguments + // the arguments are seperated by \000 + + int keySequence = rs.getInt(4); //KEY_SEQ - int advance = 4 + (keySequence-1) * 2; - for( int i=0; st.hasMoreTokens() && i < advance ; i++ ) st.nextToken(); // advance to the key column of interest + // get the args + String targs = rs.getString(9); - if ( st.hasMoreTokens() ) - { - fkeyColumn = st.nextToken(); - } - if ( st.hasMoreTokens() ) - { - pkeyColumn = st.nextToken(); - } + // args look like this + //\000ww\000vv\000UNSPECIFIED\000m\000a\000n\000b\000 + // we are primarily interested in the column names which are the last items in the string - tuple[3] = pkeyColumn.getBytes(); //PKCOLUMN_NAME - tuple[7] = fkeyColumn.getBytes(); //FKCOLUMN_NAME + StringTokenizer st = new StringTokenizer(targs, "\\000"); - tuple[8] = rs.getBytes(4); //KEY_SEQ - tuple[11] = targs.getBytes(); //FK_NAME this will give us a unique name for the foreign key - tuple[12] = rs.getBytes(5); //PK_NAME + int advance = 4 + (keySequence - 1) * 2; + for ( int i = 0; st.hasMoreTokens() && i < advance ; i++ ) + st.nextToken(); // advance to the key column of interest - // DEFERRABILITY - int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; - boolean deferrable = rs.getBoolean(6); - boolean initiallyDeferred = rs.getBoolean(7); - if (deferrable) - { - if (initiallyDeferred) - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; - else - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; - } - tuple[13] = Integer.toString(deferrability).getBytes(); + if ( st.hasMoreTokens() ) + { + fkeyColumn = st.nextToken(); + } + if ( st.hasMoreTokens() ) + { + pkeyColumn = st.nextToken(); + } + + tuple[3] = pkeyColumn.getBytes(); //PKCOLUMN_NAME + tuple[7] = fkeyColumn.getBytes(); //FKCOLUMN_NAME + + tuple[8] = rs.getBytes(4); //KEY_SEQ + tuple[11] = targs.getBytes(); //FK_NAME this will give us a unique name for the foreign key + tuple[12] = rs.getBytes(5); //PK_NAME - tuples.addElement(tuple); - } + // DEFERRABILITY + int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; + boolean deferrable = rs.getBoolean(6); + boolean initiallyDeferred = rs.getBoolean(7); + if (deferrable) + { + if (initiallyDeferred) + deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; + else + deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; + } + tuple[13] = Integer.toString(deferrability).getBytes(); - return connection.getResultSet(null, f, tuples, "OK", 1); - } + tuples.addElement(tuple); + } + + return connection.getResultSet(null, f, tuples, "OK", 1); + } /* * Get a description of the primary key columns that are diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java index 0a7e0eb0fece1861a526bfe23190e9b7d85c8c50..c415e55da55a23b7bcfdd002cd9d41e3e0ba736e 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java @@ -13,7 +13,7 @@ import org.postgresql.largeobject.*; import org.postgresql.util.PGbytea; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.5 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.6 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2 * methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet @@ -22,7 +22,7 @@ public abstract class AbstractJdbc1ResultSet { protected Vector rows; // The results - protected Statement statement; + protected Statement statement; protected Field fields[]; // The field descriptions protected String status; // Status of the result protected boolean binaryCursor = false; // is the data binary or Strings @@ -39,13 +39,13 @@ public abstract class AbstractJdbc1ResultSet protected ResultSet next = null; protected StringBuffer sbuf = null; - public byte[][] rowBuffer=null; + public byte[][] rowBuffer = null; public AbstractJdbc1ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { this.connection = conn; - this.statement = statement; + this.statement = statement; this.fields = fields; this.rows = tuples; this.status = status; @@ -59,16 +59,16 @@ public abstract class AbstractJdbc1ResultSet public boolean next() throws SQLException { - if (rows == null) - throw new PSQLException("postgresql.con.closed"); + if (rows == null) + throw new PSQLException("postgresql.con.closed"); if (++current_row >= rows.size()) return false; this_row = (byte [][])rows.elementAt(current_row); - rowBuffer=new byte[this_row.length][]; - System.arraycopy(this_row,0,rowBuffer,0,this_row.length); + rowBuffer = new byte[this_row.length][]; + System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); return true; } @@ -230,12 +230,12 @@ public abstract class AbstractJdbc1ResultSet public Time getTime(int columnIndex) throws SQLException { - return toTime( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() ); + return toTime( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex - 1].getPGType() ); } public Timestamp getTimestamp(int columnIndex) throws SQLException { - return toTimestamp( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex-1].getPGType() ); + return toTimestamp( getString(columnIndex), (java.sql.ResultSet)this, fields[columnIndex - 1].getPGType() ); } public InputStream getAsciiStream(int columnIndex) throws SQLException @@ -423,11 +423,12 @@ public abstract class AbstractJdbc1ResultSet warnings = null; } - public void addWarnings(SQLWarning warnings) { - if ( this.warnings != null ) - this.warnings.setNextWarning(warnings); - else - this.warnings = warnings; + public void addWarnings(SQLWarning warnings) + { + if ( this.warnings != null ) + this.warnings.setNextWarning(warnings); + else + this.warnings = warnings; } public String getCursorName() throws SQLException @@ -612,18 +613,18 @@ public abstract class AbstractJdbc1ResultSet /* * returns the OID of the last inserted row. Deprecated in 7.2 because - * range for OID values is greater than java signed int. + * range for OID values is greater than java signed int. * @deprecated Replaced by getLastOID() in 7.2 */ public int getInsertedOID() { - return (int) getLastOID(); + return (int) getLastOID(); } /* * returns the OID of the last inserted row - * @since 7.2 + * @since 7.2 */ public long getLastOID() { @@ -660,8 +661,10 @@ public abstract class AbstractJdbc1ResultSet protected void checkResultSet( int column ) throws SQLException { - if ( this_row == null ) throw new PSQLException("postgresql.res.nextrequired"); - if ( column < 1 || column > fields.length ) throw new PSQLException("postgresql.res.colrange" ); + if ( this_row == null ) + throw new PSQLException("postgresql.res.nextrequired"); + if ( column < 1 || column > fields.length ) + throw new PSQLException("postgresql.res.colrange" ); } //----------------- Formatting Methods ------------------- @@ -789,26 +792,34 @@ public abstract class AbstractJdbc1ResultSet return null; // SQL NULL try { - if (s.length() == 8) { - //value is a time value - return java.sql.Time.valueOf(s); - } else if (s.indexOf(".") == 8) { - //value is a time value with fractional seconds - java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0,8)); - String l_strMillis = s.substring(9); - if (l_strMillis.length() > 3) - l_strMillis = l_strMillis.substring(0,3); - int l_millis = Integer.parseInt(l_strMillis); - if (l_millis < 10) { - l_millis = l_millis * 100; - } else if (l_millis < 100) { - l_millis = l_millis * 10; - } - return new java.sql.Time(l_time.getTime() + l_millis); - } else { - //value is a timestamp - return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime()); - } + if (s.length() == 8) + { + //value is a time value + return java.sql.Time.valueOf(s); + } + else if (s.indexOf(".") == 8) + { + //value is a time value with fractional seconds + java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0, 8)); + String l_strMillis = s.substring(9); + if (l_strMillis.length() > 3) + l_strMillis = l_strMillis.substring(0, 3); + int l_millis = Integer.parseInt(l_strMillis); + if (l_millis < 10) + { + l_millis = l_millis * 100; + } + else if (l_millis < 100) + { + l_millis = l_millis * 10; + } + return new java.sql.Time(l_time.getTime() + l_millis); + } + else + { + //value is a timestamp + return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime()); + } } catch (NumberFormatException e) { @@ -827,7 +838,7 @@ public abstract class AbstractJdbc1ResultSet * From version 7.2 postgres returns fractional seconds to 6 places. * If available, we drop the last 3 digits. * - * @param s The ISO formated date string to parse. + * @param s The ISO formated date string to parse. * @param resultSet The ResultSet this date is part of. * * @return null if s is null or a timestamp of the parsed string s. @@ -837,7 +848,7 @@ public abstract class AbstractJdbc1ResultSet public static Timestamp toTimestamp(String s, java.sql.ResultSet resultSet, String pgDataType) throws SQLException { - AbstractJdbc1ResultSet rs = (AbstractJdbc1ResultSet)resultSet; + AbstractJdbc1ResultSet rs = (AbstractJdbc1ResultSet)resultSet; if (s == null) return null; @@ -847,12 +858,14 @@ public abstract class AbstractJdbc1ResultSet synchronized (rs) { SimpleDateFormat df = null; - if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug("the data from the DB is "+s); + if ( org.postgresql.Driver.logDebug ) + org.postgresql.Driver.debug("the data from the DB is " + s); // If first time, create the buffer, otherwise clear it. if (rs.sbuf == null) rs.sbuf = new StringBuffer(32); - else { + else + { rs.sbuf.setLength(0); } @@ -880,7 +893,8 @@ public abstract class AbstractJdbc1ResultSet if (i < 24) rs.sbuf.append(c); c = s.charAt(i++); - } while (i < slen && Character.isDigit(c)); + } + while (i < slen && Character.isDigit(c)); // If there wasn't at least 3 digits we should add some zeros // to make up the 3 digits we tell java to expect. @@ -911,37 +925,43 @@ public abstract class AbstractJdbc1ResultSet } else { - // Just found fractional seconds but no timezone. - //If timestamptz then we use GMT, else local timezone - if (pgDataType.equals("timestamptz")) { - rs.sbuf.append(" GMT"); - df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z"); - } else { - df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - } + // Just found fractional seconds but no timezone. + //If timestamptz then we use GMT, else local timezone + if (pgDataType.equals("timestamptz")) + { + rs.sbuf.append(" GMT"); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z"); + } + else + { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + } } } else if (slen == 19) { - // No tz or fractional second info. - //If timestamptz then we use GMT, else local timezone - if (pgDataType.equals("timestamptz")) { - rs.sbuf.append(" GMT"); - df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - } else { - df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } + // No tz or fractional second info. + //If timestamptz then we use GMT, else local timezone + if (pgDataType.equals("timestamptz")) + { + rs.sbuf.append(" GMT"); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + } + else + { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } } else { - if (slen == 8 && s.equals("infinity")) - //java doesn't have a concept of postgres's infinity - //so set to an arbitrary future date - s = "9999-01-01"; + if (slen == 8 && s.equals("infinity")) + //java doesn't have a concept of postgres's infinity + //so set to an arbitrary future date + s = "9999-01-01"; if (slen == 9 && s.equals("-infinity")) - //java doesn't have a concept of postgres's infinity - //so set to an arbitrary old date - s = "0001-01-01"; + //java doesn't have a concept of postgres's infinity + //so set to an arbitrary old date + s = "0001-01-01"; // We must just have a date. This case is // needed if this method is called on a date @@ -952,7 +972,8 @@ public abstract class AbstractJdbc1ResultSet try { // All that's left is to parse the string and return the ts. - if ( org.postgresql.Driver.logDebug ) org.postgresql.Driver.debug( "" + df.parse(rs.sbuf.toString()).getTime() ); + if ( org.postgresql.Driver.logDebug ) + org.postgresql.Driver.debug( "" + df.parse(rs.sbuf.toString()).getTime() ); return new Timestamp(df.parse(rs.sbuf.toString()).getTime()); } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java index bed9cc27e19dc541916225e2db3a1a85d51a4061..d1e34744491564c016e65534ef543d928dd4b376 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java @@ -8,7 +8,7 @@ import org.postgresql.util.*; import java.sql.SQLException; import java.sql.Types; -public abstract class AbstractJdbc1ResultSetMetaData +public abstract class AbstractJdbc1ResultSetMetaData { protected Vector rows; diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java index 600cb42f56a4d5eb2ab1c5592b44e908d340feb2..0e0067cf0f32f70d5176b6df8e96c29f94b8f8d3 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java @@ -8,7 +8,7 @@ import java.util.Vector; import org.postgresql.largeobject.*; import org.postgresql.util.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.6 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.7 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2 * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement @@ -16,8 +16,8 @@ import org.postgresql.util.*; public abstract class AbstractJdbc1Statement implements org.postgresql.PGStatement { - // The connection who created us - protected AbstractJdbc1Connection connection; + // The connection who created us + protected AbstractJdbc1Connection connection; /** The warnings chain. */ protected SQLWarning warnings = null; @@ -42,15 +42,15 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme // Some performance caches private StringBuffer sbuf = new StringBuffer(32); - //Used by the preparedstatement style methods + //Used by the preparedstatement style methods protected String[] m_sqlFragments; private String[] m_origSqlFragments; private String[] m_executeSqlFragments; protected Object[] m_binds = new Object[0]; - private String[] m_bindTypes = new String[0]; - private String m_statementName = null; - private boolean m_useServerPrepare = false; - private static int m_preparedCount = 1; + private String[] m_bindTypes = new String[0]; + private String m_statementName = null; + private boolean m_useServerPrepare = false; + private static int m_preparedCount = 1; //Used by the callablestatement style methods private static final String JDBC_SYNTAX = "{[? =] call ([? [,?]*]) }"; @@ -58,7 +58,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme private String originalSql = ""; private boolean isFunction; // functionReturnType contains the user supplied value to check - // testReturn contains a modified version to make it easier to + // testReturn contains a modified version to make it easier to // check the getXXX methods.. private int functionReturnType; private int testReturn; @@ -76,17 +76,19 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public AbstractJdbc1Statement (AbstractJdbc1Connection connection, String p_sql) throws SQLException { this.connection = connection; - parseSqlStmt(p_sql); // this allows Callable stmt to override + parseSqlStmt(p_sql); // this allows Callable stmt to override } - protected void parseSqlStmt (String p_sql) throws SQLException { - String l_sql = p_sql; + protected void parseSqlStmt (String p_sql) throws SQLException + { + String l_sql = p_sql; - l_sql = replaceProcessing(l_sql); + l_sql = replaceProcessing(l_sql); - if (this instanceof CallableStatement) { - l_sql = modifyJdbcCall(l_sql); - } + if (this instanceof CallableStatement) + { + l_sql = modifyJdbcCall(l_sql); + } Vector v = new Vector(); boolean inQuotes = false; @@ -108,8 +110,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme m_sqlFragments = new String[v.size()]; m_binds = new String[v.size() - 1]; - m_bindTypes = new String[v.size() - 1]; - //BJL why if binds is new??? + m_bindTypes = new String[v.size() - 1]; + //BJL why if binds is new??? clearParameters(); for (i = 0 ; i < m_sqlFragments.length; ++i) @@ -127,9 +129,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public java.sql.ResultSet executeQuery(String p_sql) throws SQLException { - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - return executeQuery(); + String l_sql = replaceProcessing(p_sql); + m_sqlFragments = new String[] {l_sql}; + return executeQuery(); } /* @@ -160,9 +162,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public int executeUpdate(String p_sql) throws SQLException { - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - return executeUpdate(); + String l_sql = replaceProcessing(p_sql); + m_sqlFragments = new String[] {l_sql}; + return executeUpdate(); } /* @@ -195,9 +197,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public boolean execute(String p_sql) throws SQLException { - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - return execute(); + String l_sql = replaceProcessing(p_sql); + m_sqlFragments = new String[] {l_sql}; + return execute(); } /* @@ -213,15 +215,17 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme { if (isFunction && !returnTypeSet) throw new PSQLException("postgresql.call.noreturntype"); - if (isFunction) { // set entry 1 to dummy entry.. + if (isFunction) + { // set entry 1 to dummy entry.. m_binds[0] = ""; // dummy entry which ensured that no one overrode - m_bindTypes[0] = PG_TEXT; + m_bindTypes[0] = PG_TEXT; // and calls to setXXX (2,..) really went to first arg in a function call.. } // New in 7.1, if we have a previous resultset then force it to close // This brings us nearer to compliance, and helps memory management. // Internal stuff will call ExecSQL directly, bypassing this. + if (result != null) { java.sql.ResultSet rs = getResultSet(); @@ -229,73 +233,86 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme rs.close(); } - //Use server prepared statements if directed - if (m_useServerPrepare) { - if (m_statementName == null) { - m_statementName = "JDBC_STATEMENT_" + m_preparedCount++; - m_origSqlFragments = new String[m_sqlFragments.length]; - m_executeSqlFragments = new String[m_sqlFragments.length]; - System.arraycopy(m_sqlFragments, 0, m_origSqlFragments, 0, m_sqlFragments.length); - m_executeSqlFragments[0] = "EXECUTE " + m_statementName; - if (m_sqlFragments.length > 1) { - m_executeSqlFragments[0] = m_executeSqlFragments[0] + "("; - for(int i = 1; i < m_bindTypes.length; i++) { - m_executeSqlFragments[i] = ", "; - } - m_executeSqlFragments[m_bindTypes.length] = ")"; - } - synchronized (sbuf) { - sbuf.setLength(0); - sbuf.append("PREPARE "); - sbuf.append(m_statementName); - if (m_origSqlFragments.length > 1) { - sbuf.append("("); - for(int i = 0; i < m_bindTypes.length - 1; i++) { - sbuf.append(m_bindTypes[i]); - sbuf.append(", "); - } - sbuf.append(m_bindTypes[m_bindTypes.length - 1]); - sbuf.append(")"); - } - sbuf.append(" AS "); - sbuf.append(m_origSqlFragments[0]); - for(int i = 1; i < m_origSqlFragments.length; i++) { - sbuf.append(" $"); - sbuf.append(i); - sbuf.append(" "); - sbuf.append(m_origSqlFragments[i]); - } - sbuf.append("; "); - - sbuf.append(m_executeSqlFragments[0]); - m_sqlFragments[0] = sbuf.toString(); - System.arraycopy(m_executeSqlFragments, 1, m_sqlFragments, 1, m_sqlFragments.length - 1); - } + //Use server prepared statements if directed + if (m_useServerPrepare) + { + if (m_statementName == null) + { + m_statementName = "JDBC_STATEMENT_" + m_preparedCount++; + m_origSqlFragments = new String[m_sqlFragments.length]; + m_executeSqlFragments = new String[m_sqlFragments.length]; + System.arraycopy(m_sqlFragments, 0, m_origSqlFragments, 0, m_sqlFragments.length); + m_executeSqlFragments[0] = "EXECUTE " + m_statementName; + if (m_sqlFragments.length > 1) + { + m_executeSqlFragments[0] = m_executeSqlFragments[0] + "("; + for (int i = 1; i < m_bindTypes.length; i++) + { + m_executeSqlFragments[i] = ", "; + } + m_executeSqlFragments[m_bindTypes.length] = ")"; + } + synchronized (sbuf) + { + sbuf.setLength(0); + sbuf.append("PREPARE "); + sbuf.append(m_statementName); + if (m_origSqlFragments.length > 1) + { + sbuf.append("("); + for (int i = 0; i < m_bindTypes.length - 1; i++) + { + sbuf.append(m_bindTypes[i]); + sbuf.append(", "); + } + sbuf.append(m_bindTypes[m_bindTypes.length - 1]); + sbuf.append(")"); + } + sbuf.append(" AS "); + sbuf.append(m_origSqlFragments[0]); + for (int i = 1; i < m_origSqlFragments.length; i++) + { + sbuf.append(" $"); + sbuf.append(i); + sbuf.append(" "); + sbuf.append(m_origSqlFragments[i]); + } + sbuf.append("; "); + + sbuf.append(m_executeSqlFragments[0]); + m_sqlFragments[0] = sbuf.toString(); + System.arraycopy(m_executeSqlFragments, 1, m_sqlFragments, 1, m_sqlFragments.length - 1); + } - } else { - m_sqlFragments = m_executeSqlFragments; - } + } + else + { + m_sqlFragments = m_executeSqlFragments; + } } // New in 7.1, pass Statement so that ExecSQL can customise to it result = ((AbstractJdbc1Connection)connection).ExecSQL(m_sqlFragments, m_binds, (java.sql.Statement)this); - //If we are executing a callable statement function set the return data - if (isFunction) { - if (!((AbstractJdbc1ResultSet)result).reallyResultSet()) - throw new PSQLException("postgresql.call.noreturnval"); + //If we are executing a callable statement function set the return data + if (isFunction) + { + if (!((AbstractJdbc1ResultSet)result).reallyResultSet()) + throw new PSQLException("postgresql.call.noreturnval"); if (!result.next ()) throw new PSQLException ("postgresql.call.noreturnval"); callResult = result.getObject(1); int columnType = result.getMetaData().getColumnType(1); - if (columnType != functionReturnType) + if (columnType != functionReturnType) throw new PSQLException ("postgresql.call.wrongrtntype", new Object[]{ - "java.sql.Types=" + columnType, "java.sql.Types="+functionReturnType }); - result.close (); - return true; - } else { - return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet()); + "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType }); + result.close (); + return true; + } + else + { + return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet()); } } @@ -336,8 +353,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme { if (result == null) return -1; - if (isFunction) - return 1; + if (isFunction) + return 1; if (((AbstractJdbc1ResultSet)result).reallyResultSet()) return -1; return ((AbstractJdbc1ResultSet)result).getResultCount(); @@ -437,11 +454,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme * @param msg message to add */ public void addWarning(String msg) - { - if (warnings != null) - warnings.setNextWarning(new SQLWarning(msg)); - else - warnings = new SQLWarning(msg); + { + if (warnings != null) + warnings.setNextWarning(new SQLWarning(msg)); + else + warnings = new SQLWarning(msg); } /* @@ -513,7 +530,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void cancel() throws SQLException { - throw new PSQLException("postgresql.unimplemented"); + throw new PSQLException("postgresql.unimplemented"); } /* @@ -565,82 +582,85 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ protected String replaceProcessing(String p_sql) { - if (replaceProcessingEnabled) { - // Since escape codes can only appear in SQL CODE, we keep track - // of if we enter a string or not. - StringBuffer newsql = new StringBuffer(p_sql.length()); - short state = IN_SQLCODE; - - int i = -1; - int len = p_sql.length(); - while (++i < len) + if (replaceProcessingEnabled) { - char c = p_sql.charAt(i); - switch (state) + // Since escape codes can only appear in SQL CODE, we keep track + // of if we enter a string or not. + StringBuffer newsql = new StringBuffer(p_sql.length()); + short state = IN_SQLCODE; + + int i = -1; + int len = p_sql.length(); + while (++i < len) { - case IN_SQLCODE: - if (c == '\'') // start of a string? - state = IN_STRING; - else if (c == '{') // start of an escape code? - if (i + 1 < len) - { - char next = p_sql.charAt(i + 1); - if (next == 'd') - { - state = ESC_TIMEDATE; - i++; - break; - } - else if (next == 't') + char c = p_sql.charAt(i); + switch (state) + { + case IN_SQLCODE: + if (c == '\'') // start of a string? + state = IN_STRING; + else if (c == '{') // start of an escape code? + if (i + 1 < len) { - state = ESC_TIMEDATE; - i += (i + 2 < len && p_sql.charAt(i + 2) == 's') ? 2 : 1; - break; + char next = p_sql.charAt(i + 1); + if (next == 'd') + { + state = ESC_TIMEDATE; + i++; + break; + } + else if (next == 't') + { + state = ESC_TIMEDATE; + i += (i + 2 < len && p_sql.charAt(i + 2) == 's') ? 2 : 1; + break; + } } - } - newsql.append(c); - break; - - case IN_STRING: - if (c == '\'') // end of string? - state = IN_SQLCODE; - else if (c == '\\') // a backslash? - state = BACKSLASH; + newsql.append(c); + break; - newsql.append(c); - break; + case IN_STRING: + if (c == '\'') // end of string? + state = IN_SQLCODE; + else if (c == '\\') // a backslash? + state = BACKSLASH; - case BACKSLASH: - state = IN_STRING; + newsql.append(c); + break; - newsql.append(c); - break; + case BACKSLASH: + state = IN_STRING; - case ESC_TIMEDATE: - if (c == '}') - state = IN_SQLCODE; // end of escape code. - else newsql.append(c); - break; - } // end switch - } + break; + + case ESC_TIMEDATE: + if (c == '}') + state = IN_SQLCODE; // end of escape code. + else + newsql.append(c); + break; + } // end switch + } - return newsql.toString(); - } else { - return p_sql; - } + return newsql.toString(); + } + else + { + return p_sql; + } } - /* - * - * The following methods are postgres extensions and are defined - * in the interface org.postgresql.Statement - * - */ + /* + * + * The following methods are postgres extensions and are defined + * in the interface org.postgresql.Statement + * + */ /* * Returns the Last inserted/updated oid. Deprecated in 7.2 because - * range of OID values is greater than a java signed int. + * range of OID values is greater than a java signed int. * @deprecated Replaced by getLastOID in 7.2 */ public int getInsertedOID() throws SQLException @@ -651,9 +671,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme } /* - * Returns the Last inserted/updated oid. + * Returns the Last inserted/updated oid. * @return OID of last insert - * @since 7.2 + * @since 7.2 */ public long getLastOID() throws SQLException { @@ -713,10 +733,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void setShort(int parameterIndex, short x) throws SQLException { - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex,"'" + Integer.toString(x) +"'", PG_INT2); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + Integer.toString(x) + "'", PG_INT2); } /* @@ -742,10 +762,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void setLong(int parameterIndex, long x) throws SQLException { - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex, "'"+Long.toString(x)+"'", PG_INT8); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + Long.toString(x) + "'", PG_INT8); } /* @@ -758,10 +778,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void setFloat(int parameterIndex, float x) throws SQLException { - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex, "'"+Float.toString(x)+"'", PG_FLOAT); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + Float.toString(x) + "'", PG_FLOAT); } /* @@ -774,10 +794,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void setDouble(int parameterIndex, double x) throws SQLException { - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex, "'"+Double.toString(x)+"'", PG_DOUBLE); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + Double.toString(x) + "'", PG_DOUBLE); } /* @@ -795,10 +815,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme setNull(parameterIndex, Types.OTHER); else { - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex, "'"+x.toString()+"'", PG_NUMERIC); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + x.toString() + "'", PG_NUMERIC); } } @@ -814,7 +834,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void setString(int parameterIndex, String x) throws SQLException { - setString(parameterIndex, x, PG_TEXT); + setString(parameterIndex, x, PG_TEXT); } public void setString(int parameterIndex, String x, String type) throws SQLException @@ -829,7 +849,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme synchronized (sbuf) { sbuf.setLength(0); - sbuf.ensureCapacity(x.length()); + sbuf.ensureCapacity(x.length()); int i; sbuf.append('\''); @@ -941,72 +961,89 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme setNull(parameterIndex, Types.OTHER); } else - { + { // Use the shared StringBuffer synchronized (sbuf) { sbuf.setLength(0); - sbuf.ensureCapacity(32); + sbuf.ensureCapacity(32); sbuf.append("'"); - //format the timestamp - //we do our own formating so that we can get a format - //that works with both timestamp with time zone and - //timestamp without time zone datatypes. - //The format is '2002-01-01 23:59:59.123456-0130' - //we need to include the local time and timezone offset - //so that timestamp without time zone works correctly - int l_year = x.getYear() + 1900; - sbuf.append(l_year); - sbuf.append('-'); - int l_month = x.getMonth() + 1; - if (l_month < 10) sbuf.append('0'); - sbuf.append(l_month); - sbuf.append('-'); - int l_day = x.getDate(); - if (l_day < 10) sbuf.append('0'); - sbuf.append(l_day); - sbuf.append(' '); - int l_hours = x.getHours(); - if (l_hours < 10) sbuf.append('0'); - sbuf.append(l_hours); - sbuf.append(':'); - int l_minutes = x.getMinutes(); - if (l_minutes < 10) sbuf.append('0'); - sbuf.append(l_minutes); - sbuf.append(':'); - int l_seconds = x.getSeconds(); - if (l_seconds < 10) sbuf.append('0'); - sbuf.append(l_seconds); - // Make decimal from nanos. - char[] l_decimal = {'0','0','0','0','0','0','0','0','0'}; - char[] l_nanos = Integer.toString(x.getNanos()).toCharArray(); - System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length); - sbuf.append('.'); - if (connection.haveMinimumServerVersion("7.2")) { - sbuf.append(l_decimal,0,6); - } else { - // Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00". - sbuf.append(l_decimal,0,2); - } - //add timezone offset - int l_offset = -(x.getTimezoneOffset()); - int l_houros = l_offset/60; - if (l_houros >= 0) { - sbuf.append('+'); - } else { - sbuf.append('-'); - } - if (l_houros > -10 && l_houros < 10) sbuf.append('0'); - if (l_houros >= 0) { - sbuf.append(l_houros); - } else { - sbuf.append(-l_houros); - } - int l_minos = l_offset - (l_houros *60); - if (l_minos != 0) { - if (l_minos < 10) sbuf.append('0'); - sbuf.append(l_minos); - } + //format the timestamp + //we do our own formating so that we can get a format + //that works with both timestamp with time zone and + //timestamp without time zone datatypes. + //The format is '2002-01-01 23:59:59.123456-0130' + //we need to include the local time and timezone offset + //so that timestamp without time zone works correctly + int l_year = x.getYear() + 1900; + sbuf.append(l_year); + sbuf.append('-'); + int l_month = x.getMonth() + 1; + if (l_month < 10) + sbuf.append('0'); + sbuf.append(l_month); + sbuf.append('-'); + int l_day = x.getDate(); + if (l_day < 10) + sbuf.append('0'); + sbuf.append(l_day); + sbuf.append(' '); + int l_hours = x.getHours(); + if (l_hours < 10) + sbuf.append('0'); + sbuf.append(l_hours); + sbuf.append(':'); + int l_minutes = x.getMinutes(); + if (l_minutes < 10) + sbuf.append('0'); + sbuf.append(l_minutes); + sbuf.append(':'); + int l_seconds = x.getSeconds(); + if (l_seconds < 10) + sbuf.append('0'); + sbuf.append(l_seconds); + // Make decimal from nanos. + char[] l_decimal = {'0', '0', '0', '0', '0', '0', '0', '0', '0'}; + char[] l_nanos = Integer.toString(x.getNanos()).toCharArray(); + System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length); + sbuf.append('.'); + if (connection.haveMinimumServerVersion("7.2")) + { + sbuf.append(l_decimal, 0, 6); + } + else + { + // Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00". + sbuf.append(l_decimal, 0, 2); + } + //add timezone offset + int l_offset = -(x.getTimezoneOffset()); + int l_houros = l_offset / 60; + if (l_houros >= 0) + { + sbuf.append('+'); + } + else + { + sbuf.append('-'); + } + if (l_houros > -10 && l_houros < 10) + sbuf.append('0'); + if (l_houros >= 0) + { + sbuf.append(l_houros); + } + else + { + sbuf.append( -l_houros); + } + int l_minos = l_offset - (l_houros * 60); + if (l_minos != 0) + { + if (l_minos < 10) + sbuf.append('0'); + sbuf.append(l_minos); + } sbuf.append("'"); bind(parameterIndex, sbuf.toString(), PG_TIMESTAMPTZ); } @@ -1206,9 +1243,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme { int i; - for (i = 0 ; i < m_binds.length ; i++) { + for (i = 0 ; i < m_binds.length ; i++) + { m_binds[i] = null; - m_bindTypes[i] = null; + m_bindTypes[i] = null; } } @@ -1236,12 +1274,12 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme if (x == null) { setNull(parameterIndex, Types.OTHER); - return; + return ; } switch (targetSqlType) { case Types.INTEGER: - bind(parameterIndex, x.toString(), PG_INTEGER); + bind(parameterIndex, x.toString(), PG_INTEGER); break; case Types.TINYINT: case Types.SMALLINT: @@ -1254,10 +1292,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme if (x instanceof Boolean) bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN); else - //Note this should be fixed - //as soon as the backend correctly supports int8 type - //comparisons - bind(parameterIndex, "'"+x.toString()+"'", PG_NUMERIC); + //Note this should be fixed + //as soon as the backend correctly supports int8 type + //comparisons + bind(parameterIndex, "'" + x.toString() + "'", PG_NUMERIC); break; case Types.CHAR: case Types.VARCHAR: @@ -1311,7 +1349,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme if (x == null) { setNull(parameterIndex, Types.OTHER); - return; + return ; } if (x instanceof String) setString(parameterIndex, (String)x); @@ -1362,24 +1400,24 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme * @exception SQLException if a database-access error occurs. */ public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException - { - if (parameterIndex != 1) - throw new PSQLException ("postgresql.call.noinout"); - if (!isFunction) - throw new PSQLException ("postgresql.call.procasfunc", originalSql); - - // functionReturnType contains the user supplied value to check - // testReturn contains a modified version to make it easier to - // check the getXXX methods.. - functionReturnType = sqlType; - testReturn = sqlType; - if (functionReturnType == Types.CHAR || + { + if (parameterIndex != 1) + throw new PSQLException ("postgresql.call.noinout"); + if (!isFunction) + throw new PSQLException ("postgresql.call.procasfunc", originalSql); + + // functionReturnType contains the user supplied value to check + // testReturn contains a modified version to make it easier to + // check the getXXX methods.. + functionReturnType = sqlType; + testReturn = sqlType; + if (functionReturnType == Types.CHAR || functionReturnType == Types.LONGVARCHAR) - testReturn = Types.VARCHAR; - else if (functionReturnType == Types.FLOAT) - testReturn = Types.REAL; // changes to streamline later error checking - returnTypeSet = true; - } + testReturn = Types.VARCHAR; + else if (functionReturnType == Types.FLOAT) + testReturn = Types.REAL; // changes to streamline later error checking + returnTypeSet = true; + } /* * You must also specify the scale for numeric/decimal types: @@ -1396,9 +1434,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException - { - registerOutParameter (parameterIndex, sqlType); // ignore for now.. - } + { + registerOutParameter (parameterIndex, sqlType); // ignore for now.. + } /* * An OUT parameter may have the value of SQL NULL; wasNull @@ -1440,7 +1478,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public boolean getBoolean(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.BIT, "Boolean"); - if (callResult == null) return false; + if (callResult == null) + return false; return ((Boolean)callResult).booleanValue (); } @@ -1454,7 +1493,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public byte getByte(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.TINYINT, "Byte"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return (byte)((Integer)callResult).intValue (); } @@ -1468,10 +1508,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public short getShort(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.SMALLINT, "Short"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return (short)((Integer)callResult).intValue (); } - + /* * Get the value of an INTEGER parameter as a Java int. @@ -1483,7 +1524,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public int getInt(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.INTEGER, "Int"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return ((Integer)callResult).intValue (); } @@ -1497,7 +1539,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public long getLong(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.BIGINT, "Long"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return ((Long)callResult).longValue (); } @@ -1511,7 +1554,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public float getFloat(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.REAL, "Float"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return ((Float)callResult).floatValue (); } @@ -1525,7 +1569,8 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public double getDouble(int parameterIndex) throws SQLException { checkIndex (parameterIndex, Types.DOUBLE, "Double"); - if (callResult == null) return 0; + if (callResult == null) + return 0; return ((Double)callResult).doubleValue (); } @@ -1625,7 +1670,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme public Object getObject(int parameterIndex) throws SQLException { - checkIndex (parameterIndex); + checkIndex (parameterIndex); return callResult; } @@ -1667,9 +1712,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme if (paramIndex < 1 || paramIndex > m_binds.length) throw new PSQLException("postgresql.prep.range"); if (paramIndex == 1 && isFunction) // need to registerOut instead - throw new PSQLException ("postgresql.call.funcover"); + throw new PSQLException ("postgresql.call.funcover"); m_binds[paramIndex - 1] = s; - m_bindTypes[paramIndex - 1] = type; + m_bindTypes[paramIndex - 1] = type; } /* @@ -1694,92 +1739,101 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme bind(parameterIndex, Long.toString(x) + "::" + tablename, PG_TEXT ); } - /** + /** * this method will turn a string of the form * {? = call (?, [?,..]) } - * into the PostgreSQL format which is + * into the PostgreSQL format which is * select (?, [?, ...]) as result - * + * */ - private String modifyJdbcCall(String p_sql) throws SQLException { + private String modifyJdbcCall(String p_sql) throws SQLException + { // syntax checking is not complete only a few basics :( originalSql = p_sql; // save for error msgs.. - String l_sql = p_sql; + String l_sql = p_sql; int index = l_sql.indexOf ("="); // is implied func or proc? boolean isValid = true; - if (index != -1) { + if (index != -1) + { isFunction = true; - isValid = l_sql.indexOf ("?") < index; // ? before = + isValid = l_sql.indexOf ("?") < index; // ? before = } l_sql = l_sql.trim (); - if (l_sql.startsWith ("{") && l_sql.endsWith ("}")) { - l_sql = l_sql.substring (1, l_sql.length() -1); - } else isValid = false; - index = l_sql.indexOf ("call"); + if (l_sql.startsWith ("{") && l_sql.endsWith ("}")) + { + l_sql = l_sql.substring (1, l_sql.length() - 1); + } + else + isValid = false; + index = l_sql.indexOf ("call"); if (index == -1 || !isValid) - throw new PSQLException ("postgresql.call.malformed", + throw new PSQLException ("postgresql.call.malformed", new Object[]{l_sql, JDBC_SYNTAX}); l_sql = l_sql.replace ('{', ' '); // replace these characters l_sql = l_sql.replace ('}', ' '); l_sql = l_sql.replace (';', ' '); - + // this removes the 'call' string and also puts a hidden '?' // at the front of the line for functions, this will // allow the registerOutParameter to work correctly - // because in the source sql there was one more ? for the return - // value that is not needed by the postgres syntax. But to make - // sure that the parameter numbers are the same as in the original - // sql we add a dummy parameter in this case + // because in the source sql there was one more ? for the return + // value that is not needed by the postgres syntax. But to make + // sure that the parameter numbers are the same as in the original + // sql we add a dummy parameter in this case l_sql = (isFunction ? "?" : "") + l_sql.substring (index + 4); - + l_sql = "select " + l_sql + " as " + RESULT_COLUMN + ";"; - return l_sql; + return l_sql; } /** helperfunction for the getXXX calls to check isFunction and index == 1 */ - protected void checkIndex (int parameterIndex, int type, String getName) - throws SQLException { + protected void checkIndex (int parameterIndex, int type, String getName) + throws SQLException + { checkIndex (parameterIndex); - if (type != this.testReturn) + if (type != this.testReturn) throw new PSQLException("postgresql.call.wrongget", - new Object[]{"java.sql.Types="+testReturn, - getName, - "java.sql.Types="+type}); + new Object[]{"java.sql.Types=" + testReturn, + getName, + "java.sql.Types=" + type}); } /** helperfunction for the getXXX calls to check isFunction and index == 1 * @param parameterIndex index of getXXX (index) * check to make sure is a function and index == 1 */ - private void checkIndex (int parameterIndex) throws SQLException { + private void checkIndex (int parameterIndex) throws SQLException + { if (!isFunction) throw new PSQLException("postgresql.call.noreturntype"); if (parameterIndex != 1) throw new PSQLException("postgresql.call.noinout"); } - - public void setUseServerPrepare(boolean flag) { - m_useServerPrepare = flag; - } - public boolean isUseServerPrepare() { - return m_useServerPrepare; - } + public void setUseServerPrepare(boolean flag) + { + m_useServerPrepare = flag; + } + + public boolean isUseServerPrepare() + { + return m_useServerPrepare; + } - private static final String PG_TEXT = "text"; - private static final String PG_INTEGER = "integer"; - private static final String PG_INT2 = "int2"; - private static final String PG_INT8 = "int8"; - private static final String PG_NUMERIC = "numeric"; - private static final String PG_FLOAT = "float"; - private static final String PG_DOUBLE = "double"; - private static final String PG_BOOLEAN = "boolean"; - private static final String PG_DATE = "date"; - private static final String PG_TIME = "time"; - private static final String PG_TIMESTAMPTZ = "timestamptz"; + private static final String PG_TEXT = "text"; + private static final String PG_INTEGER = "integer"; + private static final String PG_INT2 = "int2"; + private static final String PG_INT8 = "int8"; + private static final String PG_NUMERIC = "numeric"; + private static final String PG_FLOAT = "float"; + private static final String PG_DOUBLE = "double"; + private static final String PG_BOOLEAN = "boolean"; + private static final String PG_DATE = "date"; + private static final String PG_TIME = "time"; + private static final String PG_TIMESTAMPTZ = "timestamptz"; } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java index 618ffa0df8ca56c57eae065f4253b8e2fd508129..3ddb071008d37f8131d3fe422eb1841b15c5e44e 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java @@ -6,9 +6,9 @@ import java.sql.*; import org.postgresql.Field; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.4 2002/07/26 05:29:35 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.5 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Connection interface for JDBC1. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1Connection */ public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection implements java.sql.Connection diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java index 845889ed8c87a853d3b8f3004d2af0d23042f4a1..980bf87261715aebc1fc6026774875afd75b62d7 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java @@ -5,9 +5,9 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.3 2002/07/26 05:29:35 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.4 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.ResultSet interface for JDBC1. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1ResultSet */ public class Jdbc1ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet implements java.sql.ResultSet diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java index 998e7fd5a868089a68c1e1a5c0fd8bbe4cf84e49..4c4703ead2775a63da92a7e3813fbe0d20f66139 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java @@ -4,7 +4,7 @@ public class Jdbc1ResultSetMetaData extends AbstractJdbc1ResultSetMetaData imple { public Jdbc1ResultSetMetaData(java.util.Vector rows, org.postgresql.Field[] fields) { - super(rows, fields); + super(rows, fields); } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java index f56841b3df8a0ff24b1f30d052a12f57eb765d33..2b3f521cc9a130a245a5e1a14242215c08adf04a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java @@ -3,9 +3,9 @@ package org.postgresql.jdbc1; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.2 2002/07/24 22:08:40 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.3 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Statement interface for JDBC1. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1Statement */ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement implements java.sql.Statement @@ -13,7 +13,7 @@ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement public Jdbc1Statement (Jdbc1Connection c) { - super(c); + super(c); } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java index 8faefad65ff6ae1db59023212cc168aacb57afcf..d5476161ed58d7a0b149ad9431bcba707927133b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java @@ -6,194 +6,206 @@ import java.net.ConnectException; import java.sql.*; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Connection.java,v 1.1 2002/07/23 03:59:55 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1Connection which provides the jdbc1 * methods. The real Connection class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Connection */ public abstract class AbstractJdbc2Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection { - /* - * The current type mappings - */ - protected java.util.Map typemap; - - public java.sql.Statement createStatement() throws SQLException - { - // The spec says default of TYPE_FORWARD_ONLY but everyone is used to - // using TYPE_SCROLL_INSENSITIVE - return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException - { - return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.sql.CallableStatement prepareCall(String sql) throws SQLException - { - return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.util.Map getTypeMap() throws SQLException - { - return typemap; - } - - - public void setTypeMap(java.util.Map map) throws SQLException - { - typemap = map; - } - - public void cancelQuery() throws SQLException - { - org.postgresql.PG_Stream cancelStream = null; - try { - cancelStream = new org.postgresql.PG_Stream(PG_HOST, PG_PORT); - } catch (ConnectException cex) { - // Added by Peter Mount - // 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 overides the standard internal getObject method so that we can - * check the jdbc2 type map first - */ - public Object getObject(String type, String value) throws SQLException - { - if (typemap != null) - { - SQLData d = (SQLData) typemap.get(type); - if (d != null) - { - // Handle the type (requires SQLInput & SQLOutput classes to be implemented) - throw org.postgresql.Driver.notImplemented(); - } - } - - // Default to the original method - return super.getObject(type, value); - } - - - //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)); - } + /* + * The current type mappings + */ + protected java.util.Map typemap; + + public java.sql.Statement createStatement() throws SQLException + { + // The spec says default of TYPE_FORWARD_ONLY but everyone is used to + // using TYPE_SCROLL_INSENSITIVE + return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); } + public abstract java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException; - /* - * This implemetation uses the jdbc2Types array to support the jdbc2 - * datatypes. Basically jdbc1 and jdbc2 are the same, except that - * jdbc2 adds the Array types. - */ - public int getSQLType(String pgTypeName) - { - int sqlType = Types.OTHER; // default value - for (int i = 0;i < jdbc2Types.length;i++) - { - if (pgTypeName.equals(jdbc2Types[i])) - { - sqlType = jdbc2Typei[i]; - break; - } - } - return sqlType; - } - - /* - * This table holds the org.postgresql names for the types supported. - * Any types that map to Types.OTHER (eg POINT) don't go into this table. - * They default automatically to Types.OTHER - * - * Note: This must be in the same order as below. - * - * Tip: keep these grouped together by the Types. value - */ - private static final String jdbc2Types[] = { - "int2", - "int4", "oid", - "int8", - "cash", "money", - "numeric", - "float4", - "float8", - "bpchar", "char", "char2", "char4", "char8", "char16", - "varchar", "text", "name", "filename", - "bytea", - "bool", - "date", - "time", - "abstime", "timestamp", "timestamptz", - "_bool", "_char", "_int2", "_int4", "_text", - "_oid", "_varchar", "_int8", "_float4", "_float8", - "_abstime", "_date", "_time", "_timestamp", "_numeric", - "_bytea" - }; - - /* - * This table holds the JDBC type for each entry above. - * - * Note: This must be in the same order as above - * - * Tip: keep these grouped together by the Types. value - */ - private static final int jdbc2Typei[] = { - Types.SMALLINT, - Types.INTEGER, Types.INTEGER, - Types.BIGINT, - Types.DOUBLE, Types.DOUBLE, - Types.NUMERIC, - Types.REAL, - Types.DOUBLE, - Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.BINARY, - Types.BIT, - Types.DATE, - Types.TIME, - Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY - }; + public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException + { + return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + } + + public abstract java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; + + public java.sql.CallableStatement prepareCall(String sql) throws SQLException + { + return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + } + + public abstract java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; + + public java.util.Map getTypeMap() throws SQLException + { + return typemap; + } + + + public void setTypeMap(java.util.Map map) throws SQLException + { + typemap = map; + } + + public void cancelQuery() throws SQLException + { + org.postgresql.PG_Stream cancelStream = null; + try + { + cancelStream = new org.postgresql.PG_Stream(PG_HOST, PG_PORT); + } + catch (ConnectException cex) + { + // Added by Peter Mount + // 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 overides the standard internal getObject method so that we can + * check the jdbc2 type map first + */ + public Object getObject(String type, String value) throws SQLException + { + if (typemap != null) + { + SQLData d = (SQLData) typemap.get(type); + if (d != null) + { + // Handle the type (requires SQLInput & SQLOutput classes to be implemented) + throw org.postgresql.Driver.notImplemented(); + } + } + + // Default to the original method + return super.getObject(type, value); + } + + + //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)); + } + } + + + /* + * This implemetation uses the jdbc2Types array to support the jdbc2 + * datatypes. Basically jdbc1 and jdbc2 are the same, except that + * jdbc2 adds the Array types. + */ + public int getSQLType(String pgTypeName) + { + int sqlType = Types.OTHER; // default value + for (int i = 0;i < jdbc2Types.length;i++) + { + if (pgTypeName.equals(jdbc2Types[i])) + { + sqlType = jdbc2Typei[i]; + break; + } + } + return sqlType; + } + + /* + * This table holds the org.postgresql names for the types supported. + * Any types that map to Types.OTHER (eg POINT) don't go into this table. + * They default automatically to Types.OTHER + * + * Note: This must be in the same order as below. + * + * Tip: keep these grouped together by the Types. value + */ + private static final String jdbc2Types[] = { + "int2", + "int4", "oid", + "int8", + "cash", "money", + "numeric", + "float4", + "float8", + "bpchar", "char", "char2", "char4", "char8", "char16", + "varchar", "text", "name", "filename", + "bytea", + "bool", + "date", + "time", + "abstime", "timestamp", "timestamptz", + "_bool", "_char", "_int2", "_int4", "_text", + "_oid", "_varchar", "_int8", "_float4", "_float8", + "_abstime", "_date", "_time", "_timestamp", "_numeric", + "_bytea" + }; + + /* + * This table holds the JDBC type for each entry above. + * + * Note: This must be in the same order as above + * + * Tip: keep these grouped together by the Types. value + */ + private static final int jdbc2Typei[] = { + Types.SMALLINT, + Types.INTEGER, Types.INTEGER, + Types.BIGINT, + Types.DOUBLE, Types.DOUBLE, + Types.NUMERIC, + Types.REAL, + Types.DOUBLE, + Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.BINARY, + Types.BIT, + Types.DATE, + Types.TIME, + Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP, + Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, + Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, + Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, + Types.ARRAY + }; diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java index c435406aaef0873870035167b8ac2a9dae7e08a9..6fc7f940fa9113c51ee6a96d68288936c457e6b8 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java @@ -13,7 +13,7 @@ public abstract class AbstractJdbc2DatabaseMetaData extends org.postgresql.jdbc1 public AbstractJdbc2DatabaseMetaData(AbstractJdbc2Connection conn) { - super(conn); + super(conn); } @@ -61,18 +61,18 @@ public abstract class AbstractJdbc2DatabaseMetaData extends org.postgresql.jdbc1 /* lots of unsupported stuff... */ public boolean ownUpdatesAreVisible(int type) throws SQLException { - return true; + return true; } public boolean ownDeletesAreVisible(int type) throws SQLException { - return true; + return true; } public boolean ownInsertsAreVisible(int type) throws SQLException { - // indicates that - return true; + // indicates that + return true; } public boolean othersUpdatesAreVisible(int type) throws SQLException @@ -117,10 +117,10 @@ public abstract class AbstractJdbc2DatabaseMetaData extends org.postgresql.jdbc1 * Return user defined types in a schema */ public java.sql.ResultSet getUDTs(String catalog, - String schemaPattern, - String typeNamePattern, - int[] types - ) throws SQLException + String schemaPattern, + String typeNamePattern, + int[] types + ) throws SQLException { throw org.postgresql.Driver.notImplemented(); } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java index 5d6816ad6c115fbb8a1fd477e4753c3219a7bb25..cc468ff50a13f5d5be4e25148bffd4168dcc64fd 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java @@ -15,1339 +15,1578 @@ import org.postgresql.util.PGbytea; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.6 2002/09/01 23:40:36 davec Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.7 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1 * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet */ -public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet { +public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet +{ + + //needed for updateable result set support + protected boolean updateable = false; + protected boolean doingUpdates = false; + protected boolean onInsertRow = false; + protected Hashtable updateValues = new Hashtable(); + private boolean usingOID = false; // are we using the OID for the primary key? + private Vector primaryKeys; // list of primary keys + private int numKeys = 0; + private boolean singleTable = false; + protected String tableName = null; + protected PreparedStatement updateStatement = null; + protected PreparedStatement insertStatement = null; + protected PreparedStatement deleteStatement = null; + private PreparedStatement selectStatement = null; + + + + public AbstractJdbc2ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + { + super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + + public java.net.URL getURL(int columnIndex) throws SQLException + { + return null; + } + + + public java.net.URL getURL(String columnName) throws SQLException + { + return null; + } + + + /* + * Get the value of a column in the current row as a Java object + * + *

This method will return the value of the given column as a + * Java object. The type of the Java object will be the default + * Java Object type corresponding to the column's SQL type, following + * the mapping specified in the JDBC specification. + * + *

This method may also be used to read database specific abstract + * data types. + * + * @param columnIndex the first column is 1, the second is 2... + * @return a Object holding the column value + * @exception SQLException if a database access error occurs + */ + public Object getObject(int columnIndex) throws SQLException + { + Field field; + + checkResultSet( columnIndex ); + + wasNullFlag = (this_row[columnIndex - 1] == null); + if (wasNullFlag) + return null; + + field = fields[columnIndex - 1]; + + // some fields can be null, mainly from those returned by MetaData methods + if (field == null) + { + wasNullFlag = true; + return null; + } + + switch (field.getSQLType()) + { + case Types.BIT: + return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE; + + case Types.SMALLINT: + return new Short(getShort(columnIndex)); + + case Types.INTEGER: + return new Integer(getInt(columnIndex)); + + case Types.BIGINT: + return new Long(getLong(columnIndex)); + + case Types.NUMERIC: + return getBigDecimal + (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff)); + + case Types.REAL: + return new Float(getFloat(columnIndex)); + + case Types.DOUBLE: + return new Double(getDouble(columnIndex)); + + case Types.CHAR: + case Types.VARCHAR: + return getString(columnIndex); + + case Types.DATE: + return getDate(columnIndex); + + case Types.TIME: + return getTime(columnIndex); + + case Types.TIMESTAMP: + return getTimestamp(columnIndex); + + case Types.BINARY: + case Types.VARBINARY: + return getBytes(columnIndex); + + case Types.ARRAY: + return getArray(columnIndex); + + default: + String type = field.getPGType(); + // if the backend doesn't know the type then coerce to String + if (type.equals("unknown")) + { + return getString(columnIndex); + } + else + { + return connection.getObject(field.getPGType(), getString(columnIndex)); + } + } + } + + + public boolean absolute(int index) throws SQLException + { + // index is 1-based, but internally we use 0-based indices + int internalIndex; + + if (index == 0) + throw new SQLException("Cannot move to index of 0"); + + final int rows_size = rows.size(); + + //if index<0, count from the end of the result set, but check + //to be sure that it is not beyond the first index + if (index < 0) + { + if (index >= -rows_size) + internalIndex = rows_size + index; + else + { + beforeFirst(); + return false; + } + } + else + { + //must be the case that index>0, + //find the correct place, assuming that + //the index is not too large + if (index <= rows_size) + internalIndex = index - 1; + else + { + afterLast(); + return false; + } + } + + current_row = internalIndex; + this_row = (byte[][]) rows.elementAt(internalIndex); + return true; + } + + + public void afterLast() throws SQLException + { + final int rows_size = rows.size(); + if (rows_size > 0) + current_row = rows_size; + } + + + public void beforeFirst() throws SQLException + { + if (rows.size() > 0) + current_row = -1; + } + + + public boolean first() throws SQLException + { + if (rows.size() <= 0) + return false; + + onInsertRow = false; + current_row = 0; + this_row = (byte[][]) rows.elementAt(current_row); + + rowBuffer = new byte[this_row.length][]; + System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); + + return true; + } + + + public java.sql.Array getArray(String colName) throws SQLException + { + return getArray(findColumn(colName)); + } + + + public java.sql.Array getArray(int i) throws SQLException + { + wasNullFlag = (this_row[i - 1] == null); + if (wasNullFlag) + return null; + + if (i < 1 || i > fields.length) + throw new PSQLException("postgresql.res.colrange"); + return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], (java.sql.ResultSet) this ); + } + + + public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException + { + return getBigDecimal(columnIndex, -1); + } + + + public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException + { + return getBigDecimal(findColumn(columnName)); + } + + + public Blob getBlob(String columnName) throws SQLException + { + return getBlob(findColumn(columnName)); + } - //needed for updateable result set support - protected boolean updateable = false; - protected boolean doingUpdates = false; - protected boolean onInsertRow = false; - protected Hashtable updateValues = new Hashtable(); - private boolean usingOID = false; // are we using the OID for the primary key? - private Vector primaryKeys; // list of primary keys - private int numKeys = 0; - private boolean singleTable = false; - protected String tableName = null; - protected PreparedStatement updateStatement = null; - protected PreparedStatement insertStatement = null; - protected PreparedStatement deleteStatement = null; - private PreparedStatement selectStatement = null; - - - - public AbstractJdbc2ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.net.URL getURL(int columnIndex) throws SQLException { - return null; - } - - - public java.net.URL getURL(String columnName) throws SQLException { - return null; - } - - - /* - * Get the value of a column in the current row as a Java object - * - *

This method will return the value of the given column as a - * Java object. The type of the Java object will be the default - * Java Object type corresponding to the column's SQL type, following - * the mapping specified in the JDBC specification. - * - *

This method may also be used to read database specific abstract - * data types. - * - * @param columnIndex the first column is 1, the second is 2... - * @return a Object holding the column value - * @exception SQLException if a database access error occurs - */ - public Object getObject(int columnIndex) throws SQLException { - Field field; - - checkResultSet( columnIndex ); - - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - field = fields[columnIndex - 1]; - - // some fields can be null, mainly from those returned by MetaData methods - if (field == null) { - wasNullFlag = true; - return null; - } - - switch (field.getSQLType()) { - case Types.BIT: - return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE; - - case Types.SMALLINT: - return new Short(getShort(columnIndex)); - - case Types.INTEGER: - return new Integer(getInt(columnIndex)); - - case Types.BIGINT: - return new Long(getLong(columnIndex)); - - case Types.NUMERIC: - return getBigDecimal - (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff)); - - case Types.REAL: - return new Float(getFloat(columnIndex)); - - case Types.DOUBLE: - return new Double(getDouble(columnIndex)); - - case Types.CHAR: - case Types.VARCHAR: - return getString(columnIndex); - - case Types.DATE: - return getDate(columnIndex); - - case Types.TIME: - return getTime(columnIndex); - - case Types.TIMESTAMP: - return getTimestamp(columnIndex); - - case Types.BINARY: - case Types.VARBINARY: - return getBytes(columnIndex); - - case Types.ARRAY: - return getArray(columnIndex); - default: - String type = field.getPGType(); - // if the backend doesn't know the type then coerce to String - if (type.equals("unknown")) { - return getString(columnIndex); - } - else { - return connection.getObject(field.getPGType(), getString(columnIndex)); - } - } - } + public abstract Blob getBlob(int i) throws SQLException; + + + public java.io.Reader getCharacterStream(String columnName) throws SQLException + { + return getCharacterStream(findColumn(columnName)); + } + + public java.io.Reader getCharacterStream(int i) throws SQLException + { + checkResultSet( i ); + wasNullFlag = (this_row[i - 1] == null); + if (wasNullFlag) + return null; - public boolean absolute(int index) throws SQLException { - // index is 1-based, but internally we use 0-based indices - int internalIndex; + if (((AbstractJdbc2Connection) connection).haveMinimumCompatibleVersion("7.2")) + { + //Version 7.2 supports AsciiStream for all the PG text types + //As the spec/javadoc for this method indicate this is to be used for + //large text values (i.e. LONGVARCHAR) PG doesn't have a separate + //long string datatype, but with toast the text datatype is capable of + //handling very large values. Thus the implementation ends up calling + //getString() since there is no current way to stream the value from the server + return new CharArrayReader(getString(i).toCharArray()); + } + else + { + // In 7.1 Handle as BLOBS so return the LargeObject input stream + Encoding encoding = connection.getEncoding(); + InputStream input = getBinaryStream(i); + return encoding.getDecodingReader(input); + } + } - if (index == 0) - throw new SQLException("Cannot move to index of 0"); - final int rows_size = rows.size(); + public Clob getClob(String columnName) throws SQLException + { + return getClob(findColumn(columnName)); + } - //if index<0, count from the end of the result set, but check - //to be sure that it is not beyond the first index - if (index < 0) { - if (index >= -rows_size) - internalIndex = rows_size + index; - else { - beforeFirst(); - return false; - } - } - else { - //must be the case that index>0, - //find the correct place, assuming that - //the index is not too large - if (index <= rows_size) - internalIndex = index - 1; - else { - afterLast(); - return false; - } - } - current_row = internalIndex; - this_row = (byte[][]) rows.elementAt(internalIndex); - return true; - } + public abstract Clob getClob(int i) throws SQLException; - public void afterLast() throws SQLException { - final int rows_size = rows.size(); - if (rows_size > 0) - current_row = rows_size; - } + public int getConcurrency() throws SQLException + { + if (statement == null) + return java.sql.ResultSet.CONCUR_READ_ONLY; + return statement.getResultSetConcurrency(); + } - public void beforeFirst() throws SQLException { - if (rows.size() > 0) - current_row = -1; - } + public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException + { + // If I read the specs, this should use cal only if we don't + // store the timezone, and if we do, then act just like getDate()? + // for now... + return getDate(i); + } - public boolean first() throws SQLException - { - if (rows.size() <= 0) - return false; + public Time getTime(int i, java.util.Calendar cal) throws SQLException + { + // If I read the specs, this should use cal only if we don't + // store the timezone, and if we do, then act just like getTime()? + // for now... + return getTime(i); + } - onInsertRow = false; - current_row = 0; - this_row = (byte[][]) rows.elementAt(current_row); - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); + public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException + { + // If I read the specs, this should use cal only if we don't + // store the timezone, and if we do, then act just like getDate()? + // for now... + return getTimestamp(i); + } - return true; - } + public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException + { + return getDate(findColumn(c), cal); + } - public java.sql.Array getArray(String colName) throws SQLException { - return getArray(findColumn(colName)); - } + public Time getTime(String c, java.util.Calendar cal) throws SQLException + { + return getTime(findColumn(c), cal); + } - public java.sql.Array getArray(int i) throws SQLException { - wasNullFlag = (this_row[i - 1] == null); - if (wasNullFlag) - return null; - if (i < 1 || i > fields.length) - throw new PSQLException("postgresql.res.colrange"); - return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], (java.sql.ResultSet) this ); - } + public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException + { + return getTimestamp(findColumn(c), cal); + } - public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException { - return getBigDecimal(columnIndex, -1); - } + public int getFetchDirection() throws SQLException + { + //PostgreSQL normally sends rows first->last + return java.sql.ResultSet.FETCH_FORWARD; + } - public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException { - return getBigDecimal(findColumn(columnName)); - } + public int getFetchSize() throws SQLException + { + // In this implementation we return the entire result set, so + // here return the number of rows we have. Sub-classes can return a proper + // value + return rows.size(); + } - public Blob getBlob(String columnName) throws SQLException { - return getBlob(findColumn(columnName)); - } + public Object getObject(String columnName, java.util.Map map) throws SQLException + { + return getObject(findColumn(columnName), map); + } - public abstract Blob getBlob(int i) throws SQLException; + /* + * This checks against map for the type of column i, and if found returns + * an object based on that mapping. The class must implement the SQLData + * interface. + */ + public Object getObject(int i, java.util.Map map) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - public java.io.Reader getCharacterStream(String columnName) throws SQLException { - return getCharacterStream(findColumn(columnName)); - } + public Ref getRef(String columnName) throws SQLException + { + return getRef(findColumn(columnName)); + } - public java.io.Reader getCharacterStream(int i) throws SQLException { - checkResultSet( i ); - wasNullFlag = (this_row[i - 1] == null); - if (wasNullFlag) - return null; + public Ref getRef(int i) throws SQLException + { + //The backend doesn't yet have SQL3 REF types + throw new PSQLException("postgresql.psqlnotimp"); + } - if (((AbstractJdbc2Connection) connection).haveMinimumCompatibleVersion("7.2")) { - //Version 7.2 supports AsciiStream for all the PG text types - //As the spec/javadoc for this method indicate this is to be used for - //large text values (i.e. LONGVARCHAR) PG doesn't have a separate - //long string datatype, but with toast the text datatype is capable of - //handling very large values. Thus the implementation ends up calling - //getString() since there is no current way to stream the value from the server - return new CharArrayReader(getString(i).toCharArray()); - } - else { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - Encoding encoding = connection.getEncoding(); - InputStream input = getBinaryStream(i); - return encoding.getDecodingReader(input); - } - } + public int getRow() throws SQLException + { + final int rows_size = rows.size(); - public Clob getClob(String columnName) throws SQLException { - return getClob(findColumn(columnName)); - } + if (current_row < 0 || current_row >= rows_size) + return 0; + return current_row + 1; + } - public abstract Clob getClob(int i) throws SQLException; + // This one needs some thought, as not all ResultSets come from a statement + public Statement getStatement() throws SQLException + { + return statement; + } - public int getConcurrency() throws SQLException { - if (statement == null) - return java.sql.ResultSet.CONCUR_READ_ONLY; - return statement.getResultSetConcurrency(); - } + public int getType() throws SQLException + { + // This implementation allows scrolling but is not able to + // see any changes. Sub-classes may overide this to return a more + // meaningful result. + return java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; + } - public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getDate()? - // for now... - return getDate(i); - } + public boolean isAfterLast() throws SQLException + { + final int rows_size = rows.size(); + return (current_row >= rows_size && rows_size > 0); + } - public Time getTime(int i, java.util.Calendar cal) throws SQLException { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getTime()? - // for now... - return getTime(i); - } + public boolean isBeforeFirst() throws SQLException + { + return (current_row < 0 && rows.size() > 0); + } - public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getDate()? - // for now... - return getTimestamp(i); - } + public boolean isFirst() throws SQLException + { + return (current_row == 0 && rows.size() >= 0); + } - public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException { - return getDate(findColumn(c), cal); - } + public boolean isLast() throws SQLException + { + final int rows_size = rows.size(); + return (current_row == rows_size - 1 && rows_size > 0); + } - public Time getTime(String c, java.util.Calendar cal) throws SQLException { - return getTime(findColumn(c), cal); - } + public boolean last() throws SQLException + { + final int rows_size = rows.size(); + if (rows_size <= 0) + return false; - public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException { - return getTimestamp(findColumn(c), cal); - } + current_row = rows_size - 1; + this_row = (byte[][]) rows.elementAt(current_row); + rowBuffer = new byte[this_row.length][]; + System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - public int getFetchDirection() throws SQLException { - //PostgreSQL normally sends rows first->last - return java.sql.ResultSet.FETCH_FORWARD; - } + return true; + } - public int getFetchSize() throws SQLException { - // In this implementation we return the entire result set, so - // here return the number of rows we have. Sub-classes can return a proper - // value - return rows.size(); - } + public boolean previous() throws SQLException + { + if (--current_row < 0) + return false; + this_row = (byte[][]) rows.elementAt(current_row); + System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); + return true; + } - public Object getObject(String columnName, java.util.Map map) throws SQLException { - return getObject(findColumn(columnName), map); - } + public boolean relative(int rows) throws SQLException + { + //have to add 1 since absolute expects a 1-based index + return absolute(current_row + 1 + rows); + } - /* - * This checks against map for the type of column i, and if found returns - * an object based on that mapping. The class must implement the SQLData - * interface. - */ - public Object getObject(int i, java.util.Map map) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + public void setFetchDirection(int direction) throws SQLException + { + throw new PSQLException("postgresql.psqlnotimp"); + } - public Ref getRef(String columnName) throws SQLException { - return getRef(findColumn(columnName)); - } + public void setFetchSize(int rows) throws SQLException + { + // Sub-classes should implement this as part of their cursor support + throw org.postgresql.Driver.notImplemented(); + } - public Ref getRef(int i) throws SQLException { - //The backend doesn't yet have SQL3 REF types - throw new PSQLException("postgresql.psqlnotimp"); - } + public synchronized void cancelRowUpdates() + throws SQLException + { + if (doingUpdates) + { + doingUpdates = false; + clearRowBuffer(); + } + } - public int getRow() throws SQLException { - final int rows_size = rows.size(); - if (current_row < 0 || current_row >= rows_size) - return 0; + public synchronized void deleteRow() + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - return current_row + 1; - } + if (onInsertRow) + { + throw new PSQLException( "postgresql.updateable.oninsertrow" ); + } + if (rows.size() == 0) + { + throw new PSQLException( "postgresql.updateable.emptydelete" ); + } + if (isBeforeFirst()) + { + throw new PSQLException( "postgresql.updateable.beforestartdelete" ); + } + if (isAfterLast()) + { + throw new PSQLException( "postgresql.updateable.afterlastdelete" ); + } - // This one needs some thought, as not all ResultSets come from a statement - public Statement getStatement() throws SQLException { - return statement; - } + int numKeys = primaryKeys.size(); + if ( deleteStatement == null ) + { - public int getType() throws SQLException { - // This implementation allows scrolling but is not able to - // see any changes. Sub-classes may overide this to return a more - // meaningful result. - return java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; - } + StringBuffer deleteSQL = new StringBuffer("DELETE FROM " ).append(tableName).append(" where " ); - public boolean isAfterLast() throws SQLException { - final int rows_size = rows.size(); - return (current_row >= rows_size && rows_size > 0); - } + for ( int i = 0; i < numKeys; i++ ) + { + deleteSQL.append( ((PrimaryKey) primaryKeys.get(i)).name ).append( " = ? " ); + if ( i < numKeys - 1 ) + { + deleteSQL.append( " and " ); + } + } + deleteStatement = ((java.sql.Connection) connection).prepareStatement(deleteSQL.toString()); + } + deleteStatement.clearParameters(); - public boolean isBeforeFirst() throws SQLException { - return (current_row < 0 && rows.size() > 0); - } + for ( int i = 0; i < numKeys; i++ ) + { + deleteStatement.setObject(i + 1, ((PrimaryKey) primaryKeys.get(i)).getValue()); + } - public boolean isFirst() throws SQLException { - return (current_row == 0 && rows.size() >= 0); - } + deleteStatement.executeUpdate(); + rows.removeElementAt(current_row); + } - public boolean isLast() throws SQLException { - final int rows_size = rows.size(); - return (current_row == rows_size - 1 && rows_size > 0); - } + public synchronized void insertRow() + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - public boolean last() throws SQLException { - final int rows_size = rows.size(); - if (rows_size <= 0) - return false; + if (!onInsertRow) + { + throw new PSQLException( "postgresql.updateable.notoninsertrow" ); + } + else + { - current_row = rows_size - 1; - this_row = (byte[][]) rows.elementAt(current_row); + // loop through the keys in the insertTable and create the sql statement + // we have to create the sql every time since the user could insert different + // columns each time - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); + StringBuffer insertSQL = new StringBuffer("INSERT INTO ").append(tableName).append(" ("); + StringBuffer paramSQL = new StringBuffer(") values (" ); - return true; - } + Enumeration columnNames = updateValues.keys(); + int numColumns = updateValues.size(); + for ( int i = 0; columnNames.hasMoreElements(); i++ ) + { + String columnName = (String) columnNames.nextElement(); - public boolean previous() throws SQLException { - if (--current_row < 0) - return false; - this_row = (byte[][]) rows.elementAt(current_row); - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - return true; - } + insertSQL.append( columnName ); + if ( i < numColumns - 1 ) + { + insertSQL.append(", "); + paramSQL.append("?,"); + } + else + { + paramSQL.append("?)"); + } + } - public boolean relative(int rows) throws SQLException { - //have to add 1 since absolute expects a 1-based index - return absolute(current_row + 1 + rows); - } + insertSQL.append(paramSQL.toString()); + insertStatement = ((java.sql.Connection) connection).prepareStatement(insertSQL.toString()); + Enumeration keys = updateValues.keys(); - public void setFetchDirection(int direction) throws SQLException { - throw new PSQLException("postgresql.psqlnotimp"); - } + for ( int i = 1; keys.hasMoreElements(); i++) + { + String key = (String) keys.nextElement(); + insertStatement.setObject(i, updateValues.get( key ) ); + } + insertStatement.executeUpdate(); - public void setFetchSize(int rows) throws SQLException { - // Sub-classes should implement this as part of their cursor support - throw org.postgresql.Driver.notImplemented(); - } + if ( usingOID ) + { + // we have to get the last inserted OID and put it in the resultset + long insertedOID = ((AbstractJdbc2Statement) insertStatement).getLastOID(); - public synchronized void cancelRowUpdates() throws SQLException - { - if (doingUpdates) - { - doingUpdates = false; + updateValues.put("oid", new Long(insertedOID) ); - clearRowBuffer(); - } - } + } + // update the underlying row to the new inserted data + updateRowBuffer(); - public synchronized void deleteRow() throws SQLException - { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + rows.addElement(rowBuffer); - if (onInsertRow) { - throw new PSQLException( "postgresql.updateable.oninsertrow" ); - } + // we should now reflect the current data in this_row + // that way getXXX will get the newly inserted data + this_row = rowBuffer; - if (rows.size() == 0) { - throw new PSQLException( "postgresql.updateable.emptydelete" ); - } - if (isBeforeFirst()) { - throw new PSQLException( "postgresql.updateable.beforestartdelete" ); - } - if (isAfterLast()) { - throw new PSQLException( "postgresql.updateable.afterlastdelete" ); - } + // need to clear this in case of another insert + clearRowBuffer(); - int numKeys = primaryKeys.size(); - if ( deleteStatement == null ) { + } + } - StringBuffer deleteSQL = new StringBuffer("DELETE FROM " ).append(tableName).append(" where " ); + public synchronized void moveToCurrentRow() + throws SQLException + { + if (!updateable) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - for ( int i = 0; i < numKeys; i++ ) { - deleteSQL.append( ((PrimaryKey) primaryKeys.get(i)).name ).append( " = ? " ); - if ( i < numKeys - 1 ) { - deleteSQL.append( " and " ); - } - } + this_row = (byte[][]) rows.elementAt(current_row); - deleteStatement = ((java.sql.Connection) connection).prepareStatement(deleteSQL.toString()); - } - deleteStatement.clearParameters(); + rowBuffer = new byte[this_row.length][]; + System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - for ( int i = 0; i < numKeys; i++ ) { - deleteStatement.setObject(i + 1, ((PrimaryKey) primaryKeys.get(i)).getValue()); - } + onInsertRow = false; + doingUpdates = false; + } - deleteStatement.executeUpdate(); + public synchronized void moveToInsertRow() + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - rows.removeElementAt(current_row); - } + if (insertStatement != null) + { + insertStatement = null; + } - public synchronized void insertRow() throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + // make sure the underlying data is null + clearRowBuffer(); - if (!onInsertRow) { - throw new PSQLException( "postgresql.updateable.notoninsertrow" ); - } - else { + onInsertRow = true; + doingUpdates = false; - // loop through the keys in the insertTable and create the sql statement - // we have to create the sql every time since the user could insert different - // columns each time + } - StringBuffer insertSQL = new StringBuffer("INSERT INTO ").append(tableName).append(" ("); - StringBuffer paramSQL = new StringBuffer(") values (" ); - Enumeration columnNames = updateValues.keys(); - int numColumns = updateValues.size(); + private synchronized void clearRowBuffer() + throws SQLException + { + // rowBuffer is the temporary storage for the row + rowBuffer = new byte[fields.length][]; - for ( int i = 0; columnNames.hasMoreElements(); i++ ) { - String columnName = (String) columnNames.nextElement(); + // clear the updateValues hashTable for the next set of updates + updateValues.clear(); - insertSQL.append( columnName ); - if ( i < numColumns - 1 ) { - insertSQL.append(", "); - paramSQL.append("?,"); - } - else { - paramSQL.append("?)"); - } + } - } - insertSQL.append(paramSQL.toString()); - insertStatement = ((java.sql.Connection) connection).prepareStatement(insertSQL.toString()); + public boolean rowDeleted() throws SQLException + { + // only sub-classes implement CONCURuPDATEABLE + throw Driver.notImplemented(); + } - Enumeration keys = updateValues.keys(); - for ( int i = 1; keys.hasMoreElements(); i++) { - String key = (String) keys.nextElement(); - insertStatement.setObject(i, updateValues.get( key ) ); - } + public boolean rowInserted() throws SQLException + { + // only sub-classes implement CONCURuPDATEABLE + throw Driver.notImplemented(); + } - insertStatement.executeUpdate(); - if ( usingOID ) { - // we have to get the last inserted OID and put it in the resultset + public boolean rowUpdated() throws SQLException + { + // only sub-classes implement CONCURuPDATEABLE + throw Driver.notImplemented(); + } - long insertedOID = ((AbstractJdbc2Statement) insertStatement).getLastOID(); - updateValues.put("oid", new Long(insertedOID) ); + public synchronized void updateAsciiStream(int columnIndex, + java.io.InputStream x, + int length + ) + throws SQLException + { - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - // update the underlying row to the new inserted data - updateRowBuffer(); + byte[] theData = null; - rows.addElement(rowBuffer); + try + { + x.read(theData, 0, length); + } + catch (NullPointerException ex ) + { + throw new PSQLException("postgresql.updateable.inputstream"); + } + catch (IOException ie) + { + throw new PSQLException("postgresql.updateable.ioerror" + ie); + } - // we should now reflect the current data in this_row - // that way getXXX will get the newly inserted data - this_row = rowBuffer; + doingUpdates = !onInsertRow; - // need to clear this in case of another insert - clearRowBuffer(); + updateValues.put( fields[columnIndex - 1].getName(), theData ); + } - } - } + public synchronized void updateBigDecimal(int columnIndex, + java.math.BigDecimal x ) + throws SQLException + { - public synchronized void moveToCurrentRow() throws SQLException { - if (!updateable) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - this_row = (byte[][]) rows.elementAt(current_row); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); + } - onInsertRow = false; - doingUpdates = false; - } + public synchronized void updateBinaryStream(int columnIndex, + java.io.InputStream x, + int length + ) + throws SQLException + { - public synchronized void moveToInsertRow() throws SQLException - { - if ( !isUpdateable() ) - { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - if (insertStatement != null) - { - insertStatement = null; - } + byte[] theData = null; + try + { + x.read(theData, 0, length); - // make sure the underlying data is null - clearRowBuffer(); + } + catch ( NullPointerException ex ) + { + throw new PSQLException("postgresql.updateable.inputstream"); + } + catch (IOException ie) + { + throw new PSQLException("postgresql.updateable.ioerror" + ie); + } - onInsertRow = true; - doingUpdates = false; + doingUpdates = !onInsertRow; - } + updateValues.put( fields[columnIndex - 1].getName(), theData ); + } - private synchronized void clearRowBuffer() throws SQLException - { - // rowBuffer is the temporary storage for the row - rowBuffer = new byte[fields.length][]; - // clear the updateValues hashTable for the next set of updates - updateValues.clear(); + public synchronized void updateBoolean(int columnIndex, boolean x) + throws SQLException + { - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } + if ( Driver.logDebug ) + Driver.debug("updating boolean " + fields[columnIndex - 1].getName() + "=" + x); - public boolean rowDeleted() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); - } + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), new Boolean(x) ); + } - public boolean rowInserted() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); - } + public synchronized void updateByte(int columnIndex, byte x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - public boolean rowUpdated() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); - } + doingUpdates = true; + updateValues.put( fields[columnIndex - 1].getName(), String.valueOf(x) ); + } - public synchronized void updateAsciiStream(int columnIndex, - java.io.InputStream x, - int length - ) throws SQLException { + public synchronized void updateBytes(int columnIndex, byte[] x) + throws SQLException + { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - byte[] theData = null; + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); - try { - x.read(theData, 0, length); - } - catch (NullPointerException ex ) { - throw new PSQLException("postgresql.updateable.inputstream"); - } - catch (IOException ie) { - throw new PSQLException("postgresql.updateable.ioerror" + ie); - } + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), theData ); + public synchronized void updateCharacterStream(int columnIndex, + java.io.Reader x, + int length + ) + throws SQLException + { - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } + char[] theData = null; - public synchronized void updateBigDecimal(int columnIndex, - java.math.BigDecimal x ) - throws SQLException { + try + { + x.read(theData, 0, length); - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + } + catch (NullPointerException ex) + { + throw new PSQLException("postgresql.updateable.inputstream"); + } + catch (IOException ie) + { + throw new PSQLException("postgresql.updateable.ioerror" + ie); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), theData); - } + } - public synchronized void updateBinaryStream(int columnIndex, - java.io.InputStream x, - int length - ) throws SQLException { + public synchronized void updateDate(int columnIndex, java.sql.Date x) + throws SQLException + { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - byte[] theData = null; + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); + } - try { - x.read(theData, 0, length); - } - catch ( NullPointerException ex ) { - throw new PSQLException("postgresql.updateable.inputstream"); - } - catch (IOException ie) { - throw new PSQLException("postgresql.updateable.ioerror" + ie); - } + public synchronized void updateDouble(int columnIndex, double x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - doingUpdates = !onInsertRow; + if ( Driver.logDebug ) + Driver.debug("updating double " + fields[columnIndex - 1].getName() + "=" + x); - updateValues.put( fields[columnIndex - 1].getName(), theData ); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), new Double(x) ); - } + } - public synchronized void updateBoolean(int columnIndex, boolean x) throws SQLException { + public synchronized void updateFloat(int columnIndex, float x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + if ( Driver.logDebug ) + Driver.debug("updating float " + fields[columnIndex - 1].getName() + "=" + x); - if ( Driver.logDebug ) Driver.debug("updating boolean " + fields[columnIndex - 1].getName() + "=" + x); + doingUpdates = !onInsertRow; - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), new Boolean(x) ); + updateValues.put( fields[columnIndex - 1].getName(), new Float(x) ); - } + } - public synchronized void updateByte(int columnIndex, byte x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + public synchronized void updateInt(int columnIndex, int x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - doingUpdates = true; - updateValues.put( fields[columnIndex - 1].getName(), String.valueOf(x) ); - } + if ( Driver.logDebug ) + Driver.debug("updating int " + fields[columnIndex - 1].getName() + "=" + x); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), new Integer(x) ); - public synchronized void updateBytes(int columnIndex, byte[] x) throws SQLException { + } - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); + public synchronized void updateLong(int columnIndex, long x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - } + if ( Driver.logDebug ) + Driver.debug("updating long " + fields[columnIndex - 1].getName() + "=" + x); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), new Long(x) ); - public synchronized void updateCharacterStream(int columnIndex, - java.io.Reader x, - int length - ) throws SQLException { + } - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - char[] theData = null; + public synchronized void updateNull(int columnIndex) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - try { - x.read(theData, 0, length); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), null); - } - catch (NullPointerException ex) { - throw new PSQLException("postgresql.updateable.inputstream"); - } - catch (IOException ie) { - throw new PSQLException("postgresql.updateable.ioerror" + ie); - } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), theData); + } - } + public synchronized void updateObject(int columnIndex, Object x) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - public synchronized void updateDate(int columnIndex, java.sql.Date x) throws SQLException { + if ( Driver.logDebug ) + Driver.debug("updating object " + fields[columnIndex - 1].getName() + " = " + x); - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); - } + public synchronized void updateObject(int columnIndex, Object x, int scale) + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } - public synchronized void updateDouble(int columnIndex, double x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + this.updateObject(columnIndex, x); - if ( Driver.logDebug ) Driver.debug("updating double " + fields[columnIndex - 1].getName() + "=" + x); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), new Double(x) ); - } + public void refreshRow() throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } + try + { + StringBuffer selectSQL = new StringBuffer( "select "); - public synchronized void updateFloat(int columnIndex, float x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + final int numColumns = java.lang.reflect.Array.getLength(fields); - if ( Driver.logDebug ) Driver.debug("updating float " + fields[columnIndex - 1].getName() + "=" + x); + for (int i = 0; i < numColumns; i++ ) + { - doingUpdates = !onInsertRow; + selectSQL.append( fields[i].getName() ); - updateValues.put( fields[columnIndex - 1].getName(), new Float(x) ); + if ( i < numColumns - 1 ) + { - } + selectSQL.append(", "); + } + } + selectSQL.append(" from " ).append(tableName).append(" where "); - public synchronized void updateInt(int columnIndex, int x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + int numKeys = primaryKeys.size(); - if ( Driver.logDebug ) Driver.debug("updating int " + fields[columnIndex - 1].getName() + "=" + x); + for ( int i = 0; i < numKeys; i++ ) + { - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), new Integer(x) ); + PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); + selectSQL.append(primaryKey.name).append("= ?"); - } + if ( i < numKeys - 1 ) + { + selectSQL.append(" and "); + } + } + if ( Driver.logDebug ) + Driver.debug("selecting " + selectSQL.toString()); + selectStatement = ((java.sql.Connection) connection).prepareStatement(selectSQL.toString()); - public synchronized void updateLong(int columnIndex, long x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + for ( int j = 0, i = 1; j < numKeys; j++, i++) + { + selectStatement.setObject( i, ((PrimaryKey) primaryKeys.get(j)).getValue() ); + } - if ( Driver.logDebug ) Driver.debug("updating long " + fields[columnIndex - 1].getName() + "=" + x); + AbstractJdbc2ResultSet rs = (AbstractJdbc2ResultSet) selectStatement.executeQuery(); - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), new Long(x) ); + if ( rs.first() ) + { + rowBuffer = rs.rowBuffer; + } - } + rows.setElementAt( rowBuffer, current_row ); + if ( Driver.logDebug ) + Driver.debug("done updates"); + rs.close(); + selectStatement.close(); + selectStatement = null; - public synchronized void updateNull(int columnIndex) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + } + catch (Exception e) + { + if ( Driver.logDebug ) + Driver.debug(e.getClass().getName() + e); + throw new SQLException( e.getMessage() ); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), null); + } - } + public synchronized void updateRow() + throws SQLException + { + if ( !isUpdateable() ) + { + throw new PSQLException( "postgresql.updateable.notupdateable" ); + } + if (doingUpdates) + { - public synchronized void updateObject(int columnIndex, Object x) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + try + { - if ( Driver.logDebug ) Driver.debug("updating object " + fields[columnIndex - 1].getName() + " = " + x); + StringBuffer updateSQL = new StringBuffer("UPDATE " + tableName + " SET "); - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); - } + int numColumns = updateValues.size(); + Enumeration columns = updateValues.keys(); + for (int i = 0; columns.hasMoreElements(); i++ ) + { - public synchronized void updateObject(int columnIndex, Object x, int scale) throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + String column = (String) columns.nextElement(); + updateSQL.append( column + "= ?"); - this.updateObject(columnIndex, x); + if ( i < numColumns - 1 ) + { - } + updateSQL.append(", "); + } + } + updateSQL.append( " WHERE " ); - public void refreshRow() throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + int numKeys = primaryKeys.size(); - try { - StringBuffer selectSQL = new StringBuffer( "select "); + for ( int i = 0; i < numKeys; i++ ) + { - final int numColumns = java.lang.reflect.Array.getLength(fields); + PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); + updateSQL.append(primaryKey.name).append("= ?"); - for (int i = 0; i < numColumns; i++ ) { + if ( i < numKeys - 1 ) + { + updateSQL.append(" and "); + } + } + if ( Driver.logDebug ) + Driver.debug("updating " + updateSQL.toString()); + updateStatement = ((java.sql.Connection) connection).prepareStatement(updateSQL.toString()); - selectSQL.append( fields[i].getName() ); + int i = 0; + Iterator iterator = updateValues.values().iterator(); + for (; iterator.hasNext(); i++) + { + updateStatement.setObject( i + 1, iterator.next() ); - if ( i < numColumns - 1 ) { + } + for ( int j = 0; j < numKeys; j++, i++) + { + updateStatement.setObject( i + 1, ((PrimaryKey) primaryKeys.get(j)).getValue() ); + } - selectSQL.append(", "); - } + updateStatement.executeUpdate(); + updateStatement.close(); - } - selectSQL.append(" from " ).append(tableName).append(" where "); + updateStatement = null; + updateRowBuffer(); - int numKeys = primaryKeys.size(); - for ( int i = 0; i < numKeys; i++ ) { + if ( Driver.logDebug ) + Driver.debug("copying data"); + System.arraycopy(rowBuffer, 0, this_row, 0, rowBuffer.length); - PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); - selectSQL.append(primaryKey.name).append("= ?"); + rows.setElementAt( rowBuffer, current_row ); + if ( Driver.logDebug ) + Driver.debug("done updates"); - if ( i < numKeys - 1 ) { - selectSQL.append(" and "); - } - } - if ( Driver.logDebug ) Driver.debug("selecting " + selectSQL.toString()); - selectStatement = ((java.sql.Connection) connection).prepareStatement(selectSQL.toString()); + doingUpdates = false; + } + catch (Exception e) + { + if ( Driver.logDebug ) + Driver.debug(e.getClass().getName() + e); + throw new SQLException( e.getMessage() ); + } + } - for ( int j = 0, i = 1; j < numKeys; j++, i++) { - selectStatement.setObject( i, ((PrimaryKey) primaryKeys.get(j)).getValue() ); - } + } - AbstractJdbc2ResultSet rs = (AbstractJdbc2ResultSet) selectStatement.executeQuery(); - if ( rs.first() ) { - rowBuffer = rs.rowBuffer; - } + public synchronized void updateShort(int columnIndex, short x) + throws SQLException + { + if ( Driver.logDebug ) + Driver.debug("in update Short " + fields[columnIndex - 1].getName() + " = " + x); - rows.setElementAt( rowBuffer, current_row ); - if ( Driver.logDebug ) Driver.debug("done updates"); - rs.close(); - selectStatement.close(); - selectStatement = null; + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), new Short(x) ); - } - catch (Exception e) { - if ( Driver.logDebug ) Driver.debug(e.getClass().getName() + e); - throw new SQLException( e.getMessage() ); - } + } - } + public synchronized void updateString(int columnIndex, String x) + throws SQLException + { + if ( Driver.logDebug ) + Driver.debug("in update String " + fields[columnIndex - 1].getName() + " = " + x); - public synchronized void updateRow() throws SQLException { - if ( !isUpdateable() ) { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); - if (doingUpdates) { + } - try { - StringBuffer updateSQL = new StringBuffer("UPDATE " + tableName + " SET "); + public synchronized void updateTime(int columnIndex, Time x) + throws SQLException + { + if ( Driver.logDebug ) + Driver.debug("in update Time " + fields[columnIndex - 1].getName() + " = " + x); - int numColumns = updateValues.size(); - Enumeration columns = updateValues.keys(); - for (int i = 0; columns.hasMoreElements(); i++ ) { + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); - String column = (String) columns.nextElement(); - updateSQL.append( column + "= ?"); + } - if ( i < numColumns - 1 ) { - updateSQL.append(", "); - } + public synchronized void updateTimestamp(int columnIndex, Timestamp x) + throws SQLException + { + if ( Driver.logDebug ) + Driver.debug("updating Timestamp " + fields[columnIndex - 1].getName() + " = " + x); - } - updateSQL.append( " WHERE " ); + doingUpdates = !onInsertRow; + updateValues.put( fields[columnIndex - 1].getName(), x ); - int numKeys = primaryKeys.size(); - for ( int i = 0; i < numKeys; i++ ) { + } - PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); - updateSQL.append(primaryKey.name).append("= ?"); - if ( i < numKeys - 1 ) { - updateSQL.append(" and "); - } - } - if ( Driver.logDebug ) Driver.debug("updating " + updateSQL.toString()); - updateStatement = ((java.sql.Connection) connection).prepareStatement(updateSQL.toString()); + public synchronized void updateNull(String columnName) + throws SQLException + { + updateNull(findColumn(columnName)); + } - int i = 0; - Iterator iterator = updateValues.values().iterator(); - for (; iterator.hasNext(); i++) { - updateStatement.setObject( i + 1, iterator.next() ); - } - for ( int j = 0; j < numKeys; j++, i++) { - updateStatement.setObject( i + 1, ((PrimaryKey) primaryKeys.get(j)).getValue() ); - } + public synchronized void updateBoolean(String columnName, boolean x) + throws SQLException + { + updateBoolean(findColumn(columnName), x); + } - updateStatement.executeUpdate(); - updateStatement.close(); - updateStatement = null; - updateRowBuffer(); + public synchronized void updateByte(String columnName, byte x) + throws SQLException + { + updateByte(findColumn(columnName), x); + } - if ( Driver.logDebug ) Driver.debug("copying data"); - System.arraycopy(rowBuffer, 0, this_row, 0, rowBuffer.length); + public synchronized void updateShort(String columnName, short x) + throws SQLException + { + updateShort(findColumn(columnName), x); + } - rows.setElementAt( rowBuffer, current_row ); - if ( Driver.logDebug ) Driver.debug("done updates"); - doingUpdates = false; - } - catch (Exception e) { - if ( Driver.logDebug ) Driver.debug(e.getClass().getName() + e); - throw new SQLException( e.getMessage() ); - } + public synchronized void updateInt(String columnName, int x) + throws SQLException + { + updateInt(findColumn(columnName), x); + } - } - } + public synchronized void updateLong(String columnName, long x) + throws SQLException + { + updateLong(findColumn(columnName), x); + } - public synchronized void updateShort(int columnIndex, short x) throws SQLException { - if ( Driver.logDebug ) Driver.debug("in update Short " + fields[columnIndex - 1].getName() + " = " + x); + public synchronized void updateFloat(String columnName, float x) + throws SQLException + { + updateFloat(findColumn(columnName), x); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), new Short(x) ); + public synchronized void updateDouble(String columnName, double x) + throws SQLException + { + updateDouble(findColumn(columnName), x); + } - } + public synchronized void updateBigDecimal(String columnName, BigDecimal x) + throws SQLException + { + updateBigDecimal(findColumn(columnName), x); + } - public synchronized void updateString(int columnIndex, String x) throws SQLException { - if ( Driver.logDebug ) Driver.debug("in update String " + fields[columnIndex - 1].getName() + " = " + x); - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); + public synchronized void updateString(String columnName, String x) + throws SQLException + { + updateString(findColumn(columnName), x); + } - } + public synchronized void updateBytes(String columnName, byte x[]) + throws SQLException + { + updateBytes(findColumn(columnName), x); + } - public synchronized void updateTime(int columnIndex, Time x) throws SQLException { - if ( Driver.logDebug ) Driver.debug("in update Time " + fields[columnIndex - 1].getName() + " = " + x); + public synchronized void updateDate(String columnName, java.sql.Date x) + throws SQLException + { + updateDate(findColumn(columnName), x); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); - } + public synchronized void updateTime(String columnName, java.sql.Time x) + throws SQLException + { + updateTime(findColumn(columnName), x); + } - public synchronized void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { - if ( Driver.logDebug ) Driver.debug("updating Timestamp " + fields[columnIndex - 1].getName() + " = " + x); + public synchronized void updateTimestamp(String columnName, java.sql.Timestamp x) + throws SQLException + { + updateTimestamp(findColumn(columnName), x); + } - doingUpdates = !onInsertRow; - updateValues.put( fields[columnIndex - 1].getName(), x ); + public synchronized void updateAsciiStream( + String columnName, + java.io.InputStream x, + int length) + throws SQLException + { + updateAsciiStream(findColumn(columnName), x, length); + } - } + public synchronized void updateBinaryStream( + String columnName, + java.io.InputStream x, + int length) + throws SQLException + { + updateBinaryStream(findColumn(columnName), x, length); + } - public synchronized void updateNull(String columnName) throws SQLException { - updateNull(findColumn(columnName)); - } + public synchronized void updateCharacterStream( + String columnName, + java.io.Reader reader, + int length) + throws SQLException + { + updateCharacterStream(findColumn(columnName), reader, length); + } - public synchronized void updateBoolean(String columnName, boolean x) throws SQLException { - updateBoolean(findColumn(columnName), x); - } + public synchronized void updateObject(String columnName, Object x, int scale) + throws SQLException + { + updateObject(findColumn(columnName), x); + } - public synchronized void updateByte(String columnName, byte x) throws SQLException { - updateByte(findColumn(columnName), x); - } + public synchronized void updateObject(String columnName, Object x) + throws SQLException + { + updateObject(findColumn(columnName), x); + } - public synchronized void updateShort(String columnName, short x) throws SQLException { - updateShort(findColumn(columnName), x); - } + private int _findColumn( String columnName ) + { + int i; - public synchronized void updateInt(String columnName, int x) throws SQLException { - updateInt(findColumn(columnName), x); - } + final int flen = fields.length; + for (i = 0; i < flen; ++i) + { + if (fields[i].getName().equalsIgnoreCase(columnName)) + { + return (i + 1); + } + } + return -1; + } - public synchronized void updateLong(String columnName, long x) throws SQLException { - updateLong(findColumn(columnName), x); - } + /** + * Is this ResultSet updateable? + */ + boolean isUpdateable() throws SQLException + { - public synchronized void updateFloat(String columnName, float x) throws SQLException { - updateFloat(findColumn(columnName), x); - } + if (updateable) + return true; + if ( Driver.logDebug ) + Driver.debug("checking if rs is updateable"); - public synchronized void updateDouble(String columnName, double x) throws SQLException { - updateDouble(findColumn(columnName), x); - } + parseQuery(); + if ( singleTable == false ) + { + if ( Driver.logDebug ) + Driver.debug("not a single table"); + return false; + } - public synchronized void updateBigDecimal(String columnName, BigDecimal x) - throws SQLException { - updateBigDecimal(findColumn(columnName), x); - } + if ( Driver.logDebug ) + Driver.debug("getting primary keys"); + // + // Contains the primary key? + // - public synchronized void updateString(String columnName, String x) throws SQLException { - updateString(findColumn(columnName), x); - } + primaryKeys = new Vector(); + // this is not stricty jdbc spec, but it will make things much faster if used + // the user has to select oid, * from table and then we will just use oid - public synchronized void updateBytes(String columnName, byte x[]) throws SQLException { - updateBytes(findColumn(columnName), x); - } + usingOID = false; + int oidIndex = _findColumn( "oid" ); + int i = 0; - public synchronized void updateDate(String columnName, java.sql.Date x) - throws SQLException { - updateDate(findColumn(columnName), x); - } + // if we find the oid then just use it + + if ( oidIndex > 0 ) + { + i++; + primaryKeys.add( new PrimaryKey( oidIndex, "oid" ) ); + usingOID = true; + } + else + { + // otherwise go and get the primary keys and create a hashtable of keys + java.sql.ResultSet rs = ((java.sql.Connection) connection).getMetaData().getPrimaryKeys("", "", tableName); + + + for (; rs.next(); i++ ) + { + String columnName = rs.getString(4); // get the columnName + + int index = findColumn( columnName ); + + if ( index > 0 ) + { + primaryKeys.add( new PrimaryKey(index, columnName ) ); // get the primary key information + } + } + + rs.close(); + } + + numKeys = primaryKeys.size(); + + if ( Driver.logDebug ) + Driver.debug( "no of keys=" + i ); - public synchronized void updateTime(String columnName, java.sql.Time x) - throws SQLException { - updateTime(findColumn(columnName), x); - } - - - public synchronized void updateTimestamp(String columnName, java.sql.Timestamp x) - throws SQLException { - updateTimestamp(findColumn(columnName), x); - } - - - public synchronized void updateAsciiStream( - String columnName, - java.io.InputStream x, - int length) - throws SQLException { - updateAsciiStream(findColumn(columnName), x, length); - } - - - public synchronized void updateBinaryStream( - String columnName, - java.io.InputStream x, - int length) - throws SQLException { - updateBinaryStream(findColumn(columnName), x, length); - } - - - public synchronized void updateCharacterStream( - String columnName, - java.io.Reader reader, - int length) - throws SQLException { - updateCharacterStream(findColumn(columnName), reader, length); - } - - - public synchronized void updateObject(String columnName, Object x, int scale) - throws SQLException { - updateObject(findColumn(columnName), x); - } - - - public synchronized void updateObject(String columnName, Object x) throws SQLException { - updateObject(findColumn(columnName), x); - } - - - private int _findColumn( String columnName ) { - int i; - - final int flen = fields.length; - for (i = 0; i < flen; ++i) { - if (fields[i].getName().equalsIgnoreCase(columnName)) { - return (i + 1); - } - } - return -1; - } - - - /** - * Is this ResultSet updateable? - */ - - boolean isUpdateable() throws SQLException - { - - if (updateable) return true; - - if ( Driver.logDebug ) Driver.debug("checking if rs is updateable"); - - parseQuery(); - - if ( singleTable == false ) { - if ( Driver.logDebug ) Driver.debug("not a single table"); - return false; - } - - if ( Driver.logDebug ) Driver.debug("getting primary keys"); - - // - // Contains the primary key? - // - - primaryKeys = new Vector(); - - // this is not stricty jdbc spec, but it will make things much faster if used - // the user has to select oid, * from table and then we will just use oid - - - usingOID = false; - int oidIndex = _findColumn( "oid" ); - int i = 0; - - - // if we find the oid then just use it - - if ( oidIndex > 0 ) { - i++; - primaryKeys.add( new PrimaryKey( oidIndex, "oid" ) ); - usingOID = true; - } - else { - // otherwise go and get the primary keys and create a hashtable of keys - java.sql.ResultSet rs = ((java.sql.Connection) connection).getMetaData().getPrimaryKeys("", "", tableName); - - - for (; rs.next(); i++ ) { - String columnName = rs.getString(4); // get the columnName - - int index = findColumn( columnName ); - - if ( index > 0 ) { - primaryKeys.add( new PrimaryKey(index, columnName ) ); // get the primary key information - } - } - - rs.close(); - } - - numKeys = primaryKeys.size(); - - if ( Driver.logDebug ) Driver.debug( "no of keys=" + i ); - - if ( i < 1 ) { - throw new SQLException("No Primary Keys"); - } - - updateable = primaryKeys.size() > 0; - - if ( Driver.logDebug ) Driver.debug( "checking primary key " + updateable ); - - return updateable; - } - - - public void parseQuery() { - String[] l_sqlFragments = ((AbstractJdbc2Statement)statement).getSqlFragments(); - String l_sql = l_sqlFragments[0]; - StringTokenizer st = new StringTokenizer(l_sql, " \r\t"); - boolean tableFound = false, tablesChecked = false; - String name = ""; - - singleTable = true; - - while ( !tableFound && !tablesChecked && st.hasMoreTokens() ) { - name = st.nextToken(); - if ( !tableFound ) { - if (name.toLowerCase().equals("from")) { - tableName = st.nextToken(); - tableFound = true; - } - } - else { - tablesChecked = true; - // if the very next token is , then there are multiple tables - singleTable = !name.equalsIgnoreCase(","); - } - } - } - - - private void updateRowBuffer() throws SQLException { - - Enumeration columns = updateValues.keys(); - - while ( columns.hasMoreElements() ) { - String columnName = (String) columns.nextElement(); - int columnIndex = _findColumn( columnName ) - 1; - - switch ( connection.getSQLType( fields[columnIndex].getPGType() ) ) { - - case Types.DECIMAL: - case Types.BIGINT: - case Types.DOUBLE: - case Types.BIT: - case Types.VARCHAR: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - case Types.SMALLINT: - case Types.FLOAT: - case Types.INTEGER: - case Types.CHAR: - case Types.NUMERIC: - case Types.REAL: - case Types.TINYINT: - - try { - rowBuffer[columnIndex] = String.valueOf( updateValues.get( columnName ) ).getBytes(connection.getEncoding().name() ); - } - catch ( UnsupportedEncodingException ex) { - throw new SQLException("Unsupported Encoding " + connection.getEncoding().name()); - } - - case Types.NULL: - continue; - - default: - rowBuffer[columnIndex] = (byte[]) updateValues.get( columnName ); - } - - } - } - - - public void setStatement(Statement statement) { - this.statement = statement; - } - - - private class PrimaryKey { - int index; // where in the result set is this primaryKey - String name; // what is the columnName of this primary Key - - PrimaryKey( int index, String name) { - this.index = index; - this.name = name; - } - Object getValue() throws SQLException { - return getObject(index); - } - }; + if ( i < 1 ) + { + throw new SQLException("No Primary Keys"); + } + + updateable = primaryKeys.size() > 0; + + if ( Driver.logDebug ) + Driver.debug( "checking primary key " + updateable ); + + return updateable; + } + + + public void parseQuery() + { + String[] l_sqlFragments = ((AbstractJdbc2Statement)statement).getSqlFragments(); + String l_sql = l_sqlFragments[0]; + StringTokenizer st = new StringTokenizer(l_sql, " \r\t"); + boolean tableFound = false, tablesChecked = false; + String name = ""; + + singleTable = true; + + while ( !tableFound && !tablesChecked && st.hasMoreTokens() ) + { + name = st.nextToken(); + if ( !tableFound ) + { + if (name.toLowerCase().equals("from")) + { + tableName = st.nextToken(); + tableFound = true; + } + } + else + { + tablesChecked = true; + // if the very next token is , then there are multiple tables + singleTable = !name.equalsIgnoreCase(","); + } + } + } + + + private void updateRowBuffer() throws SQLException + { + + Enumeration columns = updateValues.keys(); + + while ( columns.hasMoreElements() ) + { + String columnName = (String) columns.nextElement(); + int columnIndex = _findColumn( columnName ) - 1; + + switch ( connection.getSQLType( fields[columnIndex].getPGType() ) ) + { + + case Types.DECIMAL: + case Types.BIGINT: + case Types.DOUBLE: + case Types.BIT: + case Types.VARCHAR: + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + case Types.SMALLINT: + case Types.FLOAT: + case Types.INTEGER: + case Types.CHAR: + case Types.NUMERIC: + case Types.REAL: + case Types.TINYINT: + + try + { + rowBuffer[columnIndex] = String.valueOf( updateValues.get( columnName ) ).getBytes(connection.getEncoding().name() ); + } + catch ( UnsupportedEncodingException ex) + { + throw new SQLException("Unsupported Encoding " + connection.getEncoding().name()); + } + + case Types.NULL: + continue; + + default: + rowBuffer[columnIndex] = (byte[]) updateValues.get( columnName ); + } + + } + } + + + public void setStatement(Statement statement) + { + this.statement = statement; + } + + + private class PrimaryKey + { + int index; // where in the result set is this primaryKey + String name; // what is the columnName of this primary Key + + PrimaryKey( int index, String name) + { + this.index = index; + this.name = name; + } + Object getValue() throws SQLException + { + return getObject(index); + } + }; diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSetMetaData.java index c64461607adca27dff0fd5a17faa06ac6c17ccb1..667af198a3072e2f540248dcb6fbd25f6887fc49 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSetMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSetMetaData.java @@ -19,7 +19,7 @@ public abstract class AbstractJdbc2ResultSetMetaData extends org.postgresql.jdbc */ public AbstractJdbc2ResultSetMetaData(Vector rows, Field[] fields) { - super(rows, fields); + super(rows, fields); } /* @@ -459,53 +459,53 @@ public abstract class AbstractJdbc2ResultSetMetaData extends org.postgresql.jdbc // This can hook into our PG_Object mechanism /** - * Returns the fully-qualified name of the Java class whose instances + * Returns the fully-qualified name of the Java class whose instances * are manufactured if the method ResultSet.getObject * is called to retrieve a value from the column. - * + * * ResultSet.getObject may return a subclass of the class * returned by this method. * * @param column the first column is 1, the second is 2, ... * @return the fully-qualified name of the class in the Java programming - * language that would be used by the method - * ResultSet.getObject to retrieve the value in the specified - * column. This is the class name used for custom mapping. + * language that would be used by the method + * ResultSet.getObject to retrieve the value in the specified + * column. This is the class name used for custom mapping. * @exception SQLException if a database access error occurs */ public String getColumnClassName(int column) throws SQLException { - /* - The following data type mapping came from ../Field.java. - - "int2", - "int4","oid", - "int8", - "cash","money", - "numeric", - "float4", - "float8", - "bpchar","char","char2","char4","char8","char16", - "varchar","text","name","filename", - "bool", - "date", - "time", - "abstime","timestamp" - - Types.SMALLINT, - Types.INTEGER,Types.INTEGER, - Types.BIGINT, - Types.DOUBLE,Types.DOUBLE, - Types.NUMERIC, - Types.REAL, - Types.DOUBLE, - Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR, - Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR, - Types.BIT, - Types.DATE, - Types.TIME, - Types.TIMESTAMP,Types.TIMESTAMP - */ + /* + The following data type mapping came from ../Field.java. + + "int2", + "int4","oid", + "int8", + "cash","money", + "numeric", + "float4", + "float8", + "bpchar","char","char2","char4","char8","char16", + "varchar","text","name","filename", + "bool", + "date", + "time", + "abstime","timestamp" + + Types.SMALLINT, + Types.INTEGER,Types.INTEGER, + Types.BIGINT, + Types.DOUBLE,Types.DOUBLE, + Types.NUMERIC, + Types.REAL, + Types.DOUBLE, + Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR, + Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR, + Types.BIT, + Types.DATE, + Types.TIME, + Types.TIMESTAMP,Types.TIMESTAMP + */ Field field = getField(column); int sql_type = field.getSQLType(); @@ -513,40 +513,40 @@ public abstract class AbstractJdbc2ResultSetMetaData extends org.postgresql.jdbc switch (sql_type) { case Types.BIT: - return("java.lang.Boolean"); + return ("java.lang.Boolean"); case Types.SMALLINT: - return("java.lang.Short"); + return ("java.lang.Short"); case Types.INTEGER: - return("java.lang.Integer"); + return ("java.lang.Integer"); case Types.BIGINT: - return("java.lang.Long"); + return ("java.lang.Long"); case Types.NUMERIC: - return("java.math.BigDecimal"); + return ("java.math.BigDecimal"); case Types.REAL: - return("java.lang.Float"); + return ("java.lang.Float"); case Types.DOUBLE: - return("java.lang.Double"); + return ("java.lang.Double"); case Types.CHAR: case Types.VARCHAR: - return("java.lang.String"); + return ("java.lang.String"); case Types.DATE: - return("java.sql.Date"); + return ("java.sql.Date"); case Types.TIME: - return("java.sql.Time"); + return ("java.sql.Time"); case Types.TIMESTAMP: - return("java.sql.Timestamp"); + return ("java.sql.Timestamp"); case Types.BINARY: case Types.VARBINARY: - return("[B"); + return ("[B"); case Types.ARRAY: - return("java.sql.Array"); + return ("java.sql.Array"); default: String type = field.getPGType(); if ("unknown".equals(type)) { - return("java.lang.String"); + return ("java.lang.String"); } - return("java.lang.Object"); + return ("java.lang.Object"); } } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java index 3dd4e748bcf31eee0fea9381aabbdc4f16064076..7debda09ba82ad4bd96f50ab9aa5d574a85600b5 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java @@ -8,7 +8,7 @@ import java.util.Vector; import org.postgresql.largeobject.*; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.5 2002/09/02 03:07:36 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.6 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1 * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement @@ -45,8 +45,8 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra */ public boolean execute() throws SQLException { - boolean l_return = super.execute(); - //Now do the jdbc2 specific stuff + boolean l_return = super.execute(); + //Now do the jdbc2 specific stuff //required for ResultSet.getStatement() to work and updateable resultsets ((AbstractJdbc2ResultSet)result).setStatement((Statement)this); @@ -64,7 +64,7 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra public void clearBatch() throws SQLException { - batch = null; + batch = null; } public int[] executeBatch() throws SQLException @@ -86,7 +86,7 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra PBatchUpdateException updex = new PBatchUpdateException("postgresql.stat.batch.error", - new Integer(i), batch.elementAt(i), resultSucceeded); + new Integer(i), batch.elementAt(i), resultSucceeded); updex.setNextException(e); throw updex; @@ -183,12 +183,12 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra // is buffered internally anyhow, so there would be no performance // boost gained, if anything it would be worse! int bytesRemaining = (int)x.length(); - int numRead = l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining)); + int numRead = l_inStream.read(buf, 0, Math.min(buf.length, bytesRemaining)); while (numRead != -1 && bytesRemaining > 0) { - bytesRemaining -= numRead; - los.write(buf,0,numRead); - numRead = l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining)); + bytesRemaining -= numRead; + los.write(buf, 0, numRead); + numRead = l_inStream.read(buf, 0, Math.min(buf.length, bytesRemaining)); } los.close(); } @@ -384,9 +384,10 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra } - //This is needed by AbstractJdbc2ResultSet to determine if the query is updateable or not - protected String[] getSqlFragments() { - return m_sqlFragments; - } + //This is needed by AbstractJdbc2ResultSet to determine if the query is updateable or not + protected String[] getSqlFragments() + { + return m_sqlFragments; + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java index 94cc5aab598efac4eaa385a96fc00767c55bd09e..cfaecc972b1741cb4248e8dc9a1a17784f6db7dc 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java @@ -27,7 +27,7 @@ public class Array implements java.sql.Array { private org.postgresql.PGConnection conn = null; private org.postgresql.Field field = null; - private ResultSet rs; + private ResultSet rs; private int idx = 0; private String rawString = null; @@ -44,7 +44,7 @@ public class Array implements java.sql.Array { this.conn = conn; this.field = field; - this.rs = rs; + this.rs = rs; this.idx = idx; this.rawString = ((AbstractJdbc2ResultSet)rs).getFixedString(idx); } @@ -76,9 +76,9 @@ public class Array implements java.sql.Array ArrayList array = new ArrayList(); /* Check if the String is also not an empty array - * otherwise there will be an exception thrown below - * in the ResultSet.toX with an empty string. - * -- Doug Fields Feb 20, 2002 */ + * otherwise there will be an exception thrown below + * in the ResultSet.toX with an empty string. + * -- Doug Fields Feb 20, 2002 */ if ( rawString != null && !rawString.equals("{}") ) { @@ -88,9 +88,9 @@ public class Array implements java.sql.Array boolean insideString = false; for ( int i = 0; i < chars.length; i++ ) { - if ( chars[i] == '\\' ) - //escape character that we need to skip - i++; + if ( chars[i] == '\\' ) + //escape character that we need to skip + i++; if ( chars[i] == '{' ) { if ( foundOpen ) // Only supports 1-D arrays for now diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java index 9e64350f5b5fa4d927c818b82630575e81d753fe..6ebd0850fb7cdcc21f650c1703f27655db9561da 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java @@ -6,55 +6,55 @@ import java.util.Vector; import java.util.Hashtable; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.4 2002/07/26 05:29:35 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.5 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Connection interface for JDBC2. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents */ public class Jdbc2Connection extends org.postgresql.jdbc2.AbstractJdbc2Connection implements java.sql.Connection { - public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc2Statement s = new Jdbc2Statement(this); - s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - - public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc2PreparedStatement s = new Jdbc2PreparedStatement(this, sql); - s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc2CallableStatement s = new org.postgresql.jdbc2.Jdbc2CallableStatement(this,sql); + public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc2Statement s = new Jdbc2Statement(this); s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - public java.sql.DatabaseMetaData getMetaData() throws SQLException - { - if (metadata == null) - metadata = new org.postgresql.jdbc2.Jdbc2DatabaseMetaData(this); - return metadata; - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException - { - return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); - } + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + + public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc2PreparedStatement s = new Jdbc2PreparedStatement(this, sql); + s.setResultSetType(resultSetType); + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc2CallableStatement s = new org.postgresql.jdbc2.Jdbc2CallableStatement(this, sql); + s.setResultSetType(resultSetType); + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + public java.sql.DatabaseMetaData getMetaData() throws SQLException + { + if (metadata == null) + metadata = new org.postgresql.jdbc2.Jdbc2DatabaseMetaData(this); + return metadata; + } + + public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + + public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException + { + return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java index 1e9805be1d60d53c71df7fba2f4d7db4796190c0..84e3a7b9e6b66c3ff10f0349818e18561a7d21d5 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java @@ -5,9 +5,9 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.4 2002/08/14 20:35:39 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.5 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.ResultSet interface for JDBC2. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2ResultSet or one of it's parents */ public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet implements java.sql.ResultSet @@ -23,13 +23,15 @@ public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet return new Jdbc2ResultSetMetaData(rows, fields); } - public java.sql.Clob getClob(int i) throws SQLException { - return new org.postgresql.jdbc2.Jdbc2Clob(connection, getInt(i)); - } + public java.sql.Clob getClob(int i) throws SQLException + { + return new org.postgresql.jdbc2.Jdbc2Clob(connection, getInt(i)); + } - public java.sql.Blob getBlob(int i) throws SQLException { - return new org.postgresql.jdbc2.Jdbc2Blob(connection, getInt(i)); - } + public java.sql.Blob getBlob(int i) throws SQLException + { + return new org.postgresql.jdbc2.Jdbc2Blob(connection, getInt(i)); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSetMetaData.java index e0e5a0dc7da1a5f38fca6fa5246ddf620310e90d..00ae0e8f60b4341eead3e6869181450b9b6f5392 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSetMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSetMetaData.java @@ -4,7 +4,7 @@ public class Jdbc2ResultSetMetaData extends AbstractJdbc2ResultSetMetaData imple { public Jdbc2ResultSetMetaData(java.util.Vector rows, org.postgresql.Field[] fields) { - super(rows, fields); + super(rows, fields); } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java index 4f63d10c14f485caa190501568b4812dcd533ca3..ed894f6cd10fefa11d04753587a63d5cfa833916 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java @@ -3,9 +3,9 @@ package org.postgresql.jdbc2; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.2 2002/07/24 22:08:43 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.3 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Statement interface for JDBC2. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents */ public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement implements java.sql.Statement diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/BaseDataSource.java b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/BaseDataSource.java index 0e3ae8e7661440a67e0775269010bb5c462b6549..c5fbde848ed9fbcc1ac983390ff77efce5811a47 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/BaseDataSource.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/BaseDataSource.java @@ -8,217 +8,249 @@ import java.sql.*; * Base class for data sources and related classes. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public abstract class BaseDataSource implements Referenceable { - // Load the normal driver, since we'll use it to actually connect to the - // database. That way we don't have to maintain the connecting code in - // multiple places. - static { - try { - Class.forName("org.postgresql.Driver"); - } catch (ClassNotFoundException e) { - System.err.println("PostgreSQL DataSource unable to load PostgreSQL JDBC Driver"); - } - } - - // Needed to implement the DataSource/ConnectionPoolDataSource interfaces - private transient PrintWriter logger; - // Don't track loginTimeout, since we'd just ignore it anyway - - // Standard properties, defined in the JDBC 2.0 Optional Package spec - private String serverName = "localhost"; - private String databaseName; - private String user; - private String password; - private int portNumber; - - /** - * Gets a connection to the PostgreSQL database. The database is identified by the - * DataSource properties serverName, databaseName, and portNumber. The user to - * connect as is identified by the DataSource properties user and password. - * - * @return A valid database connection. - * @throws SQLException - * Occurs when the database connection cannot be established. - */ - public Connection getConnection() throws SQLException { - return getConnection(user, password); - } - - /** - * Gets a connection to the PostgreSQL database. The database is identified by the - * DataAource properties serverName, databaseName, and portNumber. The user to - * connect as is identified by the arguments user and password, which override - * the DataSource properties by the same name. - * - * @return A valid database connection. - * @throws SQLException - * Occurs when the database connection cannot be established. - */ - public Connection getConnection(String user, String password) throws SQLException { - try { - Connection con = DriverManager.getConnection(getUrl(), user, password); - if (logger != null) { - logger.println("Created a non-pooled connection for " + user + " at " + getUrl()); - } - return con; - } catch (SQLException e) { - if (logger != null) { - logger.println("Failed to create a non-pooled connection for " + user + " at " + getUrl() + ": " + e); - } - throw e; - } - } - - /** - * This DataSource does not support a configurable login timeout. - * @return 0 - */ - public int getLoginTimeout() throws SQLException { - return 0; - } - - /** - * This DataSource does not support a configurable login timeout. Any value - * provided here will be ignored. - */ - public void setLoginTimeout(int i) throws SQLException { - } - - /** - * Gets the log writer used to log connections opened. - */ - public PrintWriter getLogWriter() throws SQLException { - return logger; - } - - /** - * The DataSource will note every connection opened to the provided log writer. - */ - public void setLogWriter(PrintWriter printWriter) throws SQLException { - logger = printWriter; - } - - /** - * Gets the name of the host the PostgreSQL database is running on. - */ - public String getServerName() { - return serverName; - } - - /** - * Sets the name of the host the PostgreSQL database is running on. If this - * is changed, it will only affect future calls to getConnection. The default - * value is localhost. - */ - public void setServerName(String serverName) { - if(serverName == null || serverName.equals("")) { - this.serverName = "localhost"; - } else { - this.serverName = serverName; - } - } - - /** - * Gets the name of the PostgreSQL database, running on the server identified - * by the serverName property. - */ - public String getDatabaseName() { - return databaseName; - } - - /** - * Sets the name of the PostgreSQL database, running on the server identified - * by the serverName property. If this is changed, it will only affect - * future calls to getConnection. - */ - public void setDatabaseName(String databaseName) { - this.databaseName = databaseName; - } - - /** - * Gets a description of this DataSource-ish thing. Must be customized by - * subclasses. - */ - public abstract String getDescription(); - - /** - * Gets the user to connect as by default. If this is not specified, you must - * use the getConnection method which takes a user and password as parameters. - */ - public String getUser() { - return user; - } - - /** - * Sets the user to connect as by default. If this is not specified, you must - * use the getConnection method which takes a user and password as parameters. - * If this is changed, it will only affect future calls to getConnection. - */ - public void setUser(String user) { - this.user = user; - } - - /** - * Gets the password to connect with by default. If this is not specified but a - * password is needed to log in, you must use the getConnection method which takes - * a user and password as parameters. - */ - public String getPassword() { - return password; - } - - /** - * Sets the password to connect with by default. If this is not specified but a - * password is needed to log in, you must use the getConnection method which takes - * a user and password as parameters. If this is changed, it will only affect - * future calls to getConnection. - */ - public void setPassword(String password) { - this.password = password; - } - - /** - * Gets the port which the PostgreSQL server is listening on for TCP/IP - * connections. - * - * @return The port, or 0 if the default port will be used. - */ - public int getPortNumber() { - return portNumber; - } - - /** - * Gets the port which the PostgreSQL server is listening on for TCP/IP - * connections. Be sure the -i flag is passed to postmaster when PostgreSQL - * is started. If this is not set, or set to 0, the default port will be used. - */ - public void setPortNumber(int portNumber) { - this.portNumber = portNumber; - } - - /** - * Generates a DriverManager URL from the other properties supplied. - */ - private String getUrl() { - return "jdbc:postgresql://"+serverName+(portNumber == 0 ? "" : ":"+portNumber)+"/"+databaseName; - } - - public Reference getReference() throws NamingException { - Reference ref = new Reference(getClass().getName(), PGObjectFactory.class.getName(), null); - ref.add(new StringRefAddr("serverName", serverName)); - if (portNumber != 0) { - ref.add(new StringRefAddr("portNumber", Integer.toString(portNumber))); - } - ref.add(new StringRefAddr("databaseName", databaseName)); - if (user != null) { - ref.add(new StringRefAddr("user", user)); - } - if (password != null) { - ref.add(new StringRefAddr("password", password)); - } - return ref; - } +public abstract class BaseDataSource implements Referenceable +{ + // Load the normal driver, since we'll use it to actually connect to the + // database. That way we don't have to maintain the connecting code in + // multiple places. + static { + try + { + Class.forName("org.postgresql.Driver"); + } + catch (ClassNotFoundException e) + { + System.err.println("PostgreSQL DataSource unable to load PostgreSQL JDBC Driver"); + } + } + + // Needed to implement the DataSource/ConnectionPoolDataSource interfaces + private transient PrintWriter logger; + // Don't track loginTimeout, since we'd just ignore it anyway + + // Standard properties, defined in the JDBC 2.0 Optional Package spec + private String serverName = "localhost"; + private String databaseName; + private String user; + private String password; + private int portNumber; + + /** + * Gets a connection to the PostgreSQL database. The database is identified by the + * DataSource properties serverName, databaseName, and portNumber. The user to + * connect as is identified by the DataSource properties user and password. + * + * @return A valid database connection. + * @throws SQLException + * Occurs when the database connection cannot be established. + */ + public Connection getConnection() throws SQLException + { + return getConnection(user, password); + } + + /** + * Gets a connection to the PostgreSQL database. The database is identified by the + * DataAource properties serverName, databaseName, and portNumber. The user to + * connect as is identified by the arguments user and password, which override + * the DataSource properties by the same name. + * + * @return A valid database connection. + * @throws SQLException + * Occurs when the database connection cannot be established. + */ + public Connection getConnection(String user, String password) throws SQLException + { + try + { + Connection con = DriverManager.getConnection(getUrl(), user, password); + if (logger != null) + { + logger.println("Created a non-pooled connection for " + user + " at " + getUrl()); + } + return con; + } + catch (SQLException e) + { + if (logger != null) + { + logger.println("Failed to create a non-pooled connection for " + user + " at " + getUrl() + ": " + e); + } + throw e; + } + } + + /** + * This DataSource does not support a configurable login timeout. + * @return 0 + */ + public int getLoginTimeout() throws SQLException + { + return 0; + } + + /** + * This DataSource does not support a configurable login timeout. Any value + * provided here will be ignored. + */ + public void setLoginTimeout(int i) throws SQLException + {} + + /** + * Gets the log writer used to log connections opened. + */ + public PrintWriter getLogWriter() throws SQLException + { + return logger; + } + + /** + * The DataSource will note every connection opened to the provided log writer. + */ + public void setLogWriter(PrintWriter printWriter) throws SQLException + { + logger = printWriter; + } + + /** + * Gets the name of the host the PostgreSQL database is running on. + */ + public String getServerName() + { + return serverName; + } + + /** + * Sets the name of the host the PostgreSQL database is running on. If this + * is changed, it will only affect future calls to getConnection. The default + * value is localhost. + */ + public void setServerName(String serverName) + { + if (serverName == null || serverName.equals("")) + { + this.serverName = "localhost"; + } + else + { + this.serverName = serverName; + } + } + + /** + * Gets the name of the PostgreSQL database, running on the server identified + * by the serverName property. + */ + public String getDatabaseName() + { + return databaseName; + } + + /** + * Sets the name of the PostgreSQL database, running on the server identified + * by the serverName property. If this is changed, it will only affect + * future calls to getConnection. + */ + public void setDatabaseName(String databaseName) + { + this.databaseName = databaseName; + } + + /** + * Gets a description of this DataSource-ish thing. Must be customized by + * subclasses. + */ + public abstract String getDescription(); + + /** + * Gets the user to connect as by default. If this is not specified, you must + * use the getConnection method which takes a user and password as parameters. + */ + public String getUser() + { + return user; + } + + /** + * Sets the user to connect as by default. If this is not specified, you must + * use the getConnection method which takes a user and password as parameters. + * If this is changed, it will only affect future calls to getConnection. + */ + public void setUser(String user) + { + this.user = user; + } + + /** + * Gets the password to connect with by default. If this is not specified but a + * password is needed to log in, you must use the getConnection method which takes + * a user and password as parameters. + */ + public String getPassword() + { + return password; + } + + /** + * Sets the password to connect with by default. If this is not specified but a + * password is needed to log in, you must use the getConnection method which takes + * a user and password as parameters. If this is changed, it will only affect + * future calls to getConnection. + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * Gets the port which the PostgreSQL server is listening on for TCP/IP + * connections. + * + * @return The port, or 0 if the default port will be used. + */ + public int getPortNumber() + { + return portNumber; + } + + /** + * Gets the port which the PostgreSQL server is listening on for TCP/IP + * connections. Be sure the -i flag is passed to postmaster when PostgreSQL + * is started. If this is not set, or set to 0, the default port will be used. + */ + public void setPortNumber(int portNumber) + { + this.portNumber = portNumber; + } + + /** + * Generates a DriverManager URL from the other properties supplied. + */ + private String getUrl() + { + return "jdbc:postgresql://" + serverName + (portNumber == 0 ? "" : ":" + portNumber) + "/" + databaseName; + } + + public Reference getReference() throws NamingException + { + Reference ref = new Reference(getClass().getName(), PGObjectFactory.class.getName(), null); + ref.add(new StringRefAddr("serverName", serverName)); + if (portNumber != 0) + { + ref.add(new StringRefAddr("portNumber", Integer.toString(portNumber))); + } + ref.add(new StringRefAddr("databaseName", databaseName)); + if (user != null) + { + ref.add(new StringRefAddr("user", user)); + } + if (password != null) + { + ref.add(new StringRefAddr("password", password)); + } + return ref; + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/ConnectionPool.java b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/ConnectionPool.java index 1ffee5d342576ddca4746eeb19199a1a7d3d3f45..f7700698e2ea2a58aa283ffad5e6347264aea12a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/ConnectionPool.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/ConnectionPool.java @@ -21,56 +21,62 @@ import java.io.Serializable; *

This implementation supports JDK 1.3 and higher.

* * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class ConnectionPool extends BaseDataSource implements Serializable, ConnectionPoolDataSource { - private boolean defaultAutoCommit = false; +public class ConnectionPool extends BaseDataSource implements Serializable, ConnectionPoolDataSource +{ + private boolean defaultAutoCommit = false; - /** - * Gets a description of this DataSource. - */ - public String getDescription() { - return "ConnectionPoolDataSource from "+org.postgresql.Driver.getVersion(); - } + /** + * Gets a description of this DataSource. + */ + public String getDescription() + { + return "ConnectionPoolDataSource from " + org.postgresql.Driver.getVersion(); + } - /** - * Gets a connection which may be pooled by the app server or middleware - * implementation of DataSource. - * - * @throws java.sql.SQLException - * Occurs when the physical database connection cannot be established. - */ - public PooledConnection getPooledConnection() throws SQLException { - return new PooledConnectionImpl(getConnection(), defaultAutoCommit); - } + /** + * Gets a connection which may be pooled by the app server or middleware + * implementation of DataSource. + * + * @throws java.sql.SQLException + * Occurs when the physical database connection cannot be established. + */ + public PooledConnection getPooledConnection() throws SQLException + { + return new PooledConnectionImpl(getConnection(), defaultAutoCommit); + } - /** - * Gets a connection which may be pooled by the app server or middleware - * implementation of DataSource. - * - * @throws java.sql.SQLException - * Occurs when the physical database connection cannot be established. - */ - public PooledConnection getPooledConnection(String user, String password) throws SQLException { - return new PooledConnectionImpl(getConnection(user, password), defaultAutoCommit); - } + /** + * Gets a connection which may be pooled by the app server or middleware + * implementation of DataSource. + * + * @throws java.sql.SQLException + * Occurs when the physical database connection cannot be established. + */ + public PooledConnection getPooledConnection(String user, String password) throws SQLException + { + return new PooledConnectionImpl(getConnection(user, password), defaultAutoCommit); + } - /** - * Gets whether connections supplied by this pool will have autoCommit - * turned on by default. The default value is false, so that - * autoCommit will be turned off by default. - */ - public boolean isDefaultAutoCommit() { - return defaultAutoCommit; - } + /** + * Gets whether connections supplied by this pool will have autoCommit + * turned on by default. The default value is false, so that + * autoCommit will be turned off by default. + */ + public boolean isDefaultAutoCommit() + { + return defaultAutoCommit; + } - /** - * Sets whether connections supplied by this pool will have autoCommit - * turned on by default. The default value is false, so that - * autoCommit will be turned off by default. - */ - public void setDefaultAutoCommit(boolean defaultAutoCommit) { - this.defaultAutoCommit = defaultAutoCommit; - } + /** + * Sets whether connections supplied by this pool will have autoCommit + * turned on by default. The default value is false, so that + * autoCommit will be turned off by default. + */ + public void setDefaultAutoCommit(boolean defaultAutoCommit) + { + this.defaultAutoCommit = defaultAutoCommit; + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PGObjectFactory.java b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PGObjectFactory.java index 0663062b7442270153ee8f0be362afbb1c5eb7e3..2ee3c10130b064347f6c55d9c08761acbe0c3d76 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PGObjectFactory.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PGObjectFactory.java @@ -13,77 +13,96 @@ import java.util.Hashtable; * consistent. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class PGObjectFactory implements ObjectFactory { - /** - * Dereferences a PostgreSQL DataSource. Other types of references are - * ignored. - */ - public Object getObjectInstance(Object obj, Name name, Context nameCtx, - Hashtable environment) throws Exception { - Reference ref = (Reference)obj; - if(ref.getClassName().equals(SimpleDataSource.class.getName())) { - return loadSimpleDataSource(ref); - } else if (ref.getClassName().equals(ConnectionPool.class.getName())) { - return loadConnectionPool(ref); - } else if (ref.getClassName().equals(PoolingDataSource.class.getName())) { - return loadPoolingDataSource(ref); - } else { - return null; - } - } +public class PGObjectFactory implements ObjectFactory +{ + /** + * Dereferences a PostgreSQL DataSource. Other types of references are + * ignored. + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, + Hashtable environment) throws Exception + { + Reference ref = (Reference)obj; + if (ref.getClassName().equals(SimpleDataSource.class.getName())) + { + return loadSimpleDataSource(ref); + } + else if (ref.getClassName().equals(ConnectionPool.class.getName())) + { + return loadConnectionPool(ref); + } + else if (ref.getClassName().equals(PoolingDataSource.class.getName())) + { + return loadPoolingDataSource(ref); + } + else + { + return null; + } + } - private Object loadPoolingDataSource(Reference ref) { - // If DataSource exists, return it - String name = getProperty(ref, "dataSourceName"); - PoolingDataSource pds = PoolingDataSource.getDataSource(name); - if(pds != null) { - return pds; - } - // Otherwise, create a new one - pds = new PoolingDataSource(); - pds.setDataSourceName(name); - loadBaseDataSource(pds, ref); - String min = getProperty(ref, "initialConnections"); - if (min != null) { - pds.setInitialConnections(Integer.parseInt(min)); - } - String max = getProperty(ref, "maxConnections"); - if (max != null) { - pds.setMaxConnections(Integer.parseInt(max)); - } - return pds; - } + private Object loadPoolingDataSource(Reference ref) + { + // If DataSource exists, return it + String name = getProperty(ref, "dataSourceName"); + PoolingDataSource pds = PoolingDataSource.getDataSource(name); + if (pds != null) + { + return pds; + } + // Otherwise, create a new one + pds = new PoolingDataSource(); + pds.setDataSourceName(name); + loadBaseDataSource(pds, ref); + String min = getProperty(ref, "initialConnections"); + if (min != null) + { + pds.setInitialConnections(Integer.parseInt(min)); + } + String max = getProperty(ref, "maxConnections"); + if (max != null) + { + pds.setMaxConnections(Integer.parseInt(max)); + } + return pds; + } - private Object loadSimpleDataSource(Reference ref) { - SimpleDataSource ds = new SimpleDataSource(); - return loadBaseDataSource(ds, ref); - } + private Object loadSimpleDataSource(Reference ref) + { + SimpleDataSource ds = new SimpleDataSource(); + return loadBaseDataSource(ds, ref); + } - private Object loadConnectionPool(Reference ref) { - ConnectionPool cp = new ConnectionPool(); - return loadBaseDataSource(cp, ref); - } + private Object loadConnectionPool(Reference ref) + { + ConnectionPool cp = new ConnectionPool(); + return loadBaseDataSource(cp, ref); + } - private Object loadBaseDataSource(BaseDataSource ds, Reference ref) { - ds.setDatabaseName(getProperty(ref, "databaseName")); - ds.setPassword(getProperty(ref, "password")); - String port = getProperty(ref, "portNumber"); - if(port != null) { - ds.setPortNumber(Integer.parseInt(port)); - } - ds.setServerName(getProperty(ref, "serverName")); - ds.setUser(getProperty(ref, "user")); - return ds; - } + private Object loadBaseDataSource(BaseDataSource ds, Reference ref) + { + ds.setDatabaseName(getProperty(ref, "databaseName")); + ds.setPassword(getProperty(ref, "password")); + String port = getProperty(ref, "portNumber"); + if (port != null) + { + ds.setPortNumber(Integer.parseInt(port)); + } + ds.setServerName(getProperty(ref, "serverName")); + ds.setUser(getProperty(ref, "user")); + return ds; + } - private String getProperty(Reference ref, String s) { - RefAddr addr = ref.get(s); - if(addr == null) { - return null; - } - return (String)addr.getContent(); - } + private String getProperty(Reference ref, String s) + { + RefAddr addr = ref.get(s); + if (addr == null) + { + return null; + } + return (String)addr.getContent(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java index bbd801e47125ba8a6e6bff919cb59278b2541016..4eb7d41b6541d586ccb8a3c7539e10d601d8b7b7 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java @@ -13,187 +13,244 @@ import java.lang.reflect.*; * @see ConnectionPool * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class PooledConnectionImpl implements PooledConnection { - private List listeners = new LinkedList(); - private Connection con; - private ConnectionHandler last; - private boolean autoCommit; +public class PooledConnectionImpl implements PooledConnection +{ + private List listeners = new LinkedList(); + private Connection con; + private ConnectionHandler last; + private boolean autoCommit; - /** - * Creates a new PooledConnection representing the specified physical - * connection. - */ - PooledConnectionImpl(Connection con, boolean autoCommit) { - this.con = con; - this.autoCommit = autoCommit; - } + /** + * Creates a new PooledConnection representing the specified physical + * connection. + */ + PooledConnectionImpl(Connection con, boolean autoCommit) + { + this.con = con; + this.autoCommit = autoCommit; + } - /** - * Adds a listener for close or fatal error events on the connection - * handed out to a client. - */ - public void addConnectionEventListener(ConnectionEventListener connectionEventListener) { - listeners.add(connectionEventListener); - } + /** + * Adds a listener for close or fatal error events on the connection + * handed out to a client. + */ + public void addConnectionEventListener(ConnectionEventListener connectionEventListener) + { + listeners.add(connectionEventListener); + } - /** - * Removes a listener for close or fatal error events on the connection - * handed out to a client. - */ - public void removeConnectionEventListener(ConnectionEventListener connectionEventListener) { - listeners.remove(connectionEventListener); - } + /** + * Removes a listener for close or fatal error events on the connection + * handed out to a client. + */ + public void removeConnectionEventListener(ConnectionEventListener connectionEventListener) + { + listeners.remove(connectionEventListener); + } - /** - * Closes the physical database connection represented by this - * PooledConnection. If any client has a connection based on - * this PooledConnection, it is forcibly closed as well. - */ - public void close() throws SQLException { - if(last != null) { - last.close(); - if(!con.getAutoCommit()) { - try {con.rollback();} catch (SQLException e) {} - } - } - try { - con.close(); - } finally { - con = null; - } - } + /** + * Closes the physical database connection represented by this + * PooledConnection. If any client has a connection based on + * this PooledConnection, it is forcibly closed as well. + */ + public void close() throws SQLException + { + if (last != null) + { + last.close(); + if (!con.getAutoCommit()) + { + try + { + con.rollback(); + } + catch (SQLException e) + {} + } + } + try + { + con.close(); + } + finally + { + con = null; + } + } - /** - * Gets a handle for a client to use. This is a wrapper around the - * physical connection, so the client can call close and it will just - * return the connection to the pool without really closing the - * pgysical connection. - * - *

According to the JDBC 2.0 Optional Package spec (6.2.3), only one - * client may have an active handle to the connection at a time, so if - * there is a previous handle active when this is called, the previous - * one is forcibly closed and its work rolled back.

- */ - public Connection getConnection() throws SQLException { - if(con == null) { - throw new SQLException("This PooledConnection has already been closed!"); - } - // Only one connection can be open at a time from this PooledConnection. See JDBC 2.0 Optional Package spec section 6.2.3 - if(last != null) { - last.close(); - if(!con.getAutoCommit()) { - try {con.rollback();} catch(SQLException e) {} - } - con.clearWarnings(); - } - con.setAutoCommit(autoCommit); - ConnectionHandler handler = new ConnectionHandler(con); - last = handler; - return (Connection)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Connection.class}, handler); - } + /** + * Gets a handle for a client to use. This is a wrapper around the + * physical connection, so the client can call close and it will just + * return the connection to the pool without really closing the + * pgysical connection. + * + *

According to the JDBC 2.0 Optional Package spec (6.2.3), only one + * client may have an active handle to the connection at a time, so if + * there is a previous handle active when this is called, the previous + * one is forcibly closed and its work rolled back.

+ */ + public Connection getConnection() throws SQLException + { + if (con == null) + { + throw new SQLException("This PooledConnection has already been closed!"); + } + // Only one connection can be open at a time from this PooledConnection. See JDBC 2.0 Optional Package spec section 6.2.3 + if (last != null) + { + last.close(); + if (!con.getAutoCommit()) + { + try + { + con.rollback(); + } + catch (SQLException e) + {} + } + con.clearWarnings(); + } + con.setAutoCommit(autoCommit); + ConnectionHandler handler = new ConnectionHandler(con); + last = handler; + return (Connection)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Connection.class}, handler); + } - /** - * Used to fire a connection event to all listeners. - */ - void fireConnectionClosed() { - ConnectionEvent evt = null; - // Copy the listener list so the listener can remove itself during this method call - ConnectionEventListener[] local = (ConnectionEventListener[]) listeners.toArray(new ConnectionEventListener[listeners.size()]); - for (int i = 0; i < local.length; i++) { - ConnectionEventListener listener = local[i]; - if (evt == null) { - evt = new ConnectionEvent(this); - } - listener.connectionClosed(evt); - } - } + /** + * Used to fire a connection event to all listeners. + */ + void fireConnectionClosed() + { + ConnectionEvent evt = null; + // Copy the listener list so the listener can remove itself during this method call + ConnectionEventListener[] local = (ConnectionEventListener[]) listeners.toArray(new ConnectionEventListener[listeners.size()]); + for (int i = 0; i < local.length; i++) + { + ConnectionEventListener listener = local[i]; + if (evt == null) + { + evt = new ConnectionEvent(this); + } + listener.connectionClosed(evt); + } + } - /** - * Used to fire a connection event to all listeners. - */ - void fireConnectionFatalError(SQLException e) { - ConnectionEvent evt = null; - // Copy the listener list so the listener can remove itself during this method call - ConnectionEventListener[] local = (ConnectionEventListener[])listeners.toArray(new ConnectionEventListener[listeners.size()]); - for (int i=0; iIf you put this DataSource in JNDI, and access it from different JVMs (or * otherwise load this class from different ClassLoaders), you'll end up with one - * pool per ClassLoader or VM. This is another area where a server-specific + * pool per ClassLoader or VM. This is another area where a server-specific * implementation may provide advanced features, such as using a single pool * across all VMs in a cluster.

* *

This implementation supports JDK 1.3 and higher.

* * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class PoolingDataSource extends BaseDataSource implements DataSource { - private static Map dataSources = new HashMap(); +public class PoolingDataSource extends BaseDataSource implements DataSource +{ + private static Map dataSources = new HashMap(); - static PoolingDataSource getDataSource(String name) { - return (PoolingDataSource)dataSources.get(name); - } + static PoolingDataSource getDataSource(String name) + { + return (PoolingDataSource)dataSources.get(name); + } - // Additional Data Source properties - private String dataSourceName; - private int initialConnections = 0; - private int maxConnections = 0; - // State variables - private boolean initialized = false; - private Stack available = new Stack(); - private Stack used = new Stack(); - private Object lock = new Object(); - private ConnectionPool source; + // Additional Data Source properties + private String dataSourceName; + private int initialConnections = 0; + private int maxConnections = 0; + // State variables + private boolean initialized = false; + private Stack available = new Stack(); + private Stack used = new Stack(); + private Object lock = new Object(); + private ConnectionPool source; - /** - * Gets a description of this DataSource. - */ - public String getDescription() { - return "Pooling DataSource '"+dataSourceName+" from "+org.postgresql.Driver.getVersion(); - } + /** + * Gets a description of this DataSource. + */ + public String getDescription() + { + return "Pooling DataSource '" + dataSourceName + " from " + org.postgresql.Driver.getVersion(); + } - /** - * Ensures the DataSource properties are not changed after the DataSource has - * been used. - * - * @throws java.lang.IllegalStateException - * The Server Name cannot be changed after the DataSource has been - * used. - */ - public void setServerName(String serverName) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - super.setServerName(serverName); - } + /** + * Ensures the DataSource properties are not changed after the DataSource has + * been used. + * + * @throws java.lang.IllegalStateException + * The Server Name cannot be changed after the DataSource has been + * used. + */ + public void setServerName(String serverName) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + super.setServerName(serverName); + } - /** - * Ensures the DataSource properties are not changed after the DataSource has - * been used. - * - * @throws java.lang.IllegalStateException - * The Database Name cannot be changed after the DataSource has been - * used. - */ - public void setDatabaseName(String databaseName) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - super.setDatabaseName(databaseName); - } + /** + * Ensures the DataSource properties are not changed after the DataSource has + * been used. + * + * @throws java.lang.IllegalStateException + * The Database Name cannot be changed after the DataSource has been + * used. + */ + public void setDatabaseName(String databaseName) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + super.setDatabaseName(databaseName); + } - /** - * Ensures the DataSource properties are not changed after the DataSource has - * been used. - * - * @throws java.lang.IllegalStateException - * The User cannot be changed after the DataSource has been - * used. - */ - public void setUser(String user) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - super.setUser(user); - } + /** + * Ensures the DataSource properties are not changed after the DataSource has + * been used. + * + * @throws java.lang.IllegalStateException + * The User cannot be changed after the DataSource has been + * used. + */ + public void setUser(String user) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + super.setUser(user); + } - /** - * Ensures the DataSource properties are not changed after the DataSource has - * been used. - * - * @throws java.lang.IllegalStateException - * The Password cannot be changed after the DataSource has been - * used. - */ - public void setPassword(String password) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - super.setPassword(password); - } + /** + * Ensures the DataSource properties are not changed after the DataSource has + * been used. + * + * @throws java.lang.IllegalStateException + * The Password cannot be changed after the DataSource has been + * used. + */ + public void setPassword(String password) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + super.setPassword(password); + } - /** - * Ensures the DataSource properties are not changed after the DataSource has - * been used. - * - * @throws java.lang.IllegalStateException - * The Port Number cannot be changed after the DataSource has been - * used. - */ - public void setPortNumber(int portNumber) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - super.setPortNumber(portNumber); - } + /** + * Ensures the DataSource properties are not changed after the DataSource has + * been used. + * + * @throws java.lang.IllegalStateException + * The Port Number cannot be changed after the DataSource has been + * used. + */ + public void setPortNumber(int portNumber) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + super.setPortNumber(portNumber); + } - /** - * Gets the number of connections that will be created when this DataSource - * is initialized. If you do not call initialize explicitly, it will be - * initialized the first time a connection is drawn from it. - */ - public int getInitialConnections() { - return initialConnections; - } + /** + * Gets the number of connections that will be created when this DataSource + * is initialized. If you do not call initialize explicitly, it will be + * initialized the first time a connection is drawn from it. + */ + public int getInitialConnections() + { + return initialConnections; + } - /** - * Sets the number of connections that will be created when this DataSource - * is initialized. If you do not call initialize explicitly, it will be - * initialized the first time a connection is drawn from it. - * - * @throws java.lang.IllegalStateException - * The Initial Connections cannot be changed after the DataSource has been - * used. - */ - public void setInitialConnections(int initialConnections) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - this.initialConnections = initialConnections; - } + /** + * Sets the number of connections that will be created when this DataSource + * is initialized. If you do not call initialize explicitly, it will be + * initialized the first time a connection is drawn from it. + * + * @throws java.lang.IllegalStateException + * The Initial Connections cannot be changed after the DataSource has been + * used. + */ + public void setInitialConnections(int initialConnections) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + this.initialConnections = initialConnections; + } - /** - * Gets the maximum number of connections that the pool will allow. If a request - * comes in and this many connections are in use, the request will block until a - * connection is available. Note that connections for a user other than the - * default user will not be pooled and don't count against this limit. - * - * @return The maximum number of pooled connection allowed, or 0 for no maximum. - */ - public int getMaxConnections() { - return maxConnections; - } + /** + * Gets the maximum number of connections that the pool will allow. If a request + * comes in and this many connections are in use, the request will block until a + * connection is available. Note that connections for a user other than the + * default user will not be pooled and don't count against this limit. + * + * @return The maximum number of pooled connection allowed, or 0 for no maximum. + */ + public int getMaxConnections() + { + return maxConnections; + } - /** - * Sets the maximum number of connections that the pool will allow. If a request - * comes in and this many connections are in use, the request will block until a - * connection is available. Note that connections for a user other than the - * default user will not be pooled and don't count against this limit. - * - * @param maxConnections The maximum number of pooled connection to allow, or - * 0 for no maximum. - * - * @throws java.lang.IllegalStateException - * The Maximum Connections cannot be changed after the DataSource has been - * used. - */ - public void setMaxConnections(int maxConnections) { - if (initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - this.maxConnections = maxConnections; - } + /** + * Sets the maximum number of connections that the pool will allow. If a request + * comes in and this many connections are in use, the request will block until a + * connection is available. Note that connections for a user other than the + * default user will not be pooled and don't count against this limit. + * + * @param maxConnections The maximum number of pooled connection to allow, or + * 0 for no maximum. + * + * @throws java.lang.IllegalStateException + * The Maximum Connections cannot be changed after the DataSource has been + * used. + */ + public void setMaxConnections(int maxConnections) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + this.maxConnections = maxConnections; + } - /** - * Gets the name of this DataSource. This uniquely identifies the DataSource. - * You cannot use more than one DataSource in the same VM with the same name. - */ - public String getDataSourceName() { - return dataSourceName; - } + /** + * Gets the name of this DataSource. This uniquely identifies the DataSource. + * You cannot use more than one DataSource in the same VM with the same name. + */ + public String getDataSourceName() + { + return dataSourceName; + } - /** - * Sets the name of this DataSource. This is required, and uniquely identifies - * the DataSource. You cannot create or use more than one DataSource in the - * same VM with the same name. - * - * @throws java.lang.IllegalStateException - * The Data Source Name cannot be changed after the DataSource has been - * used. - * @throws java.lang.IllegalArgumentException - * Another PoolingDataSource with the same dataSourceName already - * exists. - */ - public void setDataSourceName(String dataSourceName) { - if(initialized) { - throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); - } - if(this.dataSourceName != null && dataSourceName != null && dataSourceName.equals(this.dataSourceName)) { - return; - } - synchronized(dataSources) { - if(getDataSource(dataSourceName) != null) { - throw new IllegalArgumentException("DataSource with name '"+dataSourceName+"' already exists!"); - } - if (this.dataSourceName != null) { - dataSources.remove(this.dataSourceName); - } - this.dataSourceName = dataSourceName; - dataSources.put(dataSourceName, this); - } - } + /** + * Sets the name of this DataSource. This is required, and uniquely identifies + * the DataSource. You cannot create or use more than one DataSource in the + * same VM with the same name. + * + * @throws java.lang.IllegalStateException + * The Data Source Name cannot be changed after the DataSource has been + * used. + * @throws java.lang.IllegalArgumentException + * Another PoolingDataSource with the same dataSourceName already + * exists. + */ + public void setDataSourceName(String dataSourceName) + { + if (initialized) + { + throw new IllegalStateException("Cannot set Data Source properties after DataSource has been used"); + } + if (this.dataSourceName != null && dataSourceName != null && dataSourceName.equals(this.dataSourceName)) + { + return ; + } + synchronized (dataSources) + { + if (getDataSource(dataSourceName) != null) + { + throw new IllegalArgumentException("DataSource with name '" + dataSourceName + "' already exists!"); + } + if (this.dataSourceName != null) + { + dataSources.remove(this.dataSourceName); + } + this.dataSourceName = dataSourceName; + dataSources.put(dataSourceName, this); + } + } - /** - * Initializes this DataSource. If the initialConnections is greater than zero, - * that number of connections will be created. After this method is called, - * the DataSource properties cannot be changed. If you do not call this - * explicitly, it will be called the first time you get a connection from the - * Datasource. - * @throws java.sql.SQLException - * Occurs when the initialConnections is greater than zero, but the - * DataSource is not able to create enough physical connections. - */ - public void initialize() throws SQLException { - synchronized (lock) { - source = new ConnectionPool(); - source.setDatabaseName(getDatabaseName()); - source.setPassword(getPassword()); - source.setPortNumber(getPortNumber()); - source.setServerName(getServerName()); - source.setUser(getUser()); - while (available.size() < initialConnections) { - available.push(source.getPooledConnection()); - } - initialized = true; - } - } + /** + * Initializes this DataSource. If the initialConnections is greater than zero, + * that number of connections will be created. After this method is called, + * the DataSource properties cannot be changed. If you do not call this + * explicitly, it will be called the first time you get a connection from the + * Datasource. + * @throws java.sql.SQLException + * Occurs when the initialConnections is greater than zero, but the + * DataSource is not able to create enough physical connections. + */ + public void initialize() throws SQLException + { + synchronized (lock) + { + source = new ConnectionPool(); + source.setDatabaseName(getDatabaseName()); + source.setPassword(getPassword()); + source.setPortNumber(getPortNumber()); + source.setServerName(getServerName()); + source.setUser(getUser()); + while (available.size() < initialConnections) + { + available.push(source.getPooledConnection()); + } + initialized = true; + } + } - /** - * Gets a non-pooled connection, unless the user and password are the - * same as the default values for this connection pool. - * - * @return A pooled connection. - * @throws SQLException - * Occurs when no pooled connection is available, and a new physical - * connection cannot be created. - */ - public Connection getConnection(String user, String password) throws SQLException { - // If this is for the default user/password, use a pooled connection - if(user == null || - (user.equals(getUser()) && ((password == null && getPassword() == null) || (password != null && password.equals(getPassword()))))) { - return getConnection(); - } - // Otherwise, use a non-pooled connection - if (!initialized) { - initialize(); - } - return super.getConnection(user, password); - } + /** + * Gets a non-pooled connection, unless the user and password are the + * same as the default values for this connection pool. + * + * @return A pooled connection. + * @throws SQLException + * Occurs when no pooled connection is available, and a new physical + * connection cannot be created. + */ + public Connection getConnection(String user, String password) throws SQLException + { + // If this is for the default user/password, use a pooled connection + if (user == null || + (user.equals(getUser()) && ((password == null && getPassword() == null) || (password != null && password.equals(getPassword()))))) + { + return getConnection(); + } + // Otherwise, use a non-pooled connection + if (!initialized) + { + initialize(); + } + return super.getConnection(user, password); + } - /** - * Gets a connection from the connection pool. - * - * @return A pooled connection. - * @throws SQLException - * Occurs when no pooled connection is available, and a new physical - * connection cannot be created. - */ - public Connection getConnection() throws SQLException { - if(!initialized) { - initialize(); - } - return getPooledConnection(); - } + /** + * Gets a connection from the connection pool. + * + * @return A pooled connection. + * @throws SQLException + * Occurs when no pooled connection is available, and a new physical + * connection cannot be created. + */ + public Connection getConnection() throws SQLException + { + if (!initialized) + { + initialize(); + } + return getPooledConnection(); + } - /** - * Closes this DataSource, and all the pooled connections, whether in use or not. - */ - public void close() { - synchronized(lock) { - while(available.size() > 0) { - PooledConnectionImpl pci = (PooledConnectionImpl)available.pop(); - try { - pci.close(); - } catch (SQLException e) { - } - } - available = null; - while (used.size() > 0) { - PooledConnectionImpl pci = (PooledConnectionImpl)used.pop(); - pci.removeConnectionEventListener(connectionEventListener); - try { - pci.close(); - } catch (SQLException e) { - } - } - used = null; - } - synchronized (dataSources) { - dataSources.remove(dataSourceName); - } - } + /** + * Closes this DataSource, and all the pooled connections, whether in use or not. + */ + public void close() + { + synchronized (lock) + { + while (available.size() > 0) + { + PooledConnectionImpl pci = (PooledConnectionImpl)available.pop(); + try + { + pci.close(); + } + catch (SQLException e) + {} + } + available = null; + while (used.size() > 0) + { + PooledConnectionImpl pci = (PooledConnectionImpl)used.pop(); + pci.removeConnectionEventListener(connectionEventListener); + try + { + pci.close(); + } + catch (SQLException e) + {} + } + used = null; + } + synchronized (dataSources) + { + dataSources.remove(dataSourceName); + } + } - /** - * Gets a connection from the pool. Will get an available one if - * present, or create a new one if under the max limit. Will - * block if all used and a new one would exceed the max. - */ - private Connection getPooledConnection() throws SQLException { - PooledConnection pc = null; - synchronized(lock) { - if (available == null) { - throw new SQLException("DataSource has been closed."); - } - while(true) { - if(available.size() > 0) { - pc = (PooledConnection)available.pop(); - used.push(pc); - break; - } - if(maxConnections == 0 || used.size() < maxConnections) { - pc = source.getPooledConnection(); - used.push(pc); - break; - } else { - try { - // Wake up every second at a minimum - lock.wait(1000L); - } catch(InterruptedException e) { - } - } - } - } - pc.addConnectionEventListener(connectionEventListener); - return pc.getConnection(); - } + /** + * Gets a connection from the pool. Will get an available one if + * present, or create a new one if under the max limit. Will + * block if all used and a new one would exceed the max. + */ + private Connection getPooledConnection() throws SQLException + { + PooledConnection pc = null; + synchronized (lock) + { + if (available == null) + { + throw new SQLException("DataSource has been closed."); + } + while (true) + { + if (available.size() > 0) + { + pc = (PooledConnection)available.pop(); + used.push(pc); + break; + } + if (maxConnections == 0 || used.size() < maxConnections) + { + pc = source.getPooledConnection(); + used.push(pc); + break; + } + else + { + try + { + // Wake up every second at a minimum + lock.wait(1000L); + } + catch (InterruptedException e) + {} + } + } + } + pc.addConnectionEventListener(connectionEventListener); + return pc.getConnection(); + } - /** - * Notified when a pooled connection is closed, or a fatal error occurs - * on a pooled connection. This is the only way connections are marked - * as unused. - */ - private ConnectionEventListener connectionEventListener = new ConnectionEventListener() { - public void connectionClosed(ConnectionEvent event) { - ((PooledConnection)event.getSource()).removeConnectionEventListener(this); - synchronized(lock) { - if(available == null) { - return; // DataSource has been closed - } - boolean removed = used.remove(event.getSource()); - if(removed) { - available.push(event.getSource()); - // There's now a new connection available - lock.notify(); - } else { - // a connection error occured - } - } - } + /** + * Notified when a pooled connection is closed, or a fatal error occurs + * on a pooled connection. This is the only way connections are marked + * as unused. + */ + private ConnectionEventListener connectionEventListener = new ConnectionEventListener() + { + public void connectionClosed(ConnectionEvent event) + { + ((PooledConnection)event.getSource()).removeConnectionEventListener(this); + synchronized (lock) + { + if (available == null) + { + return ; // DataSource has been closed + } + boolean removed = used.remove(event.getSource()); + if (removed) + { + available.push(event.getSource()); + // There's now a new connection available + lock.notify(); + } + else + { + // a connection error occured + } + } + } - /** - * This is only called for fatal errors, where the physical connection is - * useless afterward and should be removed from the pool. - */ - public void connectionErrorOccurred(ConnectionEvent event) { - ((PooledConnection) event.getSource()).removeConnectionEventListener(this); - synchronized(lock) { - if (available == null) { - return; // DataSource has been closed - } - used.remove(event.getSource()); - // We're now at least 1 connection under the max - lock.notify(); - } - } - }; + /** + * This is only called for fatal errors, where the physical connection is + * useless afterward and should be removed from the pool. + */ + public void connectionErrorOccurred(ConnectionEvent event) + { + ((PooledConnection) event.getSource()).removeConnectionEventListener(this); + synchronized (lock) + { + if (available == null) + { + return ; // DataSource has been closed + } + used.remove(event.getSource()); + // We're now at least 1 connection under the max + lock.notify(); + } + } + }; - /** - * Adds custom properties for this DataSource to the properties defined in - * the superclass. - */ - public Reference getReference() throws NamingException { - Reference ref = super.getReference(); - ref.add(new StringRefAddr("dataSourceName", dataSourceName)); - if (initialConnections > 0) { - ref.add(new StringRefAddr("initialConnections", Integer.toString(initialConnections))); - } - if (maxConnections > 0) { - ref.add(new StringRefAddr("maxConnections", Integer.toString(maxConnections))); - } - return ref; - } + /** + * Adds custom properties for this DataSource to the properties defined in + * the superclass. + */ + public Reference getReference() throws NamingException + { + Reference ref = super.getReference(); + ref.add(new StringRefAddr("dataSourceName", dataSourceName)); + if (initialConnections > 0) + { + ref.add(new StringRefAddr("initialConnections", Integer.toString(initialConnections))); + } + if (maxConnections > 0) + { + ref.add(new StringRefAddr("maxConnections", Integer.toString(maxConnections))); + } + return ref; + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/SimpleDataSource.java b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/SimpleDataSource.java index ca06efd3551732c4b305acaf5db7a5e699a98343..6d9ef39fffb17a1a27c88e0e812572de2acac894 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/optional/SimpleDataSource.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/optional/SimpleDataSource.java @@ -5,18 +5,20 @@ import java.io.Serializable; /** * Simple DataSource which does not perform connection pooling. In order to use - * the DataSource, you must set the property databaseName. The settings for + * the DataSource, you must set the property databaseName. The settings for * serverName, portNumber, user, and password are optional. Note: these properties * are declared in the superclass. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class SimpleDataSource extends BaseDataSource implements Serializable, DataSource { - /** - * Gets a description of this DataSource. - */ - public String getDescription() { - return "Non-Pooling DataSource from "+org.postgresql.Driver.getVersion(); - } +public class SimpleDataSource extends BaseDataSource implements Serializable, DataSource +{ + /** + * Gets a description of this DataSource. + */ + public String getDescription() + { + return "Non-Pooling DataSource from " + org.postgresql.Driver.getVersion(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java index d293c7acf055124855e509a9d3294c5df1fcdb72..c5f4e8bb92d88d241e20ded90232181815957b09 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Blob.java @@ -11,80 +11,84 @@ public abstract class AbstractJdbc3Blob extends org.postgresql.jdbc2.AbstractJdb super(conn, oid); } - /** - * Writes the given array of bytes to the BLOB value that - * this Blob object represents, starting at position - * pos, and returns the number of bytes written. - * - * @param pos the position in the BLOB object at which - * to start writing - * @param bytes the array of bytes to be written to the BLOB - * value that this Blob object represents - * @return the number of bytes written - * @exception SQLException if there is an error accessing the - * BLOB value - * @see #getBytes - * @since 1.4 - */ - public int setBytes(long pos, byte[] bytes) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Writes the given array of bytes to the BLOB value that + * this Blob object represents, starting at position + * pos, and returns the number of bytes written. + * + * @param pos the position in the BLOB object at which + * to start writing + * @param bytes the array of bytes to be written to the BLOB + * value that this Blob object represents + * @return the number of bytes written + * @exception SQLException if there is an error accessing the + * BLOB value + * @see #getBytes + * @since 1.4 + */ + public int setBytes(long pos, byte[] bytes) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Writes all or part of the given byte array to the - * BLOB value that this Blob object represents - * and returns the number of bytes written. - * Writing starts at position pos in the BLOB - * value; len bytes from the given byte array are written. - * - * @param pos the position in the BLOB object at which - * to start writing - * @param bytes the array of bytes to be written to this BLOB - * object - * @param offset the offset into the array bytes at which - * to start reading the bytes to be set - * @param len the number of bytes to be written to the BLOB - * value from the array of bytes bytes - * @return the number of bytes written - * @exception SQLException if there is an error accessing the - * BLOB value - * @see #getBytes - * @since 1.4 - */ - public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Writes all or part of the given byte array to the + * BLOB value that this Blob object represents + * and returns the number of bytes written. + * Writing starts at position pos in the BLOB + * value; len bytes from the given byte array are written. + * + * @param pos the position in the BLOB object at which + * to start writing + * @param bytes the array of bytes to be written to this BLOB + * object + * @param offset the offset into the array bytes at which + * to start reading the bytes to be set + * @param len the number of bytes to be written to the BLOB + * value from the array of bytes bytes + * @return the number of bytes written + * @exception SQLException if there is an error accessing the + * BLOB value + * @see #getBytes + * @since 1.4 + */ + public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves a stream that can be used to write to the BLOB - * value that this Blob object represents. The stream begins - * at position pos. - * - * @param pos the position in the BLOB value at which - * to start writing - * @return a java.io.OutputStream object to which data can - * be written - * @exception SQLException if there is an error accessing the - * BLOB value - * @see #getBinaryStream - * @since 1.4 - */ - public java.io.OutputStream setBinaryStream(long pos) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a stream that can be used to write to the BLOB + * value that this Blob object represents. The stream begins + * at position pos. + * + * @param pos the position in the BLOB value at which + * to start writing + * @return a java.io.OutputStream object to which data can + * be written + * @exception SQLException if there is an error accessing the + * BLOB value + * @see #getBinaryStream + * @since 1.4 + */ + public java.io.OutputStream setBinaryStream(long pos) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Truncates the BLOB value that this Blob - * object represents to be len bytes in length. - * - * @param len the length, in bytes, to which the BLOB value - * that this Blob object represents should be truncated - * @exception SQLException if there is an error accessing the - * BLOB value - * @since 1.4 - */ - public void truncate(long len) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Truncates the BLOB value that this Blob + * object represents to be len bytes in length. + * + * @param len the length, in bytes, to which the BLOB value + * that this Blob object represents should be truncated + * @exception SQLException if there is an error accessing the + * BLOB value + * @since 1.4 + */ + public void truncate(long len) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java index 525530b537d3d3b0a61cf106df557ac2f17ecde2..fb2eb8ad965fdcd452eececf78fc340bc6bb449c 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Clob.java @@ -11,97 +11,102 @@ public abstract class AbstractJdbc3Clob extends org.postgresql.jdbc2.AbstractJdb super(conn, oid); } - /** - * Writes the given Java String to the CLOB - * value that this Clob object designates at the position - * pos. - * - * @param pos the position at which to start writing to the CLOB - * value that this Clob object represents - * @param str the string to be written to the CLOB - * value that this Clob designates - * @return the number of characters written - * @exception SQLException if there is an error accessing the - * CLOB value - * - * @since 1.4 - */ - public int setString(long pos, String str) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Writes the given Java String to the CLOB + * value that this Clob object designates at the position + * pos. + * + * @param pos the position at which to start writing to the CLOB + * value that this Clob object represents + * @param str the string to be written to the CLOB + * value that this Clob designates + * @return the number of characters written + * @exception SQLException if there is an error accessing the + * CLOB value + * + * @since 1.4 + */ + public int setString(long pos, String str) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Writes len characters of str, starting - * at character offset, to the CLOB value - * that this Clob represents. - * - * @param pos the position at which to start writing to this - * CLOB object - * @param str the string to be written to the CLOB - * value that this Clob object represents - * @param offset the offset into str to start reading - * the characters to be written - * @param len the number of characters to be written - * @return the number of characters written - * @exception SQLException if there is an error accessing the - * CLOB value - * - * @since 1.4 - */ - public int setString(long pos, String str, int offset, int len) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Writes len characters of str, starting + * at character offset, to the CLOB value + * that this Clob represents. + * + * @param pos the position at which to start writing to this + * CLOB object + * @param str the string to be written to the CLOB + * value that this Clob object represents + * @param offset the offset into str to start reading + * the characters to be written + * @param len the number of characters to be written + * @return the number of characters written + * @exception SQLException if there is an error accessing the + * CLOB value + * + * @since 1.4 + */ + public int setString(long pos, String str, int offset, int len) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves a stream to be used to write Ascii characters to the - * CLOB value that this Clob object represents, - * starting at position pos. - * - * @param pos the position at which to start writing to this - * CLOB object - * @return the stream to which ASCII encoded characters can be written - * @exception SQLException if there is an error accessing the - * CLOB value - * @see #getAsciiStream - * - * @since 1.4 - */ - public java.io.OutputStream setAsciiStream(long pos) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a stream to be used to write Ascii characters to the + * CLOB value that this Clob object represents, + * starting at position pos. + * + * @param pos the position at which to start writing to this + * CLOB object + * @return the stream to which ASCII encoded characters can be written + * @exception SQLException if there is an error accessing the + * CLOB value + * @see #getAsciiStream + * + * @since 1.4 + */ + public java.io.OutputStream setAsciiStream(long pos) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves a stream to be used to write a stream of Unicode characters - * to the CLOB value that this Clob object - * represents, at position pos. - * - * @param pos the position at which to start writing to the - * CLOB value - * - * @return a stream to which Unicode encoded characters can be written - * @exception SQLException if there is an error accessing the - * CLOB value - * @see #getCharacterStream - * - * @since 1.4 - */ - public java.io.Writer setCharacterStream(long pos) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a stream to be used to write a stream of Unicode characters + * to the CLOB value that this Clob object + * represents, at position pos. + * + * @param pos the position at which to start writing to the + * CLOB value + * + * @return a stream to which Unicode encoded characters can be written + * @exception SQLException if there is an error accessing the + * CLOB value + * @see #getCharacterStream + * + * @since 1.4 + */ + public java.io.Writer setCharacterStream(long pos) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Truncates the CLOB value that this Clob - * designates to have a length of len - * characters. - * @param len the length, in bytes, to which the CLOB value - * should be truncated - * @exception SQLException if there is an error accessing the - * CLOB value - * - * @since 1.4 - */ - public void truncate(long len) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Truncates the CLOB value that this Clob + * designates to have a length of len + * characters. + * @param len the length, in bytes, to which the CLOB value + * should be truncated + * @exception SQLException if there is an error accessing the + * CLOB value + * + * @since 1.4 + */ + public void truncate(long len) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java index 5988eddb4db4756b62fac75b845b6db5ff1bc1f8..710d21557bc24de7d6b07927512955da3d75316a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Connection.java @@ -2,7 +2,7 @@ package org.postgresql.jdbc3; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Connection.java,v 1.1 2002/08/14 20:35:39 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc3 specification. This class extends * org.postgresql.jdbc2.AbstractJdbc2Connection which provides the jdbc2 * methods. The real Connection class (for jdbc3) is org.postgresql.jdbc3.Jdbc3Connection @@ -10,359 +10,371 @@ import java.sql.*; public abstract class AbstractJdbc3Connection extends org.postgresql.jdbc2.AbstractJdbc2Connection { - /** - * Changes the holdability of ResultSet objects - * created using this Connection object to the given - * holdability. - * - * @param holdability a ResultSet holdability constant; one of - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @throws SQLException if a database access occurs, the given parameter - * is not a ResultSet constant indicating holdability, - * or the given holdability is not supported - * @see #getHoldability - * @see ResultSet - * @since 1.4 - */ - public void setHoldability(int holdability) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Changes the holdability of ResultSet objects + * created using this Connection object to the given + * holdability. + * + * @param holdability a ResultSet holdability constant; one of + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @throws SQLException if a database access occurs, the given parameter + * is not a ResultSet constant indicating holdability, + * or the given holdability is not supported + * @see #getHoldability + * @see ResultSet + * @since 1.4 + */ + public void setHoldability(int holdability) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the current holdability of ResultSet objects - * created using this Connection object. - * - * @return the holdability, one of - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @throws SQLException if a database access occurs - * @see #setHoldability - * @see ResultSet - * @since 1.4 - */ - public int getHoldability() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Creates an unnamed savepoint in the current transaction and - * returns the new Savepoint object that represents it. - * - * @return the new Savepoint object - * @exception SQLException if a database access error occurs - * or this Connection object is currently in - * auto-commit mode - * @see Savepoint - * @since 1.4 - */ - public Savepoint setSavepoint() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Creates a savepoint with the given name in the current transaction - * and returns the new Savepoint object that represents it. - * - * @param name a String containing the name of the savepoint - * @return the new Savepoint object - * @exception SQLException if a database access error occurs - * or this Connection object is currently in - * auto-commit mode - * @see Savepoint - * @since 1.4 - */ - public Savepoint setSavepoint(String name) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Undoes all changes made after the given Savepoint object - * was set. - *

- * This method should be used only when auto-commit has been disabled. - * - * @param savepoint the Savepoint object to roll back to - * @exception SQLException if a database access error occurs, - * the Savepoint object is no longer valid, - * or this Connection object is currently in - * auto-commit mode - * @see Savepoint - * @see #rollback - * @since 1.4 - */ - public void rollback(Savepoint savepoint) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Retrieves the current holdability of ResultSet objects + * created using this Connection object. + * + * @return the holdability, one of + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @throws SQLException if a database access occurs + * @see #setHoldability + * @see ResultSet + * @since 1.4 + */ + public int getHoldability() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Removes the given Savepoint object from the current - * transaction. Any reference to the savepoint after it have been removed - * will cause an SQLException to be thrown. - * - * @param savepoint the Savepoint object to be removed - * @exception SQLException if a database access error occurs or - * the given Savepoint object is not a valid - * savepoint in the current transaction - * @since 1.4 - */ - public void releaseSavepoint(Savepoint savepoint) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Creates an unnamed savepoint in the current transaction and + * returns the new Savepoint object that represents it. + * + * @return the new Savepoint object + * @exception SQLException if a database access error occurs + * or this Connection object is currently in + * auto-commit mode + * @see Savepoint + * @since 1.4 + */ + public Savepoint setSavepoint() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Creates a Statement object that will generate - * ResultSet objects with the given type, concurrency, - * and holdability. - * This method is the same as the createStatement method - * above, but it allows the default result set - * type, concurrency, and holdability to be overridden. - * - * @param resultSetType one of the following ResultSet - * constants: - * ResultSet.TYPE_FORWARD_ONLY, - * ResultSet.TYPE_SCROLL_INSENSITIVE, or - * ResultSet.TYPE_SCROLL_SENSITIVE - * @param resultSetConcurrency one of the following ResultSet - * constants: - * ResultSet.CONCUR_READ_ONLY or - * ResultSet.CONCUR_UPDATABLE - * @param resultSetHoldability one of the following ResultSet - * constants: - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @return a new Statement object that will generate - * ResultSet objects with the given type, - * concurrency, and holdability - * @exception SQLException if a database access error occurs - * or the given parameters are not ResultSet - * constants indicating type, concurrency, and holdability - * @see ResultSet - * @since 1.4 - */ - public Statement createStatement(int resultSetType, int resultSetConcurrency, - int resultSetHoldability) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Creates a savepoint with the given name in the current transaction + * and returns the new Savepoint object that represents it. + * + * @param name a String containing the name of the savepoint + * @return the new Savepoint object + * @exception SQLException if a database access error occurs + * or this Connection object is currently in + * auto-commit mode + * @see Savepoint + * @since 1.4 + */ + public Savepoint setSavepoint(String name) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Creates a PreparedStatement object that will generate - * ResultSet objects with the given type, concurrency, - * and holdability. - *

- * This method is the same as the prepareStatement method - * above, but it allows the default result set - * type, concurrency, and holdability to be overridden. - * - * @param sql a String object that is the SQL statement to - * be sent to the database; may contain one or more ? IN - * parameters - * @param resultSetType one of the following ResultSet - * constants: - * ResultSet.TYPE_FORWARD_ONLY, - * ResultSet.TYPE_SCROLL_INSENSITIVE, or - * ResultSet.TYPE_SCROLL_SENSITIVE - * @param resultSetConcurrency one of the following ResultSet - * constants: - * ResultSet.CONCUR_READ_ONLY or - * ResultSet.CONCUR_UPDATABLE - * @param resultSetHoldability one of the following ResultSet - * constants: - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @return a new PreparedStatement object, containing the - * pre-compiled SQL statement, that will generate - * ResultSet objects with the given type, - * concurrency, and holdability - * @exception SQLException if a database access error occurs - * or the given parameters are not ResultSet - * constants indicating type, concurrency, and holdability - * @see ResultSet - * @since 1.4 - */ - public PreparedStatement prepareStatement(String sql, int resultSetType, - int resultSetConcurrency, int resultSetHoldability) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Undoes all changes made after the given Savepoint object + * was set. + *

+ * This method should be used only when auto-commit has been disabled. + * + * @param savepoint the Savepoint object to roll back to + * @exception SQLException if a database access error occurs, + * the Savepoint object is no longer valid, + * or this Connection object is currently in + * auto-commit mode + * @see Savepoint + * @see #rollback + * @since 1.4 + */ + public void rollback(Savepoint savepoint) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Creates a CallableStatement object that will generate - * ResultSet objects with the given type and concurrency. - * This method is the same as the prepareCall method - * above, but it allows the default result set - * type, result set concurrency type and holdability to be overridden. - * - * @param sql a String object that is the SQL statement to - * be sent to the database; may contain on or more ? parameters - * @param resultSetType one of the following ResultSet - * constants: - * ResultSet.TYPE_FORWARD_ONLY, - * ResultSet.TYPE_SCROLL_INSENSITIVE, or - * ResultSet.TYPE_SCROLL_SENSITIVE - * @param resultSetConcurrency one of the following ResultSet - * constants: - * ResultSet.CONCUR_READ_ONLY or - * ResultSet.CONCUR_UPDATABLE - * @param resultSetHoldability one of the following ResultSet - * constants: - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @return a new CallableStatement object, containing the - * pre-compiled SQL statement, that will generate - * ResultSet objects with the given type, - * concurrency, and holdability - * @exception SQLException if a database access error occurs - * or the given parameters are not ResultSet - * constants indicating type, concurrency, and holdability - * @see ResultSet - * @since 1.4 - */ - public CallableStatement prepareCall(String sql, int resultSetType, - int resultSetConcurrency, - int resultSetHoldability) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Removes the given Savepoint object from the current + * transaction. Any reference to the savepoint after it have been removed + * will cause an SQLException to be thrown. + * + * @param savepoint the Savepoint object to be removed + * @exception SQLException if a database access error occurs or + * the given Savepoint object is not a valid + * savepoint in the current transaction + * @since 1.4 + */ + public void releaseSavepoint(Savepoint savepoint) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Creates a default PreparedStatement object that has - * the capability to retrieve auto-generated keys. The given constant - * tells the driver whether it should make auto-generated keys - * available for retrieval. This parameter is ignored if the SQL - * statement is not an INSERT statement. - *

- * Note: This method is optimized for handling - * parametric SQL statements that benefit from precompilation. If - * the driver supports precompilation, - * the method prepareStatement will send - * the statement to the database for precompilation. Some drivers - * may not support precompilation. In this case, the statement may - * not be sent to the database until the PreparedStatement - * object is executed. This has no direct effect on users; however, it does - * affect which methods throw certain SQLExceptions. - *

- * Result sets created using the returned PreparedStatement - * object will by default be type TYPE_FORWARD_ONLY - * and have a concurrency level of CONCUR_READ_ONLY. - * - * @param sql an SQL statement that may contain one or more '?' IN - * parameter placeholders - * @param autoGeneratedKeys a flag indicating whether auto-generated keys - * should be returned; one of the following Statement - * constants: - * @param autoGeneratedKeys a flag indicating that auto-generated keys should be returned, one of - * Statement.RETURN_GENERATED_KEYS or - * Statement.NO_GENERATED_KEYS. - * @return a new PreparedStatement object, containing the - * pre-compiled SQL statement, that will have the capability of - * returning auto-generated keys - * @exception SQLException if a database access error occurs - * or the given parameter is not a Statement - * constant indicating whether auto-generated keys should be - * returned - * @since 1.4 - */ - public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Creates a default PreparedStatement object capable - * of returning the auto-generated keys designated by the given array. - * This array contains the indexes of the columns in the target - * table that contain the auto-generated keys that should be made - * available. This array is ignored if the SQL - * statement is not an INSERT statement. - *

- * An SQL statement with or without IN parameters can be - * pre-compiled and stored in a PreparedStatement object. This - * object can then be used to efficiently execute this statement - * multiple times. - *

- * Note: This method is optimized for handling - * parametric SQL statements that benefit from precompilation. If - * the driver supports precompilation, - * the method prepareStatement will send - * the statement to the database for precompilation. Some drivers - * may not support precompilation. In this case, the statement may - * not be sent to the database until the PreparedStatement - * object is executed. This has no direct effect on users; however, it does - * affect which methods throw certain SQLExceptions. - *

- * Result sets created using the returned PreparedStatement - * object will by default be type TYPE_FORWARD_ONLY - * and have a concurrency level of CONCUR_READ_ONLY. - * - * @param sql an SQL statement that may contain one or more '?' IN - * parameter placeholders - * @param columnIndexes an array of column indexes indicating the columns - * that should be returned from the inserted row or rows - * @return a new PreparedStatement object, containing the - * pre-compiled statement, that is capable of returning the - * auto-generated keys designated by the given array of column - * indexes - * @exception SQLException if a database access error occurs - * - * @since 1.4 - */ - public PreparedStatement prepareStatement(String sql, int columnIndexes[]) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - + /** + * Creates a Statement object that will generate + * ResultSet objects with the given type, concurrency, + * and holdability. + * This method is the same as the createStatement method + * above, but it allows the default result set + * type, concurrency, and holdability to be overridden. + * + * @param resultSetType one of the following ResultSet + * constants: + * ResultSet.TYPE_FORWARD_ONLY, + * ResultSet.TYPE_SCROLL_INSENSITIVE, or + * ResultSet.TYPE_SCROLL_SENSITIVE + * @param resultSetConcurrency one of the following ResultSet + * constants: + * ResultSet.CONCUR_READ_ONLY or + * ResultSet.CONCUR_UPDATABLE + * @param resultSetHoldability one of the following ResultSet + * constants: + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @return a new Statement object that will generate + * ResultSet objects with the given type, + * concurrency, and holdability + * @exception SQLException if a database access error occurs + * or the given parameters are not ResultSet + * constants indicating type, concurrency, and holdability + * @see ResultSet + * @since 1.4 + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + /** + * Creates a PreparedStatement object that will generate + * ResultSet objects with the given type, concurrency, + * and holdability. + *

+ * This method is the same as the prepareStatement method + * above, but it allows the default result set + * type, concurrency, and holdability to be overridden. + * + * @param sql a String object that is the SQL statement to + * be sent to the database; may contain one or more ? IN + * parameters + * @param resultSetType one of the following ResultSet + * constants: + * ResultSet.TYPE_FORWARD_ONLY, + * ResultSet.TYPE_SCROLL_INSENSITIVE, or + * ResultSet.TYPE_SCROLL_SENSITIVE + * @param resultSetConcurrency one of the following ResultSet + * constants: + * ResultSet.CONCUR_READ_ONLY or + * ResultSet.CONCUR_UPDATABLE + * @param resultSetHoldability one of the following ResultSet + * constants: + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @return a new PreparedStatement object, containing the + * pre-compiled SQL statement, that will generate + * ResultSet objects with the given type, + * concurrency, and holdability + * @exception SQLException if a database access error occurs + * or the given parameters are not ResultSet + * constants indicating type, concurrency, and holdability + * @see ResultSet + * @since 1.4 + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + /** + * Creates a CallableStatement object that will generate + * ResultSet objects with the given type and concurrency. + * This method is the same as the prepareCall method + * above, but it allows the default result set + * type, result set concurrency type and holdability to be overridden. + * + * @param sql a String object that is the SQL statement to + * be sent to the database; may contain on or more ? parameters + * @param resultSetType one of the following ResultSet + * constants: + * ResultSet.TYPE_FORWARD_ONLY, + * ResultSet.TYPE_SCROLL_INSENSITIVE, or + * ResultSet.TYPE_SCROLL_SENSITIVE + * @param resultSetConcurrency one of the following ResultSet + * constants: + * ResultSet.CONCUR_READ_ONLY or + * ResultSet.CONCUR_UPDATABLE + * @param resultSetHoldability one of the following ResultSet + * constants: + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @return a new CallableStatement object, containing the + * pre-compiled SQL statement, that will generate + * ResultSet objects with the given type, + * concurrency, and holdability + * @exception SQLException if a database access error occurs + * or the given parameters are not ResultSet + * constants indicating type, concurrency, and holdability + * @see ResultSet + * @since 1.4 + */ + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + + /** + * Creates a default PreparedStatement object that has + * the capability to retrieve auto-generated keys. The given constant + * tells the driver whether it should make auto-generated keys + * available for retrieval. This parameter is ignored if the SQL + * statement is not an INSERT statement. + *

+ * Note: This method is optimized for handling + * parametric SQL statements that benefit from precompilation. If + * the driver supports precompilation, + * the method prepareStatement will send + * the statement to the database for precompilation. Some drivers + * may not support precompilation. In this case, the statement may + * not be sent to the database until the PreparedStatement + * object is executed. This has no direct effect on users; however, it does + * affect which methods throw certain SQLExceptions. + *

+ * Result sets created using the returned PreparedStatement + * object will by default be type TYPE_FORWARD_ONLY + * and have a concurrency level of CONCUR_READ_ONLY. + * + * @param sql an SQL statement that may contain one or more '?' IN + * parameter placeholders + * @param autoGeneratedKeys a flag indicating whether auto-generated keys + * should be returned; one of the following Statement + * constants: + * @param autoGeneratedKeys a flag indicating that auto-generated keys should be returned, one of + * Statement.RETURN_GENERATED_KEYS or + * Statement.NO_GENERATED_KEYS. + * @return a new PreparedStatement object, containing the + * pre-compiled SQL statement, that will have the capability of + * returning auto-generated keys + * @exception SQLException if a database access error occurs + * or the given parameter is not a Statement + * constant indicating whether auto-generated keys should be + * returned + * @since 1.4 + */ + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + /** + * Creates a default PreparedStatement object capable + * of returning the auto-generated keys designated by the given array. + * This array contains the indexes of the columns in the target + * table that contain the auto-generated keys that should be made + * available. This array is ignored if the SQL + * statement is not an INSERT statement. + *

+ * An SQL statement with or without IN parameters can be + * pre-compiled and stored in a PreparedStatement object. This + * object can then be used to efficiently execute this statement + * multiple times. + *

+ * Note: This method is optimized for handling + * parametric SQL statements that benefit from precompilation. If + * the driver supports precompilation, + * the method prepareStatement will send + * the statement to the database for precompilation. Some drivers + * may not support precompilation. In this case, the statement may + * not be sent to the database until the PreparedStatement + * object is executed. This has no direct effect on users; however, it does + * affect which methods throw certain SQLExceptions. + *

+ * Result sets created using the returned PreparedStatement + * object will by default be type TYPE_FORWARD_ONLY + * and have a concurrency level of CONCUR_READ_ONLY. + * + * @param sql an SQL statement that may contain one or more '?' IN + * parameter placeholders + * @param columnIndexes an array of column indexes indicating the columns + * that should be returned from the inserted row or rows + * @return a new PreparedStatement object, containing the + * pre-compiled statement, that is capable of returning the + * auto-generated keys designated by the given array of column + * indexes + * @exception SQLException if a database access error occurs + * + * @since 1.4 + */ + public PreparedStatement prepareStatement(String sql, int columnIndexes[]) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + /** + * Creates a default PreparedStatement object capable + * of returning the auto-generated keys designated by the given array. + * This array contains the names of the columns in the target + * table that contain the auto-generated keys that should be returned. + * This array is ignored if the SQL + * statement is not an INSERT statement. + *

+ * An SQL statement with or without IN parameters can be + * pre-compiled and stored in a PreparedStatement object. This + * object can then be used to efficiently execute this statement + * multiple times. + *

+ * Note: This method is optimized for handling + * parametric SQL statements that benefit from precompilation. If + * the driver supports precompilation, + * the method prepareStatement will send + * the statement to the database for precompilation. Some drivers + * may not support precompilation. In this case, the statement may + * not be sent to the database until the PreparedStatement + * object is executed. This has no direct effect on users; however, it does + * affect which methods throw certain SQLExceptions. + *

+ * Result sets created using the returned PreparedStatement + * object will by default be type TYPE_FORWARD_ONLY + * and have a concurrency level of CONCUR_READ_ONLY. + * + * @param sql an SQL statement that may contain one or more '?' IN + * parameter placeholders + * @param columnNames an array of column names indicating the columns + * that should be returned from the inserted row or rows + * @return a new PreparedStatement object, containing the + * pre-compiled statement, that is capable of returning the + * auto-generated keys designated by the given array of column + * names + * @exception SQLException if a database access error occurs + * + * @since 1.4 + */ + public PreparedStatement prepareStatement(String sql, String columnNames[]) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Creates a default PreparedStatement object capable - * of returning the auto-generated keys designated by the given array. - * This array contains the names of the columns in the target - * table that contain the auto-generated keys that should be returned. - * This array is ignored if the SQL - * statement is not an INSERT statement. - *

- * An SQL statement with or without IN parameters can be - * pre-compiled and stored in a PreparedStatement object. This - * object can then be used to efficiently execute this statement - * multiple times. - *

- * Note: This method is optimized for handling - * parametric SQL statements that benefit from precompilation. If - * the driver supports precompilation, - * the method prepareStatement will send - * the statement to the database for precompilation. Some drivers - * may not support precompilation. In this case, the statement may - * not be sent to the database until the PreparedStatement - * object is executed. This has no direct effect on users; however, it does - * affect which methods throw certain SQLExceptions. - *

- * Result sets created using the returned PreparedStatement - * object will by default be type TYPE_FORWARD_ONLY - * and have a concurrency level of CONCUR_READ_ONLY. - * - * @param sql an SQL statement that may contain one or more '?' IN - * parameter placeholders - * @param columnNames an array of column names indicating the columns - * that should be returned from the inserted row or rows - * @return a new PreparedStatement object, containing the - * pre-compiled statement, that is capable of returning the - * auto-generated keys designated by the given array of column - * names - * @exception SQLException if a database access error occurs - * - * @since 1.4 - */ - public PreparedStatement prepareStatement(String sql, String columnNames[]) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java index 0c2e61d3a266f933b3a5fc47056cb0f3470ba4bf..5d34547737dad5bb08040aa332a3d5f9b64eb840 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java @@ -8,332 +8,348 @@ public abstract class AbstractJdbc3DatabaseMetaData extends org.postgresql.jdbc2 public AbstractJdbc3DatabaseMetaData(AbstractJdbc3Connection conn) { - super(conn); + super(conn); } - /** - * Retrieves whether this database supports savepoints. - * - * @return true if savepoints are supported; - * false otherwise - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public boolean supportsSavepoints() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves whether this database supports savepoints. + * + * @return true if savepoints are supported; + * false otherwise + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public boolean supportsSavepoints() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves whether this database supports named parameters to callable - * statements. - * - * @return true if named parameters are supported; - * false otherwise - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public boolean supportsNamedParameters() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves whether this database supports named parameters to callable + * statements. + * + * @return true if named parameters are supported; + * false otherwise + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public boolean supportsNamedParameters() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves whether it is possible to have multiple ResultSet objects - * returned from a CallableStatement object - * simultaneously. - * - * @return true if a CallableStatement object - * can return multiple ResultSet objects - * simultaneously; false otherwise - * @exception SQLException if a datanase access error occurs - * @since 1.4 - */ - public boolean supportsMultipleOpenResults() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves whether it is possible to have multiple ResultSet objects + * returned from a CallableStatement object + * simultaneously. + * + * @return true if a CallableStatement object + * can return multiple ResultSet objects + * simultaneously; false otherwise + * @exception SQLException if a datanase access error occurs + * @since 1.4 + */ + public boolean supportsMultipleOpenResults() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves whether auto-generated keys can be retrieved after - * a statement has been executed. - * - * @return true if auto-generated keys can be retrieved - * after a statement has executed; false otherwise - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public boolean supportsGetGeneratedKeys() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves whether auto-generated keys can be retrieved after + * a statement has been executed. + * + * @return true if auto-generated keys can be retrieved + * after a statement has executed; false otherwise + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public boolean supportsGetGeneratedKeys() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves a description of the user-defined type (UDT) hierarchies defined in a - * particular schema in this database. Only the immediate super type/ - * sub type relationship is modeled. - *

- * Only supertype information for UDTs matching the catalog, - * schema, and type name is returned. The type name parameter - * may be a fully-qualified name. When the UDT name supplied is a - * fully-qualified name, the catalog and schemaPattern parameters are - * ignored. - *

- * If a UDT does not have a direct super type, it is not listed here. - * A row of the ResultSet object returned by this method - * describes the designated UDT and a direct supertype. A row has the following - * columns: - *

    - *
  1. TYPE_CAT String => the UDT's catalog (may be null) - *
  2. TYPE_SCHEM String => UDT's schema (may be null) - *
  3. TYPE_NAME String => type name of the UDT - *
  4. SUPERTYPE_CAT String => the direct super type's catalog - * (may be null) - *
  5. SUPERTYPE_SCHEM String => the direct super type's schema - * (may be null) - *
  6. SUPERTYPE_NAME String => the direct super type's name - *
- * - *

Note: If the driver does not support type hierarchies, an - * empty result set is returned. - * - * @param catalog a catalog name; "" retrieves those without a catalog; - * null means drop catalog name from the selection criteria - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param typeNamePattern a UDT name pattern; may be a fully-qualified - * name - * @return a ResultSet object in which a row gives information - * about the designated UDT - * @throws SQLException if a database access error occurs - * @since 1.4 - */ - public ResultSet getSuperTypes(String catalog, String schemaPattern, - String typeNamePattern) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves a description of the table hierarchies defined in a particular - * schema in this database. - * - *

Only supertable information for tables matching the catalog, schema - * and table name are returned. The table name parameter may be a fully- - * qualified name, in which case, the catalog and schemaPattern parameters - * are ignored. If a table does not have a super table, it is not listed here. - * Supertables have to be defined in the same catalog and schema as the - * sub tables. Therefore, the type description does not need to include - * this information for the supertable. - * - *

Each type description has the following columns: - *

    - *
  1. TABLE_CAT String => the type's catalog (may be null) - *
  2. TABLE_SCHEM String => type's schema (may be null) - *
  3. TABLE_NAME String => type name - *
  4. SUPERTABLE_NAME String => the direct super type's name - *
- * - *

Note: If the driver does not support type hierarchies, an - * empty result set is returned. - * - * @param catalog a catalog name; "" retrieves those without a catalog; - * null means drop catalog name from the selection criteria - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern; may be a fully-qualified - * name - * @return a ResultSet object in which each row is a type description - * @throws SQLException if a database access error occurs - * @since 1.4 - */ - public ResultSet getSuperTables(String catalog, String schemaPattern, - String tableNamePattern) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a description of the user-defined type (UDT) hierarchies defined in a + * particular schema in this database. Only the immediate super type/ + * sub type relationship is modeled. + *

+ * Only supertype information for UDTs matching the catalog, + * schema, and type name is returned. The type name parameter + * may be a fully-qualified name. When the UDT name supplied is a + * fully-qualified name, the catalog and schemaPattern parameters are + * ignored. + *

+ * If a UDT does not have a direct super type, it is not listed here. + * A row of the ResultSet object returned by this method + * describes the designated UDT and a direct supertype. A row has the following + * columns: + *

    + *
  1. TYPE_CAT String => the UDT's catalog (may be null) + *
  2. TYPE_SCHEM String => UDT's schema (may be null) + *
  3. TYPE_NAME String => type name of the UDT + *
  4. SUPERTYPE_CAT String => the direct super type's catalog + * (may be null) + *
  5. SUPERTYPE_SCHEM String => the direct super type's schema + * (may be null) + *
  6. SUPERTYPE_NAME String => the direct super type's name + *
+ * + *

Note: If the driver does not support type hierarchies, an + * empty result set is returned. + * + * @param catalog a catalog name; "" retrieves those without a catalog; + * null means drop catalog name from the selection criteria + * @param schemaPattern a schema name pattern; "" retrieves those + * without a schema + * @param typeNamePattern a UDT name pattern; may be a fully-qualified + * name + * @return a ResultSet object in which a row gives information + * about the designated UDT + * @throws SQLException if a database access error occurs + * @since 1.4 + */ + public ResultSet getSuperTypes(String catalog, String schemaPattern, + String typeNamePattern) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves a description of the given attribute of the given type - * for a user-defined type (UDT) that is available in the given schema - * and catalog. - *

- * Descriptions are returned only for attributes of UDTs matching the - * catalog, schema, type, and attribute name criteria. They are ordered by - * TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description - * does not contain inherited attributes. - *

- * The ResultSet object that is returned has the following - * columns: - *

    - *
  1. TYPE_CAT String => type catalog (may be null) - *
  2. TYPE_SCHEM String => type schema (may be null) - *
  3. TYPE_NAME String => type name - *
  4. ATTR_NAME String => attribute name - *
  5. DATA_TYPE short => attribute type SQL type from java.sql.Types - *
  6. ATTR_TYPE_NAME String => Data source dependent type name. - * For a UDT, the type name is fully qualified. For a REF, the type name is - * fully qualified and represents the target type of the reference type. - *
  7. ATTR_SIZE int => column size. For char or date - * types this is the maximum number of characters; for numeric or - * decimal types this is precision. - *
  8. DECIMAL_DIGITS int => the number of fractional digits - *
  9. NUM_PREC_RADIX int => Radix (typically either 10 or 2) - *
  10. NULLABLE int => whether NULL is allowed - *
      - *
    • attributeNoNulls - might not allow NULL values - *
    • attributeNullable - definitely allows NULL values - *
    • attributeNullableUnknown - nullability unknown - *
    - *
  11. REMARKS String => comment describing column (may be null) - *
  12. ATTR_DEF String => default value (may be null) - *
  13. SQL_DATA_TYPE int => unused - *
  14. SQL_DATETIME_SUB int => unused - *
  15. CHAR_OCTET_LENGTH int => for char types the - * maximum number of bytes in the column - *
  16. ORDINAL_POSITION int => index of column in table - * (starting at 1) - *
  17. IS_NULLABLE String => "NO" means column definitely - * does not allow NULL values; "YES" means the column might - * allow NULL values. An empty string means unknown. - *
  18. SCOPE_CATALOG String => catalog of table that is the - * scope of a reference attribute (null if DATA_TYPE isn't REF) - *
  19. SCOPE_SCHEMA String => schema of table that is the - * scope of a reference attribute (null if DATA_TYPE isn't REF) - *
  20. SCOPE_TABLE String => table name that is the scope of a - * reference attribute (null if the DATA_TYPE isn't REF) - *
  21. SOURCE_DATA_TYPE short => source type of a distinct type or user-generated - * Ref type,SQL type from java.sql.Types (null if DATA_TYPE - * isn't DISTINCT or user-generated REF) - *
- * @param catalog a catalog name; must match the catalog name as it - * is stored in the database; "" retrieves those without a catalog; - * null means that the catalog name should not be used to narrow - * the search - * @param schemaPattern a schema name pattern; must match the schema name - * as it is stored in the database; "" retrieves those without a schema; - * null means that the schema name should not be used to narrow - * the search - * @param typeNamePattern a type name pattern; must match the - * type name as it is stored in the database - * @param attributeNamePattern an attribute name pattern; must match the attribute - * name as it is declared in the database - * @return a ResultSet object in which each row is an - * attribute description - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public ResultSet getAttributes(String catalog, String schemaPattern, - String typeNamePattern, String attributeNamePattern) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a description of the table hierarchies defined in a particular + * schema in this database. + * + *

Only supertable information for tables matching the catalog, schema + * and table name are returned. The table name parameter may be a fully- + * qualified name, in which case, the catalog and schemaPattern parameters + * are ignored. If a table does not have a super table, it is not listed here. + * Supertables have to be defined in the same catalog and schema as the + * sub tables. Therefore, the type description does not need to include + * this information for the supertable. + * + *

Each type description has the following columns: + *

    + *
  1. TABLE_CAT String => the type's catalog (may be null) + *
  2. TABLE_SCHEM String => type's schema (may be null) + *
  3. TABLE_NAME String => type name + *
  4. SUPERTABLE_NAME String => the direct super type's name + *
+ * + *

Note: If the driver does not support type hierarchies, an + * empty result set is returned. + * + * @param catalog a catalog name; "" retrieves those without a catalog; + * null means drop catalog name from the selection criteria + * @param schemaPattern a schema name pattern; "" retrieves those + * without a schema + * @param tableNamePattern a table name pattern; may be a fully-qualified + * name + * @return a ResultSet object in which each row is a type description + * @throws SQLException if a database access error occurs + * @since 1.4 + */ + public ResultSet getSuperTables(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves whether this database supports the given result set holdability. - * - * @param holdability one of the following constants: - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @return true if so; false otherwise - * @exception SQLException if a database access error occurs - * @see Connection - * @since 1.4 - */ - public boolean supportsResultSetHoldability(int holdability) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves a description of the given attribute of the given type + * for a user-defined type (UDT) that is available in the given schema + * and catalog. + *

+ * Descriptions are returned only for attributes of UDTs matching the + * catalog, schema, type, and attribute name criteria. They are ordered by + * TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description + * does not contain inherited attributes. + *

+ * The ResultSet object that is returned has the following + * columns: + *

    + *
  1. TYPE_CAT String => type catalog (may be null) + *
  2. TYPE_SCHEM String => type schema (may be null) + *
  3. TYPE_NAME String => type name + *
  4. ATTR_NAME String => attribute name + *
  5. DATA_TYPE short => attribute type SQL type from java.sql.Types + *
  6. ATTR_TYPE_NAME String => Data source dependent type name. + * For a UDT, the type name is fully qualified. For a REF, the type name is + * fully qualified and represents the target type of the reference type. + *
  7. ATTR_SIZE int => column size. For char or date + * types this is the maximum number of characters; for numeric or + * decimal types this is precision. + *
  8. DECIMAL_DIGITS int => the number of fractional digits + *
  9. NUM_PREC_RADIX int => Radix (typically either 10 or 2) + *
  10. NULLABLE int => whether NULL is allowed + *
      + *
    • attributeNoNulls - might not allow NULL values + *
    • attributeNullable - definitely allows NULL values + *
    • attributeNullableUnknown - nullability unknown + *
    + *
  11. REMARKS String => comment describing column (may be null) + *
  12. ATTR_DEF String => default value (may be null) + *
  13. SQL_DATA_TYPE int => unused + *
  14. SQL_DATETIME_SUB int => unused + *
  15. CHAR_OCTET_LENGTH int => for char types the + * maximum number of bytes in the column + *
  16. ORDINAL_POSITION int => index of column in table + * (starting at 1) + *
  17. IS_NULLABLE String => "NO" means column definitely + * does not allow NULL values; "YES" means the column might + * allow NULL values. An empty string means unknown. + *
  18. SCOPE_CATALOG String => catalog of table that is the + * scope of a reference attribute (null if DATA_TYPE isn't REF) + *
  19. SCOPE_SCHEMA String => schema of table that is the + * scope of a reference attribute (null if DATA_TYPE isn't REF) + *
  20. SCOPE_TABLE String => table name that is the scope of a + * reference attribute (null if the DATA_TYPE isn't REF) + *
  21. SOURCE_DATA_TYPE short => source type of a distinct type or user-generated + * Ref type,SQL type from java.sql.Types (null if DATA_TYPE + * isn't DISTINCT or user-generated REF) + *
+ * @param catalog a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * null means that the catalog name should not be used to narrow + * the search + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * null means that the schema name should not be used to narrow + * the search + * @param typeNamePattern a type name pattern; must match the + * type name as it is stored in the database + * @param attributeNamePattern an attribute name pattern; must match the attribute + * name as it is declared in the database + * @return a ResultSet object in which each row is an + * attribute description + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public ResultSet getAttributes(String catalog, String schemaPattern, + String typeNamePattern, String attributeNamePattern) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the default holdability of this ResultSet - * object. - * - * @return the default holdability; either - * ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public int getResultSetHoldability() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves whether this database supports the given result set holdability. + * + * @param holdability one of the following constants: + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @return true if so; false otherwise + * @exception SQLException if a database access error occurs + * @see Connection + * @since 1.4 + */ + public boolean supportsResultSetHoldability(int holdability) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the major version number of the underlying database. - * - * @return the underlying database's major version - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public int getDatabaseMajorVersion() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves the default holdability of this ResultSet + * object. + * + * @return the default holdability; either + * ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public int getResultSetHoldability() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the major version number of the underlying database. + * + * @return the underlying database's major version + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public int getDatabaseMajorVersion() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the minor version number of the underlying database. - * - * @return underlying database's minor version - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public int getDatabaseMinorVersion() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves the minor version number of the underlying database. + * + * @return underlying database's minor version + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public int getDatabaseMinorVersion() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the major JDBC version number for this - * driver. - * - * @return JDBC version major number - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public int getJDBCMajorVersion() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves the major JDBC version number for this + * driver. + * + * @return JDBC version major number + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public int getJDBCMajorVersion() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves the minor JDBC version number for this - * driver. - * - * @return JDBC version minor number - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public int getJDBCMinorVersion() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves the minor JDBC version number for this + * driver. + * + * @return JDBC version minor number + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public int getJDBCMinorVersion() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Indicates whether the SQLSTATEs returned by SQLException.getSQLState - * is X/Open (now known as Open Group) SQL CLI or SQL99. - * @return the type of SQLSTATEs, one of: - * sqlStateXOpen or - * sqlStateSQL99 - * @throws SQLException if a database access error occurs - * @since 1.4 - */ - public int getSQLStateType() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Indicates whether the SQLSTATEs returned by SQLException.getSQLState + * is X/Open (now known as Open Group) SQL CLI or SQL99. + * @return the type of SQLSTATEs, one of: + * sqlStateXOpen or + * sqlStateSQL99 + * @throws SQLException if a database access error occurs + * @since 1.4 + */ + public int getSQLStateType() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Indicates whether updates made to a LOB are made on a copy or directly - * to the LOB. - * @return true if updates are made to a copy of the LOB; - * false if updates are made directly to the LOB - * @throws SQLException if a database access error occurs - * @since 1.4 - */ - public boolean locatorsUpdateCopy() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Indicates whether updates made to a LOB are made on a copy or directly + * to the LOB. + * @return true if updates are made to a copy of the LOB; + * false if updates are made directly to the LOB + * @throws SQLException if a database access error occurs + * @since 1.4 + */ + public boolean locatorsUpdateCopy() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } - /** - * Retrieves weather this database supports statement pooling. - * - * @return true is so; - false otherwise - * @throws SQLExcpetion if a database access error occurs - * @since 1.4 - */ - public boolean supportsStatementPooling() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Retrieves weather this database supports statement pooling. + * + * @return true is so; + false otherwise + * @throws SQLExcpetion if a database access error occurs + * @since 1.4 + */ + public boolean supportsStatementPooling() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java index cc1609d6462b5a18ac9be27165d1b2d738f92bd2..4be956e0439ddc6d5c346ad7c0b2958a01946542 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java @@ -4,178 +4,190 @@ package org.postgresql.jdbc3; import java.sql.*; import java.util.Vector; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3ResultSet.java,v 1.1 2002/08/14 20:35:39 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3ResultSet.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc3 specification. This class extends * org.postgresql.jdbc2.AbstractJdbc2ResultSet which provides the jdbc2 * methods. The real Statement class (for jdbc3) is org.postgresql.jdbc3.Jdbc3ResultSet */ -public abstract class AbstractJdbc3ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet { - - public AbstractJdbc3ResultSet(org.postgresql.PGConnection conn, Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - /** - * Retrieves the value of the designated column in the current row - * of this ResultSet object as a java.net.URL - * object in the Java programming language. - * - * @param columnIndex the index of the column 1 is the first, 2 is the second,... - * @return the column value as a java.net.URL object; - * if the value is SQL NULL, - * the value returned is null in the Java programming language - * @exception SQLException if a database access error occurs, - * or if a URL is malformed - * @since 1.4 - */ - public java.net.URL getURL(int columnIndex) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of the designated column in the current row - * of this ResultSet object as a java.net.URL - * object in the Java programming language. - * - * @param columnName the SQL name of the column - * @return the column value as a java.net.URL object; - * if the value is SQL NULL, - * the value returned is null in the Java programming language - * @exception SQLException if a database access error occurs - * or if a URL is malformed - * @since 1.4 - */ - public java.net.URL getURL(String columnName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Ref value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnIndex the first column is 1, the second is 2, ... - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateRef(int columnIndex, java.sql.Ref x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Ref value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnName the name of the column - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateRef(String columnName, java.sql.Ref x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Blob value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnIndex the first column is 1, the second is 2, ... - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateBlob(int columnIndex, java.sql.Blob x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Blob value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnName the name of the column - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateBlob(String columnName, java.sql.Blob x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Clob value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnIndex the first column is 1, the second is 2, ... - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateClob(int columnIndex, java.sql.Clob x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Clob value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnName the name of the column - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateClob(String columnName, java.sql.Clob x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Array value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnIndex the first column is 1, the second is 2, ... - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateArray(int columnIndex, java.sql.Array x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Updates the designated column with a java.sql.Array value. - * The updater methods are used to update column values in the - * current row or the insert row. The updater methods do not - * update the underlying database; instead the updateRow or - * insertRow methods are called to update the database. - * - * @param columnName the name of the column - * @param x the new column value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void updateArray(String columnName, java.sql.Array x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } +public abstract class AbstractJdbc3ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet +{ + + public AbstractJdbc3ResultSet(org.postgresql.PGConnection conn, Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + { + super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a java.net.URL + * object in the Java programming language. + * + * @param columnIndex the index of the column 1 is the first, 2 is the second,... + * @return the column value as a java.net.URL object; + * if the value is SQL NULL, + * the value returned is null in the Java programming language + * @exception SQLException if a database access error occurs, + * or if a URL is malformed + * @since 1.4 + */ + public java.net.URL getURL(int columnIndex) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a java.net.URL + * object in the Java programming language. + * + * @param columnName the SQL name of the column + * @return the column value as a java.net.URL object; + * if the value is SQL NULL, + * the value returned is null in the Java programming language + * @exception SQLException if a database access error occurs + * or if a URL is malformed + * @since 1.4 + */ + public java.net.URL getURL(String columnName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Ref value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateRef(int columnIndex, java.sql.Ref x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Ref value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateRef(String columnName, java.sql.Ref x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Blob value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateBlob(int columnIndex, java.sql.Blob x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Blob value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateBlob(String columnName, java.sql.Blob x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Clob value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateClob(int columnIndex, java.sql.Clob x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Clob value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateClob(String columnName, java.sql.Clob x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Array value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateArray(int columnIndex, java.sql.Array x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Updates the designated column with a java.sql.Array value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void updateArray(String columnName, java.sql.Array x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java index 8b18e6153d9617290097ecdf11f02e0497eeb163..9db54ae215170880a6a98d7021850bcc13487e7b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3Statement.java @@ -5,7 +5,7 @@ import java.math.BigDecimal; import java.sql.*; import java.util.Calendar; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Statement.java,v 1.1 2002/08/14 20:35:39 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3Statement.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class defines methods of the jdbc3 specification. This class extends * org.postgresql.jdbc2.AbstractJdbc2Statement which provides the jdbc2 * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc3.Jdbc3Statement @@ -23,1278 +23,1341 @@ public abstract class AbstractJdbc3Statement extends org.postgresql.jdbc2.Abstra super(connection, sql); } - /** - * Moves to this Statement object's next result, deals with - * any current ResultSet object(s) according to the instructions - * specified by the given flag, and returns - * true if the next result is a ResultSet object. - * - *

There are no more results when the following is true: - *

-     *      (!getMoreResults() && (getUpdateCount() == -1)
-     * 
- * - * @param current one of the following Statement - * constants indicating what should happen to current - * ResultSet objects obtained using the method - * getResultSetCLOSE_CURRENT_RESULT, - * KEEP_CURRENT_RESULT, or - * CLOSE_ALL_RESULTS - * @return true if the next result is a ResultSet - * object; false if it is an update count or there are no - * more results - * @exception SQLException if a database access error occurs - * @since 1.4 - * @see #execute - */ - public boolean getMoreResults(int current) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves any auto-generated keys created as a result of executing this - * Statement object. If this Statement object did - * not generate any keys, an empty ResultSet - * object is returned. - * - * @return a ResultSet object containing the auto-generated key(s) - * generated by the execution of this Statement object - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public ResultSet getGeneratedKeys() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement and signals the driver with the - * given flag about whether the - * auto-generated keys produced by this Statement object - * should be made available for retrieval. - * - * @param sql must be an SQL INSERT, UPDATE or - * DELETE statement or an SQL statement that - * returns nothing - * @param autoGeneratedKeys a flag indicating whether auto-generated keys - * should be made available for retrieval; - * one of the following constants: - * Statement.RETURN_GENERATED_KEYS - * Statement.NO_GENERATED_KEYS - * @return either the row count for INSERT, UPDATE - * or DELETE statements, or 0 for SQL - * statements that return nothing - * @exception SQLException if a database access error occurs, the given - * SQL statement returns a ResultSet object, or - * the given constant is not one of those allowed - * @since 1.4 - */ - public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement and signals the driver that the - * auto-generated keys indicated in the given array should be made available - * for retrieval. The driver will ignore the array if the SQL statement - * is not an INSERT statement. - * - * @param sql an SQL INSERT, UPDATE or - * DELETE statement or an SQL statement that returns nothing, - * such as an SQL DDL statement - * @param columnIndexes an array of column indexes indicating the columns - * that should be returned from the inserted row - * @return either the row count for INSERT, UPDATE, - * or DELETE statements, or 0 for SQL statements - * that return nothing - * @exception SQLException if a database access error occurs or the SQL - * statement returns a ResultSet object - * @since 1.4 - */ - public int executeUpdate(String sql, int columnIndexes[]) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement and signals the driver that the - * auto-generated keys indicated in the given array should be made available - * for retrieval. The driver will ignore the array if the SQL statement - * is not an INSERT statement. - * - * @param sql an SQL INSERT, UPDATE or - * DELETE statement or an SQL statement that returns nothing - * @param columnNames an array of the names of the columns that should be - * returned from the inserted row - * @return either the row count for INSERT, UPDATE, - * or DELETE statements, or 0 for SQL statements - * that return nothing - * @exception SQLException if a database access error occurs - * - * @since 1.4 - */ - public int executeUpdate(String sql, String columnNames[]) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement, which may return multiple results, - * and signals the driver that any - * auto-generated keys should be made available - * for retrieval. The driver will ignore this signal if the SQL statement - * is not an INSERT statement. - *

- * In some (uncommon) situations, a single SQL statement may return - * multiple result sets and/or update counts. Normally you can ignore - * this unless you are (1) executing a stored procedure that you know may - * return multiple results or (2) you are dynamically executing an - * unknown SQL string. - *

- * The execute method executes an SQL statement and indicates the - * form of the first result. You must then use the methods - * getResultSet or getUpdateCount - * to retrieve the result, and getMoreResults to - * move to any subsequent result(s). - * - * @param sql any SQL statement - * @param autoGeneratedKeys a constant indicating whether auto-generated - * keys should be made available for retrieval using the method - * getGeneratedKeys; one of the following constants: - * Statement.RETURN_GENERATED_KEYS or - * Statement.NO_GENERATED_KEYS - * @return true if the first result is a ResultSet - * object; false if it is an update count or there are - * no results - * @exception SQLException if a database access error occurs - * @see #getResultSet - * @see #getUpdateCount - * @see #getMoreResults - * @see #getGeneratedKeys - * - * @since 1.4 - */ - public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement, which may return multiple results, - * and signals the driver that the - * auto-generated keys indicated in the given array should be made available - * for retrieval. This array contains the indexes of the columns in the - * target table that contain the auto-generated keys that should be made - * available. The driver will ignore the array if the given SQL statement - * is not an INSERT statement. - *

- * Under some (uncommon) situations, a single SQL statement may return - * multiple result sets and/or update counts. Normally you can ignore - * this unless you are (1) executing a stored procedure that you know may - * return multiple results or (2) you are dynamically executing an - * unknown SQL string. - *

- * The execute method executes an SQL statement and indicates the - * form of the first result. You must then use the methods - * getResultSet or getUpdateCount - * to retrieve the result, and getMoreResults to - * move to any subsequent result(s). - * - * @param sql any SQL statement - * @param columnIndexes an array of the indexes of the columns in the - * inserted row that should be made available for retrieval by a - * call to the method getGeneratedKeys - * @return true if the first result is a ResultSet - * object; false if it is an update count or there - * are no results - * @exception SQLException if a database access error occurs - * @see #getResultSet - * @see #getUpdateCount - * @see #getMoreResults - * - * @since 1.4 - */ - public boolean execute(String sql, int columnIndexes[]) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Executes the given SQL statement, which may return multiple results, - * and signals the driver that the - * auto-generated keys indicated in the given array should be made available - * for retrieval. This array contains the names of the columns in the - * target table that contain the auto-generated keys that should be made - * available. The driver will ignore the array if the given SQL statement - * is not an INSERT statement. - *

- * In some (uncommon) situations, a single SQL statement may return - * multiple result sets and/or update counts. Normally you can ignore - * this unless you are (1) executing a stored procedure that you know may - * return multiple results or (2) you are dynamically executing an - * unknown SQL string. - *

- * The execute method executes an SQL statement and indicates the - * form of the first result. You must then use the methods - * getResultSet or getUpdateCount - * to retrieve the result, and getMoreResults to - * move to any subsequent result(s). - * - * @param sql any SQL statement - * @param columnNames an array of the names of the columns in the inserted - * row that should be made available for retrieval by a call to the - * method getGeneratedKeys - * @return true if the next result is a ResultSet - * object; false if it is an update count or there - * are no more results - * @exception SQLException if a database access error occurs - * @see #getResultSet - * @see #getUpdateCount - * @see #getMoreResults - * @see #getGeneratedKeys - * - * @since 1.4 - */ - public boolean execute(String sql, String columnNames[]) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the result set holdability for ResultSet objects - * generated by this Statement object. - * - * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or - * ResultSet.CLOSE_CURSORS_AT_COMMIT - * @exception SQLException if a database access error occurs - * - * @since 1.4 - */ - public int getResultSetHoldability() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.net.URL value. - * The driver converts this to an SQL DATALINK value - * when it sends it to the database. - * - * @param parameterIndex the first parameter is 1, the second is 2, ... - * @param x the java.net.URL object to be set - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setURL(int parameterIndex, java.net.URL x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the number, types and properties of this - * PreparedStatement object's parameters. - * - * @return a ParameterMetaData object that contains information - * about the number, types and properties of this - * PreparedStatement object's parameters - * @exception SQLException if a database access error occurs - * @see ParameterMetaData - * @since 1.4 - */ - public ParameterMetaData getParameterMetaData() throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Registers the OUT parameter named - * parameterName to the JDBC type - * sqlType. All OUT parameters must be registered - * before a stored procedure is executed. - *

- * The JDBC type specified by sqlType for an OUT - * parameter determines the Java type that must be used - * in the get method to read the value of that parameter. - *

- * If the JDBC type expected to be returned to this output parameter - * is specific to this particular database, sqlType - * should be java.sql.Types.OTHER. The method - * {@link #getObject} retrieves the value. - * @param parameterName the name of the parameter - * @param sqlType the JDBC type code defined by java.sql.Types. - * If the parameter is of JDBC type NUMERIC - * or DECIMAL, the version of - * registerOutParameter that accepts a scale value - * should be used. - * @exception SQLException if a database access error occurs - * @since 1.4 - * @see Types - */ - public void registerOutParameter(String parameterName, int sqlType) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Registers the parameter named - * parameterName to be of JDBC type - * sqlType. This method must be called - * before a stored procedure is executed. - *

- * The JDBC type specified by sqlType for an OUT - * parameter determines the Java type that must be used - * in the get method to read the value of that parameter. - *

- * This version of registerOutParameter should be - * used when the parameter is of JDBC type NUMERIC - * or DECIMAL. - * @param parameterName the name of the parameter - * @param sqlType SQL type code defined by java.sql.Types. - * @param scale the desired number of digits to the right of the - * decimal point. It must be greater than or equal to zero. - * @exception SQLException if a database access error occurs - * @since 1.4 - * @see Types - */ - public void registerOutParameter(String parameterName, int sqlType, int scale) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Registers the designated output parameter. This version of - * the method registerOutParameter - * should be used for a user-named or REF output parameter. Examples - * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and - * named array types. - * - * Before executing a stored procedure call, you must explicitly - * call registerOutParameter to register the type from - * java.sql.Types for each - * OUT parameter. For a user-named parameter the fully-qualified SQL - * type name of the parameter should also be given, while a REF - * parameter requires that the fully-qualified type name of the - * referenced type be given. A JDBC driver that does not need the - * type code and type name information may ignore it. To be portable, - * however, applications should always provide these values for - * user-named and REF parameters. - * - * Although it is intended for user-named and REF parameters, - * this method may be used to register a parameter of any JDBC type. - * If the parameter does not have a user-named or REF type, the - * typeName parameter is ignored. - * - *

Note: When reading the value of an out parameter, you - * must use the getXXX method whose Java type XXX corresponds to the - * parameter's registered SQL type. - * - * @param parameterName the name of the parameter - * @param sqlType a value from {@link java.sql.Types} - * @param typeName the fully-qualified name of an SQL structured type - * @exception SQLException if a database access error occurs - * @see Types - * @since 1.4 - */ - public void registerOutParameter (String parameterName, int sqlType, String typeName) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of the designated JDBC DATALINK parameter as a - * java.net.URL object. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return a java.net.URL object that represents the - * JDBC DATALINK value used as the designated - * parameter - * @exception SQLException if a database access error occurs, - * or if the URL being returned is - * not a valid URL on the Java platform - * @see #setURL - * @since 1.4 - */ - public java.net.URL getURL(int parameterIndex) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.net.URL object. - * The driver converts this to an SQL DATALINK value when - * it sends it to the database. - * - * @param parameterName the name of the parameter - * @param val the parameter value - * @exception SQLException if a database access error occurs, - * or if a URL is malformed - * @see #getURL - * @since 1.4 - */ - public void setURL(String parameterName, java.net.URL val) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to SQL NULL. - * - *

Note: You must specify the parameter's SQL type. - * - * @param parameterName the name of the parameter - * @param sqlType the SQL type code defined in java.sql.Types - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setNull(String parameterName, int sqlType) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java boolean value. - * The driver converts this - * to an SQL BIT value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getBoolean - * @since 1.4 - */ - public void setBoolean(String parameterName, boolean x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java byte value. - * The driver converts this - * to an SQL TINYINT value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getByte - * @since 1.4 - */ - public void setByte(String parameterName, byte x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java short value. - * The driver converts this - * to an SQL SMALLINT value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getShort - * @since 1.4 - */ - public void setShort(String parameterName, short x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java int value. - * The driver converts this - * to an SQL INTEGER value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getInt - * @since 1.4 - */ - public void setInt(String parameterName, int x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java long value. - * The driver converts this - * to an SQL BIGINT value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getLong - * @since 1.4 - */ - public void setLong(String parameterName, long x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java float value. - * The driver converts this - * to an SQL FLOAT value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getFloat - * @since 1.4 - */ - public void setFloat(String parameterName, float x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java double value. - * The driver converts this - * to an SQL DOUBLE value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getDouble - * @since 1.4 - */ - public void setDouble(String parameterName, double x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given - * java.math.BigDecimal value. - * The driver converts this to an SQL NUMERIC value when - * it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getBigDecimal - * @since 1.4 - */ - public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java String value. - * The driver converts this - * to an SQL VARCHAR or LONGVARCHAR value - * (depending on the argument's - * size relative to the driver's limits on VARCHAR values) - * when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getString - * @since 1.4 - */ - public void setString(String parameterName, String x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given Java array of bytes. - * The driver converts this to an SQL VARBINARY or - * LONGVARBINARY (depending on the argument's size relative - * to the driver's limits on VARBINARY values) when it sends - * it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getBytes - * @since 1.4 - */ - public void setBytes(String parameterName, byte x[]) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Date value. - * The driver converts this - * to an SQL DATE value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getDate - * @since 1.4 - */ - public void setDate(String parameterName, java.sql.Date x) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Time value. - * The driver converts this - * to an SQL TIME value when it sends it to the database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getTime - * @since 1.4 - */ - public void setTime(String parameterName, java.sql.Time x) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Timestamp value. - * The driver - * converts this to an SQL TIMESTAMP value when it sends it to the - * database. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @exception SQLException if a database access error occurs - * @see #getTimestamp - * @since 1.4 - */ - public void setTimestamp(String parameterName, java.sql.Timestamp x) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given input stream, which will have - * the specified number of bytes. - * When a very large ASCII value is input to a LONGVARCHAR - * parameter, it may be more practical to send it via a - * java.io.InputStream. Data will be read from the stream - * as needed until end-of-file is reached. The JDBC driver will - * do any necessary conversion from ASCII to the database char format. - * - *

Note: This stream object can either be a standard - * Java stream object or your own subclass that implements the - * standard interface. - * - * @param parameterName the name of the parameter - * @param x the Java input stream that contains the ASCII parameter value - * @param length the number of bytes in the stream - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setAsciiStream(String parameterName, java.io.InputStream x, int length) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given input stream, which will have - * the specified number of bytes. - * When a very large binary value is input to a LONGVARBINARY - * parameter, it may be more practical to send it via a - * java.io.InputStream object. The data will be read from the stream - * as needed until end-of-file is reached. - * - *

Note: This stream object can either be a standard - * Java stream object or your own subclass that implements the - * standard interface. - * - * @param parameterName the name of the parameter - * @param x the java input stream which contains the binary parameter value - * @param length the number of bytes in the stream - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setBinaryStream(String parameterName, java.io.InputStream x, - int length) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the value of the designated parameter with the given object. The second - * argument must be an object type; for integral values, the - * java.lang equivalent objects should be used. - * - *

The given Java object will be converted to the given targetSqlType - * before being sent to the database. - * - * If the object has a custom mapping (is of a class implementing the - * interface SQLData), - * the JDBC driver should call the method SQLData.writeSQL to write it - * to the SQL data stream. - * If, on the other hand, the object is of a class implementing - * Ref, Blob, Clob, Struct, - * or Array, the driver should pass it to the database as a - * value of the corresponding SQL type. - *

- * Note that this method may be used to pass datatabase- - * specific abstract data types. - * - * @param parameterName the name of the parameter - * @param x the object containing the input parameter value - * @param targetSqlType the SQL type (as defined in java.sql.Types) to be - * sent to the database. The scale argument may further qualify this type. - * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, - * this is the number of digits after the decimal point. For all other - * types, this value will be ignored. - * @exception SQLException if a database access error occurs - * @see Types - * @see #getObject - * @since 1.4 - */ - public void setObject(String parameterName, Object x, int targetSqlType, int scale) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the value of the designated parameter with the given object. - * This method is like the method setObject - * above, except that it assumes a scale of zero. - * - * @param parameterName the name of the parameter - * @param x the object containing the input parameter value - * @param targetSqlType the SQL type (as defined in java.sql.Types) to be - * sent to the database - * @exception SQLException if a database access error occurs - * @see #getObject - * @since 1.4 - */ - public void setObject(String parameterName, Object x, int targetSqlType) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the value of the designated parameter with the given object. - * The second parameter must be of type Object; therefore, the - * java.lang equivalent objects should be used for built-in types. - * - *

The JDBC specification specifies a standard mapping from - * Java Object types to SQL types. The given argument - * will be converted to the corresponding SQL type before being - * sent to the database. - * - *

Note that this method may be used to pass datatabase- - * specific abstract data types, by using a driver-specific Java - * type. - * - * If the object is of a class implementing the interface SQLData, - * the JDBC driver should call the method SQLData.writeSQL - * to write it to the SQL data stream. - * If, on the other hand, the object is of a class implementing - * Ref, Blob, Clob, Struct, - * or Array, the driver should pass it to the database as a - * value of the corresponding SQL type. - *

- * This method throws an exception if there is an ambiguity, for example, if the - * object is of a class implementing more than one of the interfaces named above. - * - * @param parameterName the name of the parameter - * @param x the object containing the input parameter value - * @exception SQLException if a database access error occurs or if the given - * Object parameter is ambiguous - * @see #getObject - * @since 1.4 - */ - public void setObject(String parameterName, Object x) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - - /** - * Sets the designated parameter to the given Reader - * object, which is the given number of characters long. - * When a very large UNICODE value is input to a LONGVARCHAR - * parameter, it may be more practical to send it via a - * java.io.Reader object. The data will be read from the stream - * as needed until end-of-file is reached. The JDBC driver will - * do any necessary conversion from UNICODE to the database char format. - * - *

Note: This stream object can either be a standard - * Java stream object or your own subclass that implements the - * standard interface. - * - * @param parameterName the name of the parameter - * @param reader the java.io.Reader object that - * contains the UNICODE data used as the designated parameter - * @param length the number of characters in the stream - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setCharacterStream(String parameterName, - java.io.Reader reader, - int length) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Date value, - * using the given Calendar object. The driver uses - * the Calendar object to construct an SQL DATE value, - * which the driver then sends to the database. With a - * a Calendar object, the driver can calculate the date - * taking into account a custom timezone. If no - * Calendar object is specified, the driver uses the default - * timezone, which is that of the virtual machine running the application. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @param cal the Calendar object the driver will use - * to construct the date - * @exception SQLException if a database access error occurs - * @see #getDate - * @since 1.4 - */ - public void setDate(String parameterName, java.sql.Date x, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Time value, - * using the given Calendar object. The driver uses - * the Calendar object to construct an SQL TIME value, - * which the driver then sends to the database. With a - * a Calendar object, the driver can calculate the time - * taking into account a custom timezone. If no - * Calendar object is specified, the driver uses the default - * timezone, which is that of the virtual machine running the application. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @param cal the Calendar object the driver will use - * to construct the time - * @exception SQLException if a database access error occurs - * @see #getTime - * @since 1.4 - */ - public void setTime(String parameterName, java.sql.Time x, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to the given java.sql.Timestamp value, - * using the given Calendar object. The driver uses - * the Calendar object to construct an SQL TIMESTAMP value, - * which the driver then sends to the database. With a - * a Calendar object, the driver can calculate the timestamp - * taking into account a custom timezone. If no - * Calendar object is specified, the driver uses the default - * timezone, which is that of the virtual machine running the application. - * - * @param parameterName the name of the parameter - * @param x the parameter value - * @param cal the Calendar object the driver will use - * to construct the timestamp - * @exception SQLException if a database access error occurs - * @see #getTimestamp - * @since 1.4 - */ - public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Sets the designated parameter to SQL NULL. - * This version of the method setNull should - * be used for user-defined types and REF type parameters. Examples - * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and - * named array types. - * - *

Note: To be portable, applications must give the - * SQL type code and the fully-qualified SQL type name when specifying - * a NULL user-defined or REF parameter. In the case of a user-defined type - * the name is the type name of the parameter itself. For a REF - * parameter, the name is the type name of the referenced type. If - * a JDBC driver does not need the type code or type name information, - * it may ignore it. - * - * Although it is intended for user-defined and Ref parameters, - * this method may be used to set a null parameter of any JDBC type. - * If the parameter does not have a user-defined or REF type, the given - * typeName is ignored. - * - * - * @param paramName the name of the parameter - * @param sqlType a value from java.sql.Types - * @param typeName the fully-qualified name of an SQL user-defined type; - * ignored if the parameter is not a user-defined type or - * SQL REF value - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public void setNull (String parameterName, int sqlType, String typeName) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC CHAR, VARCHAR, - * or LONGVARCHAR parameter as a String in - * the Java programming language. - *

- * For the fixed-length type JDBC CHAR, - * the String object - * returned has exactly the same value the JDBC - * CHAR value had in the - * database, including any padding added by the database. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is null. - * @exception SQLException if a database access error occurs - * @see #setString - * @since 1.4 - */ - public String getString(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC BIT parameter as a - * boolean in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is false. - * @exception SQLException if a database access error occurs - * @see #setBoolean - * @since 1.4 - */ - public boolean getBoolean(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC TINYINT parameter as a byte - * in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is 0. - * @exception SQLException if a database access error occurs - * @see #setByte - * @since 1.4 - */ - public byte getByte(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC SMALLINT parameter as a short - * in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is 0. - * @exception SQLException if a database access error occurs - * @see #setShort - * @since 1.4 - */ - public short getShort(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC INTEGER parameter as an int - * in the Java programming language. - * - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, - * the result is 0. - * @exception SQLException if a database access error occurs - * @see #setInt - * @since 1.4 - */ - public int getInt(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC BIGINT parameter as a long - * in the Java programming language. - * - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, - * the result is 0. - * @exception SQLException if a database access error occurs - * @see #setLong - * @since 1.4 - */ - public long getLong(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC FLOAT parameter as a float - * in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, - * the result is 0. - * @exception SQLException if a database access error occurs - * @see #setFloat - * @since 1.4 - */ - public float getFloat(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC DOUBLE parameter as a double - * in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, - * the result is 0. - * @exception SQLException if a database access error occurs - * @see #setDouble - * @since 1.4 - */ - public double getDouble(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC BINARY or VARBINARY - * parameter as an array of byte values in the Java - * programming language. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result is - * null. - * @exception SQLException if a database access error occurs - * @see #setBytes - * @since 1.4 - */ - public byte[] getBytes(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC DATE parameter as a - * java.sql.Date object. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is null. - * @exception SQLException if a database access error occurs - * @see #setDate - * @since 1.4 - */ - public java.sql.Date getDate(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC TIME parameter as a - * java.sql.Time object. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is null. - * @exception SQLException if a database access error occurs - * @see #setTime - * @since 1.4 - */ - public java.sql.Time getTime(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC TIMESTAMP parameter as a - * java.sql.Timestamp object. - * @param parameterName the name of the parameter - * @return the parameter value. If the value is SQL NULL, the result - * is null. - * @exception SQLException if a database access error occurs - * @see #setTimestamp - * @since 1.4 - */ - public java.sql.Timestamp getTimestamp(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a parameter as an Object in the Java - * programming language. If the value is an SQL NULL, the - * driver returns a Java null. - *

- * This method returns a Java object whose type corresponds to the JDBC - * type that was registered for this parameter using the method - * registerOutParameter. By registering the target JDBC - * type as java.sql.Types.OTHER, this method can be used - * to read database-specific abstract data types. - * @param parameterName the name of the parameter - * @return A java.lang.Object holding the OUT parameter value. - * @exception SQLException if a database access error occurs - * @see Types - * @see #setObject - * @since 1.4 - */ - public Object getObject(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC NUMERIC parameter as a - * java.math.BigDecimal object with as many digits to the - * right of the decimal point as the value contains. - * @param parameterName the name of the parameter - * @return the parameter value in full precision. If the value is - * SQL NULL, the result is null. - * @exception SQLException if a database access error occurs - * @see #setBigDecimal - * @since 1.4 - */ - public BigDecimal getBigDecimal(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Returns an object representing the value of OUT parameter - * i and uses map for the custom - * mapping of the parameter value. - *

- * This method returns a Java object whose type corresponds to the - * JDBC type that was registered for this parameter using the method - * registerOutParameter. By registering the target - * JDBC type as java.sql.Types.OTHER, this method can - * be used to read database-specific abstract data types. - * @param parameterName the name of the parameter - * @param map the mapping from SQL type names to Java classes - * @return a java.lang.Object holding the OUT parameter value - * @exception SQLException if a database access error occurs - * @see #setObject - * @since 1.4 - */ - public Object getObject (String parameterName, java.util.Map map) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC REF(<structured-type>) - * parameter as a {@link Ref} object in the Java programming language. - * - * @param parameterName the name of the parameter - * @return the parameter value as a Ref object in the - * Java programming language. If the value was SQL NULL, - * the value null is returned. - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public Ref getRef (String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC BLOB parameter as a - * {@link Blob} object in the Java programming language. - * - * @param parameterName the name of the parameter - * @return the parameter value as a Blob object in the - * Java programming language. If the value was SQL NULL, - * the value null is returned. - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public Blob getBlob (String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC CLOB parameter as a - * Clob object in the Java programming language. - * @param parameterName the name of the parameter - * @return the parameter value as a Clob object in the - * Java programming language. If the value was SQL NULL, - * the value null is returned. - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public Clob getClob (String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC ARRAY parameter as an - * {@link Array} object in the Java programming language. - * - * @param parameterName the name of the parameter - * @return the parameter value as an Array object in - * Java programming language. If the value was SQL NULL, - * the value null is returned. - * @exception SQLException if a database access error occurs - * @since 1.4 - */ - public Array getArray (String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC DATE parameter as a - * java.sql.Date object, using - * the given Calendar object - * to construct the date. - * With a Calendar object, the driver - * can calculate the date taking into account a custom timezone and locale. - * If no Calendar object is specified, the driver uses the - * default timezone and locale. - * - * @param parameterName the name of the parameter - * @param cal the Calendar object the driver will use - * to construct the date - * @return the parameter value. If the value is SQL NULL, - * the result is null. - * @exception SQLException if a database access error occurs - * @see #setDate - * @since 1.4 - */ - public java.sql.Date getDate(String parameterName, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC TIME parameter as a - * java.sql.Time object, using - * the given Calendar object - * to construct the time. - * With a Calendar object, the driver - * can calculate the time taking into account a custom timezone and locale. - * If no Calendar object is specified, the driver uses the - * default timezone and locale. - * - * @param parameterName the name of the parameter - * @param cal the Calendar object the driver will use - * to construct the time - * @return the parameter value; if the value is SQL NULL, the result is - * null. - * @exception SQLException if a database access error occurs - * @see #setTime - * @since 1.4 - */ - public java.sql.Time getTime(String parameterName, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC TIMESTAMP parameter as a - * java.sql.Timestamp object, using - * the given Calendar object to construct - * the Timestamp object. - * With a Calendar object, the driver - * can calculate the timestamp taking into account a custom timezone and locale. - * If no Calendar object is specified, the driver uses the - * default timezone and locale. - * - * - * @param parameterName the name of the parameter - * @param cal the Calendar object the driver will use - * to construct the timestamp - * @return the parameter value. If the value is SQL NULL, the result is - * null. - * @exception SQLException if a database access error occurs - * @see #setTimestamp - * @since 1.4 - */ - public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal) - throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } - - /** - * Retrieves the value of a JDBC DATALINK parameter as a - * java.net.URL object. - * - * @param parameterName the name of the parameter - * @return the parameter value as a java.net.URL object in the - * Java programming language. If the value was SQL NULL, the - * value null is returned. - * @exception SQLException if a database access error occurs, - * or if there is a problem with the URL - * @see #setURL - * @since 1.4 - */ - public java.net.URL getURL(String parameterName) throws SQLException { - throw org.postgresql.Driver.notImplemented(); - } + /** + * Moves to this Statement object's next result, deals with + * any current ResultSet object(s) according to the instructions + * specified by the given flag, and returns + * true if the next result is a ResultSet object. + * + *

There are no more results when the following is true: + *

+	 *		(!getMoreResults() && (getUpdateCount() == -1)
+	 * 
+ * + * @param current one of the following Statement + * constants indicating what should happen to current + * ResultSet objects obtained using the method + * getResultSetCLOSE_CURRENT_RESULT, + * KEEP_CURRENT_RESULT, or + * CLOSE_ALL_RESULTS + * @return true if the next result is a ResultSet + * object; false if it is an update count or there are no + * more results + * @exception SQLException if a database access error occurs + * @since 1.4 + * @see #execute + */ + public boolean getMoreResults(int current) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves any auto-generated keys created as a result of executing this + * Statement object. If this Statement object did + * not generate any keys, an empty ResultSet + * object is returned. + * + * @return a ResultSet object containing the auto-generated key(s) + * generated by the execution of this Statement object + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public ResultSet getGeneratedKeys() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement and signals the driver with the + * given flag about whether the + * auto-generated keys produced by this Statement object + * should be made available for retrieval. + * + * @param sql must be an SQL INSERT, UPDATE or + * DELETE statement or an SQL statement that + * returns nothing + * @param autoGeneratedKeys a flag indicating whether auto-generated keys + * should be made available for retrieval; + * one of the following constants: + * Statement.RETURN_GENERATED_KEYS + * Statement.NO_GENERATED_KEYS + * @return either the row count for INSERT, UPDATE + * or DELETE statements, or 0 for SQL + * statements that return nothing + * @exception SQLException if a database access error occurs, the given + * SQL statement returns a ResultSet object, or + * the given constant is not one of those allowed + * @since 1.4 + */ + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement and signals the driver that the + * auto-generated keys indicated in the given array should be made available + * for retrieval. The driver will ignore the array if the SQL statement + * is not an INSERT statement. + * + * @param sql an SQL INSERT, UPDATE or + * DELETE statement or an SQL statement that returns nothing, + * such as an SQL DDL statement + * @param columnIndexes an array of column indexes indicating the columns + * that should be returned from the inserted row + * @return either the row count for INSERT, UPDATE, + * or DELETE statements, or 0 for SQL statements + * that return nothing + * @exception SQLException if a database access error occurs or the SQL + * statement returns a ResultSet object + * @since 1.4 + */ + public int executeUpdate(String sql, int columnIndexes[]) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement and signals the driver that the + * auto-generated keys indicated in the given array should be made available + * for retrieval. The driver will ignore the array if the SQL statement + * is not an INSERT statement. + * + * @param sql an SQL INSERT, UPDATE or + * DELETE statement or an SQL statement that returns nothing + * @param columnNames an array of the names of the columns that should be + * returned from the inserted row + * @return either the row count for INSERT, UPDATE, + * or DELETE statements, or 0 for SQL statements + * that return nothing + * @exception SQLException if a database access error occurs + * + * @since 1.4 + */ + public int executeUpdate(String sql, String columnNames[]) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement, which may return multiple results, + * and signals the driver that any + * auto-generated keys should be made available + * for retrieval. The driver will ignore this signal if the SQL statement + * is not an INSERT statement. + *

+ * In some (uncommon) situations, a single SQL statement may return + * multiple result sets and/or update counts. Normally you can ignore + * this unless you are (1) executing a stored procedure that you know may + * return multiple results or (2) you are dynamically executing an + * unknown SQL string. + *

+ * The execute method executes an SQL statement and indicates the + * form of the first result. You must then use the methods + * getResultSet or getUpdateCount + * to retrieve the result, and getMoreResults to + * move to any subsequent result(s). + * + * @param sql any SQL statement + * @param autoGeneratedKeys a constant indicating whether auto-generated + * keys should be made available for retrieval using the method + * getGeneratedKeys; one of the following constants: + * Statement.RETURN_GENERATED_KEYS or + * Statement.NO_GENERATED_KEYS + * @return true if the first result is a ResultSet + * object; false if it is an update count or there are + * no results + * @exception SQLException if a database access error occurs + * @see #getResultSet + * @see #getUpdateCount + * @see #getMoreResults + * @see #getGeneratedKeys + * + * @since 1.4 + */ + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement, which may return multiple results, + * and signals the driver that the + * auto-generated keys indicated in the given array should be made available + * for retrieval. This array contains the indexes of the columns in the + * target table that contain the auto-generated keys that should be made + * available. The driver will ignore the array if the given SQL statement + * is not an INSERT statement. + *

+ * Under some (uncommon) situations, a single SQL statement may return + * multiple result sets and/or update counts. Normally you can ignore + * this unless you are (1) executing a stored procedure that you know may + * return multiple results or (2) you are dynamically executing an + * unknown SQL string. + *

+ * The execute method executes an SQL statement and indicates the + * form of the first result. You must then use the methods + * getResultSet or getUpdateCount + * to retrieve the result, and getMoreResults to + * move to any subsequent result(s). + * + * @param sql any SQL statement + * @param columnIndexes an array of the indexes of the columns in the + * inserted row that should be made available for retrieval by a + * call to the method getGeneratedKeys + * @return true if the first result is a ResultSet + * object; false if it is an update count or there + * are no results + * @exception SQLException if a database access error occurs + * @see #getResultSet + * @see #getUpdateCount + * @see #getMoreResults + * + * @since 1.4 + */ + public boolean execute(String sql, int columnIndexes[]) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Executes the given SQL statement, which may return multiple results, + * and signals the driver that the + * auto-generated keys indicated in the given array should be made available + * for retrieval. This array contains the names of the columns in the + * target table that contain the auto-generated keys that should be made + * available. The driver will ignore the array if the given SQL statement + * is not an INSERT statement. + *

+ * In some (uncommon) situations, a single SQL statement may return + * multiple result sets and/or update counts. Normally you can ignore + * this unless you are (1) executing a stored procedure that you know may + * return multiple results or (2) you are dynamically executing an + * unknown SQL string. + *

+ * The execute method executes an SQL statement and indicates the + * form of the first result. You must then use the methods + * getResultSet or getUpdateCount + * to retrieve the result, and getMoreResults to + * move to any subsequent result(s). + * + * @param sql any SQL statement + * @param columnNames an array of the names of the columns in the inserted + * row that should be made available for retrieval by a call to the + * method getGeneratedKeys + * @return true if the next result is a ResultSet + * object; false if it is an update count or there + * are no more results + * @exception SQLException if a database access error occurs + * @see #getResultSet + * @see #getUpdateCount + * @see #getMoreResults + * @see #getGeneratedKeys + * + * @since 1.4 + */ + public boolean execute(String sql, String columnNames[]) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the result set holdability for ResultSet objects + * generated by this Statement object. + * + * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or + * ResultSet.CLOSE_CURSORS_AT_COMMIT + * @exception SQLException if a database access error occurs + * + * @since 1.4 + */ + public int getResultSetHoldability() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.net.URL value. + * The driver converts this to an SQL DATALINK value + * when it sends it to the database. + * + * @param parameterIndex the first parameter is 1, the second is 2, ... + * @param x the java.net.URL object to be set + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setURL(int parameterIndex, java.net.URL x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the number, types and properties of this + * PreparedStatement object's parameters. + * + * @return a ParameterMetaData object that contains information + * about the number, types and properties of this + * PreparedStatement object's parameters + * @exception SQLException if a database access error occurs + * @see ParameterMetaData + * @since 1.4 + */ + public ParameterMetaData getParameterMetaData() throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Registers the OUT parameter named + * parameterName to the JDBC type + * sqlType. All OUT parameters must be registered + * before a stored procedure is executed. + *

+ * The JDBC type specified by sqlType for an OUT + * parameter determines the Java type that must be used + * in the get method to read the value of that parameter. + *

+ * If the JDBC type expected to be returned to this output parameter + * is specific to this particular database, sqlType + * should be java.sql.Types.OTHER. The method + * {@link #getObject} retrieves the value. + * @param parameterName the name of the parameter + * @param sqlType the JDBC type code defined by java.sql.Types. + * If the parameter is of JDBC type NUMERIC + * or DECIMAL, the version of + * registerOutParameter that accepts a scale value + * should be used. + * @exception SQLException if a database access error occurs + * @since 1.4 + * @see Types + */ + public void registerOutParameter(String parameterName, int sqlType) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Registers the parameter named + * parameterName to be of JDBC type + * sqlType. This method must be called + * before a stored procedure is executed. + *

+ * The JDBC type specified by sqlType for an OUT + * parameter determines the Java type that must be used + * in the get method to read the value of that parameter. + *

+ * This version of registerOutParameter should be + * used when the parameter is of JDBC type NUMERIC + * or DECIMAL. + * @param parameterName the name of the parameter + * @param sqlType SQL type code defined by java.sql.Types. + * @param scale the desired number of digits to the right of the + * decimal point. It must be greater than or equal to zero. + * @exception SQLException if a database access error occurs + * @since 1.4 + * @see Types + */ + public void registerOutParameter(String parameterName, int sqlType, int scale) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Registers the designated output parameter. This version of + * the method registerOutParameter + * should be used for a user-named or REF output parameter. Examples + * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and + * named array types. + * + * Before executing a stored procedure call, you must explicitly + * call registerOutParameter to register the type from + * java.sql.Types for each + * OUT parameter. For a user-named parameter the fully-qualified SQL + * type name of the parameter should also be given, while a REF + * parameter requires that the fully-qualified type name of the + * referenced type be given. A JDBC driver that does not need the + * type code and type name information may ignore it. To be portable, + * however, applications should always provide these values for + * user-named and REF parameters. + * + * Although it is intended for user-named and REF parameters, + * this method may be used to register a parameter of any JDBC type. + * If the parameter does not have a user-named or REF type, the + * typeName parameter is ignored. + * + *

Note: When reading the value of an out parameter, you + * must use the getXXX method whose Java type XXX corresponds to the + * parameter's registered SQL type. + * + * @param parameterName the name of the parameter + * @param sqlType a value from {@link java.sql.Types} + * @param typeName the fully-qualified name of an SQL structured type + * @exception SQLException if a database access error occurs + * @see Types + * @since 1.4 + */ + public void registerOutParameter (String parameterName, int sqlType, String typeName) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of the designated JDBC DATALINK parameter as a + * java.net.URL object. + * + * @param parameterIndex the first parameter is 1, the second is 2,... + * @return a java.net.URL object that represents the + * JDBC DATALINK value used as the designated + * parameter + * @exception SQLException if a database access error occurs, + * or if the URL being returned is + * not a valid URL on the Java platform + * @see #setURL + * @since 1.4 + */ + public java.net.URL getURL(int parameterIndex) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.net.URL object. + * The driver converts this to an SQL DATALINK value when + * it sends it to the database. + * + * @param parameterName the name of the parameter + * @param val the parameter value + * @exception SQLException if a database access error occurs, + * or if a URL is malformed + * @see #getURL + * @since 1.4 + */ + public void setURL(String parameterName, java.net.URL val) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to SQL NULL. + * + *

Note: You must specify the parameter's SQL type. + * + * @param parameterName the name of the parameter + * @param sqlType the SQL type code defined in java.sql.Types + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setNull(String parameterName, int sqlType) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java boolean value. + * The driver converts this + * to an SQL BIT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getBoolean + * @since 1.4 + */ + public void setBoolean(String parameterName, boolean x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java byte value. + * The driver converts this + * to an SQL TINYINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getByte + * @since 1.4 + */ + public void setByte(String parameterName, byte x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java short value. + * The driver converts this + * to an SQL SMALLINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getShort + * @since 1.4 + */ + public void setShort(String parameterName, short x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java int value. + * The driver converts this + * to an SQL INTEGER value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getInt + * @since 1.4 + */ + public void setInt(String parameterName, int x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java long value. + * The driver converts this + * to an SQL BIGINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getLong + * @since 1.4 + */ + public void setLong(String parameterName, long x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java float value. + * The driver converts this + * to an SQL FLOAT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getFloat + * @since 1.4 + */ + public void setFloat(String parameterName, float x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java double value. + * The driver converts this + * to an SQL DOUBLE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getDouble + * @since 1.4 + */ + public void setDouble(String parameterName, double x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given + * java.math.BigDecimal value. + * The driver converts this to an SQL NUMERIC value when + * it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getBigDecimal + * @since 1.4 + */ + public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java String value. + * The driver converts this + * to an SQL VARCHAR or LONGVARCHAR value + * (depending on the argument's + * size relative to the driver's limits on VARCHAR values) + * when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getString + * @since 1.4 + */ + public void setString(String parameterName, String x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given Java array of bytes. + * The driver converts this to an SQL VARBINARY or + * LONGVARBINARY (depending on the argument's size relative + * to the driver's limits on VARBINARY values) when it sends + * it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getBytes + * @since 1.4 + */ + public void setBytes(String parameterName, byte x[]) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Date value. + * The driver converts this + * to an SQL DATE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Time value. + * The driver converts this + * to an SQL TIME value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, java.sql.Time x) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Timestamp value. + * The driver + * converts this to an SQL TIMESTAMP value when it sends it to the + * database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, java.sql.Timestamp x) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the Java input stream that contains the ASCII parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setAsciiStream(String parameterName, java.io.InputStream x, int length) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large binary value is input to a LONGVARBINARY + * parameter, it may be more practical to send it via a + * java.io.InputStream object. The data will be read from the stream + * as needed until end-of-file is reached. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the java input stream which contains the binary parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setBinaryStream(String parameterName, java.io.InputStream x, + int length) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the value of the designated parameter with the given object. The second + * argument must be an object type; for integral values, the + * java.lang equivalent objects should be used. + * + *

The given Java object will be converted to the given targetSqlType + * before being sent to the database. + * + * If the object has a custom mapping (is of a class implementing the + * interface SQLData), + * the JDBC driver should call the method SQLData.writeSQL to write it + * to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, Struct, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * Note that this method may be used to pass datatabase- + * specific abstract data types. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database. The scale argument may further qualify this type. + * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, + * this is the number of digits after the decimal point. For all other + * types, this value will be ignored. + * @exception SQLException if a database access error occurs + * @see Types + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType, int scale) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the value of the designated parameter with the given object. + * This method is like the method setObject + * above, except that it assumes a scale of zero. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database + * @exception SQLException if a database access error occurs + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the value of the designated parameter with the given object. + * The second parameter must be of type Object; therefore, the + * java.lang equivalent objects should be used for built-in types. + * + *

The JDBC specification specifies a standard mapping from + * Java Object types to SQL types. The given argument + * will be converted to the corresponding SQL type before being + * sent to the database. + * + *

Note that this method may be used to pass datatabase- + * specific abstract data types, by using a driver-specific Java + * type. + * + * If the object is of a class implementing the interface SQLData, + * the JDBC driver should call the method SQLData.writeSQL + * to write it to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, Struct, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * This method throws an exception if there is an ambiguity, for example, if the + * object is of a class implementing more than one of the interfaces named above. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @exception SQLException if a database access error occurs or if the given + * Object parameter is ambiguous + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + + /** + * Sets the designated parameter to the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param reader the java.io.Reader object that + * contains the UNICODE data used as the designated parameter + * @param length the number of characters in the stream + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setCharacterStream(String parameterName, + java.io.Reader reader, + int length) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Date value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL DATE value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the date + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the date + * @exception SQLException if a database access error occurs + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Time value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIME value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the time + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the time + * @exception SQLException if a database access error occurs + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, java.sql.Time x, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to the given java.sql.Timestamp value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIMESTAMP value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the timestamp + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the timestamp + * @exception SQLException if a database access error occurs + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Sets the designated parameter to SQL NULL. + * This version of the method setNull should + * be used for user-defined types and REF type parameters. Examples + * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and + * named array types. + * + *

Note: To be portable, applications must give the + * SQL type code and the fully-qualified SQL type name when specifying + * a NULL user-defined or REF parameter. In the case of a user-defined type + * the name is the type name of the parameter itself. For a REF + * parameter, the name is the type name of the referenced type. If + * a JDBC driver does not need the type code or type name information, + * it may ignore it. + * + * Although it is intended for user-defined and Ref parameters, + * this method may be used to set a null parameter of any JDBC type. + * If the parameter does not have a user-defined or REF type, the given + * typeName is ignored. + * + * + * @param paramName the name of the parameter + * @param sqlType a value from java.sql.Types + * @param typeName the fully-qualified name of an SQL user-defined type; + * ignored if the parameter is not a user-defined type or + * SQL REF value + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public void setNull (String parameterName, int sqlType, String typeName) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC CHAR, VARCHAR, + * or LONGVARCHAR parameter as a String in + * the Java programming language. + *

+ * For the fixed-length type JDBC CHAR, + * the String object + * returned has exactly the same value the JDBC + * CHAR value had in the + * database, including any padding added by the database. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is null. + * @exception SQLException if a database access error occurs + * @see #setString + * @since 1.4 + */ + public String getString(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC BIT parameter as a + * boolean in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is false. + * @exception SQLException if a database access error occurs + * @see #setBoolean + * @since 1.4 + */ + public boolean getBoolean(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC TINYINT parameter as a byte + * in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is 0. + * @exception SQLException if a database access error occurs + * @see #setByte + * @since 1.4 + */ + public byte getByte(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC SMALLINT parameter as a short + * in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is 0. + * @exception SQLException if a database access error occurs + * @see #setShort + * @since 1.4 + */ + public short getShort(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC INTEGER parameter as an int + * in the Java programming language. + * + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, + * the result is 0. + * @exception SQLException if a database access error occurs + * @see #setInt + * @since 1.4 + */ + public int getInt(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC BIGINT parameter as a long + * in the Java programming language. + * + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, + * the result is 0. + * @exception SQLException if a database access error occurs + * @see #setLong + * @since 1.4 + */ + public long getLong(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC FLOAT parameter as a float + * in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, + * the result is 0. + * @exception SQLException if a database access error occurs + * @see #setFloat + * @since 1.4 + */ + public float getFloat(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC DOUBLE parameter as a double + * in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, + * the result is 0. + * @exception SQLException if a database access error occurs + * @see #setDouble + * @since 1.4 + */ + public double getDouble(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC BINARY or VARBINARY + * parameter as an array of byte values in the Java + * programming language. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result is + * null. + * @exception SQLException if a database access error occurs + * @see #setBytes + * @since 1.4 + */ + public byte[] getBytes(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC DATE parameter as a + * java.sql.Date object. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is null. + * @exception SQLException if a database access error occurs + * @see #setDate + * @since 1.4 + */ + public java.sql.Date getDate(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC TIME parameter as a + * java.sql.Time object. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is null. + * @exception SQLException if a database access error occurs + * @see #setTime + * @since 1.4 + */ + public java.sql.Time getTime(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC TIMESTAMP parameter as a + * java.sql.Timestamp object. + * @param parameterName the name of the parameter + * @return the parameter value. If the value is SQL NULL, the result + * is null. + * @exception SQLException if a database access error occurs + * @see #setTimestamp + * @since 1.4 + */ + public java.sql.Timestamp getTimestamp(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a parameter as an Object in the Java + * programming language. If the value is an SQL NULL, the + * driver returns a Java null. + *

+ * This method returns a Java object whose type corresponds to the JDBC + * type that was registered for this parameter using the method + * registerOutParameter. By registering the target JDBC + * type as java.sql.Types.OTHER, this method can be used + * to read database-specific abstract data types. + * @param parameterName the name of the parameter + * @return A java.lang.Object holding the OUT parameter value. + * @exception SQLException if a database access error occurs + * @see Types + * @see #setObject + * @since 1.4 + */ + public Object getObject(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC NUMERIC parameter as a + * java.math.BigDecimal object with as many digits to the + * right of the decimal point as the value contains. + * @param parameterName the name of the parameter + * @return the parameter value in full precision. If the value is + * SQL NULL, the result is null. + * @exception SQLException if a database access error occurs + * @see #setBigDecimal + * @since 1.4 + */ + public BigDecimal getBigDecimal(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Returns an object representing the value of OUT parameter + * i and uses map for the custom + * mapping of the parameter value. + *

+ * This method returns a Java object whose type corresponds to the + * JDBC type that was registered for this parameter using the method + * registerOutParameter. By registering the target + * JDBC type as java.sql.Types.OTHER, this method can + * be used to read database-specific abstract data types. + * @param parameterName the name of the parameter + * @param map the mapping from SQL type names to Java classes + * @return a java.lang.Object holding the OUT parameter value + * @exception SQLException if a database access error occurs + * @see #setObject + * @since 1.4 + */ + public Object getObject (String parameterName, java.util.Map map) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC REF(<structured-type>) + * parameter as a {@link Ref} object in the Java programming language. + * + * @param parameterName the name of the parameter + * @return the parameter value as a Ref object in the + * Java programming language. If the value was SQL NULL, + * the value null is returned. + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public Ref getRef (String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC BLOB parameter as a + * {@link Blob} object in the Java programming language. + * + * @param parameterName the name of the parameter + * @return the parameter value as a Blob object in the + * Java programming language. If the value was SQL NULL, + * the value null is returned. + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public Blob getBlob (String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC CLOB parameter as a + * Clob object in the Java programming language. + * @param parameterName the name of the parameter + * @return the parameter value as a Clob object in the + * Java programming language. If the value was SQL NULL, + * the value null is returned. + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public Clob getClob (String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC ARRAY parameter as an + * {@link Array} object in the Java programming language. + * + * @param parameterName the name of the parameter + * @return the parameter value as an Array object in + * Java programming language. If the value was SQL NULL, + * the value null is returned. + * @exception SQLException if a database access error occurs + * @since 1.4 + */ + public Array getArray (String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC DATE parameter as a + * java.sql.Date object, using + * the given Calendar object + * to construct the date. + * With a Calendar object, the driver + * can calculate the date taking into account a custom timezone and locale. + * If no Calendar object is specified, the driver uses the + * default timezone and locale. + * + * @param parameterName the name of the parameter + * @param cal the Calendar object the driver will use + * to construct the date + * @return the parameter value. If the value is SQL NULL, + * the result is null. + * @exception SQLException if a database access error occurs + * @see #setDate + * @since 1.4 + */ + public java.sql.Date getDate(String parameterName, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC TIME parameter as a + * java.sql.Time object, using + * the given Calendar object + * to construct the time. + * With a Calendar object, the driver + * can calculate the time taking into account a custom timezone and locale. + * If no Calendar object is specified, the driver uses the + * default timezone and locale. + * + * @param parameterName the name of the parameter + * @param cal the Calendar object the driver will use + * to construct the time + * @return the parameter value; if the value is SQL NULL, the result is + * null. + * @exception SQLException if a database access error occurs + * @see #setTime + * @since 1.4 + */ + public java.sql.Time getTime(String parameterName, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC TIMESTAMP parameter as a + * java.sql.Timestamp object, using + * the given Calendar object to construct + * the Timestamp object. + * With a Calendar object, the driver + * can calculate the timestamp taking into account a custom timezone and locale. + * If no Calendar object is specified, the driver uses the + * default timezone and locale. + * + * + * @param parameterName the name of the parameter + * @param cal the Calendar object the driver will use + * to construct the timestamp + * @return the parameter value. If the value is SQL NULL, the result is + * null. + * @exception SQLException if a database access error occurs + * @see #setTimestamp + * @since 1.4 + */ + public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal) + throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } + + /** + * Retrieves the value of a JDBC DATALINK parameter as a + * java.net.URL object. + * + * @param parameterName the name of the parameter + * @return the parameter value as a java.net.URL object in the + * Java programming language. If the value was SQL NULL, the + * value null is returned. + * @exception SQLException if a database access error occurs, + * or if there is a problem with the URL + * @see #setURL + * @since 1.4 + */ + public java.net.URL getURL(String parameterName) throws SQLException + { + throw org.postgresql.Driver.notImplemented(); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java index eef5bd4fbc679e583b5799960cdc4fcfb0361ca6..64b2be2d41f74a1080e9d49a656345649980f5da 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java @@ -5,11 +5,11 @@ import java.sql.*; public class Jdbc3CallableStatement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.CallableStatement { - + public Jdbc3CallableStatement(Jdbc3Connection connection, String sql) throws SQLException { super(connection, sql); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java index b6f279d7e23acb1144293c73a6a543ddcf518dfd..2e1ba7d8cbf78e05bf4008e9315cc6150338aaa0 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java @@ -6,56 +6,56 @@ import java.util.Vector; import java.util.Hashtable; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Connection.java,v 1.1 2002/08/14 20:35:40 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Connection interface for JDBC3. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3Connection or one of it's parents */ public class Jdbc3Connection extends org.postgresql.jdbc3.AbstractJdbc3Connection implements java.sql.Connection { - - public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc3Statement s = new Jdbc3Statement(this); - s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - - public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc3PreparedStatement s = new Jdbc3PreparedStatement(this, sql); - s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - Jdbc3CallableStatement s = new Jdbc3CallableStatement(this,sql); + + public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc3Statement s = new Jdbc3Statement(this); + s.setResultSetType(resultSetType); + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + + public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc3PreparedStatement s = new Jdbc3PreparedStatement(this, sql); s.setResultSetType(resultSetType); - s.setResultSetConcurrency(resultSetConcurrency); - return s; - } - - public java.sql.DatabaseMetaData getMetaData() throws SQLException - { - if (metadata == null) - metadata = new Jdbc3DatabaseMetaData(this); - return metadata; - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException - { - return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); - } - + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + Jdbc3CallableStatement s = new Jdbc3CallableStatement(this, sql); + s.setResultSetType(resultSetType); + s.setResultSetConcurrency(resultSetConcurrency); + return s; + } + + public java.sql.DatabaseMetaData getMetaData() throws SQLException + { + if (metadata == null) + metadata = new Jdbc3DatabaseMetaData(this); + return metadata; + } + + public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + + public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException + { + return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); + } + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java index c242c6322837d135b6d34715c2a10079d0b85229..24fe763073018be451b32068b7c9095d02596ee3 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3DatabaseMetaData.java @@ -3,10 +3,10 @@ package org.postgresql.jdbc3; public class Jdbc3DatabaseMetaData extends org.postgresql.jdbc3.AbstractJdbc3DatabaseMetaData implements java.sql.DatabaseMetaData { - + public Jdbc3DatabaseMetaData(Jdbc3Connection conn) { super(conn); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java index bc570129ebdddc72aa6acf1640d39f410849f2f5..85ccbbb5e89955994f52ad23f673c99e1a72b566 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java @@ -5,11 +5,11 @@ import java.sql.*; public class Jdbc3PreparedStatement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.PreparedStatement { - + public Jdbc3PreparedStatement(Jdbc3Connection connection, String sql) throws SQLException { super(connection, sql); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java index f2652ee1f5a2982a6e2a9a4291971672e5cf281d..c988127fe46519a350f9d4aa4527a3f26655b1e0 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java @@ -5,31 +5,33 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3ResultSet.java,v 1.1 2002/08/14 20:35:40 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3ResultSet.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.ResultSet interface for JDBC3. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3ResultSet or one of it's parents */ public class Jdbc3ResultSet extends org.postgresql.jdbc3.AbstractJdbc3ResultSet implements java.sql.ResultSet { - + public Jdbc3ResultSet(Jdbc3Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } - + public java.sql.ResultSetMetaData getMetaData() throws SQLException { return new Jdbc3ResultSetMetaData(rows, fields); } - - public java.sql.Clob getClob(int i) throws SQLException { - return new Jdbc3Clob(connection, getInt(i)); - } - - public java.sql.Blob getBlob(int i) throws SQLException { - return new Jdbc3Blob(connection, getInt(i)); - } + + public java.sql.Clob getClob(int i) throws SQLException + { + return new Jdbc3Clob(connection, getInt(i)); + } + + public java.sql.Blob getBlob(int i) throws SQLException + { + return new Jdbc3Blob(connection, getInt(i)); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java index 5dd48a9846334a30cc5442b3b6d8fdfe24ca98fb..cc49aadd58df6720df390df08efa117c5b9de3b6 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSetMetaData.java @@ -2,11 +2,11 @@ package org.postgresql.jdbc3; public class Jdbc3ResultSetMetaData extends org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData implements java.sql.ResultSetMetaData { - + public Jdbc3ResultSetMetaData(java.util.Vector rows, org.postgresql.Field[] fields) { - super(rows, fields); + super(rows, fields); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java index bf6a0d5155ac43a4f964ea350f479c81c4e57f71..c711b11696b59a9428cc8d3864fd98b92bdb5e8b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java @@ -3,17 +3,17 @@ package org.postgresql.jdbc3; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.1 2002/08/14 20:35:40 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ * This class implements the java.sql.Statement interface for JDBC3. - * However most of the implementation is really done in + * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3Statement or one of it's parents */ public class Jdbc3Statement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.Statement { - + public Jdbc3Statement (Jdbc3Connection c) { super(c); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObject.java b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObject.java index 5910482bffce5cb31307738c7cb092ae6312d8a9..316716e42d0964386a482410fc06b288369b24b0 100644 --- a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObject.java +++ b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObject.java @@ -92,12 +92,12 @@ public class LargeObject /* Release large object resources during garbage cleanup */ protected void finalize() throws SQLException { - //This code used to call close() however that was problematic - //because the scope of the fd is a transaction, thus if commit - //or rollback was called before garbage collection ran then - //the call to close would error out with an invalid large object - //handle. So this method now does nothing and lets the server - //handle cleanup when it ends the transaction. + //This code used to call close() however that was problematic + //because the scope of the fd is a transaction, thus if commit + //or rollback was called before garbage collection ran then + //the call to close would error out with an invalid large object + //handle. So this method now does nothing and lets the server + //handle cleanup when it ends the transaction. } /* diff --git a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java index a037ab28a21719cc183e5fc246badf38d06341dc..a57c01cd232cc26acfd05710567fa02d2de02287 100644 --- a/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java +++ b/src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java @@ -104,21 +104,22 @@ public class LargeObjectManager // This is an example of Fastpath.addFunctions(); // ResultSet res = conn.createStatement().executeQuery("select proname, oid from pg_proc" + - " where proname = 'lo_open'" + - " or proname = 'lo_close'" + - " or proname = 'lo_creat'" + - " or proname = 'lo_unlink'" + - " or proname = 'lo_lseek'" + - " or proname = 'lo_tell'" + - " or proname = 'loread'" + - " or proname = 'lowrite'"); + " where proname = 'lo_open'" + + " or proname = 'lo_close'" + + " or proname = 'lo_creat'" + + " or proname = 'lo_unlink'" + + " or proname = 'lo_lseek'" + + " or proname = 'lo_tell'" + + " or proname = 'loread'" + + " or proname = 'lowrite'"); if (res == null) throw new PSQLException("postgresql.lo.init"); fp.addFunctions(res); res.close(); - if (Driver.logDebug) Driver.debug("Large Object initialised"); + if (Driver.logDebug) + Driver.debug("Large Object initialised"); } /* diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java index 23cc28697f7cd2b4c3bd08d1205c77b764496ab6..eb05fa97ab8f1c9e9d4142ced8d84148f1b7d3dd 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/CallableStmtTest.java @@ -22,17 +22,17 @@ public class CallableStmtTest extends TestCase { con = TestUtil.openDB(); Statement stmt = con.createStatement (); - stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + - "RETURNS varchar AS ' DECLARE inString alias for $1; begin "+ + stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + + "RETURNS varchar AS ' DECLARE inString alias for $1; begin " + "return ''bob''; end; ' LANGUAGE 'plpgsql';"); - stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getDouble (float) " + + stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getDouble (float) " + "RETURNS float AS ' DECLARE inString alias for $1; begin " + "return 42.42; end; ' LANGUAGE 'plpgsql';"); stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getInt (int) RETURNS int " + - " AS 'DECLARE inString alias for $1; begin " + - "return 42; end;' LANGUAGE 'plpgsql';"); - stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getNumeric (numeric) " + - "RETURNS numeric AS ' DECLARE inString alias for $1; " + + " AS 'DECLARE inString alias for $1; begin " + + "return 42; end;' LANGUAGE 'plpgsql';"); + stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getNumeric (numeric) " + + "RETURNS numeric AS ' DECLARE inString alias for $1; " + "begin return 42; end; ' LANGUAGE 'plpgsql';"); stmt.close (); } @@ -54,7 +54,8 @@ public class CallableStmtTest extends TestCase //testGetString (); //} - public void testGetDouble () throws Throwable { + public void testGetDouble () throws Throwable + { // System.out.println ("Testing CallableStmt Types.DOUBLE"); CallableStatement call = con.prepareCall (func + pkgName + "getDouble (?) }"); call.setDouble (2, (double)3.04); @@ -64,7 +65,8 @@ public class CallableStmtTest extends TestCase assertTrue ("correct return from getString ()", result == 42.42); } - public void testGetInt () throws Throwable { + public void testGetInt () throws Throwable + { // System.out.println ("Testing CallableStmt Types.INTEGER"); CallableStatement call = con.prepareCall (func + pkgName + "getInt (?) }"); call.setInt (2, 4); @@ -74,18 +76,20 @@ public class CallableStmtTest extends TestCase assertTrue ("correct return from getString ()", result == 42); } - public void testGetNumeric () throws Throwable { + public void testGetNumeric () throws Throwable + { // System.out.println ("Testing CallableStmt Types.NUMERIC"); CallableStatement call = con.prepareCall (func + pkgName + "getNumeric (?) }"); call.setBigDecimal (2, new java.math.BigDecimal(4)); call.registerOutParameter (1, Types.NUMERIC); call.execute (); java.math.BigDecimal result = call.getBigDecimal (1); - assertTrue ("correct return from getString ()", + assertTrue ("correct return from getString ()", result.equals (new java.math.BigDecimal(42))); } - public void testGetString () throws Throwable { + public void testGetString () throws Throwable + { // System.out.println ("Testing CallableStmt Types.VARCHAR"); CallableStatement call = con.prepareCall (func + pkgName + "getString (?) }"); call.setString (2, "foo"); @@ -96,20 +100,25 @@ public class CallableStmtTest extends TestCase } - public void testBadStmt () throws Throwable { + public void testBadStmt () throws Throwable + { tryOneBadStmt ("{ ?= " + pkgName + "getString (?) }"); tryOneBadStmt ("{ ?= call getString (?) "); tryOneBadStmt ("{ = ? call getString (?); }"); } - protected void tryOneBadStmt (String sql) throws Throwable { + protected void tryOneBadStmt (String sql) throws Throwable + { boolean wasCaught = false; - try { + try + { CallableStatement call = con.prepareCall (sql); - } catch (SQLException e) { + } + catch (SQLException e) + { wasCaught = true; // good -> this statement was missing something } - assertTrue ("bad statment ('"+sql+"')was not caught", wasCaught); + assertTrue ("bad statment ('" + sql + "')was not caught", wasCaught); } - + } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java index cb7d036a77f9a0827754451ee7d59665fc5028c6..87341925c5d5b99991a6baba45daf8eaff1a480f 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java @@ -9,7 +9,7 @@ import java.sql.*; * * PS: Do you know how difficult it is to type on a train? ;-) * - * $Id: DatabaseMetaDataTest.java,v 1.12 2002/08/23 20:45:49 barry Exp $ + * $Id: DatabaseMetaDataTest.java,v 1.13 2002/09/06 21:23:06 momjian Exp $ */ public class DatabaseMetaDataTest extends TestCase @@ -48,7 +48,7 @@ public class DatabaseMetaDataTest extends TestCase ResultSet rs = dbmd.getTables( null, null, "test%", new String[] {"TABLE"}); assertTrue( rs.next() ); - String tableName = rs.getString("TABLE_NAME"); + String tableName = rs.getString("TABLE_NAME"); assertTrue( tableName.equals("testmetadata") ); rs.close(); @@ -102,10 +102,10 @@ public class DatabaseMetaDataTest extends TestCase assertTrue(dbmd.supportsMinimumSQLGrammar()); assertTrue(!dbmd.supportsCoreSQLGrammar()); assertTrue(!dbmd.supportsExtendedSQLGrammar()); - if (((org.postgresql.jdbc1.AbstractJdbc1Connection)con).haveMinimumServerVersion("7.3")) - assertTrue(dbmd.supportsANSI92EntryLevelSQL()); - else - assertTrue(!dbmd.supportsANSI92EntryLevelSQL()); + if (((org.postgresql.jdbc1.AbstractJdbc1Connection)con).haveMinimumServerVersion("7.3")) + assertTrue(dbmd.supportsANSI92EntryLevelSQL()); + else + assertTrue(!dbmd.supportsANSI92EntryLevelSQL()); assertTrue(!dbmd.supportsANSI92IntermediateSQL()); assertTrue(!dbmd.supportsANSI92FullSQL()); @@ -232,124 +232,124 @@ public class DatabaseMetaDataTest extends TestCase } } - public void testCrossReference() - { + public void testCrossReference() + { try { - Connection con1 = TestUtil.openDB(); + Connection con1 = TestUtil.openDB(); - TestUtil.createTable( con1, "vv", "a int not null, b int not null, primary key ( a, b )" ); + TestUtil.createTable( con1, "vv", "a int not null, b int not null, primary key ( a, b )" ); - TestUtil.createTable( con1, "ww", "m int not null, n int not null, primary key ( m, n ), foreign key ( m, n ) references vv ( a, b )" ); + TestUtil.createTable( con1, "ww", "m int not null, n int not null, primary key ( m, n ), foreign key ( m, n ) references vv ( a, b )" ); DatabaseMetaData dbmd = con.getMetaData(); assertNotNull(dbmd); - ResultSet rs = dbmd.getCrossReference(null, "", "vv", null, "", "ww" ); + ResultSet rs = dbmd.getCrossReference(null, "", "vv", null, "", "ww" ); - for (int j=1; rs.next(); j++ ) - { + for (int j = 1; rs.next(); j++ ) + { - String pkTableName = rs.getString( "PKTABLE_NAME" ); - assertTrue ( pkTableName.equals("vv") ); + String pkTableName = rs.getString( "PKTABLE_NAME" ); + assertTrue ( pkTableName.equals("vv") ); - String pkColumnName = rs.getString( "PKCOLUMN_NAME" ); - assertTrue( pkColumnName.equals("a") || pkColumnName.equals("b")); + String pkColumnName = rs.getString( "PKCOLUMN_NAME" ); + assertTrue( pkColumnName.equals("a") || pkColumnName.equals("b")); - String fkTableName = rs.getString( "FKTABLE_NAME" ); - assertTrue( fkTableName.equals( "ww" ) ); + String fkTableName = rs.getString( "FKTABLE_NAME" ); + assertTrue( fkTableName.equals( "ww" ) ); - String fkColumnName = rs.getString( "FKCOLUMN_NAME" ); - assertTrue( fkColumnName.equals( "m" ) || fkColumnName.equals( "n" ) ) ; + String fkColumnName = rs.getString( "FKCOLUMN_NAME" ); + assertTrue( fkColumnName.equals( "m" ) || fkColumnName.equals( "n" ) ) ; - String fkName = rs.getString( "FK_NAME" ); - assertTrue( fkName.equals( "") ); + String fkName = rs.getString( "FK_NAME" ); + assertTrue( fkName.equals( "") ); - String pkName = rs.getString( "PK_NAME" ); - assertTrue( pkName.equals("vv_pkey") ); + String pkName = rs.getString( "PK_NAME" ); + assertTrue( pkName.equals("vv_pkey") ); - int keySeq = rs.getInt( "KEY_SEQ" ); - assertTrue( keySeq == j ); - } + int keySeq = rs.getInt( "KEY_SEQ" ); + assertTrue( keySeq == j ); + } - TestUtil.dropTable( con1, "vv" ); - TestUtil.dropTable( con1, "ww" ); + TestUtil.dropTable( con1, "vv" ); + TestUtil.dropTable( con1, "ww" ); } catch (SQLException ex) { fail(ex.getMessage()); } - } - public void testForeignKeys() - { + } + public void testForeignKeys() + { try { - Connection con1 = TestUtil.openDB(); - TestUtil.createTable( con1, "people", "id int4 primary key, name text" ); - TestUtil.createTable( con1, "policy", "id int4 primary key, name text" ); + Connection con1 = TestUtil.openDB(); + TestUtil.createTable( con1, "people", "id int4 primary key, name text" ); + TestUtil.createTable( con1, "policy", "id int4 primary key, name text" ); - TestUtil.createTable( con1, "users", "id int4 primary key, people_id int4, policy_id int4,"+ - "CONSTRAINT people FOREIGN KEY (people_id) references people(id),"+ - "constraint policy FOREIGN KEY (policy_id) references policy(id)" ); + TestUtil.createTable( con1, "users", "id int4 primary key, people_id int4, policy_id int4," + + "CONSTRAINT people FOREIGN KEY (people_id) references people(id)," + + "constraint policy FOREIGN KEY (policy_id) references policy(id)" ); DatabaseMetaData dbmd = con.getMetaData(); assertNotNull(dbmd); - ResultSet rs = dbmd.getImportedKeys(null, "", "users" ); - int j = 0; - for (; rs.next(); j++ ) - { + ResultSet rs = dbmd.getImportedKeys(null, "", "users" ); + int j = 0; + for (; rs.next(); j++ ) + { - String pkTableName = rs.getString( "PKTABLE_NAME" ); - assertTrue ( pkTableName.equals("people") || pkTableName.equals("policy") ); + String pkTableName = rs.getString( "PKTABLE_NAME" ); + assertTrue ( pkTableName.equals("people") || pkTableName.equals("policy") ); - String pkColumnName = rs.getString( "PKCOLUMN_NAME" ); - assertTrue( pkColumnName.equals("id") ); + String pkColumnName = rs.getString( "PKCOLUMN_NAME" ); + assertTrue( pkColumnName.equals("id") ); - String fkTableName = rs.getString( "FKTABLE_NAME" ); - assertTrue( fkTableName.equals( "users" ) ); + String fkTableName = rs.getString( "FKTABLE_NAME" ); + assertTrue( fkTableName.equals( "users" ) ); - String fkColumnName = rs.getString( "FKCOLUMN_NAME" ); - assertTrue( fkColumnName.equals( "people_id" ) || fkColumnName.equals( "policy_id" ) ) ; + String fkColumnName = rs.getString( "FKCOLUMN_NAME" ); + assertTrue( fkColumnName.equals( "people_id" ) || fkColumnName.equals( "policy_id" ) ) ; - String fkName = rs.getString( "FK_NAME" ); - assertTrue( fkName.equals( "people") || fkName.equals( "policy" ) ); + String fkName = rs.getString( "FK_NAME" ); + assertTrue( fkName.equals( "people") || fkName.equals( "policy" ) ); - String pkName = rs.getString( "PK_NAME" ); - assertTrue( pkName.equals( "people_pkey") || pkName.equals( "policy_pkey" ) ); + String pkName = rs.getString( "PK_NAME" ); + assertTrue( pkName.equals( "people_pkey") || pkName.equals( "policy_pkey" ) ); - } + } - assertTrue ( j== 2 ); + assertTrue ( j == 2 ); - rs = dbmd.getExportedKeys( null, "", "people" ); + rs = dbmd.getExportedKeys( null, "", "people" ); - // this is hacky, but it will serve the purpose - assertTrue ( rs.next() ); + // this is hacky, but it will serve the purpose + assertTrue ( rs.next() ); - assertTrue( rs.getString( "PKTABLE_NAME" ).equals( "people" ) ); - assertTrue( rs.getString( "PKCOLUMN_NAME" ).equals( "id" ) ); + assertTrue( rs.getString( "PKTABLE_NAME" ).equals( "people" ) ); + assertTrue( rs.getString( "PKCOLUMN_NAME" ).equals( "id" ) ); - assertTrue( rs.getString( "FKTABLE_NAME" ).equals( "users" ) ); - assertTrue( rs.getString( "FKCOLUMN_NAME" ).equals( "people_id" ) ); + assertTrue( rs.getString( "FKTABLE_NAME" ).equals( "users" ) ); + assertTrue( rs.getString( "FKCOLUMN_NAME" ).equals( "people_id" ) ); - assertTrue( rs.getString( "FK_NAME" ).equals( "people" ) ); + assertTrue( rs.getString( "FK_NAME" ).equals( "people" ) ); - TestUtil.dropTable( con1, "users" ); - TestUtil.dropTable( con1, "people" ); - TestUtil.dropTable( con1, "policy" ); + TestUtil.dropTable( con1, "users" ); + TestUtil.dropTable( con1, "people" ); + TestUtil.dropTable( con1, "policy" ); } catch (SQLException ex) { fail(ex.getMessage()); } - } + } public void testTables() { try @@ -422,20 +422,20 @@ public class DatabaseMetaDataTest extends TestCase { try { - assertTrue(con instanceof org.postgresql.PGConnection); + assertTrue(con instanceof org.postgresql.PGConnection); org.postgresql.jdbc2.AbstractJdbc2Connection pc = (org.postgresql.jdbc2.AbstractJdbc2Connection) con; DatabaseMetaData dbmd = con.getMetaData(); assertNotNull(dbmd); assertTrue(dbmd.getDatabaseProductName().equals("PostgreSQL")); - //The test below doesn't make sense to me, it tests that - //the version of the driver = the version of the database it is connected to - //since the driver should be backwardly compatible this test is commented out + //The test below doesn't make sense to me, it tests that + //the version of the driver = the version of the database it is connected to + //since the driver should be backwardly compatible this test is commented out //assertTrue(dbmd.getDatabaseProductVersion().startsWith( - // Integer.toString(pc.getDriver().getMajorVersion()) - // + "." - // + Integer.toString(pc.getDriver().getMinorVersion()))); + // Integer.toString(pc.getDriver().getMajorVersion()) + // + "." + // + Integer.toString(pc.getDriver().getMinorVersion()))); assertTrue(dbmd.getDriverName().equals("PostgreSQL Native Driver")); } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java index ee4a0ebd5af2b22dc0868b21982c0f1d474103ab..13ce93b24d81cd79351602f4a05068a9bcabce7a 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java @@ -6,7 +6,7 @@ import java.sql.*; import java.math.BigDecimal; /* - * $Id: JBuilderTest.java,v 1.6 2002/08/14 20:35:40 barry Exp $ + * $Id: JBuilderTest.java,v 1.7 2002/09/06 21:23:06 momjian Exp $ * * Some simple tests to check that the required components needed for JBuilder * stay working @@ -26,7 +26,7 @@ public class JBuilderTest extends TestCase Connection con = TestUtil.openDB(); TestUtil.createTable( con, "test_c", - "source text,cost money,imageid int4" ); + "source text,cost money,imageid int4" ); TestUtil.closeDB(con); } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java index 64dd44848a84f223bb0fc635b8aab1a2f7c7bb10..3dbc1f8d321f38bf2f09c76a1b46cc6d54e70a7e 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java @@ -63,7 +63,7 @@ public class Jdbc2TestSuite extends TestSuite suite.addTestSuite( UpdateableResultTest.class ); suite.addTestSuite( CallableStmtTest.class ); - + // That's all folks return suite; } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java index 7164327f04158ed988ed4cc6ff3fda61ba5e6b5e..025f8c0e7222207c50eb8655dd981660453e6c51 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java @@ -5,7 +5,7 @@ import junit.framework.TestCase; import java.sql.*; /* - * $Id: MiscTest.java,v 1.7 2002/08/14 20:35:40 barry Exp $ + * $Id: MiscTest.java,v 1.8 2002/09/06 21:23:06 momjian Exp $ * * Some simple tests based on problems reported by users. Hopefully these will * help prevent previous problems from re-occuring ;-) @@ -52,28 +52,29 @@ public class MiscTest extends TestCase } } - public void testError() - { - Connection con = TestUtil.openDB(); + public void testError() + { + Connection con = TestUtil.openDB(); try { - // transaction mode - con.setAutoCommit(false); - Statement stmt = con.createStatement(); - stmt.execute("select 1/0"); + // transaction mode + con.setAutoCommit(false); + Statement stmt = con.createStatement(); + stmt.execute("select 1/0"); fail( "Should not execute this, as a SQLException s/b thrown" ); - con.commit(); + con.commit(); } catch ( Exception ex ) + {} + try { + con.commit(); + con.close(); } - try - { - con.commit(); - con.close(); - }catch ( Exception ex) {} - } + catch ( Exception ex) + {} + } public void xtestLocking() { @@ -90,7 +91,7 @@ public class MiscTest extends TestCase con.setAutoCommit(false); st.execute("lock table test_lock"); st2.executeUpdate( "insert into test_lock ( name ) values ('hello')" ); - con.commit(); + con.commit(); TestUtil.dropTable(con, "test_lock"); con.close(); } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java index 0a818c529bdef48f1ef4e63f5a27c71afceef63f..b983d20b0acea1697f5dab8279cdcd2efe7f9cf3 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java @@ -63,24 +63,24 @@ public class ResultSetTest extends TestCase stmt.close(); } - public void testEmptyResult() - { - try - { - Statement stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT * FROM testrs where id=100"); - rs.beforeFirst(); - rs.afterLast(); - assertTrue(!rs.first()); - assertTrue(!rs.last()); - assertTrue(!rs.next()); - - - } - catch ( Exception ex ) - { - fail( ex.getMessage() ); - } - - } + public void testEmptyResult() + { + try + { + Statement stmt = con.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM testrs where id=100"); + rs.beforeFirst(); + rs.afterLast(); + assertTrue(!rs.first()); + assertTrue(!rs.last()); + assertTrue(!rs.next()); + + + } + catch ( Exception ex ) + { + fail( ex.getMessage() ); + } + + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java index 444427f13fcde93652b8834cbae4ebdd152b4276..2472a3d3d82aff9dfe005e97ae93e1397385256e 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java @@ -5,9 +5,9 @@ import junit.framework.TestCase; import java.sql.*; /* - * $Id: TimestampTest.java,v 1.8 2002/08/14 20:35:40 barry Exp $ + * $Id: TimestampTest.java,v 1.9 2002/09/06 21:23:06 momjian Exp $ * - * Test get/setTimestamp for both timestamp with time zone and + * Test get/setTimestamp for both timestamp with time zone and * timestamp without time zone datatypes * */ @@ -39,8 +39,8 @@ public class TimestampTest extends TestCase /* * Tests the timestamp methods in ResultSet on timestamp with time zone - * we insert a known string value (don't use setTimestamp) then see that - * we get back the same value from getTimestamp + * we insert a known string value (don't use setTimestamp) then see that + * we get back the same value from getTimestamp */ public void testGetTimestampWTZ() { @@ -48,15 +48,15 @@ public class TimestampTest extends TestCase { Statement stmt = con.createStatement(); - //Insert the three timestamp values in raw pg format - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS1WTZ_PGFORMAT + "'"))); - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS2WTZ_PGFORMAT + "'"))); - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE,"'" + TS3WTZ_PGFORMAT + "'"))); + //Insert the three timestamp values in raw pg format + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE, "'" + TS1WTZ_PGFORMAT + "'"))); + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE, "'" + TS2WTZ_PGFORMAT + "'"))); + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWTZ_TABLE, "'" + TS3WTZ_PGFORMAT + "'"))); // Fall through helper - timestampTestWTZ(); + timestampTestWTZ(); - assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE)); + assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE)); stmt.close(); } @@ -68,9 +68,9 @@ public class TimestampTest extends TestCase /* * Tests the timestamp methods in PreparedStatement on timestamp with time zone - * we insert a value using setTimestamp then see that - * we get back the same value from getTimestamp (which we know works as it was tested - * independently of setTimestamp + * we insert a value using setTimestamp then see that + * we get back the same value from getTimestamp (which we know works as it was tested + * independently of setTimestamp */ public void testSetTimestampWTZ() { @@ -80,18 +80,18 @@ public class TimestampTest extends TestCase PreparedStatement pstmt = con.prepareStatement(TestUtil.insertSQL(TSWTZ_TABLE, "?")); pstmt.setTimestamp(1, TS1WTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); pstmt.setTimestamp(1, TS2WTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); pstmt.setTimestamp(1, TS3WTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); // Fall through helper timestampTestWTZ(); - assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE)); + assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWTZ_TABLE)); pstmt.close(); stmt.close(); @@ -104,8 +104,8 @@ public class TimestampTest extends TestCase /* * Tests the timestamp methods in ResultSet on timestamp without time zone - * we insert a known string value (don't use setTimestamp) then see that - * we get back the same value from getTimestamp + * we insert a known string value (don't use setTimestamp) then see that + * we get back the same value from getTimestamp */ public void testGetTimestampWOTZ() { @@ -113,15 +113,15 @@ public class TimestampTest extends TestCase { Statement stmt = con.createStatement(); - //Insert the three timestamp values in raw pg format - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS1WOTZ_PGFORMAT + "'"))); - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS2WOTZ_PGFORMAT + "'"))); - assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,"'" + TS3WOTZ_PGFORMAT + "'"))); + //Insert the three timestamp values in raw pg format + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS1WOTZ_PGFORMAT + "'"))); + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS2WOTZ_PGFORMAT + "'"))); + assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS3WOTZ_PGFORMAT + "'"))); // Fall through helper timestampTestWOTZ(); - assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE)); + assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE)); stmt.close(); } @@ -134,9 +134,9 @@ public class TimestampTest extends TestCase /* * Tests the timestamp methods in PreparedStatement on timestamp without time zone - * we insert a value using setTimestamp then see that - * we get back the same value from getTimestamp (which we know works as it was tested - * independently of setTimestamp + * we insert a value using setTimestamp then see that + * we get back the same value from getTimestamp (which we know works as it was tested + * independently of setTimestamp */ public void testSetTimestampWOTZ() { @@ -146,18 +146,18 @@ public class TimestampTest extends TestCase PreparedStatement pstmt = con.prepareStatement(TestUtil.insertSQL(TSWOTZ_TABLE, "?")); pstmt.setTimestamp(1, TS1WOTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); pstmt.setTimestamp(1, TS2WOTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); pstmt.setTimestamp(1, TS3WOTZ); - assertEquals(1, pstmt.executeUpdate()); + assertEquals(1, pstmt.executeUpdate()); // Fall through helper timestampTestWOTZ(); - assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE)); + assertEquals(3, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE)); pstmt.close(); stmt.close(); @@ -178,22 +178,22 @@ public class TimestampTest extends TestCase java.sql.Timestamp t; rs = stmt.executeQuery("select ts from " + TSWTZ_TABLE + " order by ts"); - assertNotNull(rs); + assertNotNull(rs); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); + assertNotNull(t); assertTrue(t.equals(TS1WTZ)); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); + assertNotNull(t); assertTrue(t.equals(TS2WTZ)); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); - assertTrue(t.equals(TS3WTZ)); + assertNotNull(t); + assertTrue(t.equals(TS3WTZ)); assertTrue(! rs.next()); // end of table. Fail if more entries exist. @@ -211,21 +211,21 @@ public class TimestampTest extends TestCase java.sql.Timestamp t; rs = stmt.executeQuery("select ts from " + TSWOTZ_TABLE + " order by ts"); - assertNotNull(rs); + assertNotNull(rs); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); + assertNotNull(t); assertTrue(t.toString().equals(TS1WOTZ_JAVAFORMAT)); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); + assertNotNull(t); assertTrue(t.toString().equals(TS2WOTZ_JAVAFORMAT)); assertTrue(rs.next()); t = rs.getTimestamp(1); - assertNotNull(t); + assertNotNull(t); assertTrue(t.toString().equals(TS3WOTZ_JAVAFORMAT)); assertTrue(! rs.next()); // end of table. Fail if more entries exist. @@ -236,57 +236,63 @@ public class TimestampTest extends TestCase private static java.sql.Timestamp getTimestamp(int y, int m, int d, int h, int mn, int se, int f, String tz) { - java.sql.Timestamp l_return = null; - java.text.DateFormat l_df; - try { - String l_ts; - l_ts = TestUtil.fix(y, 4) + "-" + - TestUtil.fix(m, 2) + "-" + - TestUtil.fix(d, 2) + " " + - TestUtil.fix(h, 2) + ":" + - TestUtil.fix(mn, 2) + ":" + - TestUtil.fix(se, 2) + " "; - - if (tz == null) { - l_df = new java.text.SimpleDateFormat("y-M-d H:m:s"); - } else { - l_ts = l_ts + tz; - l_df = new java.text.SimpleDateFormat("y-M-d H:m:s z"); + java.sql.Timestamp l_return = null; + java.text.DateFormat l_df; + try + { + String l_ts; + l_ts = TestUtil.fix(y, 4) + "-" + + TestUtil.fix(m, 2) + "-" + + TestUtil.fix(d, 2) + " " + + TestUtil.fix(h, 2) + ":" + + TestUtil.fix(mn, 2) + ":" + + TestUtil.fix(se, 2) + " "; + + if (tz == null) + { + l_df = new java.text.SimpleDateFormat("y-M-d H:m:s"); + } + else + { + l_ts = l_ts + tz; + l_df = new java.text.SimpleDateFormat("y-M-d H:m:s z"); + } + java.util.Date l_date = l_df.parse(l_ts); + l_return = new java.sql.Timestamp(l_date.getTime()); + l_return.setNanos(f); } - java.util.Date l_date = l_df.parse(l_ts); - l_return = new java.sql.Timestamp(l_date.getTime()); - l_return.setNanos(f); - } catch (Exception ex) { - fail(ex.getMessage()); - } - return l_return; + catch (Exception ex) + { + fail(ex.getMessage()); + } + return l_return; } - private static final java.sql.Timestamp TS1WTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, "PST"); - private static final String TS1WTZ_PGFORMAT = "1950-02-07 15:00:00.1-08"; - - private static final java.sql.Timestamp TS2WTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, "GMT"); - private static final String TS2WTZ_PGFORMAT = "2000-02-07 15:00:00.12+00"; + private static final java.sql.Timestamp TS1WTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, "PST"); + private static final String TS1WTZ_PGFORMAT = "1950-02-07 15:00:00.1-08"; + + private static final java.sql.Timestamp TS2WTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, "GMT"); + private static final String TS2WTZ_PGFORMAT = "2000-02-07 15:00:00.12+00"; + + private static final java.sql.Timestamp TS3WTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, "GMT"); + private static final String TS3WTZ_PGFORMAT = "2000-07-07 15:00:00.123+00"; - private static final java.sql.Timestamp TS3WTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, "GMT"); - private static final String TS3WTZ_PGFORMAT = "2000-07-07 15:00:00.123+00"; + private static final java.sql.Timestamp TS1WOTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, null); + private static final String TS1WOTZ_PGFORMAT = "1950-02-07 15:00:00.1"; + private static final String TS1WOTZ_JAVAFORMAT = "1950-02-07 15:00:00.1"; - private static final java.sql.Timestamp TS1WOTZ = getTimestamp(1950, 2, 7, 15, 0, 0, 100000000, null); - private static final String TS1WOTZ_PGFORMAT = "1950-02-07 15:00:00.1"; - private static final String TS1WOTZ_JAVAFORMAT = "1950-02-07 15:00:00.1"; - - private static final java.sql.Timestamp TS2WOTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, null); - private static final String TS2WOTZ_PGFORMAT = "2000-02-07 15:00:00.12"; - //there is probably a bug here in that this needs to be .1 instead of .12, but I couldn't find it now - private static final String TS2WOTZ_JAVAFORMAT = "2000-02-07 15:00:00.1"; + private static final java.sql.Timestamp TS2WOTZ = getTimestamp(2000, 2, 7, 15, 0, 0, 120000000, null); + private static final String TS2WOTZ_PGFORMAT = "2000-02-07 15:00:00.12"; + //there is probably a bug here in that this needs to be .1 instead of .12, but I couldn't find it now + private static final String TS2WOTZ_JAVAFORMAT = "2000-02-07 15:00:00.1"; - private static final java.sql.Timestamp TS3WOTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, null); - private static final String TS3WOTZ_PGFORMAT = "2000-07-07 15:00:00.123"; - //there is probably a bug here in that this needs to be .12 instead of .123, but I couldn't find it now - private static final String TS3WOTZ_JAVAFORMAT = "2000-07-07 15:00:00.12"; + private static final java.sql.Timestamp TS3WOTZ = getTimestamp(2000, 7, 7, 15, 0, 0, 123000000, null); + private static final String TS3WOTZ_PGFORMAT = "2000-07-07 15:00:00.123"; + //there is probably a bug here in that this needs to be .12 instead of .123, but I couldn't find it now + private static final String TS3WOTZ_JAVAFORMAT = "2000-07-07 15:00:00.12"; - private static final String TSWTZ_TABLE = "testtimestampwtz"; - private static final String TSWOTZ_TABLE = "testtimestampwotz"; + private static final String TSWTZ_TABLE = "testtimestampwtz"; + private static final String TSWOTZ_TABLE = "testtimestampwotz"; } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java index d6324a3e99225afdef11386629a94121668ef161..3e5519e3178f54eae06925b8074cf979a4316589 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java @@ -16,120 +16,121 @@ import org.postgresql.test.TestUtil; public class UpdateableResultTest extends TestCase { - public UpdateableResultTest( String name ) - { - super( name ); - } - - public void testUpdateable() - { - try - { - Connection con = TestUtil.openDB(); - TestUtil.createTable(con, "updateable","id int primary key, name text, notselected text"); - TestUtil.createTable(con, "second","id1 int primary key, name1 text"); - - // put some dummy data into second - Statement st2 = con.createStatement(); - st2.execute( "insert into second values (1,'anyvalue' )"); - st2.close(); - - Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); - ResultSet rs = st.executeQuery( "select * from updateable"); - assertNotNull( rs ); - rs.moveToInsertRow(); - rs.updateInt( 1, 1 ); - rs.updateString( 2, "jake" ); - rs.updateString( 3, "avalue" ); - rs.insertRow(); - rs.first(); - - rs.updateInt( "id",2 ); - rs.updateString( "name","dave" ); - rs.updateRow(); - - assertTrue( rs.getInt("id") == 2 ); - assertTrue( rs.getString("name").equals("dave")); - assertTrue( rs.getString("notselected").equals("avalue") ); - - rs.deleteRow(); - rs.moveToInsertRow(); - rs.updateInt("id",3); - rs.updateString("name", "paul"); - - rs.insertRow(); - rs.refreshRow(); - assertTrue( rs.getInt("id") == 3 ); - assertTrue( rs.getString("name").equals("paul")); - assertTrue( rs.getString("notselected") == null ); - - - rs.close(); - - rs = st.executeQuery("select id1, id, name, name1 from updateable, second" ); - try - { - while( rs.next() ) - { - rs.updateInt( "id",2 ); - rs.updateString( "name","dave" ); - rs.updateRow(); - } - - - assertTrue( "should not get here, update should fail", false ); - } - catch (SQLException ex){} - - try - { - rs = st.executeQuery("select oid,* from updateable"); - if ( rs.first() ) - { - rs.updateInt( "id", 3 ); - rs.updateString( "name", "dave3"); - rs.updateRow(); - assertTrue(rs.getInt("id") == 3 ); - assertTrue(rs.getString("name").equals("dave3")); - - rs.moveToInsertRow(); - rs.updateInt( "id", 4 ); - rs.updateString( "name", "dave4" ); - - rs.insertRow(); - rs.updateInt("id", 5 ); - rs.updateString( "name", "dave5" ); - rs.insertRow(); - - rs.moveToCurrentRow(); - assertTrue(rs.getInt("id") == 3 ); - assertTrue(rs.getString("name").equals("dave3")); - - assertTrue( rs.next() ); - assertTrue(rs.getInt("id") == 4 ); - assertTrue(rs.getString("name").equals("dave4")); - - assertTrue( rs.next() ); - assertTrue(rs.getInt("id") == 5 ); - assertTrue(rs.getString("name").equals("dave5")); - - } - } - catch(SQLException ex) - { - fail(ex.getMessage()); - } - - st.close(); - - TestUtil.dropTable( con,"updateable" ); - TestUtil.closeDB( con ); - } - catch (Exception ex) - { - fail(ex.getMessage()); - } - } + public UpdateableResultTest( String name ) + { + super( name ); + } + + public void testUpdateable() + { + try + { + Connection con = TestUtil.openDB(); + TestUtil.createTable(con, "updateable", "id int primary key, name text, notselected text"); + TestUtil.createTable(con, "second", "id1 int primary key, name1 text"); + + // put some dummy data into second + Statement st2 = con.createStatement(); + st2.execute( "insert into second values (1,'anyvalue' )"); + st2.close(); + + Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); + ResultSet rs = st.executeQuery( "select * from updateable"); + assertNotNull( rs ); + rs.moveToInsertRow(); + rs.updateInt( 1, 1 ); + rs.updateString( 2, "jake" ); + rs.updateString( 3, "avalue" ); + rs.insertRow(); + rs.first(); + + rs.updateInt( "id", 2 ); + rs.updateString( "name", "dave" ); + rs.updateRow(); + + assertTrue( rs.getInt("id") == 2 ); + assertTrue( rs.getString("name").equals("dave")); + assertTrue( rs.getString("notselected").equals("avalue") ); + + rs.deleteRow(); + rs.moveToInsertRow(); + rs.updateInt("id", 3); + rs.updateString("name", "paul"); + + rs.insertRow(); + rs.refreshRow(); + assertTrue( rs.getInt("id") == 3 ); + assertTrue( rs.getString("name").equals("paul")); + assertTrue( rs.getString("notselected") == null ); + + + rs.close(); + + rs = st.executeQuery("select id1, id, name, name1 from updateable, second" ); + try + { + while ( rs.next() ) + { + rs.updateInt( "id", 2 ); + rs.updateString( "name", "dave" ); + rs.updateRow(); + } + + + assertTrue( "should not get here, update should fail", false ); + } + catch (SQLException ex) + {} + + try + { + rs = st.executeQuery("select oid,* from updateable"); + if ( rs.first() ) + { + rs.updateInt( "id", 3 ); + rs.updateString( "name", "dave3"); + rs.updateRow(); + assertTrue(rs.getInt("id") == 3 ); + assertTrue(rs.getString("name").equals("dave3")); + + rs.moveToInsertRow(); + rs.updateInt( "id", 4 ); + rs.updateString( "name", "dave4" ); + + rs.insertRow(); + rs.updateInt("id", 5 ); + rs.updateString( "name", "dave5" ); + rs.insertRow(); + + rs.moveToCurrentRow(); + assertTrue(rs.getInt("id") == 3 ); + assertTrue(rs.getString("name").equals("dave3")); + + assertTrue( rs.next() ); + assertTrue(rs.getInt("id") == 4 ); + assertTrue(rs.getString("name").equals("dave4")); + + assertTrue( rs.next() ); + assertTrue(rs.getInt("id") == 5 ); + assertTrue(rs.getString("name").equals("dave5")); + + } + } + catch (SQLException ex) + { + fail(ex.getMessage()); + } + + st.close(); + + TestUtil.dropTable( con, "updateable" ); + TestUtil.closeDB( con ); + } + catch (Exception ex) + { + fail(ex.getMessage()); + } + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java index f26fca20c91d8662974c07baf075867e9df5e507..dbb73d3e72d0c238bf1e6c8f36cc15464f3045d4 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java @@ -10,151 +10,179 @@ import java.sql.*; /** * Common tests for all the BaseDataSource implementations. This is * a small variety to make sure that a connection can be opened and - * some basic queries run. The different BaseDataSource subclasses + * some basic queries run. The different BaseDataSource subclasses * have different subclasses of this which add additional custom * tests. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public abstract class BaseDataSourceTest extends TestCase { - protected Connection con; - protected BaseDataSource bds; +public abstract class BaseDataSourceTest extends TestCase +{ + protected Connection con; + protected BaseDataSource bds; - /** - * Constructor required by JUnit - */ - public BaseDataSourceTest(String name) { - super(name); - } + /** + * Constructor required by JUnit + */ + public BaseDataSourceTest(String name) + { + super(name); + } - /** - * Creates a test table using a standard connection (not from a - * DataSource). - */ - protected void setUp() throws Exception { - con = JDBC2Tests.openDB(); - JDBC2Tests.createTable(con, "poolingtest", "id int4 not null primary key, name varchar(50)"); - Statement stmt = con.createStatement(); - stmt.executeUpdate("INSERT INTO poolingtest VALUES (1, 'Test Row 1')"); - stmt.executeUpdate("INSERT INTO poolingtest VALUES (2, 'Test Row 2')"); - JDBC2Tests.closeDB(con); - } + /** + * Creates a test table using a standard connection (not from a + * DataSource). + */ + protected void setUp() throws Exception + { + con = JDBC2Tests.openDB(); + JDBC2Tests.createTable(con, "poolingtest", "id int4 not null primary key, name varchar(50)"); + Statement stmt = con.createStatement(); + stmt.executeUpdate("INSERT INTO poolingtest VALUES (1, 'Test Row 1')"); + stmt.executeUpdate("INSERT INTO poolingtest VALUES (2, 'Test Row 2')"); + JDBC2Tests.closeDB(con); + } - /** - * Removes the test table using a standard connection (not from - * a DataSource) - */ - protected void tearDown() throws Exception { - con = JDBC2Tests.openDB(); - JDBC2Tests.dropTable(con, "poolingtest"); - JDBC2Tests.closeDB(con); - } + /** + * Removes the test table using a standard connection (not from + * a DataSource) + */ + protected void tearDown() throws Exception + { + con = JDBC2Tests.openDB(); + JDBC2Tests.dropTable(con, "poolingtest"); + JDBC2Tests.closeDB(con); + } - /** - * Gets a connection from the current BaseDataSource - */ - protected Connection getDataSourceConnection() throws SQLException { - initializeDataSource(); - return bds.getConnection(); - } + /** + * Gets a connection from the current BaseDataSource + */ + protected Connection getDataSourceConnection() throws SQLException + { + initializeDataSource(); + return bds.getConnection(); + } - /** - * Creates an instance of the current BaseDataSource for - * testing. Must be customized by each subclass. - */ - protected abstract void initializeDataSource(); + /** + * Creates an instance of the current BaseDataSource for + * testing. Must be customized by each subclass. + */ + protected abstract void initializeDataSource(); - /** - * Test to make sure you can instantiate and configure the - * appropriate DataSource - */ - public void testCreateDataSource() { - initializeDataSource(); - } + /** + * Test to make sure you can instantiate and configure the + * appropriate DataSource + */ + public void testCreateDataSource() + { + initializeDataSource(); + } - /** - * Test to make sure you can get a connection from the DataSource, - * which in turn means the DataSource was able to open it. - */ - public void testGetConnection() { - try { - con = getDataSourceConnection(); - con.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Test to make sure you can get a connection from the DataSource, + * which in turn means the DataSource was able to open it. + */ + public void testGetConnection() + { + try + { + con = getDataSourceConnection(); + con.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * A simple test to make sure you can execute SQL using the - * Connection from the DataSource - */ - public void testUseConnection() { - try { - con = getDataSourceConnection(); - Statement st = con.createStatement(); - ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM poolingtest"); - if(rs.next()) { - int count = rs.getInt(1); - if(rs.next()) { - fail("Should only have one row in SELECT COUNT result set"); - } - if(count != 2) { - fail("Count returned "+count+" expecting 2"); - } - } else { - fail("Should have one row in SELECT COUNT result set"); - } - rs.close(); - st.close(); - con.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * A simple test to make sure you can execute SQL using the + * Connection from the DataSource + */ + public void testUseConnection() + { + try + { + con = getDataSourceConnection(); + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM poolingtest"); + if (rs.next()) + { + int count = rs.getInt(1); + if (rs.next()) + { + fail("Should only have one row in SELECT COUNT result set"); + } + if (count != 2) + { + fail("Count returned " + count + " expecting 2"); + } + } + else + { + fail("Should have one row in SELECT COUNT result set"); + } + rs.close(); + st.close(); + con.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * A test to make sure you can execute DDL SQL using the - * Connection from the DataSource. - */ - public void testDdlOverConnection() { - try { - con = getDataSourceConnection(); - JDBC2Tests.dropTable(con, "poolingtest"); - JDBC2Tests.createTable(con, "poolingtest", "id int4 not null primary key, name varchar(50)"); - con.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * A test to make sure you can execute DDL SQL using the + * Connection from the DataSource. + */ + public void testDdlOverConnection() + { + try + { + con = getDataSourceConnection(); + JDBC2Tests.dropTable(con, "poolingtest"); + JDBC2Tests.createTable(con, "poolingtest", "id int4 not null primary key, name varchar(50)"); + con.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * A test to make sure the connections are not being pooled by the - * current DataSource. Obviously need to be overridden in the case - * of a pooling Datasource. - */ - public void testNotPooledConnection() { - try { - con = getDataSourceConnection(); - String name = con.toString(); - con.close(); - con = getDataSourceConnection(); - String name2 = con.toString(); - con.close(); - assertTrue(!name.equals(name2)); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * A test to make sure the connections are not being pooled by the + * current DataSource. Obviously need to be overridden in the case + * of a pooling Datasource. + */ + public void testNotPooledConnection() + { + try + { + con = getDataSourceConnection(); + String name = con.toString(); + con.close(); + con = getDataSourceConnection(); + String name2 = con.toString(); + con.close(); + assertTrue(!name.equals(name2)); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Eventually, we must test stuffing the DataSource in JNDI and - * then getting it back out and make sure it's still usable. This - * should ideally test both Serializable and Referenceable - * mechanisms. Will probably be multiple tests when implemented. - */ - public void testJndi() { - // TODO: Put the DS in JNDI, retrieve it, and try some of this stuff again - } + /** + * Eventually, we must test stuffing the DataSource in JNDI and + * then getting it back out and make sure it's still usable. This + * should ideally test both Serializable and Referenceable + * mechanisms. Will probably be multiple tests when implemented. + */ + public void testJndi() + { + // TODO: Put the DS in JNDI, retrieve it, and try some of this stuff again + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java index 5802f156caa1b0cb6fdd5b128feaa7209eadfc3c..2e405f2a547dcc091c760143cd2c33496d89cdc9 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java @@ -11,317 +11,382 @@ import java.sql.*; * interface to the PooledConnection is through the CPDS. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class ConnectionPoolTest extends BaseDataSourceTest { - /** - * Constructor required by JUnit - */ - public ConnectionPoolTest(String name) { - super(name); - } +public class ConnectionPoolTest extends BaseDataSourceTest +{ + /** + * Constructor required by JUnit + */ + public ConnectionPoolTest(String name) + { + super(name); + } - /** - * Creates and configures a ConnectionPool - */ - protected void initializeDataSource() { - if(bds == null) { - bds = new ConnectionPool(); - String db = JDBC2Tests.getURL(); - if(db.indexOf('/') > -1) { - db = db.substring(db.lastIndexOf('/')+1); - } else if(db.indexOf(':') > -1) { - db = db.substring(db.lastIndexOf(':')+1); - } - bds.setDatabaseName(db); - bds.setUser(JDBC2Tests.getUser()); - bds.setPassword(JDBC2Tests.getPassword()); - } - } + /** + * Creates and configures a ConnectionPool + */ + protected void initializeDataSource() + { + if (bds == null) + { + bds = new ConnectionPool(); + String db = JDBC2Tests.getURL(); + if (db.indexOf('/') > -1) + { + db = db.substring(db.lastIndexOf('/') + 1); + } + else if (db.indexOf(':') > -1) + { + db = db.substring(db.lastIndexOf(':') + 1); + } + bds.setDatabaseName(db); + bds.setUser(JDBC2Tests.getUser()); + bds.setPassword(JDBC2Tests.getPassword()); + } + } - /** - * Though the normal client interface is to grab a Connection, in - * order to test the middleware/server interface, we need to deal - * with PooledConnections. Some tests use each. - */ - protected PooledConnection getPooledConnection() throws SQLException { - initializeDataSource(); - return ((ConnectionPool)bds).getPooledConnection(); - } + /** + * Though the normal client interface is to grab a Connection, in + * order to test the middleware/server interface, we need to deal + * with PooledConnections. Some tests use each. + */ + protected PooledConnection getPooledConnection() throws SQLException + { + initializeDataSource(); + return ((ConnectionPool)bds).getPooledConnection(); + } - /** - * Instead of just fetching a Connection from the ConnectionPool, - * get a PooledConnection, add a listener to close it when the - * Connection is closed, and then get the Connection. Without - * the listener the PooledConnection (and thus the physical connection) - * would never by closed. Probably not a disaster during testing, but - * you never know. - */ - protected Connection getDataSourceConnection() throws SQLException { - initializeDataSource(); - final PooledConnection pc = getPooledConnection(); - // Since the pooled connection won't be reused in these basic tests, close it when the connection is closed - pc.addConnectionEventListener(new ConnectionEventListener() { - public void connectionClosed(ConnectionEvent event) { - try { - pc.close(); - } catch (SQLException e) { - fail("Unable to close PooledConnection: "+e); - } - } + /** + * Instead of just fetching a Connection from the ConnectionPool, + * get a PooledConnection, add a listener to close it when the + * Connection is closed, and then get the Connection. Without + * the listener the PooledConnection (and thus the physical connection) + * would never by closed. Probably not a disaster during testing, but + * you never know. + */ + protected Connection getDataSourceConnection() throws SQLException + { + initializeDataSource(); + final PooledConnection pc = getPooledConnection(); + // Since the pooled connection won't be reused in these basic tests, close it when the connection is closed + pc.addConnectionEventListener(new ConnectionEventListener() + { + public void connectionClosed(ConnectionEvent event) + { + try + { + pc.close(); + } + catch (SQLException e) + { + fail("Unable to close PooledConnection: " + e); + } + } - public void connectionErrorOccurred(ConnectionEvent event) { - } - }); - return pc.getConnection(); - } + public void connectionErrorOccurred(ConnectionEvent event) + {} + } + ); + return pc.getConnection(); + } - /** - * Makes sure that if you get a connection from a PooledConnection, - * close it, and then get another one, you're really using the same - * physical connection. Depends on the implementation of toString - * for the connection handle. - */ - public void testPoolReuse() { - try { - PooledConnection pc = getPooledConnection(); - con = pc.getConnection(); - String name = con.toString(); - con.close(); - con = pc.getConnection(); - String name2 = con.toString(); - con.close(); - pc.close(); - assertTrue("Physical connection doesn't appear to be reused across PooledConnection wrappers", name.equals(name2)); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that if you get a connection from a PooledConnection, + * close it, and then get another one, you're really using the same + * physical connection. Depends on the implementation of toString + * for the connection handle. + */ + public void testPoolReuse() + { + try + { + PooledConnection pc = getPooledConnection(); + con = pc.getConnection(); + String name = con.toString(); + con.close(); + con = pc.getConnection(); + String name2 = con.toString(); + con.close(); + pc.close(); + assertTrue("Physical connection doesn't appear to be reused across PooledConnection wrappers", name.equals(name2)); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure that when you request a connection from the - * PooledConnection, and previous connection it might have given - * out is closed. See JDBC 2.0 Optional Package spec section - * 6.2.3 - */ - public void testPoolCloseOldWrapper() { - try { - PooledConnection pc = getPooledConnection(); - con = pc.getConnection(); - Connection con2 = pc.getConnection(); - try { - con.createStatement(); - fail("Original connection wrapper should be closed when new connection wrapper is generated"); - } catch(SQLException e) {} - try { - con.close(); - fail("Original connection wrapper should be closed when new connection wrapper is generated"); - } catch(SQLException e) {} - con2.close(); - pc.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that when you request a connection from the + * PooledConnection, and previous connection it might have given + * out is closed. See JDBC 2.0 Optional Package spec section + * 6.2.3 + */ + public void testPoolCloseOldWrapper() + { + try + { + PooledConnection pc = getPooledConnection(); + con = pc.getConnection(); + Connection con2 = pc.getConnection(); + try + { + con.createStatement(); + fail("Original connection wrapper should be closed when new connection wrapper is generated"); + } + catch (SQLException e) + {} + try + { + con.close(); + fail("Original connection wrapper should be closed when new connection wrapper is generated"); + } + catch (SQLException e) + {} + con2.close(); + pc.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure that if you get two connection wrappers from the same - * PooledConnection, they are different, even though the represent - * the same physical connection. See JDBC 2.0 Optional Pacakge spec - * section 6.2.2 - */ - public void testPoolNewWrapper() { - try { - PooledConnection pc = getPooledConnection(); - con = pc.getConnection(); - Connection con2 = pc.getConnection(); - con2.close(); - pc.close(); - assertTrue("Two calls to PooledConnection.getConnection should not return the same connection wrapper", con != con2); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that if you get two connection wrappers from the same + * PooledConnection, they are different, even though the represent + * the same physical connection. See JDBC 2.0 Optional Pacakge spec + * section 6.2.2 + */ + public void testPoolNewWrapper() + { + try + { + PooledConnection pc = getPooledConnection(); + con = pc.getConnection(); + Connection con2 = pc.getConnection(); + con2.close(); + pc.close(); + assertTrue("Two calls to PooledConnection.getConnection should not return the same connection wrapper", con != con2); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure that exactly one close event is fired for each time a - * connection handle is closed. Also checks that events are not - * fired after a given handle has been closed once. - */ - public void testCloseEvent() { - try { - PooledConnection pc = getPooledConnection(); - CountClose cc = new CountClose(); - pc.addConnectionEventListener(cc); - con = pc.getConnection(); - assertTrue(cc.getCount() == 0); - assertTrue(cc.getErrorCount() == 0); - con.close(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - con = pc.getConnection(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - con.close(); - assertTrue(cc.getCount() == 2); - assertTrue(cc.getErrorCount() == 0); - try { - con.close(); - fail("Should not be able to close a connection wrapper twice"); - } catch (SQLException e) {} - assertTrue(cc.getCount() == 2); - assertTrue(cc.getErrorCount() == 0); - pc.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that exactly one close event is fired for each time a + * connection handle is closed. Also checks that events are not + * fired after a given handle has been closed once. + */ + public void testCloseEvent() + { + try + { + PooledConnection pc = getPooledConnection(); + CountClose cc = new CountClose(); + pc.addConnectionEventListener(cc); + con = pc.getConnection(); + assertTrue(cc.getCount() == 0); + assertTrue(cc.getErrorCount() == 0); + con.close(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + con = pc.getConnection(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + con.close(); + assertTrue(cc.getCount() == 2); + assertTrue(cc.getErrorCount() == 0); + try + { + con.close(); + fail("Should not be able to close a connection wrapper twice"); + } + catch (SQLException e) + {} + assertTrue(cc.getCount() == 2); + assertTrue(cc.getErrorCount() == 0); + pc.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure that close events are not fired after a listener has - * been removed. - */ - public void testNoCloseEvent() { - try { - PooledConnection pc = getPooledConnection(); - CountClose cc = new CountClose(); - pc.addConnectionEventListener(cc); - con = pc.getConnection(); - assertTrue(cc.getCount() == 0); - assertTrue(cc.getErrorCount() == 0); - con.close(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - pc.removeConnectionEventListener(cc); - con = pc.getConnection(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - con.close(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that close events are not fired after a listener has + * been removed. + */ + public void testNoCloseEvent() + { + try + { + PooledConnection pc = getPooledConnection(); + CountClose cc = new CountClose(); + pc.addConnectionEventListener(cc); + con = pc.getConnection(); + assertTrue(cc.getCount() == 0); + assertTrue(cc.getErrorCount() == 0); + con.close(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + pc.removeConnectionEventListener(cc); + con = pc.getConnection(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + con.close(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure that a listener can be removed while dispatching - * events. Sometimes this causes a ConcurrentModificationException - * or something. - */ - public void testInlineCloseEvent() { - try { - PooledConnection pc = getPooledConnection(); - RemoveClose rc1 = new RemoveClose(); - RemoveClose rc2 = new RemoveClose(); - RemoveClose rc3 = new RemoveClose(); - pc.addConnectionEventListener(rc1); - pc.addConnectionEventListener(rc2); - pc.addConnectionEventListener(rc3); - con = pc.getConnection(); - con.close(); - con = pc.getConnection(); - con.close(); - } catch (Exception e) { - fail(e.getMessage()); - } - } + /** + * Makes sure that a listener can be removed while dispatching + * events. Sometimes this causes a ConcurrentModificationException + * or something. + */ + public void testInlineCloseEvent() + { + try + { + PooledConnection pc = getPooledConnection(); + RemoveClose rc1 = new RemoveClose(); + RemoveClose rc2 = new RemoveClose(); + RemoveClose rc3 = new RemoveClose(); + pc.addConnectionEventListener(rc1); + pc.addConnectionEventListener(rc2); + pc.addConnectionEventListener(rc3); + con = pc.getConnection(); + con.close(); + con = pc.getConnection(); + con.close(); + } + catch (Exception e) + { + fail(e.getMessage()); + } + } - /** - * Tests that a close event is not generated when a connection - * handle is closed automatically due to a new connection handle - * being opened for the same PooledConnection. See JDBC 2.0 - * Optional Package spec section 6.3 - */ - public void testAutomaticCloseEvent() { - try { - PooledConnection pc = getPooledConnection(); - CountClose cc = new CountClose(); - pc.addConnectionEventListener(cc); - con = pc.getConnection(); - assertTrue(cc.getCount() == 0); - assertTrue(cc.getErrorCount() == 0); - con.close(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - con = pc.getConnection(); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - // Open a 2nd connection, causing the first to be closed. No even should be generated. - Connection con2 = pc.getConnection(); - assertTrue("Connection handle was not closed when new handle was opened", con.isClosed()); - assertTrue(cc.getCount() == 1); - assertTrue(cc.getErrorCount() == 0); - con2.close(); - assertTrue(cc.getCount() == 2); - assertTrue(cc.getErrorCount() == 0); - pc.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Tests that a close event is not generated when a connection + * handle is closed automatically due to a new connection handle + * being opened for the same PooledConnection. See JDBC 2.0 + * Optional Package spec section 6.3 + */ + public void testAutomaticCloseEvent() + { + try + { + PooledConnection pc = getPooledConnection(); + CountClose cc = new CountClose(); + pc.addConnectionEventListener(cc); + con = pc.getConnection(); + assertTrue(cc.getCount() == 0); + assertTrue(cc.getErrorCount() == 0); + con.close(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + con = pc.getConnection(); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + // Open a 2nd connection, causing the first to be closed. No even should be generated. + Connection con2 = pc.getConnection(); + assertTrue("Connection handle was not closed when new handle was opened", con.isClosed()); + assertTrue(cc.getCount() == 1); + assertTrue(cc.getErrorCount() == 0); + con2.close(); + assertTrue(cc.getCount() == 2); + assertTrue(cc.getErrorCount() == 0); + pc.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Makes sure the isClosed method on a connection wrapper does what - * you'd expect. Checks the usual case, as well as automatic - * closure when a new handle is opened on the same physical connection. - */ - public void testIsClosed() { - try { - PooledConnection pc = getPooledConnection(); - Connection con = pc.getConnection(); - assertTrue(!con.isClosed()); - con.close(); - assertTrue(con.isClosed()); - con = pc.getConnection(); - Connection con2 = pc.getConnection(); - assertTrue(con.isClosed()); - assertTrue(!con2.isClosed()); - con2.close(); - assertTrue(con.isClosed()); - pc.close(); - } catch (SQLException e) { - fail(e.getMessage()); - } - } + /** + * Makes sure the isClosed method on a connection wrapper does what + * you'd expect. Checks the usual case, as well as automatic + * closure when a new handle is opened on the same physical connection. + */ + public void testIsClosed() + { + try + { + PooledConnection pc = getPooledConnection(); + Connection con = pc.getConnection(); + assertTrue(!con.isClosed()); + con.close(); + assertTrue(con.isClosed()); + con = pc.getConnection(); + Connection con2 = pc.getConnection(); + assertTrue(con.isClosed()); + assertTrue(!con2.isClosed()); + con2.close(); + assertTrue(con.isClosed()); + pc.close(); + } + catch (SQLException e) + { + fail(e.getMessage()); + } + } - /** - * Helper class to remove a listener during event dispatching. - */ - private class RemoveClose implements ConnectionEventListener { - public void connectionClosed(ConnectionEvent event) { - ((PooledConnection)event.getSource()).removeConnectionEventListener(this); - } + /** + * Helper class to remove a listener during event dispatching. + */ + private class RemoveClose implements ConnectionEventListener + { + public void connectionClosed(ConnectionEvent event) + { + ((PooledConnection)event.getSource()).removeConnectionEventListener(this); + } - public void connectionErrorOccurred(ConnectionEvent event) { - ((PooledConnection)event.getSource()).removeConnectionEventListener(this); - } - } + public void connectionErrorOccurred(ConnectionEvent event) + { + ((PooledConnection)event.getSource()).removeConnectionEventListener(this); + } + } - /** - * Helper class that implements the event listener interface, and - * counts the number of events it sees. - */ - private class CountClose implements ConnectionEventListener { - private int count = 0, errorCount = 0; - public void connectionClosed(ConnectionEvent event) { - count++; - } + /** + * Helper class that implements the event listener interface, and + * counts the number of events it sees. + */ + private class CountClose implements ConnectionEventListener + { + private int count = 0, errorCount = 0; + public void connectionClosed(ConnectionEvent event) + { + count++; + } - public void connectionErrorOccurred(ConnectionEvent event) { - errorCount++; - } + public void connectionErrorOccurred(ConnectionEvent event) + { + errorCount++; + } - public int getCount() { - return count; - } + public int getCount() + { + return count; + } - public int getErrorCount() { - return errorCount; - } + public int getErrorCount() + { + return errorCount; + } - public void clear() { - count = errorCount = 0; - } - } + public void clear() + { + count = errorCount = 0; + } + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java index ded7503a4578f31d62ed0faa2253710ce2574d7b..49108910f9051b1372583c1af6012437906b82ba 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java @@ -8,17 +8,19 @@ import junit.framework.TestSuite; * PooledConnection implementations. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class OptionalTestSuite extends TestSuite { - /** - * Gets the test suite for the entire JDBC 2.0 Optional Package - * implementation. - */ - public static TestSuite suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(SimpleDataSourceTest.class); - suite.addTestSuite(ConnectionPoolTest.class); - return suite; - } +public class OptionalTestSuite extends TestSuite +{ + /** + * Gets the test suite for the entire JDBC 2.0 Optional Package + * implementation. + */ + public static TestSuite suite() + { + TestSuite suite = new TestSuite(); + suite.addTestSuite(SimpleDataSourceTest.class); + suite.addTestSuite(ConnectionPoolTest.class); + return suite; + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/SimpleDataSourceTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/SimpleDataSourceTest.java index 1c917db6a1b2547f896a7cd17c916bcba4a1c909..3eb42733a2cb4158b7e123e0ca1c5aa7a8d7ba07 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/SimpleDataSourceTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/SimpleDataSourceTest.java @@ -4,35 +4,42 @@ import org.postgresql.test.JDBC2Tests; import org.postgresql.jdbc2.optional.SimpleDataSource; /** - * Performs the basic tests defined in the superclass. Just adds the + * Performs the basic tests defined in the superclass. Just adds the * configuration logic. * * @author Aaron Mulder (ammulder@chariotsolutions.com) - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -public class SimpleDataSourceTest extends BaseDataSourceTest { - /** - * Constructor required by JUnit - */ - public SimpleDataSourceTest(String name) { - super(name); - } +public class SimpleDataSourceTest extends BaseDataSourceTest +{ + /** + * Constructor required by JUnit + */ + public SimpleDataSourceTest(String name) + { + super(name); + } - /** - * Creates and configures a new SimpleDataSource. - */ - protected void initializeDataSource() { - if(bds == null) { - bds = new SimpleDataSource(); - String db = JDBC2Tests.getURL(); - if(db.indexOf('/') > -1) { - db = db.substring(db.lastIndexOf('/')+1); - } else if(db.indexOf(':') > -1) { - db = db.substring(db.lastIndexOf(':')+1); - } - bds.setDatabaseName(db); - bds.setUser(JDBC2Tests.getUser()); - bds.setPassword(JDBC2Tests.getPassword()); - } - } + /** + * Creates and configures a new SimpleDataSource. + */ + protected void initializeDataSource() + { + if (bds == null) + { + bds = new SimpleDataSource(); + String db = JDBC2Tests.getURL(); + if (db.indexOf('/') > -1) + { + db = db.substring(db.lastIndexOf('/') + 1); + } + else if (db.indexOf(':') > -1) + { + db = db.substring(db.lastIndexOf(':') + 1); + } + bds.setDatabaseName(db); + bds.setUser(JDBC2Tests.getUser()); + bds.setPassword(JDBC2Tests.getPassword()); + } + } } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java b/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java index 5e01e4ffe87fc4b989fa69f5d67a69704be548f0..5278977de46f7a85d2e6882acd909cf541472c52 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java @@ -7,7 +7,7 @@ import junit.framework.Test; import java.sql.*; /* - * Executes all known tests for JDBC3 + * Executes all known tests for JDBC3 */ public class Jdbc3TestSuite extends TestSuite { @@ -17,7 +17,7 @@ public class Jdbc3TestSuite extends TestSuite */ public static TestSuite suite() { - //Currently there are no specific jdbc3 tests so just run the jdbc2 tests - return org.postgresql.test.jdbc2.Jdbc2TestSuite.suite(); + //Currently there are no specific jdbc3 tests so just run the jdbc2 tests + return org.postgresql.test.jdbc2.Jdbc2TestSuite.suite(); } } diff --git a/src/interfaces/jdbc/org/postgresql/util/PGbytea.java b/src/interfaces/jdbc/org/postgresql/util/PGbytea.java index a6d1c011bf54e8e0fc0176b1dd49e9ed36d30cd0..21e204dec5de61bda5ca67ddc993fdc5820b5306 100644 --- a/src/interfaces/jdbc/org/postgresql/util/PGbytea.java +++ b/src/interfaces/jdbc/org/postgresql/util/PGbytea.java @@ -5,7 +5,7 @@ import java.sql.*; /* * Converts to and from the postgresql bytea datatype used by the backend. * - * $Id: PGbytea.java,v 1.5 2002/08/16 17:51:38 barry Exp $ + * $Id: PGbytea.java,v 1.6 2002/09/06 21:23:06 momjian Exp $ */ public class PGbytea @@ -19,7 +19,7 @@ public class PGbytea { if (s == null) return null; - int slength = s.length; + int slength = s.length; byte[] buf = new byte[slength]; int bufpos = 0; int thebyte; diff --git a/src/interfaces/jdbc/org/postgresql/util/PGtokenizer.java b/src/interfaces/jdbc/org/postgresql/util/PGtokenizer.java index f5fe685e8084e408ab9e347979a38e03c90a54ac..fc4efc4c31a479d5566cab51c422c13f1f32e154 100644 --- a/src/interfaces/jdbc/org/postgresql/util/PGtokenizer.java +++ b/src/interfaces/jdbc/org/postgresql/util/PGtokenizer.java @@ -78,6 +78,7 @@ public class PGtokenizer // Don't forget the last token ;-) + if (s < string.length()) tokens.addElement(string.substring(s)); diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java index 8898e1ecf4e3e5f4948cb97f9b011085d042d8d7..57c77f0b9f9422872cbc2204d998a84c103937ea 100644 --- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java +++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java @@ -129,14 +129,16 @@ public class Serialize try { conn = c; - if (Driver.logDebug) Driver.debug("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) { - if (Driver.logDebug) Driver.debug("Serialize: " + className + " java class not found"); + if (Driver.logDebug) + Driver.debug("Serialize: " + className + " java class not found"); throw new PSQLException("postgresql.serial.noclass", type); } @@ -148,14 +150,16 @@ public class Serialize if (rs.next()) { status = true; - if (Driver.logDebug) Driver.debug("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) { - if (Driver.logDebug) Driver.debug("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 @@ -187,9 +191,11 @@ public class Serialize { try { - if (Driver.logDebug) Driver.debug("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(); - if (Driver.logDebug) Driver.debug("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 @@ -220,7 +226,8 @@ public class Serialize sb.append(" where oid="); sb.append(oid); - if (Driver.logDebug) Driver.debug("Serialize.fetch: " + sb.toString()); + if (Driver.logDebug) + Driver.debug("Serialize.fetch: " + sb.toString()); ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString()); if (rs != null) @@ -270,13 +277,13 @@ public class Serialize /* * This stores an object into a table, returning it's OID.

- * This method was deprecated in 7.2 because the value of an OID - * can be larger than a java signed int. + * This method was deprecated in 7.2 because the value of an OID + * can be larger than a java signed int. * @deprecated Replaced by storeObject() in 7.2 */ public int store(Object o) throws SQLException { - return (int) storeObject(o); + return (int) storeObject(o); } /* @@ -296,7 +303,7 @@ public class Serialize * @param o Object to store (must implement Serializable) * @return oid of stored object * @exception SQLException on error - * @since 7.2 + * @since 7.2 */ public long storeObject(Object o) throws SQLException { @@ -389,7 +396,8 @@ public class Serialize sb.append(')'); } - if (Driver.logDebug) Driver.debug("Serialize.store: " + sb.toString() ); + if (Driver.logDebug) + Driver.debug("Serialize.store: " + sb.toString() ); ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString()); // fetch the OID for returning @@ -496,13 +504,15 @@ public class Serialize ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL("select relname from pg_class where relname = '" + tableName + "'"); if ( rs.next() ) { - if (Driver.logDebug) Driver.debug("Serialize.create: table " + tableName + " exists, skipping"); + if (Driver.logDebug) + Driver.debug("Serialize.create: table " + tableName + " exists, skipping"); rs.close(); - return; + return ; } // else table not found, so create it - if (Driver.logDebug) Driver.debug("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 "); @@ -548,7 +558,8 @@ public class Serialize sb.append(")"); // Now create the table - if (Driver.logDebug) Driver.debug("Serialize.create: " + sb ); + if (Driver.logDebug) + Driver.debug("Serialize.create: " + sb ); ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL(sb.toString()); }