diff options
Diffstat (limited to 'src')
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 + }; } |