mirror of
https://github.com/postgres/postgres.git
synced 2025-08-31 17:02:12 +03:00
Thu Jan 18 12:24:00 GMT 2001 peter@retep.org.uk
- These methods in org.postgresql.jdbc2.ResultSet are now implemented: getBigDecimal(int) ie: without a scale (why did this get missed?) getBlob(int) getCharacterStream(int) getConcurrency() getDate(int,Calendar) getFetchDirection() getFetchSize() getTime(int,Calendar) getTimestamp(int,Calendar) getType() NB: Where int represents the column name, the associated version taking a String were already implemented by calling the int version. - These methods no longer throw the not implemented but the new noupdate error. This is in preparation for the Updateable ResultSet support which will overide these methods by extending the existing class to implement that functionality, but needed to show something other than notimplemented: cancelRowUpdates() deleteRow() - Added new error message into errors.properties "postgresql.noupdate" This is used by jdbc2.ResultSet when an update method is called and the ResultSet is not updateable. A new method notUpdateable() has been added to that class to throw this exception, keeping the binary size down. - Added new error message into errors.properties "postgresql.psqlnotimp" This is used instead of unimplemented when it's a feature in the backend that is preventing this method from being implemented. - Removed getKeysetSize() as its not part of the ResultSet API Thu Jan 18 09:46:00 GMT 2001 peter@retep.org.uk - Applied modified patch from Richard Bullington-McGuire <rbulling@microstate.com>. I had to modify it as some of the code patched now exists in different classes, and some of it actually patched obsolete code. Wed Jan 17 10:19:00 GMT 2001 peter@retep.org.uk - Updated Implementation to include both ANT & JBuilder - Updated README to reflect the changes since 7.0 - Created jdbc.jpr file which allows JBuilder to be used to edit the source. JBuilder _CAN_NOT_ be used to compile. You must use ANT for that. It's only to allow JBuilders syntax checking to improve the drivers source. Refer to Implementation for more details
This commit is contained in:
@@ -10,7 +10,7 @@ import org.postgresql.largeobject.*;
|
||||
import org.postgresql.util.*;
|
||||
|
||||
/**
|
||||
* $Id: Connection.java,v 1.11 2000/12/22 03:08:52 momjian Exp $
|
||||
* $Id: Connection.java,v 1.12 2001/01/18 14:50:14 peter Exp $
|
||||
*
|
||||
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
|
||||
* JDBC2 versions of the Connection class.
|
||||
@@ -20,10 +20,10 @@ public abstract class Connection
|
||||
{
|
||||
// This is the network stream associated with this connection
|
||||
public PG_Stream pg_stream;
|
||||
|
||||
|
||||
// This is set by org.postgresql.Statement.setMaxRows()
|
||||
public int maxrows = 0; // maximum no. of rows; 0 = unlimited
|
||||
|
||||
|
||||
private String PG_HOST;
|
||||
private int PG_PORT;
|
||||
private String PG_USER;
|
||||
@@ -38,17 +38,17 @@ public abstract class Connection
|
||||
* used.
|
||||
*/
|
||||
private String encoding;
|
||||
|
||||
|
||||
public boolean CONNECTION_OK = true;
|
||||
public boolean CONNECTION_BAD = false;
|
||||
|
||||
|
||||
public boolean autoCommit = true;
|
||||
public boolean readOnly = false;
|
||||
|
||||
|
||||
public Driver this_driver;
|
||||
private String this_url;
|
||||
private String cursor = null; // The positioned update cursor name
|
||||
|
||||
|
||||
// These are new for v6.3, they determine the current protocol versions
|
||||
// supported by this version of the driver. They are defined in
|
||||
// src/include/libpq/pqcomm.h
|
||||
@@ -59,41 +59,41 @@ public abstract class Connection
|
||||
private static final int SM_OPTIONS = 64;
|
||||
private static final int SM_UNUSED = 64;
|
||||
private static final int SM_TTY = 64;
|
||||
|
||||
|
||||
private static final int AUTH_REQ_OK = 0;
|
||||
private static final int AUTH_REQ_KRB4 = 1;
|
||||
private static final int AUTH_REQ_KRB5 = 2;
|
||||
private static final int AUTH_REQ_PASSWORD = 3;
|
||||
private static final int AUTH_REQ_CRYPT = 4;
|
||||
|
||||
|
||||
// New for 6.3, salt value for crypt authorisation
|
||||
private String salt;
|
||||
|
||||
|
||||
// This is used by Field to cache oid -> names.
|
||||
// It's here, because it's shared across this connection only.
|
||||
// Hence it cannot be static within the Field class, because it would then
|
||||
// be across all connections, which could be to different backends.
|
||||
public Hashtable fieldCache = new Hashtable();
|
||||
|
||||
|
||||
// Now handle notices as warnings, so things like "show" now work
|
||||
public SQLWarning firstWarning = null;
|
||||
|
||||
|
||||
// The PID an cancellation key we get from the backend process
|
||||
public int pid;
|
||||
public int ckey;
|
||||
|
||||
// This receive_sbuf should be used by the different methods
|
||||
// that call pg_stream.ReceiveString() in this Connection, so
|
||||
// so we avoid uneccesary new allocations.
|
||||
// that call pg_stream.ReceiveString() in this Connection, so
|
||||
// so we avoid uneccesary new allocations.
|
||||
byte receive_sbuf[] = new byte[8192];
|
||||
|
||||
|
||||
/**
|
||||
* This is called by Class.forName() from within org.postgresql.Driver
|
||||
*/
|
||||
public Connection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method actually opens the connection. It is called by Driver.
|
||||
*
|
||||
@@ -115,7 +115,7 @@ public abstract class Connection
|
||||
throw new PSQLException("postgresql.con.user");
|
||||
if(info.getProperty("password")==null)
|
||||
throw new PSQLException("postgresql.con.pass");
|
||||
|
||||
|
||||
this_driver = d;
|
||||
this_url = url;
|
||||
PG_DATABASE = database;
|
||||
@@ -137,7 +137,7 @@ public abstract class Connection
|
||||
} catch (IOException e) {
|
||||
throw new PSQLException ("postgresql.con.failed",e);
|
||||
}
|
||||
|
||||
|
||||
// Now we need to construct and send a startup packet
|
||||
try
|
||||
{
|
||||
@@ -146,13 +146,13 @@ public abstract class Connection
|
||||
pg_stream.SendInteger(PG_PROTOCOL_LATEST_MAJOR,2);
|
||||
pg_stream.SendInteger(PG_PROTOCOL_LATEST_MINOR,2);
|
||||
pg_stream.Send(database.getBytes(),SM_DATABASE);
|
||||
|
||||
|
||||
// This last send includes the unused fields
|
||||
pg_stream.Send(PG_USER.getBytes(),SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY);
|
||||
|
||||
|
||||
// now flush the startup packets to the backend
|
||||
pg_stream.flush();
|
||||
|
||||
|
||||
// Now get the response from the backend, either an error message
|
||||
// or an authentication request
|
||||
int areq = -1; // must have a value here
|
||||
@@ -169,11 +169,11 @@ public abstract class Connection
|
||||
//
|
||||
throw new SQLException(pg_stream.ReceiveString
|
||||
(receive_sbuf, 4096, getEncoding()));
|
||||
|
||||
|
||||
case 'R':
|
||||
// Get the type of request
|
||||
areq = pg_stream.ReceiveIntegerR(4);
|
||||
|
||||
|
||||
// Get the password salt if there is one
|
||||
if(areq == AUTH_REQ_CRYPT) {
|
||||
byte[] rst = new byte[2];
|
||||
@@ -182,21 +182,21 @@ public abstract class Connection
|
||||
salt = new String(rst,0,2);
|
||||
DriverManager.println("Salt="+salt);
|
||||
}
|
||||
|
||||
|
||||
// now send the auth packet
|
||||
switch(areq)
|
||||
{
|
||||
case AUTH_REQ_OK:
|
||||
break;
|
||||
|
||||
|
||||
case AUTH_REQ_KRB4:
|
||||
DriverManager.println("postgresql: KRB4");
|
||||
throw new PSQLException("postgresql.con.kerb4");
|
||||
|
||||
|
||||
case AUTH_REQ_KRB5:
|
||||
DriverManager.println("postgresql: KRB5");
|
||||
throw new PSQLException("postgresql.con.kerb5");
|
||||
|
||||
|
||||
case AUTH_REQ_PASSWORD:
|
||||
DriverManager.println("postgresql: PASSWORD");
|
||||
pg_stream.SendInteger(5+PG_PASSWORD.length(),4);
|
||||
@@ -204,7 +204,7 @@ public abstract class Connection
|
||||
pg_stream.SendInteger(0,1);
|
||||
pg_stream.flush();
|
||||
break;
|
||||
|
||||
|
||||
case AUTH_REQ_CRYPT:
|
||||
DriverManager.println("postgresql: CRYPT");
|
||||
String crypted = UnixCrypt.crypt(salt,PG_PASSWORD);
|
||||
@@ -213,21 +213,21 @@ public abstract class Connection
|
||||
pg_stream.SendInteger(0,1);
|
||||
pg_stream.flush();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new PSQLException("postgresql.con.auth",new Integer(areq));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new PSQLException("postgresql.con.authfail");
|
||||
}
|
||||
} while(areq != AUTH_REQ_OK);
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new PSQLException("postgresql.con.failed",e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// As of protocol version 2.0, we should now receive the cancellation key and the pid
|
||||
int beresp = pg_stream.ReceiveChar();
|
||||
@@ -266,7 +266,7 @@ public abstract class Connection
|
||||
// We also ask the DB for certain properties (i.e. DatabaseEncoding at this time)
|
||||
//
|
||||
firstWarning = null;
|
||||
|
||||
|
||||
java.sql.ResultSet initrset = ExecSQL("set datestyle to 'ISO'; select getdatabaseencoding()");
|
||||
|
||||
String dbEncoding = null;
|
||||
@@ -341,19 +341,19 @@ public abstract class Connection
|
||||
encoding = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialise object handling
|
||||
initObjectTypes();
|
||||
|
||||
|
||||
// Mark the connection as ok, and cleanup
|
||||
firstWarning = null;
|
||||
PG_STATUS = CONNECTION_OK;
|
||||
}
|
||||
|
||||
|
||||
// These methods used to be in the main Connection implementation. As they
|
||||
// are common to all implementations (JDBC1 or 2), they are placed here.
|
||||
// This should make it easy to maintain the two specifications.
|
||||
|
||||
|
||||
/**
|
||||
* This adds a warning to the warning chain.
|
||||
* @param msg message to add
|
||||
@@ -361,15 +361,15 @@ public abstract class Connection
|
||||
public void addWarning(String msg)
|
||||
{
|
||||
DriverManager.println(msg);
|
||||
|
||||
|
||||
// Add the warning to the chain
|
||||
if(firstWarning!=null)
|
||||
firstWarning.setNextWarning(new SQLWarning(msg));
|
||||
else
|
||||
firstWarning = new SQLWarning(msg);
|
||||
|
||||
|
||||
// Now check for some specific messages
|
||||
|
||||
|
||||
// This is obsolete in 6.5, but I've left it in here so if we need to use this
|
||||
// technique again, we'll know where to place it.
|
||||
//
|
||||
@@ -377,13 +377,13 @@ public abstract class Connection
|
||||
//if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
|
||||
//// 13 is the length off "DateStyle is "
|
||||
//msg = msg.substring(msg.indexOf("DateStyle is ")+13);
|
||||
//
|
||||
//
|
||||
//for(int i=0;i<dateStyles.length;i+=2)
|
||||
//if(msg.startsWith(dateStyles[i]))
|
||||
//currentDateStyle=i+1; // this is the index of the format
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a query to the backend. Returns one of the ResultSet
|
||||
* objects.
|
||||
@@ -404,8 +404,10 @@ public abstract class Connection
|
||||
// This will let the driver reuse byte arrays that has already
|
||||
// been allocated instead of allocating new ones in order
|
||||
// to gain performance improvements.
|
||||
pg_stream.deallocate();
|
||||
|
||||
// PM 17/01/01: Commented out due to race bug. See comments in
|
||||
// PG_Stream
|
||||
//pg_stream.deallocate();
|
||||
|
||||
Field[] fields = null;
|
||||
Vector tuples = new Vector();
|
||||
byte[] buf = null;
|
||||
@@ -415,7 +417,7 @@ public abstract class Connection
|
||||
int update_count = 1;
|
||||
int insert_oid = 0;
|
||||
SQLException final_error = null;
|
||||
|
||||
|
||||
// Commented out as the backend can now handle queries
|
||||
// larger than 8K. Peter June 6 2000
|
||||
//if (sql.length() > 8192)
|
||||
@@ -441,13 +443,13 @@ public abstract class Connection
|
||||
} catch (IOException e) {
|
||||
throw new PSQLException("postgresql.con.ioerror",e);
|
||||
}
|
||||
|
||||
|
||||
while (!hfr || fqp > 0)
|
||||
{
|
||||
Object tup=null; // holds rows as they are recieved
|
||||
|
||||
|
||||
int c = pg_stream.ReceiveChar();
|
||||
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'A': // Asynchronous Notify
|
||||
@@ -464,7 +466,7 @@ public abstract class Connection
|
||||
break;
|
||||
case 'C': // Command Status
|
||||
recv_status = pg_stream.ReceiveString(receive_sbuf,8192,getEncoding());
|
||||
|
||||
|
||||
// Now handle the update count correctly.
|
||||
if(recv_status.startsWith("INSERT") || recv_status.startsWith("UPDATE") || recv_status.startsWith("DELETE")) {
|
||||
try {
|
||||
@@ -511,7 +513,7 @@ public abstract class Connection
|
||||
break;
|
||||
case 'I': // Empty Query
|
||||
int t = pg_stream.ReceiveChar();
|
||||
|
||||
|
||||
if (t != 0)
|
||||
throw new PSQLException("postgresql.con.garbled");
|
||||
if (fqp > 0)
|
||||
@@ -538,7 +540,7 @@ public abstract class Connection
|
||||
}
|
||||
if (final_error != null)
|
||||
throw final_error;
|
||||
|
||||
|
||||
return getResultSet(this, fields, tuples, recv_status, update_count, insert_oid);
|
||||
}
|
||||
}
|
||||
@@ -553,7 +555,7 @@ public abstract class Connection
|
||||
{
|
||||
int nf = pg_stream.ReceiveIntegerR(2), i;
|
||||
Field[] fields = new Field[nf];
|
||||
|
||||
|
||||
for (i = 0 ; i < nf ; ++i)
|
||||
{
|
||||
String typname = pg_stream.ReceiveString(receive_sbuf,8192,getEncoding());
|
||||
@@ -564,7 +566,7 @@ public abstract class Connection
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In SQL, a result table can be retrieved through a cursor that
|
||||
* is named. The current row of a result can be updated or deleted
|
||||
@@ -582,7 +584,7 @@ public abstract class Connection
|
||||
{
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getCursorName gets the cursor name.
|
||||
*
|
||||
@@ -593,7 +595,7 @@ public abstract class Connection
|
||||
{
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We are required to bring back certain information by
|
||||
* the DatabaseMetaData class. These functions do that.
|
||||
@@ -607,7 +609,7 @@ public abstract class Connection
|
||||
{
|
||||
return this_url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method getUserName() brings back the User Name (again, we
|
||||
* saved it)
|
||||
@@ -622,13 +624,13 @@ public abstract class Connection
|
||||
|
||||
/**
|
||||
* Get the character encoding to use for this connection.
|
||||
* @return the encoding to use, or <b>null</b> for the
|
||||
* @return the encoding to use, or <b>null</b> for the
|
||||
* default encoding.
|
||||
*/
|
||||
public String getEncoding() throws SQLException {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This returns the Fastpath API for the current connection.
|
||||
*
|
||||
@@ -657,10 +659,10 @@ public abstract class Connection
|
||||
fastpath = new Fastpath(this,pg_stream);
|
||||
return fastpath;
|
||||
}
|
||||
|
||||
|
||||
// This holds a reference to the Fastpath API if already open
|
||||
private Fastpath fastpath = null;
|
||||
|
||||
|
||||
/**
|
||||
* This returns the LargeObject API for the current connection.
|
||||
*
|
||||
@@ -686,10 +688,10 @@ public abstract class Connection
|
||||
largeobject = new LargeObjectManager(this);
|
||||
return largeobject;
|
||||
}
|
||||
|
||||
|
||||
// This holds a reference to the LargeObject API if already open
|
||||
private LargeObjectManager largeobject = null;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used internally to return an object based around
|
||||
* org.postgresql's more unique data types.
|
||||
@@ -713,7 +715,7 @@ public abstract class Connection
|
||||
{
|
||||
try {
|
||||
Object o = objectTypes.get(type);
|
||||
|
||||
|
||||
// If o is null, then the type is unknown, so check to see if type
|
||||
// is an actual table name. If it does, see if a Class is known that
|
||||
// can handle it
|
||||
@@ -722,7 +724,7 @@ public abstract class Connection
|
||||
objectTypes.put(type,ser);
|
||||
return ser.fetch(Integer.parseInt(value));
|
||||
}
|
||||
|
||||
|
||||
// If o is not null, and it is a String, then its a class name that
|
||||
// extends PGobject.
|
||||
//
|
||||
@@ -748,11 +750,11 @@ public abstract class Connection
|
||||
} catch(Exception ex) {
|
||||
throw new PSQLException("postgresql.con.creobj",type,ex);
|
||||
}
|
||||
|
||||
|
||||
// should never be reached
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This stores an object into the database.
|
||||
* @param o Object to store
|
||||
@@ -765,7 +767,7 @@ public abstract class Connection
|
||||
try {
|
||||
String type = o.getClass().getName();
|
||||
Object x = objectTypes.get(type);
|
||||
|
||||
|
||||
// If x is null, then the type is unknown, so check to see if type
|
||||
// is an actual table name. If it does, see if a Class is known that
|
||||
// can handle it
|
||||
@@ -774,15 +776,15 @@ public abstract class Connection
|
||||
objectTypes.put(type,ser);
|
||||
return ser.store(o);
|
||||
}
|
||||
|
||||
|
||||
// If it's an object, it should be an instance of our Serialize class
|
||||
// If so, then call it's fetch method.
|
||||
if(x instanceof Serialize)
|
||||
return ((Serialize)x).store(o);
|
||||
|
||||
|
||||
// Thow an exception because the type is unknown
|
||||
throw new PSQLException("postgresql.con.strobj");
|
||||
|
||||
|
||||
} catch(SQLException sx) {
|
||||
// rethrow the exception. Done because we capture any others next
|
||||
sx.fillInStackTrace();
|
||||
@@ -791,7 +793,7 @@ public abstract class Connection
|
||||
throw new PSQLException("postgresql.con.strobjex",ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This allows client code to add a handler for one of org.postgresql's
|
||||
* more unique data types.
|
||||
@@ -816,10 +818,10 @@ public abstract class Connection
|
||||
{
|
||||
objectTypes.put(type,name);
|
||||
}
|
||||
|
||||
|
||||
// This holds the available types
|
||||
private Hashtable objectTypes = new Hashtable();
|
||||
|
||||
|
||||
// This array contains the types that are supported as standard.
|
||||
//
|
||||
// The first entry is the types name on the database, the second
|
||||
@@ -835,25 +837,25 @@ public abstract class Connection
|
||||
{"polygon", "org.postgresql.geometric.PGpolygon"},
|
||||
{"money", "org.postgresql.util.PGmoney"}
|
||||
};
|
||||
|
||||
|
||||
// This initialises the objectTypes hashtable
|
||||
private void initObjectTypes()
|
||||
{
|
||||
for(int i=0;i<defaultObjectTypes.length;i++)
|
||||
objectTypes.put(defaultObjectTypes[i][0],defaultObjectTypes[i][1]);
|
||||
}
|
||||
|
||||
|
||||
// These are required by other common classes
|
||||
public abstract java.sql.Statement createStatement() throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* This returns a resultset. It must be overridden, so that the correct
|
||||
* version (from jdbc1 or jdbc2) are returned.
|
||||
*/
|
||||
protected abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) throws SQLException;
|
||||
|
||||
|
||||
public abstract void close() throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* Overides finalize(). If called, it closes the connection.
|
||||
*
|
||||
@@ -866,12 +868,33 @@ public abstract class Connection
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is an attempt to implement SQL Escape clauses
|
||||
*/
|
||||
public String EscapeSQL(String sql) {
|
||||
return sql;
|
||||
//if (DEBUG) { System.out.println ("parseSQLEscapes called"); }
|
||||
|
||||
// If we find a "{d", assume we have a date escape.
|
||||
//
|
||||
// Since the date escape syntax is very close to the
|
||||
// native Postgres date format, we just remove the escape
|
||||
// delimiters.
|
||||
//
|
||||
// This implementation could use some optimization, but it has
|
||||
// worked in practice for two years of solid use.
|
||||
int index = sql.indexOf("{d");
|
||||
while (index != -1) {
|
||||
//System.out.println ("escape found at index: " + index);
|
||||
StringBuffer buf = new StringBuffer(sql);
|
||||
buf.setCharAt(index, ' ');
|
||||
buf.setCharAt(index + 1, ' ');
|
||||
buf.setCharAt(sql.indexOf('}', index), ' ');
|
||||
sql = new String(buf);
|
||||
index = sql.indexOf("{d");
|
||||
}
|
||||
//System.out.println ("modified SQL: " + sql);
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import java.net.*;
|
||||
import java.util.*;
|
||||
import java.sql.*;
|
||||
import org.postgresql.*;
|
||||
import org.postgresql.core.*;
|
||||
import org.postgresql.util.*;
|
||||
|
||||
/**
|
||||
@@ -22,10 +23,10 @@ public class PG_Stream
|
||||
private Socket connection;
|
||||
private InputStream pg_input;
|
||||
private BufferedOutputStream pg_output;
|
||||
|
||||
|
||||
BytePoolDim1 bytePoolDim1 = new BytePoolDim1();
|
||||
BytePoolDim2 bytePoolDim2 = new BytePoolDim2();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor: Connect to the PostgreSQL back end and return
|
||||
* a stream connection.
|
||||
@@ -37,16 +38,16 @@ public class PG_Stream
|
||||
public PG_Stream(String host, int port) throws IOException
|
||||
{
|
||||
connection = new Socket(host, port);
|
||||
|
||||
|
||||
// Submitted by Jason Venner <jason@idiom.com> adds a 10x speed
|
||||
// improvement on FreeBSD machines (caused by a bug in their TCP Stack)
|
||||
connection.setTcpNoDelay(true);
|
||||
|
||||
|
||||
// Buffer sizes submitted by Sverre H Huseby <sverrehu@online.no>
|
||||
pg_input = new BufferedInputStream(connection.getInputStream(), 8192);
|
||||
pg_output = new BufferedOutputStream(connection.getOutputStream(), 8192);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a single character to the back end
|
||||
*
|
||||
@@ -59,11 +60,11 @@ public class PG_Stream
|
||||
//byte b[] = new byte[1];
|
||||
//b[0] = (byte)val;
|
||||
//pg_output.write(b);
|
||||
|
||||
|
||||
// Optimised version by Sverre H. Huseby Aug 22 1999 Applied Sep 13 1999
|
||||
pg_output.write((byte)val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends an integer to the back end
|
||||
*
|
||||
@@ -74,7 +75,7 @@ public class PG_Stream
|
||||
public void SendInteger(int val, int siz) throws IOException
|
||||
{
|
||||
byte[] buf = bytePoolDim1.allocByte(siz);
|
||||
|
||||
|
||||
while (siz-- > 0)
|
||||
{
|
||||
buf[siz] = (byte)(val & 0xff);
|
||||
@@ -82,7 +83,7 @@ public class PG_Stream
|
||||
}
|
||||
Send(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends an integer to the back end in reverse order.
|
||||
*
|
||||
@@ -106,7 +107,7 @@ public class PG_Stream
|
||||
}
|
||||
Send(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an array of bytes to the backend
|
||||
*
|
||||
@@ -117,7 +118,7 @@ public class PG_Stream
|
||||
{
|
||||
pg_output.write(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an exact array of bytes to the backend - if the length
|
||||
* has not been reached, send nulls until it has.
|
||||
@@ -130,7 +131,7 @@ public class PG_Stream
|
||||
{
|
||||
Send(buf,0,siz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an exact array of bytes to the backend - if the length
|
||||
* has not been reached, send nulls until it has.
|
||||
@@ -143,7 +144,7 @@ public class PG_Stream
|
||||
public void Send(byte buf[], int off, int siz) throws IOException
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
pg_output.write(buf, off, ((buf.length-off) < siz ? (buf.length-off) : siz));
|
||||
if((buf.length-off) < siz)
|
||||
{
|
||||
@@ -153,7 +154,7 @@ public class PG_Stream
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a packet, prefixed with the packet's length
|
||||
* @param buf buffer to send
|
||||
@@ -164,7 +165,7 @@ public class PG_Stream
|
||||
SendInteger(buf.length+4,4);
|
||||
Send(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives a single character from the backend
|
||||
*
|
||||
@@ -174,7 +175,7 @@ public class PG_Stream
|
||||
public int ReceiveChar() throws SQLException
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
c = pg_input.read();
|
||||
@@ -184,7 +185,7 @@ public class PG_Stream
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives an integer from the backend
|
||||
*
|
||||
@@ -195,13 +196,13 @@ public class PG_Stream
|
||||
public int ReceiveInteger(int siz) throws SQLException
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0 ; i < siz ; i++)
|
||||
{
|
||||
int b = pg_input.read();
|
||||
|
||||
|
||||
if (b < 0)
|
||||
throw new PSQLException("postgresql.stream.eof");
|
||||
n = n | (b << (8 * i)) ;
|
||||
@@ -211,7 +212,7 @@ public class PG_Stream
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives an integer from the backend
|
||||
*
|
||||
@@ -222,13 +223,13 @@ public class PG_Stream
|
||||
public int ReceiveIntegerR(int siz) throws SQLException
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0 ; i < siz ; i++)
|
||||
{
|
||||
int b = pg_input.read();
|
||||
|
||||
|
||||
if (b < 0)
|
||||
throw new PSQLException("postgresql.stream.eof");
|
||||
n = b | (n << 8);
|
||||
@@ -270,24 +271,24 @@ public class PG_Stream
|
||||
byte[] rst = bytePoolDim1.allocByte(maxsiz);
|
||||
return ReceiveString(rst, maxsiz, encoding);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives a null-terminated string from the backend. Maximum of
|
||||
* maxsiz bytes - if we don't see a null, then we assume something
|
||||
* has gone wrong.
|
||||
*
|
||||
* @param rst byte array to read the String into. rst.length must
|
||||
* equal to or greater than maxsize.
|
||||
* @param rst byte array to read the String into. rst.length must
|
||||
* equal to or greater than maxsize.
|
||||
* @param maxsiz maximum length of string in bytes
|
||||
* @param encoding the charset encoding to use.
|
||||
* @return string from back end
|
||||
* @exception SQLException if an I/O error occurs
|
||||
*/
|
||||
public String ReceiveString(byte rst[], int maxsiz, String encoding)
|
||||
public String ReceiveString(byte rst[], int maxsiz, String encoding)
|
||||
throws SQLException
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
while (s < maxsiz)
|
||||
@@ -318,7 +319,7 @@ public class PG_Stream
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a tuple from the back end. A tuple is a two dimensional
|
||||
* array of bytes
|
||||
@@ -334,10 +335,10 @@ public class PG_Stream
|
||||
int i, bim = (nf + 7)/8;
|
||||
byte[] bitmask = Receive(bim);
|
||||
byte[][] answer = bytePoolDim2.allocByte(nf);
|
||||
|
||||
|
||||
int whichbit = 0x80;
|
||||
int whichbyte = 0;
|
||||
|
||||
|
||||
for (i = 0 ; i < nf ; ++i)
|
||||
{
|
||||
boolean isNull = ((bitmask[whichbyte] & whichbit) == 0);
|
||||
@@ -347,21 +348,21 @@ public class PG_Stream
|
||||
++whichbyte;
|
||||
whichbit = 0x80;
|
||||
}
|
||||
if (isNull)
|
||||
if (isNull)
|
||||
answer[i] = null;
|
||||
else
|
||||
{
|
||||
int len = ReceiveIntegerR(4);
|
||||
if (!bin)
|
||||
if (!bin)
|
||||
len -= 4;
|
||||
if (len < 0)
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
answer[i] = Receive(len);
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads in a given number of bytes from the backend
|
||||
*
|
||||
@@ -375,7 +376,7 @@ public class PG_Stream
|
||||
Receive(answer,0,siz);
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads in a given number of bytes from the backend
|
||||
*
|
||||
@@ -387,8 +388,8 @@ public class PG_Stream
|
||||
public void Receive(byte[] b,int off,int siz) throws SQLException
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
while (s < siz)
|
||||
{
|
||||
@@ -401,7 +402,7 @@ public class PG_Stream
|
||||
throw new PSQLException("postgresql.stream.ioerror",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This flushes any pending output to the backend. It is used primarily
|
||||
* by the Fastpath code.
|
||||
@@ -415,7 +416,7 @@ public class PG_Stream
|
||||
throw new PSQLException("postgresql.stream.flush",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the connection
|
||||
*
|
||||
@@ -430,151 +431,5 @@ public class PG_Stream
|
||||
connection.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocate all resources that has been associated with any previous
|
||||
* query.
|
||||
*/
|
||||
public void deallocate(){
|
||||
bytePoolDim1.deallocate();
|
||||
bytePoolDim2.deallocate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple and fast object pool implementation that can pool objects
|
||||
* of any type. This implementation is not thread safe, it is up to the users
|
||||
* of this class to assure thread safety.
|
||||
*/
|
||||
class ObjectPool {
|
||||
int cursize = 0;
|
||||
int maxsize = 16;
|
||||
Object arr[] = new Object[maxsize];
|
||||
|
||||
public void add(Object o){
|
||||
if(cursize >= maxsize){
|
||||
Object newarr[] = new Object[maxsize*2];
|
||||
System.arraycopy(arr, 0, newarr, 0, maxsize);
|
||||
maxsize = maxsize * 2;
|
||||
arr = newarr;
|
||||
}
|
||||
arr[cursize++] = o;
|
||||
}
|
||||
|
||||
public Object remove(){
|
||||
return arr[--cursize];
|
||||
}
|
||||
public boolean isEmpty(){
|
||||
return cursize == 0;
|
||||
}
|
||||
public int size(){
|
||||
return cursize;
|
||||
}
|
||||
public void addAll(ObjectPool pool){
|
||||
int srcsize = pool.size();
|
||||
if(srcsize == 0)
|
||||
return;
|
||||
int totalsize = srcsize + cursize;
|
||||
if(totalsize > maxsize){
|
||||
Object newarr[] = new Object[totalsize*2];
|
||||
System.arraycopy(arr, 0, newarr, 0, cursize);
|
||||
maxsize = maxsize = totalsize * 2;
|
||||
arr = newarr;
|
||||
}
|
||||
System.arraycopy(pool.arr, 0, arr, cursize, srcsize);
|
||||
cursize = totalsize;
|
||||
}
|
||||
public void clear(){
|
||||
cursize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple and efficient class to pool one dimensional byte arrays
|
||||
* of different sizes.
|
||||
*/
|
||||
class BytePoolDim1 {
|
||||
int maxsize = 256;
|
||||
ObjectPool notusemap[] = new ObjectPool[maxsize];
|
||||
ObjectPool inusemap[] = new ObjectPool[maxsize];
|
||||
byte binit[][] = new byte[maxsize][0];
|
||||
|
||||
public BytePoolDim1(){
|
||||
for(int i = 0; i < maxsize; i++){
|
||||
binit[i] = new byte[i];
|
||||
inusemap[i] = new ObjectPool();
|
||||
notusemap[i] = new ObjectPool();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] allocByte(int size){
|
||||
if(size > maxsize){
|
||||
return new byte[size];
|
||||
}
|
||||
|
||||
ObjectPool not_usel = notusemap[size];
|
||||
ObjectPool in_usel = inusemap[size];
|
||||
byte b[] = null;
|
||||
|
||||
if(!not_usel.isEmpty()) {
|
||||
Object o = not_usel.remove();
|
||||
b = (byte[]) o;
|
||||
} else
|
||||
b = new byte[size];
|
||||
in_usel.add(b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public void deallocate(){
|
||||
for(int i = 0; i < maxsize; i++){
|
||||
notusemap[i].addAll(inusemap[i]);
|
||||
inusemap[i].clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple and efficient class to pool two dimensional byte arrays
|
||||
* of different sizes.
|
||||
*/
|
||||
class BytePoolDim2 {
|
||||
int maxsize = 32;
|
||||
ObjectPool notusemap[] = new ObjectPool[maxsize];
|
||||
ObjectPool inusemap[] = new ObjectPool[maxsize];
|
||||
|
||||
public BytePoolDim2(){
|
||||
for(int i = 0; i < maxsize; i++){
|
||||
inusemap[i] = new ObjectPool();
|
||||
notusemap[i] = new ObjectPool();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[][] allocByte(int size){
|
||||
if(size > maxsize){
|
||||
return new byte[size][0];
|
||||
}
|
||||
ObjectPool not_usel = notusemap[size];
|
||||
ObjectPool in_usel = inusemap[size];
|
||||
|
||||
byte b[][] = null;
|
||||
|
||||
if(!not_usel.isEmpty()) {
|
||||
Object o = not_usel.remove();
|
||||
b = (byte[][]) o;
|
||||
} else
|
||||
b = new byte[size][0];
|
||||
in_usel.add(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
public void deallocate(){
|
||||
for(int i = 0; i < maxsize; i++){
|
||||
notusemap[i].addAll(inusemap[i]);
|
||||
inusemap[i].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
95
src/interfaces/jdbc/org/postgresql/core/BytePoolDim1.java
Normal file
95
src/interfaces/jdbc/org/postgresql/core/BytePoolDim1.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package org.postgresql.core;
|
||||
|
||||
/**
|
||||
* A simple and efficient class to pool one dimensional byte arrays
|
||||
* of different sizes.
|
||||
*/
|
||||
public class BytePoolDim1 {
|
||||
|
||||
/**
|
||||
* The maximum size of the array we manage.
|
||||
*/
|
||||
int maxsize = 256;
|
||||
/**
|
||||
* The pools not currently in use
|
||||
*/
|
||||
ObjectPool notusemap[] = new ObjectPool[maxsize+1];
|
||||
/**
|
||||
* The pools currently in use
|
||||
*/
|
||||
ObjectPool inusemap[] = new ObjectPool[maxsize+1];
|
||||
/**
|
||||
*
|
||||
*/
|
||||
byte binit[][] = new byte[maxsize][0];
|
||||
|
||||
/**
|
||||
* Construct a new pool
|
||||
*/
|
||||
public BytePoolDim1(){
|
||||
for(int i = 0; i <= maxsize; i++){
|
||||
binit[i] = new byte[i];
|
||||
inusemap[i] = new SimpleObjectPool();
|
||||
notusemap[i] = new SimpleObjectPool();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a byte[] of a specified size and put it in the pool. If it's
|
||||
* larger than maxsize then it is not pooled.
|
||||
* @return the byte[] allocated
|
||||
*/
|
||||
public byte[] allocByte(int size) {
|
||||
// for now until the bug can be removed
|
||||
return new byte[size];
|
||||
/*
|
||||
// Don't pool if >maxsize
|
||||
if(size > maxsize){
|
||||
return new byte[size];
|
||||
}
|
||||
|
||||
ObjectPool not_usel = notusemap[size];
|
||||
ObjectPool in_usel = inusemap[size];
|
||||
byte b[] = null;
|
||||
|
||||
// Fetch from the unused pool if available otherwise allocate a new
|
||||
// now array
|
||||
if(!not_usel.isEmpty()) {
|
||||
Object o = not_usel.remove();
|
||||
b = (byte[]) o;
|
||||
} else
|
||||
b = new byte[size];
|
||||
in_usel.add(b);
|
||||
|
||||
return b;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Release an array
|
||||
* @param b byte[] to release
|
||||
*/
|
||||
public void release(byte[] b) {
|
||||
// If it's larger than maxsize then we don't touch it
|
||||
if(b.length>maxsize)
|
||||
return;
|
||||
|
||||
ObjectPool not_usel = notusemap[b.length];
|
||||
ObjectPool in_usel = inusemap[b.length];
|
||||
|
||||
in_usel.remove(b);
|
||||
not_usel.add(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocate all
|
||||
* @deprecated Real bad things happen if this is called!
|
||||
*/
|
||||
public void deallocate() {
|
||||
//for(int i = 0; i <= maxsize; i++){
|
||||
// notusemap[i].addAll(inusemap[i]);
|
||||
// inusemap[i].clear();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
62
src/interfaces/jdbc/org/postgresql/core/BytePoolDim2.java
Normal file
62
src/interfaces/jdbc/org/postgresql/core/BytePoolDim2.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package org.postgresql.core;
|
||||
|
||||
public class BytePoolDim2 {
|
||||
int maxsize = 32;
|
||||
ObjectPool notusemap[] = new ObjectPool[maxsize+1];
|
||||
ObjectPool inusemap[] = new ObjectPool[maxsize+1];
|
||||
|
||||
public BytePoolDim2(){
|
||||
for(int i = 0; i <= maxsize; i++){
|
||||
inusemap[i] = new SimpleObjectPool();
|
||||
notusemap[i] = new SimpleObjectPool();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[][] allocByte(int size){
|
||||
// For now until the bug can be removed
|
||||
return new byte[size][0];
|
||||
/*
|
||||
if(size > maxsize){
|
||||
return new byte[size][0];
|
||||
}
|
||||
ObjectPool not_usel = notusemap[size];
|
||||
ObjectPool in_usel = inusemap[size];
|
||||
|
||||
byte b[][] = null;
|
||||
|
||||
if(!not_usel.isEmpty()) {
|
||||
Object o = not_usel.remove();
|
||||
b = (byte[][]) o;
|
||||
} else
|
||||
b = new byte[size][0];
|
||||
in_usel.add(b);
|
||||
return b;
|
||||
*/
|
||||
}
|
||||
|
||||
public void release(byte[][] b){
|
||||
if(b.length > maxsize){
|
||||
return;
|
||||
}
|
||||
ObjectPool not_usel = notusemap[b.length];
|
||||
ObjectPool in_usel = inusemap[b.length];
|
||||
|
||||
in_usel.remove(b);
|
||||
not_usel.add(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocate the object cache.
|
||||
* PM 17/01/01: Commented out this code as it blows away any hope of
|
||||
* multiple queries on the same connection. I'll redesign the allocation
|
||||
* code to use some form of Statement context, so the buffers are per
|
||||
* Statement and not per Connection/PG_Stream as it is now.
|
||||
*/
|
||||
public void deallocate(){
|
||||
//for(int i = 0; i <= maxsize; i++){
|
||||
// notusemap[i].addAll(inusemap[i]);
|
||||
// inusemap[i].clear();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
18
src/interfaces/jdbc/org/postgresql/core/MemoryPool.java
Normal file
18
src/interfaces/jdbc/org/postgresql/core/MemoryPool.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package org.postgresql.core;
|
||||
|
||||
/**
|
||||
* This interface defines the methods to access the memory pool classes.
|
||||
*/
|
||||
public interface MemoryPool {
|
||||
/**
|
||||
* Allocate an array from the pool
|
||||
* @return byte[] allocated
|
||||
*/
|
||||
public byte[] allocByte(int size);
|
||||
|
||||
/**
|
||||
* Frees an object back to the pool
|
||||
* @param o Object to release
|
||||
*/
|
||||
public void release(Object o);
|
||||
}
|
48
src/interfaces/jdbc/org/postgresql/core/ObjectPool.java
Normal file
48
src/interfaces/jdbc/org/postgresql/core/ObjectPool.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package org.postgresql.core;
|
||||
|
||||
/**
|
||||
* This interface defines methods needed to implement a simple object pool.
|
||||
* There are two known classes that implement this, one for jdk1.1 and the
|
||||
* other for jdk1.2+
|
||||
*/
|
||||
|
||||
public interface ObjectPool {
|
||||
/**
|
||||
* Adds an object to the pool
|
||||
* @param o Object to add
|
||||
*/
|
||||
public void add(Object o);
|
||||
|
||||
/**
|
||||
* Removes an object from the pool
|
||||
* @param o Object to remove
|
||||
*/
|
||||
public void remove(Object o);
|
||||
|
||||
/**
|
||||
* Removes the top object from the pool
|
||||
* @return Object from the top.
|
||||
*/
|
||||
public Object remove();
|
||||
|
||||
/**
|
||||
* @return true if the pool is empty
|
||||
*/
|
||||
public boolean isEmpty();
|
||||
|
||||
/**
|
||||
* @return the number of objects in the pool
|
||||
*/
|
||||
public int size();
|
||||
|
||||
/**
|
||||
* Adds all objects in one pool to this one
|
||||
* @param pool The pool to take the objects from
|
||||
*/
|
||||
public void addAll(ObjectPool pool);
|
||||
|
||||
/**
|
||||
* Clears the pool of all objects
|
||||
*/
|
||||
public void clear();
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
package org.postgresql.core;
|
||||
|
||||
/**
|
||||
* A simple and fast object pool implementation that can pool objects
|
||||
* of any type. This implementation is not thread safe, it is up to the users
|
||||
* of this class to assure thread safety.
|
||||
*/
|
||||
|
||||
public class SimpleObjectPool implements ObjectPool
|
||||
{
|
||||
// This was originally in PG_Stream but moved out to fix the major problem
|
||||
// where more than one query (usually all the time) overwrote the results
|
||||
// of another query.
|
||||
int cursize = 0;
|
||||
int maxsize = 16;
|
||||
Object arr[] = new Object[maxsize];
|
||||
|
||||
/**
|
||||
* Adds an object to the pool
|
||||
* @param o Object to add
|
||||
*/
|
||||
public void add(Object o)
|
||||
{
|
||||
if(cursize >= maxsize){
|
||||
Object newarr[] = new Object[maxsize*2];
|
||||
System.arraycopy(arr, 0, newarr, 0, maxsize);
|
||||
maxsize = maxsize * 2;
|
||||
arr = newarr;
|
||||
}
|
||||
arr[cursize++] = o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the top object from the pool
|
||||
* @return Object from the top.
|
||||
*/
|
||||
public Object remove(){
|
||||
return arr[--cursize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given object from the pool
|
||||
* @param o Object to remove
|
||||
*/
|
||||
public void remove(Object o) {
|
||||
int p=0;
|
||||
while(p<cursize && !arr[p].equals(o))
|
||||
p++;
|
||||
if(arr[p].equals(o)) {
|
||||
// This should be ok as there should be no overlap conflict
|
||||
System.arraycopy(arr,p+1,arr,p,cursize-p);
|
||||
cursize--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the pool is empty
|
||||
*/
|
||||
public boolean isEmpty(){
|
||||
return cursize == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of objects in the pool
|
||||
*/
|
||||
public int size(){
|
||||
return cursize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all objects in one pool to this one
|
||||
* @param pool The pool to take the objects from
|
||||
*/
|
||||
public void addAll(ObjectPool p){
|
||||
SimpleObjectPool pool = (SimpleObjectPool)p;
|
||||
|
||||
int srcsize = pool.size();
|
||||
if(srcsize == 0)
|
||||
return;
|
||||
int totalsize = srcsize + cursize;
|
||||
if(totalsize > maxsize){
|
||||
Object newarr[] = new Object[totalsize*2];
|
||||
System.arraycopy(arr, 0, newarr, 0, cursize);
|
||||
maxsize = maxsize = totalsize * 2;
|
||||
arr = newarr;
|
||||
}
|
||||
System.arraycopy(pool.arr, 0, arr, cursize, srcsize);
|
||||
cursize = totalsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the pool of all objects
|
||||
*/
|
||||
public void clear(){
|
||||
cursize = 0;
|
||||
}
|
||||
}
|
@@ -35,6 +35,8 @@ postgresql.geo.point:Conversion of point failed - {0}
|
||||
postgresql.jvm.version:The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding. If that fails, try forcing the version supplying it to the command line using the argument -Djava.version=1.1 or -Djava.version=1.2\nException thrown was {0}
|
||||
postgresql.lo.init:failed to initialise LargeObject API
|
||||
postgresql.money:conversion of money failed - {0}.
|
||||
postgresql.noupdate:This ResultSet is not updateable
|
||||
postgresql.psqlnotimp:The backend currently does not support this feature.
|
||||
postgresql.prep.is:InputStream as parameter not supported
|
||||
postgresql.prep.param:No value specified for parameter {0}.
|
||||
postgresql.prep.range:Parameter index out of range.
|
||||
|
@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
|
||||
* A Statement object is used for executing a static SQL statement and
|
||||
* obtaining the results produced by it.
|
||||
*
|
||||
* <p>Only one ResultSet per Statement can be open at any point in time.
|
||||
* <p>Only one ResultSet per Statement can be open at any point in time.
|
||||
* Therefore, if the reading of one ResultSet is interleaved with the
|
||||
* reading of another, each must have been generated by different
|
||||
* Statements. All statement execute methods implicitly close a
|
||||
@@ -29,7 +29,7 @@ public class Statement implements java.sql.Statement
|
||||
SQLWarning warnings = null; // The warnings chain.
|
||||
int timeout = 0; // The timeout for a query (not used)
|
||||
boolean escapeProcessing = true;// escape processing flag
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for a Statement. It simply sets the connection
|
||||
* that created us.
|
||||
@@ -81,8 +81,8 @@ public class Statement implements java.sql.Statement
|
||||
* for this to happen when it is automatically closed. The
|
||||
* close method provides this immediate release.
|
||||
*
|
||||
* <p><B>Note:</B> A Statement is automatically closed when it is
|
||||
* garbage collected. When a Statement is closed, its current
|
||||
* <p><B>Note:</B> A Statement is automatically closed when it is
|
||||
* garbage collected. When a Statement is closed, its current
|
||||
* ResultSet, if one exists, is also closed.
|
||||
*
|
||||
* @exception SQLException if a database access error occurs (why?)
|
||||
@@ -146,7 +146,7 @@ public class Statement implements java.sql.Statement
|
||||
|
||||
/**
|
||||
* If escape scanning is on (the default), the driver will do escape
|
||||
* substitution before sending the SQL to the database.
|
||||
* substitution before sending the SQL to the database.
|
||||
*
|
||||
* @param enable true to enable; false to disable
|
||||
* @exception SQLException if a database access error occurs
|
||||
@@ -183,7 +183,7 @@ public class Statement implements java.sql.Statement
|
||||
/**
|
||||
* Cancel can be used by one thread to cancel a statement that
|
||||
* is being executed by another thread. However, PostgreSQL is
|
||||
* a sync. sort of thing, so this really has no meaning - we
|
||||
* a sync. sort of thing, so this really has no meaning - we
|
||||
* define it as a no-op (i.e. you can't cancel, but there is no
|
||||
* error if you try.)
|
||||
*
|
||||
@@ -256,7 +256,7 @@ public class Statement implements java.sql.Statement
|
||||
/**
|
||||
* Execute a SQL statement that may return multiple results. We
|
||||
* don't have to worry about this since we do not support multiple
|
||||
* ResultSets. You can use getResultSet or getUpdateCount to
|
||||
* ResultSets. You can use getResultSet or getUpdateCount to
|
||||
* retrieve the result.
|
||||
*
|
||||
* @param sql any SQL statement
|
||||
@@ -266,8 +266,10 @@ public class Statement implements java.sql.Statement
|
||||
*/
|
||||
public boolean execute(String sql) throws SQLException
|
||||
{
|
||||
result = connection.ExecSQL(sql);
|
||||
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
|
||||
if(escapeProcessing)
|
||||
sql=connection.EscapeSQL(sql);
|
||||
result = connection.ExecSQL(sql);
|
||||
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,7 +311,7 @@ public class Statement implements java.sql.Statement
|
||||
result = ((org.postgresql.ResultSet)result).getNext();
|
||||
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the status message from the current Result.<p>
|
||||
* This is used internally by the driver.
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -10,10 +10,10 @@ import java.util.*;
|
||||
public class PSQLException extends SQLException
|
||||
{
|
||||
private String message;
|
||||
|
||||
|
||||
// Cache for future errors
|
||||
static ResourceBundle bundle;
|
||||
|
||||
|
||||
/**
|
||||
* This provides the same functionality to SQLException
|
||||
* @param error Error string
|
||||
@@ -22,7 +22,7 @@ public class PSQLException extends SQLException
|
||||
super();
|
||||
translate(error,null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A more generic entry point.
|
||||
* @param error Error string or standard message id
|
||||
@@ -33,7 +33,7 @@ public class PSQLException extends SQLException
|
||||
//super();
|
||||
translate(error,args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper version for 1 arg
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public class PSQLException extends SQLException
|
||||
argv[0] = arg;
|
||||
translate(error,argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper version for 2 args
|
||||
*/
|
||||
@@ -56,7 +56,7 @@ public class PSQLException extends SQLException
|
||||
argv[1] = arg2;
|
||||
translate(error,argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This does the actual translation
|
||||
*/
|
||||
@@ -70,7 +70,7 @@ public class PSQLException extends SQLException
|
||||
message = id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bundle != null) {
|
||||
// Now look up a localized message. If one is not found, then use
|
||||
// the supplied message instead.
|
||||
@@ -81,13 +81,13 @@ public class PSQLException extends SQLException
|
||||
message = id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Expand any arguments
|
||||
if(args!=null)
|
||||
if(args!=null && message != null)
|
||||
message = MessageFormat.format(message,args);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overides Throwable
|
||||
*/
|
||||
@@ -95,7 +95,7 @@ public class PSQLException extends SQLException
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overides Throwable
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ public class PSQLException extends SQLException
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overides Object
|
||||
*/
|
||||
@@ -111,5 +111,5 @@ public class PSQLException extends SQLException
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user