diff options
author | Bruce Momjian | 2001-02-13 16:18:15 +0000 |
---|---|---|
committer | Bruce Momjian | 2001-02-13 16:18:15 +0000 |
commit | 2410963e8cc6272022c0a556a3fd3c9a3bd617e9 (patch) | |
tree | 7bcdea9af505c1c94c0bcb4a46e6c877378f01e8 /src/interfaces/jdbc/postgresql/Connection.java | |
parent | 934c5b841edb9fda9ef3d25196c3adaef6cdb935 (diff) |
Remove postgresql jdbc files, per Peter.
Diffstat (limited to 'src/interfaces/jdbc/postgresql/Connection.java')
-rw-r--r-- | src/interfaces/jdbc/postgresql/Connection.java | 744 |
1 files changed, 0 insertions, 744 deletions
diff --git a/src/interfaces/jdbc/postgresql/Connection.java b/src/interfaces/jdbc/postgresql/Connection.java deleted file mode 100644 index 4d95a585f73..00000000000 --- a/src/interfaces/jdbc/postgresql/Connection.java +++ /dev/null @@ -1,744 +0,0 @@ -package postgresql; - -import java.io.*; -import java.net.*; -import java.sql.*; -import java.util.*; -import postgresql.Field; -import postgresql.fastpath.*; -import postgresql.largeobject.*; -import postgresql.util.*; - -/** - * $Id: Connection.java,v 1.20 1999/09/15 20:39:50 peter Exp $ - * - * This abstract class is used by postgresql.Driver to open either the JDBC1 or - * JDBC2 versions of the Connection class. - * - */ -public abstract class Connection -{ - // This is the network stream associated with this connection - public PG_Stream pg_stream; - - // This is set by 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; - private String PG_PASSWORD; - private String PG_DATABASE; - private boolean PG_STATUS; - - public boolean CONNECTION_OK = true; - public boolean CONNECTION_BAD = false; - - public boolean autoCommit = true; - public boolean readOnly = false; - - public Driver this_driver; - private String this_url; - private String cursor = null; // The positioned update cursor name - - // These are new for v6.3, they determine the current protocol versions - // supported by this version of the driver. They are defined in - // src/include/libpq/pqcomm.h - protected static final int PG_PROTOCOL_LATEST_MAJOR = 2; - protected static final int PG_PROTOCOL_LATEST_MINOR = 0; - private static final int SM_DATABASE = 64; - private static final int SM_USER = 32; - 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 is called by Class.forName() from within postgresql.Driver - */ - public Connection() - { - } - - /** - * This method actually opens the connection. It is called by Driver. - * - * @param host the hostname of the database back end - * @param port the port number of the postmaster process - * @param info a Properties[] thing of the user and password - * @param database the database to connect to - * @param u the URL of the connection - * @param d the Driver instantation of the connection - * @return a valid connection profile - * @exception SQLException if a database access error occurs - */ - protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException - { - // Throw an exception if the user or password properties are missing - // This occasionally occurs when the client uses the properties version - // of getConnection(), and is a common question on the email lists - if(info.getProperty("user")==null) - throw new PSQLException("postgresql.con.user"); - if(info.getProperty("password")==null) - throw new PSQLException("postgresql.con.pass"); - - this_driver = d; - this_url = new String(url); - PG_DATABASE = new String(database); - PG_PASSWORD = new String(info.getProperty("password")); - PG_USER = new String(info.getProperty("user")); - PG_PORT = port; - PG_HOST = new String(host); - PG_STATUS = CONNECTION_BAD; - - // Now make the initial connection - try - { - pg_stream = new PG_Stream(host, port); - } catch (ConnectException cex) { - // Added by Peter Mount <[email protected]> - // ConnectException is thrown when the connection cannot be made. - // we trap this an return a more meaningful message for the end user - throw new PSQLException ("postgresql.con.refused"); - } catch (IOException e) { - throw new PSQLException ("postgresql.con.failed",e); - } - - // Now we need to construct and send a startup packet - try - { - // Ver 6.3 code - pg_stream.SendInteger(4+4+SM_DATABASE+SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY,4); - 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 - do { - int beresp = pg_stream.ReceiveChar(); - switch(beresp) - { - case 'E': - // An error occured, so pass the error message to the - // user. - // - // The most common one to be thrown here is: - // "User authentication failed" - // - throw new SQLException(pg_stream.ReceiveString(4096)); - - 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]; - rst[0] = (byte)pg_stream.ReceiveChar(); - rst[1] = (byte)pg_stream.ReceiveChar(); - 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); - pg_stream.Send(PG_PASSWORD.getBytes()); - pg_stream.SendInteger(0,1); - pg_stream.flush(); - break; - - case AUTH_REQ_CRYPT: - DriverManager.println("postgresql: CRYPT"); - String crypted = UnixCrypt.crypt(salt,PG_PASSWORD); - pg_stream.SendInteger(5+crypted.length(),4); - pg_stream.Send(crypted.getBytes()); - 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(); - switch(beresp) { - case 'K': - pid = pg_stream.ReceiveInteger(4); - ckey = pg_stream.ReceiveInteger(4); - break; - case 'E': - case 'N': - throw new SQLException(pg_stream.ReceiveString(4096)); - default: - throw new PSQLException("postgresql.con.setup"); - } - - // Expect ReadyForQuery packet - beresp = pg_stream.ReceiveChar(); - switch(beresp) { - case 'Z': - break; - case 'E': - case 'N': - throw new SQLException(pg_stream.ReceiveString(4096)); - default: - throw new PSQLException("postgresql.con.setup"); - } - - // Originally we issued a SHOW DATESTYLE statement to find the databases default - // datestyle. However, this caused some problems with timestamps, so in 6.5, we - // went the way of ODBC, and set the connection to ISO. - // - // This may cause some clients to break when they assume anything other than ISO, - // but then - they should be using the proper methods ;-) - // - // - firstWarning = null; - - ExecSQL("set datestyle to 'ISO'"); - - // 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 - */ - 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. - // - // This is generated by the SQL "show datestyle" - //if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) { - //// 13 is the length off "DateStyle is " - //msg = msg.substring(msg.indexOf("DateStyle is ")+13); - // - //for(int i=0;i<dateStyles.length;i+=2) - //if(msg.startsWith(dateStyles[i])) - //currentDateStyle=i+1; // this is the index of the format - //} - } - - /** - * Send a query to the backend. Returns one of the ResultSet - * objects. - * - * <B>Note:</B> there does not seem to be any method currently - * in existance to return the update count. - * - * @param sql the SQL statement to be executed - * @return a ResultSet holding the results - * @exception SQLException if a database error occurs - */ - public java.sql.ResultSet ExecSQL(String sql) throws SQLException - { - // added Oct 7 1998 to give us thread safety. - synchronized(pg_stream) { - - Field[] fields = null; - Vector tuples = new Vector(); - byte[] buf = new byte[sql.length()]; - int fqp = 0; - boolean hfr = false; - String recv_status = null, msg; - int update_count = 1; - SQLException final_error = null; - - if (sql.length() > 8192) - throw new PSQLException("postgresql.con.toolong",sql); - try - { - pg_stream.SendChar('Q'); - buf = sql.getBytes(); - pg_stream.Send(buf); - pg_stream.SendChar(0); - pg_stream.flush(); - } 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 - pid = pg_stream.ReceiveInteger(4); - msg = pg_stream.ReceiveString(8192); - break; - case 'B': // Binary Data Transfer - if (fields == null) - throw new PSQLException("postgresql.con.tuple"); - tup = pg_stream.ReceiveTuple(fields.length, true); - // This implements Statement.setMaxRows() - if(maxrows==0 || tuples.size()<maxrows) - tuples.addElement(tup); - break; - case 'C': // Command Status - recv_status = pg_stream.ReceiveString(8192); - - // Now handle the update count correctly. - if(recv_status.startsWith("INSERT") || recv_status.startsWith("UPDATE")) { - try { - update_count = Integer.parseInt(recv_status.substring(1+recv_status.lastIndexOf(' '))); - } catch(NumberFormatException nfe) { - throw new PSQLException("postgresql.con.fathom",recv_status); - } - } - if (fields != null) - hfr = true; - else - { - try - { - pg_stream.SendChar('Q'); - pg_stream.SendChar(' '); - pg_stream.SendChar(0); - pg_stream.flush(); - } catch (IOException e) { - throw new PSQLException("postgresql.con.ioerror",e); - } - fqp++; - } - break; - case 'D': // Text Data Transfer - if (fields == null) - throw new PSQLException("postgresql.con.tuple"); - tup = pg_stream.ReceiveTuple(fields.length, false); - // This implements Statement.setMaxRows() - if(maxrows==0 || tuples.size()<maxrows) - tuples.addElement(tup); - break; - case 'E': // Error Message - msg = pg_stream.ReceiveString(4096); - final_error = new SQLException(msg); - hfr = true; - 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 - addWarning(pg_stream.ReceiveString(4096)); - break; - case 'P': // Portal Name - String pname = pg_stream.ReceiveString(8192); - break; - case 'T': // MetaData Field Description - if (fields != null) - throw new PSQLException("postgresql.con.multres"); - fields = ReceiveFields(); - break; - case 'Z': // backend ready for query, ignore for now :-) - break; - default: - throw new PSQLException("postgresql.con.type",new Character((char)c)); - } - } - if (final_error != null) - throw final_error; - - return getResultSet(this, fields, tuples, recv_status, update_count); - } - } - - /** - * Receive the field descriptions from the back end - * - * @return an array of the Field object describing the fields - * @exception SQLException if a database error occurs - */ - private Field[] ReceiveFields() throws SQLException - { - int nf = pg_stream.ReceiveIntegerR(2), i; - Field[] fields = new Field[nf]; - - for (i = 0 ; i < nf ; ++i) - { - String typname = pg_stream.ReceiveString(8192); - int typid = pg_stream.ReceiveIntegerR(4); - int typlen = pg_stream.ReceiveIntegerR(2); - int typmod = pg_stream.ReceiveIntegerR(4); - fields[i] = new Field(this, typname, typid, typlen, typmod); - } - 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 - * using a positioned update/delete statement that references the - * cursor name. - * - * We support one cursor per connection. - * - * setCursorName sets the cursor name. - * - * @param cursor the cursor name - * @exception SQLException if a database access error occurs - */ - public void setCursorName(String cursor) throws SQLException - { - this.cursor = cursor; - } - - /** - * getCursorName gets the cursor name. - * - * @return the current cursor name - * @exception SQLException if a database access error occurs - */ - public String getCursorName() throws SQLException - { - return cursor; - } - - /** - * We are required to bring back certain information by - * the DatabaseMetaData class. These functions do that. - * - * Method getURL() brings back the URL (good job we saved it) - * - * @return the url - * @exception SQLException just in case... - */ - public String getURL() throws SQLException - { - return this_url; - } - - /** - * Method getUserName() brings back the User Name (again, we - * saved it) - * - * @return the user name - * @exception SQLException just in case... - */ - public String getUserName() throws SQLException - { - return PG_USER; - } - - /** - * This returns the Fastpath API for the current connection. - * - * <p><b>NOTE:</b> This is not part of JDBC, but allows access to - * functions on the postgresql backend itself. - * - * <p>It is primarily used by the LargeObject API - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * import postgresql.fastpath.*; - * ... - * Fastpath fp = ((postgresql.Connection)myconn).getFastpathAPI(); - * </pre> - * - * <p>where myconn is an open Connection to postgresql. - * - * @return Fastpath object allowing access to functions on the postgresql - * backend. - * @exception SQLException by Fastpath when initialising for first time - */ - public Fastpath getFastpathAPI() throws SQLException - { - if(fastpath==null) - fastpath = new Fastpath(this,pg_stream); - return fastpath; - } - - // This holds a reference to the Fastpath API if already open - private Fastpath fastpath = null; - - /** - * This returns the LargeObject API for the current connection. - * - * <p><b>NOTE:</b> This is not part of JDBC, but allows access to - * functions on the postgresql backend itself. - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * import postgresql.largeobject.*; - * ... - * LargeObjectManager lo = ((postgresql.Connection)myconn).getLargeObjectAPI(); - * </pre> - * - * <p>where myconn is an open Connection to postgresql. - * - * @return LargeObject object that implements the API - * @exception SQLException by LargeObject when initialising for first time - */ - public LargeObjectManager getLargeObjectAPI() throws SQLException - { - if(largeobject==null) - largeobject = new LargeObjectManager(this); - return largeobject; - } - - // This holds a reference to the LargeObject API if already open - private LargeObjectManager largeobject = null; - - /** - * This method is used internally to return an object based around - * postgresql's more unique data types. - * - * <p>It uses an internal Hashtable to get the handling class. If the - * type is not supported, then an instance of postgresql.util.PGobject - * is returned. - * - * You can use the getValue() or setValue() methods to handle the returned - * object. Custom objects can have their own methods. - * - * In 6.4, this is extended to use the postgresql.util.Serialize class to - * allow the Serialization of Java Objects into the database without using - * Blobs. Refer to that class for details on how this new feature works. - * - * @return PGobject for this type, and set to value - * @exception SQLException if value is not correct for this type - * @see postgresql.util.Serialize - */ - public Object getObject(String type,String value) throws SQLException - { - try { - Object o = objectTypes.get(type); - - // If o is null, then the type is unknown, so check to see if type - // is an actual table name. If it does, see if a Class is known that - // can handle it - if(o == null) { - Serialize ser = new Serialize(this,type); - objectTypes.put(type,ser); - return ser.fetch(Integer.parseInt(value)); - } - - // If o is not null, and it is a String, then its a class name that - // extends PGobject. - // - // This is used to implement the postgresql unique types (like lseg, - // point, etc). - if(o instanceof String) { - // 6.3 style extending PG_Object - PGobject obj = null; - obj = (PGobject)(Class.forName((String)o).newInstance()); - obj.setType(type); - obj.setValue(value); - return (Object)obj; - } else { - // If it's an object, it should be an instance of our Serialize class - // If so, then call it's fetch method. - if(o instanceof Serialize) - return ((Serialize)o).fetch(Integer.parseInt(value)); - } - } catch(SQLException sx) { - // rethrow the exception. Done because we capture any others next - sx.fillInStackTrace(); - throw sx; - } catch(Exception ex) { - throw new PSQLException("postgresql.con.creobj",type,ex); - } - - // should never be reached - return null; - } - - /** - * This stores an object into the database. - * @param o Object to store - * @return OID of the new rectord - * @exception SQLException if value is not correct for this type - * @see postgresql.util.Serialize - */ - public int putObject(Object o) throws SQLException - { - try { - String type = o.getClass().getName(); - Object x = objectTypes.get(type); - - // If x is null, then the type is unknown, so check to see if type - // is an actual table name. If it does, see if a Class is known that - // can handle it - if(x == null) { - Serialize ser = new Serialize(this,type); - objectTypes.put(type,ser); - return ser.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(); - throw sx; - } catch(Exception ex) { - throw new PSQLException("postgresql.con.strobjex",ex); - } - } - - /** - * This allows client code to add a handler for one of postgresql's - * more unique data types. - * - * <p><b>NOTE:</b> This is not part of JDBC, but an extension. - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * ... - * ((postgresql.Connection)myconn).addDataType("mytype","my.class.name"); - * ... - * </pre> - * - * <p>where myconn is an open Connection to postgresql. - * - * <p>The handling class must extend postgresql.util.PGobject - * - * @see postgresql.util.PGobject - */ - public void addDataType(String type,String name) - { - objectTypes.put(type,name); - } - - // This holds the available types - private Hashtable objectTypes = new Hashtable(); - - // This array contains the types that are supported as standard. - // - // The first entry is the types name on the database, the second - // the full class name of the handling class. - // - private static final String defaultObjectTypes[][] = { - {"box", "postgresql.geometric.PGbox"}, - {"circle", "postgresql.geometric.PGcircle"}, - {"line", "postgresql.geometric.PGline"}, - {"lseg", "postgresql.geometric.PGlseg"}, - {"path", "postgresql.geometric.PGpath"}, - {"point", "postgresql.geometric.PGpoint"}, - {"polygon", "postgresql.geometric.PGpolygon"}, - {"money", "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(postgresql.Connection conn, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException; - - public abstract void close() throws SQLException; - - /** - * Overides finalize(). If called, it closes the connection. - * - * This was done at the request of Rachel Greenham - * <[email protected]> who hit a problem where multiple - * clients didn't close the connection, and once a fortnight enough - * clients were open to kill the postgres server. - */ - public void finalize() throws Throwable - { - close(); - } -} |