From 9142ca2faf25ad6d3b96bde65ed687612de51d97 Mon Sep 17 00:00:00 2001 From: Peter Mount Date: Mon, 5 Mar 2001 09:17:43 +0000 Subject: [PATCH] Minor fixes... --- .../jdbc/org/postgresql/Driver.java.in | 4 + .../org/postgresql/core/ConnectionHook.java | 95 +++++++++++++++++++ .../postgresql/jdbc2/CallableStatement.java | 81 ++++++++-------- 3 files changed, 140 insertions(+), 40 deletions(-) create mode 100644 src/interfaces/jdbc/org/postgresql/core/ConnectionHook.java diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in index 3b67ff577e..d7452c6752 100644 --- a/src/interfaces/jdbc/org/postgresql/Driver.java.in +++ b/src/interfaces/jdbc/org/postgresql/Driver.java.in @@ -35,6 +35,10 @@ public class Driver implements java.sql.Driver // my early jdbc work did - and that was based on other examples). // Placing it here, means that the driver is registered once only. java.sql.DriverManager.registerDriver(new Driver()); + + // New in 7.1 - register ourselves with the JVM - JDK1.3+ only + @JDK1.3ONLY@org.postgresql.core.ConnectionHook.init(); + } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/interfaces/jdbc/org/postgresql/core/ConnectionHook.java b/src/interfaces/jdbc/org/postgresql/core/ConnectionHook.java new file mode 100644 index 0000000000..71555b012f --- /dev/null +++ b/src/interfaces/jdbc/org/postgresql/core/ConnectionHook.java @@ -0,0 +1,95 @@ +package org.postgresql.core; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import org.postgresql.Connection; + +/** + * ConnectionHook keeps track of all open Connections. It's used only in + * Java2 (JDK1.3+) VM's, and it's purpose is to close all connections cleanly + * when the VM terminates. + * + * Important: This only works for JDK1.3 or later as it uses methods new to + * that JDK. + * + * This is a singleton object ;-) + * + * How it works: This is an initiated but un-started Thread. When it's created, + * it registers it'self with the Runtime.addShutdownHook() method. + * + * When a Connection is made, two static methods in org.postgresql.Driver are + * called. For pre JDK1.3 these are noops, but for 1.3+ ANT adds calls to + * methods in this class, which add/remove it from an ArrayList. + * + * Now when the VM terminates it starts this thread, which then Itterates + * through the ArrayList and closes each Connection. + * + * Obviously this doesn't trap things like Runtime.halt() or SIGKILL etc, but + * this captures 99% of all other forms of VM termination. + * + */ + +public class ConnectionHook implements Runnable +{ + /** + * This ensures that the hook is created and the system is notified of it. + * + * Important: We have to use an instance, as we have to pass a reference to + * the VM. + */ + private static final ConnectionHook SINGLETON = new ConnectionHook(); + + /** + * The currently open connections + */ + private ArrayList cons = new ArrayList(); + + /** + * Constructor. This is private because we are a singleton. Here we set + * our selves up, and then register with the VM. + */ + private ConnectionHook() { + super(); + Runtime.getRuntime().addShutdownHook(new Thread(this)); + } + + /** + * Called by Driver, this simply forces us to be created. + */ + public static final void init() { + } + + /** + * This is used by org.postgresql.Connection to register itself. Because it's + * called internally, we don't bother with checking to see if it's already + * present (performance boost). + */ + public static final void open(Connection con) { + SINGLETON.cons.add(con); + } + + /** + * This is used by org.postgresql.Connection to remove itself. + */ + public static final void close(Connection con) { + SINGLETON.cons.remove(con); + } + + /** + * This is called by the VM when it terminates. It itterates through the list + * of connections and implicitly closes them. + */ + public void run() { + Iterator i = cons.iterator(); + while(i.hasNext()) { + Connection c = (Connection) i.next(); + try { + c.close(); + } catch(SQLException e) { + // Ignore as at this point we are dying anyhow ;-) + } + } + } + +} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java index 1ea33231a9..fc2c60f29f 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java @@ -19,8 +19,8 @@ import java.math.*; * Parameters are refered to sequentially, by number. The first parameter * is 1. * - * {?= call [,, ...]} - * {call [,, ...]} + * {?= call [,, ...]} + * {call [,, ...]} * * *

IN parameter values are set using the set methods inherited from @@ -32,8 +32,8 @@ import java.math.*; * Multiple ResultSets are handled using operations inherited from * Statement. * - *

For maximum portability, a call's ResultSets and update counts should - * be processed prior to getting the values of output parameters. + *

For maximum portability, a call's ResultSets and update counts should + * be processed prior to getting the values of output parameters. * * @see Connection#prepareCall * @see ResultSet @@ -48,7 +48,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im { super(c,q); } - + /** * Before executing a stored procedure call you must explicitly * call registerOutParameter to register the java.sql.Type of each @@ -66,7 +66,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im */ public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException { } - + /** * You must also specify the scale for numeric/decimal types: * @@ -84,12 +84,12 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im int scale) throws SQLException { } - + // Old api? //public boolean isNull(int parameterIndex) throws SQLException { //return true; //} - + /** * An OUT parameter may have the value of SQL NULL; wasNull * reports whether the last value read has this special value. @@ -103,12 +103,12 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im // check to see if the last access threw an exception return false; // fake it for now } - + // Old api? //public String getChar(int parameterIndex) throws SQLException { //return null; //} - + /** * Get the value of a CHAR, VARCHAR, or LONGVARCHAR parameter as a * Java String. @@ -123,11 +123,11 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im //public String getVarChar(int parameterIndex) throws SQLException { // return null; //} - + //public String getLongVarChar(int parameterIndex) throws SQLException { //return null; //} - + /** * Get the value of a BIT parameter as a Java boolean. * @@ -138,7 +138,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im public boolean getBoolean(int parameterIndex) throws SQLException { return false; } - + /** * Get the value of a TINYINT parameter as a Java byte. * @@ -149,7 +149,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im public byte getByte(int parameterIndex) throws SQLException { return 0; } - + /** * Get the value of a SMALLINT parameter as a Java short. * @@ -160,7 +160,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im public short getShort(int parameterIndex) throws SQLException { return 0; } - + /** * Get the value of an INTEGER parameter as a Java int. * @@ -171,7 +171,7 @@ public class CallableStatement extends org.postgresql.jdbc2.PreparedStatement im public int getInt(int parameterIndex) throws SQLException { return 0; } - + /** * Get the value of a BIGINT parameter as a Java long. * @@ -182,7 +182,7 @@ public int getInt(int parameterIndex) throws SQLException { public long getLong(int parameterIndex) throws SQLException { return 0; } - + /** * Get the value of a FLOAT parameter as a Java float. * @@ -193,7 +193,7 @@ public int getInt(int parameterIndex) throws SQLException { public float getFloat(int parameterIndex) throws SQLException { return (float) 0.0; } - + /** * Get the value of a DOUBLE parameter as a Java double. * @@ -204,7 +204,7 @@ public int getInt(int parameterIndex) throws SQLException { public double getDouble(int parameterIndex) throws SQLException { return 0.0; } - + /** * Get the value of a NUMERIC parameter as a java.math.BigDecimal * object. @@ -214,12 +214,13 @@ public int getInt(int parameterIndex) throws SQLException { * desired number of digits to the right of the decimal point * @return the parameter value; if the value is SQL NULL, the result is null * @exception SQLException if a database-access error occurs. + * @deprecated in Java2.0 */ public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { return null; } - + /** * Get the value of a SQL BINARY or VARBINARY parameter as a Java * byte[] @@ -231,12 +232,12 @@ public int getInt(int parameterIndex) throws SQLException { public byte[] getBytes(int parameterIndex) throws SQLException { return null; } - + // New API (JPM) (getLongVarBinary) //public byte[] getBinaryStream(int parameterIndex) throws SQLException { //return null; //} - + /** * Get the value of a SQL DATE parameter as a java.sql.Date object * @@ -247,7 +248,7 @@ public int getInt(int parameterIndex) throws SQLException { public java.sql.Date getDate(int parameterIndex) throws SQLException { return null; } - + /** * Get the value of a SQL TIME parameter as a java.sql.Time object. * @@ -258,7 +259,7 @@ public int getInt(int parameterIndex) throws SQLException { public java.sql.Time getTime(int parameterIndex) throws SQLException { return null; } - + /** * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp object. * @@ -270,16 +271,16 @@ public int getInt(int parameterIndex) throws SQLException { throws SQLException { return null; } - + //---------------------------------------------------------------------- // Advanced features: - - // You can obtain a ParameterMetaData object to get information + + // You can obtain a ParameterMetaData object to get information // about the parameters to this CallableStatement. //public DatabaseMetaData getMetaData() { //return null; //} - + // getObject returns a Java object for the parameter. // See the JDBC spec's "Dynamic Programming" chapter for details. /** @@ -304,58 +305,58 @@ public int getInt(int parameterIndex) throws SQLException { throws SQLException { return null; } - + // ** JDBC 2 Extensions ** - + public Array getArray(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public java.math.BigDecimal getBigDecimal(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Blob getBlob(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Clob getClob(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Object getObject(int i,java.util.Map map) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Ref getRef(int i) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public java.sql.Date getDate(int i,java.util.Calendar cal) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Time getTime(int i,java.util.Calendar cal) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public Timestamp getTimestamp(int i,java.util.Calendar cal) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + public void registerOutParameter(int parameterIndex, int sqlType,String typeName) throws SQLException { throw org.postgresql.Driver.notImplemented(); } - + }