aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/jdbc/org/postgresql/Connection.java9
-rw-r--r--src/interfaces/jdbc/org/postgresql/Driver.java.in2
-rw-r--r--src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java393
-rw-r--r--src/interfaces/jdbc/org/postgresql/core/QueryExecutor2.java259
-rw-r--r--src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java494
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java542
6 files changed, 694 insertions, 1005 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/Connection.java
index 3ee6deea0a5..54f067542de 100644
--- a/src/interfaces/jdbc/org/postgresql/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/Connection.java
@@ -11,7 +11,7 @@ import org.postgresql.util.*;
import org.postgresql.core.*;
/*
- * $Id: Connection.java,v 1.44 2002/03/21 02:39:06 davec Exp $
+ * $Id: Connection.java,v 1.45 2002/03/26 05:52:48 barry Exp $
*
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
* JDBC2 versions of the Connection class.
@@ -59,10 +59,6 @@ public abstract class Connection
private static final int AUTH_REQ_CRYPT = 4;
private static final int AUTH_REQ_MD5 = 5;
- public final static int PGASYNC_IDLE = 0; /* nothing's happening, dude */
- public final static int PGASYNC_BUSY = 1; /* query in progress */
- public final static int PGASYNC_READY = 2; /* result ready for PQgetResult */
-
// These are used to cache oids, PGTypes and SQLTypes
private static Hashtable sqlTypeCache = new Hashtable(); // oid -> SQLType
@@ -81,7 +77,6 @@ public abstract class Connection
public int pid;
public int ckey;
- public int asyncStatus = PGASYNC_READY;
/*
* This is called by Class.forName() from within org.postgresql.Driver
*/
@@ -427,7 +422,7 @@ public abstract class Connection
*/
public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException
{
- return new QueryExecutor2(sql, stat, pg_stream, this).execute();
+ return new QueryExecutor(sql, stat, pg_stream, this).execute();
}
/*
diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in
index a6d0fb03a25..bc1925efe56 100644
--- a/src/interfaces/jdbc/org/postgresql/Driver.java.in
+++ b/src/interfaces/jdbc/org/postgresql/Driver.java.in
@@ -419,7 +419,7 @@ public class Driver implements java.sql.Driver
*/
public String database()
{
- return props.getProperty("PGDBNAME");
+ return props.getProperty("PGDBNAME", "");
}
/*
diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
index 237aa49684f..bfa6af35723 100644
--- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
+++ b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
@@ -13,212 +13,199 @@ import org.postgresql.util.PSQLException;
* <p>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.11 2002/03/21 03:20:30 davec Exp $
+ * $Id: QueryExecutor.java,v 1.12 2002/03/26 05:52:49 barry Exp $
*/
public class QueryExecutor
{
- private final String sql;
- private final java.sql.Statement statement;
- private final PG_Stream pg_stream;
- private final org.postgresql.Connection connection;
-
- public QueryExecutor(String sql,
- java.sql.Statement statement,
- PG_Stream pg_stream,
- org.postgresql.Connection connection)
- throws SQLException
- {
- this.sql = sql;
- this.statement = statement;
- this.pg_stream = pg_stream;
- this.connection = 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
- {
-
- int fqp = 0;
- boolean hfr = false;
-
- StringBuffer errorMessage = null;
-
- synchronized (pg_stream)
- {
-
- sendQuery(sql);
-
- while (!hfr || fqp > 0)
- {
- int c = pg_stream.ReceiveChar();
-
- switch (c)
- {
- case 'A': // Asynchronous Notify
- int pid = pg_stream.ReceiveInteger(4);
- String msg = pg_stream.ReceiveString(connection.getEncoding());
- break;
- case 'B': // Binary Data Transfer
- receiveTuple(true);
- break;
- case 'C': // Command Status
- receiveCommandStatus();
-
- if (fields != null)
- hfr = true;
- else
- {
- sendQuery(" ");
- fqp++;
- }
- 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();
- if (t != 0)
- throw new PSQLException("postgresql.con.garbled");
-
- if (fqp > 0)
- fqp--;
- if (fqp == 0)
- hfr = true;
- 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': // backend ready for query, ignore for now :-)
- 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(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
- }
- }
-
- /*
- * Send a query to the backend.
- */
- private void sendQuery(String query) throws SQLException
- {
- try
- {
- pg_stream.SendChar('Q');
- pg_stream.Send(connection.getEncoding().encode(query));
- 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);
- }
- }
+ private final String sql;
+ private final java.sql.Statement statement;
+ private final PG_Stream pg_stream;
+ private final org.postgresql.Connection connection;
+
+ public QueryExecutor(String sql,
+ java.sql.Statement statement,
+ PG_Stream pg_stream,
+ org.postgresql.Connection connection)
+ throws SQLException
+ {
+ this.sql = sql;
+ this.statement = statement;
+ this.pg_stream = pg_stream;
+ this.connection = 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(sql);
+
+ 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());
+ 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(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
+ }
+ }
+
+ /*
+ * Send a query to the backend.
+ */
+ private void sendQuery(String query) throws SQLException
+ {
+ try
+ {
+ pg_stream.SendChar('Q');
+ pg_stream.Send(connection.getEncoding().encode(query));
+ 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/QueryExecutor2.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor2.java
deleted file mode 100644
index f48c95cc309..00000000000
--- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor2.java
+++ /dev/null
@@ -1,259 +0,0 @@
-
-package org.postgresql.core;
-
-import java.util.Vector;
-import java.io.IOException;
-import java.sql.*;
-import org.postgresql.*;
-import org.postgresql.util.PSQLException;
-
-/*
- * Executes a query on the backend.
- *
- * <p>The lifetime of a QueryExecutor object is from sending the query
- * until the response has been received from the backend.
- *
- * $Id: QueryExecutor2.java,v 1.1 2002/03/21 03:20:29 davec Exp $
- */
-
-public class QueryExecutor2
-{
-
- private final String sql;
- private final java.sql.Statement statement;
- private final PG_Stream pg_stream;
- private final org.postgresql.Connection connection;
-
- public QueryExecutor2(String sql,
- java.sql.Statement statement,
- PG_Stream pg_stream,
- org.postgresql.Connection connection)
- throws SQLException
- {
- this.sql = sql;
- this.statement = statement;
- this.pg_stream = pg_stream;
- this.connection = 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(sql);
- connection.asyncStatus = org.postgresql.Connection.PGASYNC_BUSY;
-
- while ( connection.asyncStatus != org.postgresql.Connection.PGASYNC_IDLE )
- {
- int c = pg_stream.ReceiveChar();
-
- if ( c == 'A' )
- {
-
- int pid = pg_stream.ReceiveIntegerR(4);
- String msg = pg_stream.ReceiveString(connection.getEncoding());
-
- org.postgresql.Driver.debug(msg);
- continue;
- }
- else if ( c == 'N' )
- {
- String notification = pg_stream.ReceiveString(connection.getEncoding());
- org.postgresql.Driver.debug(notification);
- connection.addWarning(notification);
- continue;
- }
- else if ( connection.asyncStatus != org.postgresql.Connection.PGASYNC_BUSY )
- {
- if ( connection.asyncStatus != org.postgresql.Connection.PGASYNC_IDLE )
- {
- // only one possibility left which is PGASYNC_READY, so let's get out
- break;
- }
- if ( c == 'E' ) {
- String error = pg_stream.ReceiveString(connection.getEncoding());
- org.postgresql.Driver.debug(error);
-
- // no sense in creating this object until we really need it
- if ( errorMessage == null ) {
- errorMessage = new StringBuffer();
- }
-
- errorMessage.append(error);
- break;
- }
- }else{
-
- switch (c)
- {
- case 'C': // Command Status
- receiveCommandStatus();
- break;
-
- case 'E': // Error Message
-
- // it's possible to get multiple error messages from one query
- // see libpq, there are some comments about a connection being closed
- // by the backend after real error occurs, so append error messages here
- // so append them and just remember that an error occured
- // throw the exception at the end of processing
-
- String error = pg_stream.ReceiveString(connection.getEncoding());
- org.postgresql.Driver.debug(error);
-
- // no sense in creating this object until we really need it
- if ( errorMessage == null ) {
- errorMessage = new StringBuffer();
- }
-
- errorMessage.append(error);
- connection.asyncStatus = org.postgresql.Connection.PGASYNC_READY;
- break;
-
- case 'Z': // backend ready for query, ignore for now :-)
- connection.asyncStatus = org.postgresql.Connection.PGASYNC_IDLE;
- break;
-
- case 'I': // Empty Query
- int t = pg_stream.ReceiveChar();
- if (t != 0)
- throw new PSQLException("postgresql.con.garbled");
-
- connection.asyncStatus = org.postgresql.Connection.PGASYNC_READY;
- break;
-
- case 'P': // Portal Name
- String pname = pg_stream.ReceiveString(connection.getEncoding());
- org.postgresql.Driver.debug(pname);
- break;
-
- case 'T': // MetaData Field Description
- receiveFields();
- break;
-
- case 'B': // Binary Data Transfer
- receiveTuple(true);
- break;
-
- case 'D': // Text Data Transfer
- receiveTuple(false);
- break;
-
- default:
- throw new PSQLException("postgresql.con.type",
- new Character((char) c));
- }
- }
- }
- // did we get an error message?
-
- if ( errorMessage != null ) {
- // yes, throw an exception
- throw new SQLException(errorMessage.toString());
- }
- return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
- }
- }
-
- /*
- * Send a query to the backend.
- */
- private void sendQuery(String query) throws SQLException
- {
- try
- {
- pg_stream.SendChar('Q');
- pg_stream.Send(connection.getEncoding().encode(query));
- 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/fastpath/Fastpath.java b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
index 2581f59b52c..a74645015a8 100644
--- a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
+++ b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
@@ -23,283 +23,269 @@ 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.Connection conn; // our connection
- protected org.postgresql.PG_Stream stream; // the network stream
+ protected org.postgresql.Connection conn; // our connection
+ protected org.postgresql.PG_Stream stream; // the network stream
- /*
- * Initialises the fastpath system
- *
- * <p><b>Important Notice</b>
- * <br>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.Connection conn, org.postgresql.PG_Stream stream)
- {
- this.conn = conn;
- this.stream = stream;
- //DriverManager.println("Fastpath initialised");
- }
+ /*
+ * Initialises the fastpath system
+ *
+ * <p><b>Important Notice</b>
+ * <br>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.Connection conn, org.postgresql.PG_Stream stream)
+ {
+ this.conn = conn;
+ this.stream = stream;
+ //DriverManager.println("Fastpath initialised");
+ }
- /*
- * 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
- // We should get 'V' on sucess or 'E' on error. Anything else is treated
- // as an error.
- //int in = stream.ReceiveChar();
- //DriverManager.println("ReceiveChar() = "+in+" '"+((char)in)+"'");
- //if (in!='V') {
- //if (in=='E')
- //throw new SQLException(stream.ReceiveString(conn.getEncoding()));
- //throw new SQLException("Fastpath: expected 'V' from backend, got "+((char)in));
- //}
+ // 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;
- boolean loop = true;
- while (loop)
- {
- int in = stream.ReceiveChar();
- //DriverManager.println("ReceiveChar() = "+in+" '"+((char)in)+"'");
- switch (in)
- {
- case 'V':
- break;
+ switch (c)
+ {
+ case 'A': // Asynchronous Notify
+ int pid = stream.ReceiveInteger(4);
+ String msg = stream.ReceiveString(conn.getEncoding());
+ break;
- //------------------------------
- // Function returned properly
- //
- case 'G':
- int sz = stream.ReceiveIntegerR(4);
- //DriverManager.println("G: size="+sz); //debug
+ //------------------------------
+ // Error message returned
+ case 'E':
+ if ( errorMessage == null )
+ errorMessage = new StringBuffer();
+ errorMessage.append(stream.ReceiveString(conn.getEncoding()));
+ break;
- // 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;
- }
- break;
+ //------------------------------
+ // Notice from backend
+ case 'N':
+ conn.addWarning(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':
- 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;
- //------------------------------
- // End of results
- //
- // Here we simply return res, which would contain the result
- // processed earlier. If no result, this already contains null
- case '0':
- //DriverManager.println("returning "+result);
- // return result;
- break;
- case 'Z':
- // cause the loop to exit
- loop = false;
- break;
+ case 'Z':
+ l_endQuery = true;
+ break;
- default:
- throw new PSQLException("postgresql.fp.protocol", new Character((char)in));
- }
- }
-
- if ( errorMessage != null )
- throw new PSQLException("postgresql.fp.error", errorMessage.toString());
+ default:
+ throw new PSQLException("postgresql.fp.protocol", new Character((char)c));
+ }
+ }
- return result;
- }
- }
+ if ( errorMessage != null )
+ throw new PSQLException("postgresql.fp.error", errorMessage.toString());
- /*
- * 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
- {
- //DriverManager.println("Fastpath: calling "+name);
- return fastpath(getID(name), resulttype, args);
- }
+ return result;
+ }
+ }
- /*
- * 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();
- }
+ /*
+ * 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
+ {
+ //DriverManager.println("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 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 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 adds a function to our lookup table.
- *
- * <p>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 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 takes a ResultSet containing two columns. Column 1 contains the
- * function name, Column 2 the oid.
- *
- * <p>It reads the entire ResultSet, loading the values into the function
- * table.
- *
- * <p><b>REMEMBER</b> to close() the resultset after calling this!!
- *
- * <p><b><em>Implementation note about function name lookups:</em></b>
- *
- * <p>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.
- *
- * <p>The org.postgresql.LargeObject class performs a query upon it's startup,
- * and passes the returned ResultSet to the addFunctions() method here.
- *
- * <p>Once this has been done, the LargeObject api refers to the functions by
- * name.
- *
- * <p>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 adds a function to our lookup table.
+ *
+ * <p>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 returns the function id associated by its name
- *
- * <p>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 takes a ResultSet containing two columns. Column 1 contains the
+ * function name, Column 2 the oid.
+ *
+ * <p>It reads the entire ResultSet, loading the values into the function
+ * table.
+ *
+ * <p><b>REMEMBER</b> to close() the resultset after calling this!!
+ *
+ * <p><b><em>Implementation note about function name lookups:</em></b>
+ *
+ * <p>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.
+ *
+ * <p>The org.postgresql.LargeObject class performs a query upon it's startup,
+ * and passes the returned ResultSet to the addFunctions() method here.
+ *
+ * <p>Once this has been done, the LargeObject api refers to the functions by
+ * name.
+ *
+ * <p>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)));
+ }
+ }
- // 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);
+ /*
+ * This returns the function id associated by its name
+ *
+ * <p>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);
- return id.intValue();
- }
+ // 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();
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
index e3ff6393940..0d62c74c9ad 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.*;
/*
- * $Id: Connection.java,v 1.17 2002/01/15 06:55:13 barry Exp $
+ * $Id: Connection.java,v 1.18 2002/03/26 05:52:50 barry Exp $
*
* A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are
@@ -36,307 +36,287 @@ import org.postgresql.util.*;
*/
public class Connection extends org.postgresql.Connection implements java.sql.Connection
{
- // This is a cache of the DatabaseMetaData instance for this connection
- protected DatabaseMetaData metadata;
+ // This is a cache of the DatabaseMetaData instance for this connection
+ protected DatabaseMetaData metadata;
- /*
- * The current type mappings
- */
- protected java.util.Map typemap;
+ /*
+ * The current type mappings
+ */
+ protected java.util.Map typemap;
- /*
- * SQL statements without parameters are normally executed using
- * Statement objects. If the same SQL statement is executed many
- * times, it is more efficient to use a PreparedStatement
- *
- * @return a new Statement object
- * @exception SQLException passed through from the constructor
- */
- 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);
- }
+ /*
+ * SQL statements without parameters are normally executed using
+ * Statement objects. If the same SQL statement is executed many
+ * times, it is more efficient to use a PreparedStatement
+ *
+ * @return a new Statement object
+ * @exception SQLException passed through from the constructor
+ */
+ 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);
+ }
- /*
- * SQL statements without parameters are normally executed using
- * Statement objects. If the same SQL statement is executed many
- * times, it is more efficient to use a PreparedStatement
- *
- * @param resultSetType to use
- * @param resultSetCuncurrency to use
- * @return a new Statement object
- * @exception SQLException passed through from the constructor
- */
- public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
- {
- Statement s = new Statement(this);
- s.setResultSetType(resultSetType);
- s.setResultSetConcurrency(resultSetConcurrency);
- return s;
- }
+ /*
+ * SQL statements without parameters are normally executed using
+ * Statement objects. If the same SQL statement is executed many
+ * times, it is more efficient to use a PreparedStatement
+ *
+ * @param resultSetType to use
+ * @param resultSetCuncurrency to use
+ * @return a new Statement object
+ * @exception SQLException passed through from the constructor
+ */
+ public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ Statement s = new Statement(this);
+ s.setResultSetType(resultSetType);
+ s.setResultSetConcurrency(resultSetConcurrency);
+ return s;
+ }
- /*
- * A 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.
- *
- * <B>Note:</B> This method is optimized for handling parametric
- * SQL statements that benefit from precompilation if the drivers
- * supports precompilation. PostgreSQL does not support precompilation.
- * In this case, the statement is not sent to the database until the
- * PreparedStatement is executed. This has no direct effect on users;
- * however it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' IN
- * parameter placeholders
- * @return a new PreparedStatement object containing the pre-compiled
- * statement.
- * @exception SQLException if a database access error occurs.
- */
- public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
- {
- return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
- }
+ /*
+ * A 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.
+ *
+ * <B>Note:</B> This method is optimized for handling parametric
+ * SQL statements that benefit from precompilation if the drivers
+ * supports precompilation. PostgreSQL does not support precompilation.
+ * In this case, the statement is not sent to the database until the
+ * PreparedStatement is executed. This has no direct effect on users;
+ * however it does affect which method throws certain SQLExceptions
+ *
+ * @param sql a SQL statement that may contain one or more '?' IN
+ * parameter placeholders
+ * @return a new PreparedStatement object containing the pre-compiled
+ * statement.
+ * @exception SQLException if a database access error occurs.
+ */
+ 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 java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
- {
- PreparedStatement s = new PreparedStatement(this, sql);
- s.setResultSetType(resultSetType);
- s.setResultSetConcurrency(resultSetConcurrency);
- return s;
- }
+ public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ PreparedStatement s = new PreparedStatement(this, sql);
+ s.setResultSetType(resultSetType);
+ s.setResultSetConcurrency(resultSetConcurrency);
+ return s;
+ }
- /*
- * A SQL stored procedure call statement is handled by creating a
- * CallableStatement for it. The CallableStatement provides methods
- * for setting up its IN and OUT parameters and methods for executing
- * it.
- *
- * <B>Note:</B> This method is optimised for handling stored procedure
- * call statements. Some drivers may send the call statement to the
- * database when the prepareCall is done; others may wait until the
- * CallableStatement is executed. This has no direct effect on users;
- * however, it does affect which method throws certain SQLExceptions
- *
- * @param sql a SQL statement that may contain one or more '?' parameter
- * placeholders. Typically this statement is a JDBC function call
- * escape string.
- * @return a new CallableStatement object containing the pre-compiled
- * SQL statement
- * @exception SQLException if a database access error occurs
- */
- public java.sql.CallableStatement prepareCall(String sql) throws SQLException
- {
- return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
- }
+ /*
+ * A SQL stored procedure call statement is handled by creating a
+ * CallableStatement for it. The CallableStatement provides methods
+ * for setting up its IN and OUT parameters and methods for executing
+ * it.
+ *
+ * <B>Note:</B> This method is optimised for handling stored procedure
+ * call statements. Some drivers may send the call statement to the
+ * database when the prepareCall is done; others may wait until the
+ * CallableStatement is executed. This has no direct effect on users;
+ * however, it does affect which method throws certain SQLExceptions
+ *
+ * @param sql a SQL statement that may contain one or more '?' parameter
+ * placeholders. Typically this statement is a JDBC function call
+ * escape string.
+ * @return a new CallableStatement object containing the pre-compiled
+ * SQL statement
+ * @exception SQLException if a database access error occurs
+ */
+ 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 java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
- {
- throw new PSQLException("postgresql.con.call");
- //CallableStatement s = new CallableStatement(this,sql);
- //s.setResultSetType(resultSetType);
- //s.setResultSetConcurrency(resultSetConcurrency);
- //return s;
- }
+ public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ throw new PSQLException("postgresql.con.call");
+ //CallableStatement s = new CallableStatement(this,sql);
+ //s.setResultSetType(resultSetType);
+ //s.setResultSetConcurrency(resultSetConcurrency);
+ //return s;
+ }
- /*
- * Tests to see if a Connection is closed.
- *
- * Peter Feb 7 2000: Now I've discovered that this doesn't actually obey the
- * specifications. Under JDBC2.1, this should only be valid _after_ close()
- * has been called. It's result is not guraranteed to be valid before, and
- * client code should not use it to see if a connection is open. The spec says
- * that the client should monitor the SQLExceptions thrown when their queries
- * fail because the connection is dead.
- *
- * I don't like this definition. As it doesn't hurt breaking it here, our
- * isClosed() implementation does test the connection, so for PostgreSQL, you
- * can rely on isClosed() returning a valid result.
- *
- * @return the status of the connection
- * @exception SQLException (why?)
- */
- public boolean isClosed() throws SQLException
- {
- // If the stream is gone, then close() was called
- if (pg_stream == null)
- return true;
+ /*
+ * Tests to see if a Connection is closed.
+ *
+ * Peter Feb 7 2000: Now I've discovered that this doesn't actually obey the
+ * specifications. Under JDBC2.1, this should only be valid _after_ close()
+ * has been called. It's result is not guraranteed to be valid before, and
+ * client code should not use it to see if a connection is open. The spec says
+ * that the client should monitor the SQLExceptions thrown when their queries
+ * fail because the connection is dead.
+ *
+ * I don't like this definition. As it doesn't hurt breaking it here, our
+ * isClosed() implementation does test the connection, so for PostgreSQL, you
+ * can rely on isClosed() returning a valid result.
+ *
+ * @return the status of the connection
+ * @exception SQLException (why?)
+ */
+ public boolean isClosed() throws SQLException
+ {
+ // If the stream is gone, then close() was called
+ if (pg_stream == null)
+ return true;
+ return false;
+ }
- // ok, test the connection
- try
- {
- // by sending an empty query. If we are dead, then an SQLException should
- // be thrown
- java.sql.ResultSet rs = ExecSQL(" ");
- if (rs != null)
- rs.close();
+ /*
+ * A connection's database is able to provide information describing
+ * its tables, its supported SQL grammar, its stored procedures, the
+ * capabilities of this connection, etc. This information is made
+ * available through a DatabaseMetaData object.
+ *
+ * @return a DatabaseMetaData object for this connection
+ * @exception SQLException if a database access error occurs
+ */
+ public java.sql.DatabaseMetaData getMetaData() throws SQLException
+ {
+ if (metadata == null)
+ metadata = new DatabaseMetaData(this);
+ return metadata;
+ }
- // By now, we must be alive
- return false;
- }
- catch (SQLException se)
- {
- // Why throw an SQLException as this may fail without throwing one,
- // ie isClosed() is called incase the connection has died, and we don't
- // want to find out by an Exception, so instead we return true, as its
- // most likely why it was thrown in the first place.
- return true;
- }
- }
+ /*
+ * This overides the method in org.postgresql.Connection and returns a
+ * ResultSet.
+ */
+ public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+ {
+ // In 7.1 we now test concurrency to see which class to return. If we are not working with a
+ // Statement then default to a normal ResultSet object.
+ if (stat != null)
+ {
+ if (stat.getResultSetConcurrency() == java.sql.ResultSet.CONCUR_UPDATABLE)
+ return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
- /*
- * A connection's database is able to provide information describing
- * its tables, its supported SQL grammar, its stored procedures, the
- * capabilities of this connection, etc. This information is made
- * available through a DatabaseMetaData object.
- *
- * @return a DatabaseMetaData object for this connection
- * @exception SQLException if a database access error occurs
- */
- public java.sql.DatabaseMetaData getMetaData() throws SQLException
- {
- if (metadata == null)
- metadata = new DatabaseMetaData(this);
- return metadata;
- }
+ return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
- /*
- * This overides the method in org.postgresql.Connection and returns a
- * ResultSet.
- */
- public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
- {
- // In 7.1 we now test concurrency to see which class to return. If we are not working with a
- // Statement then default to a normal ResultSet object.
- if (stat != null)
- {
- if (stat.getResultSetConcurrency() == java.sql.ResultSet.CONCUR_UPDATABLE)
- return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
+ // *****************
+ // JDBC 2 extensions
+ // *****************
- return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
- }
+ public java.util.Map getTypeMap() throws SQLException
+ {
+ // new in 7.1
+ return typemap;
+ }
- // *****************
- // JDBC 2 extensions
- // *****************
- public java.util.Map getTypeMap() throws SQLException
- {
- // new in 7.1
- return typemap;
- }
+ public void setTypeMap(java.util.Map map) throws SQLException
+ {
+ // new in 7.1
+ typemap = map;
+ }
+ /*
+ * This overides the standard internal getObject method so that we can
+ * check the jdbc2 type map first
+ *
+ * @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
+ {
+ 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();
+ }
+ }
- public void setTypeMap(java.util.Map map) throws SQLException
- {
- // new in 7.1
- typemap = map;
- }
+ // Default to the original method
+ return super.getObject(type, value);
+ }
- /*
- * This overides the standard internal getObject method so that we can
- * check the jdbc2 type map first
- *
- * @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
- {
- 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();
- }
- }
+ /* An implementation of the abstract method in the parent class.
+ * 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;
+ }
- // Default to the original method
- return super.getObject(type, value);
- }
+ /*
+ * 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"
+ };
- /* An implementation of the abstract method in the parent class.
- * 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
- };
+ /*
+ * 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
+ };
}