1 package org.postgresql.jdbc2;
3 // IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
4 // If you make any modifications to this file, you must make sure that the
5 // changes are also made (if relevent) to the related JDBC 1 class in the
6 // org.postgresql.jdbc1 package.
10 import java.lang.reflect.*;
14 import org.postgresql.Field;
15 import org.postgresql.fastpath.*;
16 import org.postgresql.largeobject.*;
17 import org.postgresql.util.*;
20 * $Id: Connection.java,v 1.6 2001/01/31 08:26:02 peter Exp $
22 * A Connection represents a session with a specific database. Within the
23 * context of a Connection, SQL statements are executed and results are
26 * <P>A Connection's database is able to provide information describing
27 * its tables, its supported SQL grammar, its stored procedures, the
28 * capabilities of this connection, etc. This information is obtained
29 * with the getMetaData method.
31 * <p><B>Note:</B> By default, the Connection automatically commits changes
32 * after executing each statement. If auto-commit has been disabled, an
33 * explicit commit must be done or database changes will not be saved.
35 * @see java.sql.Connection
37 public class Connection extends org.postgresql.Connection implements java.sql.Connection
39 // This is a cache of the DatabaseMetaData instance for this connection
40 protected DatabaseMetaData metadata;
42 protected java.util.Map typemap;
45 * SQL statements without parameters are normally executed using
46 * Statement objects. If the same SQL statement is executed many
47 * times, it is more efficient to use a PreparedStatement
49 * @return a new Statement object
50 * @exception SQLException passed through from the constructor
52 public java.sql.Statement createStatement() throws SQLException
54 // The spec says default of TYPE_FORWARD_ONLY but everyone is used to
55 // using TYPE_SCROLL_INSENSITIVE
56 return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
60 * SQL statements without parameters are normally executed using
61 * Statement objects. If the same SQL statement is executed many
62 * times, it is more efficient to use a PreparedStatement
64 * @param resultSetType to use
65 * @param resultSetCuncurrency to use
66 * @return a new Statement object
67 * @exception SQLException passed through from the constructor
69 public java.sql.Statement createStatement(int resultSetType,int resultSetConcurrency) throws SQLException
71 Statement s = new Statement(this);
72 s.setResultSetType(resultSetType);
73 s.setResultSetConcurrency(resultSetConcurrency);
79 * A SQL statement with or without IN parameters can be pre-compiled
80 * and stored in a PreparedStatement object. This object can then
81 * be used to efficiently execute this statement multiple times.
83 * <B>Note:</B> This method is optimized for handling parametric
84 * SQL statements that benefit from precompilation if the drivers
85 * supports precompilation. PostgreSQL does not support precompilation.
86 * In this case, the statement is not sent to the database until the
87 * PreparedStatement is executed. This has no direct effect on users;
88 * however it does affect which method throws certain SQLExceptions
90 * @param sql a SQL statement that may contain one or more '?' IN
91 * parameter placeholders
92 * @return a new PreparedStatement object containing the pre-compiled
94 * @exception SQLException if a database access error occurs.
96 public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException
98 return prepareStatement(sql,java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
101 public java.sql.PreparedStatement prepareStatement(String sql,int resultSetType,int resultSetConcurrency) throws SQLException
103 PreparedStatement s = new PreparedStatement(this,sql);
104 s.setResultSetType(resultSetType);
105 s.setResultSetConcurrency(resultSetConcurrency);
110 * A SQL stored procedure call statement is handled by creating a
111 * CallableStatement for it. The CallableStatement provides methods
112 * for setting up its IN and OUT parameters and methods for executing
115 * <B>Note:</B> This method is optimised for handling stored procedure
116 * call statements. Some drivers may send the call statement to the
117 * database when the prepareCall is done; others may wait until the
118 * CallableStatement is executed. This has no direct effect on users;
119 * however, it does affect which method throws certain SQLExceptions
121 * @param sql a SQL statement that may contain one or more '?' parameter
122 * placeholders. Typically this statement is a JDBC function call
124 * @return a new CallableStatement object containing the pre-compiled
126 * @exception SQLException if a database access error occurs
128 public java.sql.CallableStatement prepareCall(String sql) throws SQLException
130 return prepareCall(sql,java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
133 public java.sql.CallableStatement prepareCall(String sql,int resultSetType,int resultSetConcurrency) throws SQLException
135 throw new PSQLException("postgresql.con.call");
136 //CallableStatement s = new CallableStatement(this,sql);
137 //s.setResultSetType(resultSetType);
138 //s.setResultSetConcurrency(resultSetConcurrency);
144 * A driver may convert the JDBC sql grammar into its system's
145 * native SQL grammar prior to sending it; nativeSQL returns the
146 * native form of the statement that the driver would have sent.
148 * @param sql a SQL statement that may contain one or more '?'
149 * parameter placeholders
150 * @return the native form of this statement
151 * @exception SQLException if a database access error occurs
153 public String nativeSQL(String sql) throws SQLException
159 * If a connection is in auto-commit mode, than all its SQL
160 * statements will be executed and committed as individual
161 * transactions. Otherwise, its SQL statements are grouped
162 * into transactions that are terminated by either commit()
163 * or rollback(). By default, new connections are in auto-
164 * commit mode. The commit occurs when the statement completes
165 * or the next execute occurs, whichever comes first. In the
166 * case of statements returning a ResultSet, the statement
167 * completes when the last row of the ResultSet has been retrieved
168 * or the ResultSet has been closed. In advanced cases, a single
169 * statement may return multiple results as well as output parameter
170 * values. Here the commit occurs when all results and output param
171 * values have been retrieved.
173 * @param autoCommit - true enables auto-commit; false disables it
174 * @exception SQLException if a database access error occurs
176 public void setAutoCommit(boolean autoCommit) throws SQLException
178 if (this.autoCommit == autoCommit)
184 this.autoCommit = autoCommit;
188 * gets the current auto-commit state
190 * @return Current state of the auto-commit mode
191 * @exception SQLException (why?)
194 public boolean getAutoCommit() throws SQLException
196 return this.autoCommit;
200 * The method commit() makes all changes made since the previous
201 * commit/rollback permanent and releases any database locks currently
202 * held by the Connection. This method should only be used when
203 * auto-commit has been disabled. (If autoCommit == true, then we
204 * just return anyhow)
206 * @exception SQLException if a database access error occurs
209 public void commit() throws SQLException
220 * The method rollback() drops all changes made since the previous
221 * commit/rollback and releases any database locks currently held by
224 * @exception SQLException if a database access error occurs
227 public void rollback() throws SQLException
238 * In some cases, it is desirable to immediately release a Connection's
239 * database and JDBC resources instead of waiting for them to be
240 * automatically released (cant think why off the top of my head)
242 * <B>Note:</B> A Connection is automatically closed when it is
243 * garbage collected. Certain fatal errors also result in a closed
246 * @exception SQLException if a database access error occurs
248 public void close() throws SQLException
250 if (pg_stream != null)
255 } catch (IOException e) {}
261 * Tests to see if a Connection is closed
263 * @return the status of the connection
264 * @exception SQLException (why?)
266 public boolean isClosed() throws SQLException
268 // If the stream is gone, then close() was called
269 if(pg_stream == null)
272 // ok, test the connection
274 // by sending an empty query. If we are dead, then an SQLException should
276 java.sql.ResultSet rs = ExecSQL(" ");
280 // By now, we must be alive
282 } catch(SQLException se) {
283 // Why throw an SQLException as this may fail without throwing one,
284 // ie isClosed() is called incase the connection has died, and we don't
285 // want to find out by an Exception, so instead we return true, as its
286 // most likely why it was thrown in the first place.
292 * A connection's database is able to provide information describing
293 * its tables, its supported SQL grammar, its stored procedures, the
294 * capabilities of this connection, etc. This information is made
295 * available through a DatabaseMetaData object.
297 * @return a DatabaseMetaData object for this connection
298 * @exception SQLException if a database access error occurs
300 public java.sql.DatabaseMetaData getMetaData() throws SQLException
303 metadata = new DatabaseMetaData(this);
308 * You can put a connection in read-only mode as a hunt to enable
309 * database optimizations
311 * <B>Note:</B> setReadOnly cannot be called while in the middle
314 * @param readOnly - true enables read-only mode; false disables it
315 * @exception SQLException if a database access error occurs
317 public void setReadOnly (boolean readOnly) throws SQLException
319 this.readOnly = readOnly;
323 * Tests to see if the connection is in Read Only Mode. Note that
324 * we cannot really put the database in read only mode, but we pretend
325 * we can by returning the value of the readOnly flag
327 * @return true if the connection is read only
328 * @exception SQLException if a database access error occurs
330 public boolean isReadOnly() throws SQLException
336 * A sub-space of this Connection's database may be selected by
337 * setting a catalog name. If the driver does not support catalogs,
338 * it will silently ignore this request
340 * @exception SQLException if a database access error occurs
342 public void setCatalog(String catalog) throws SQLException
348 * Return the connections current catalog name, or null if no
349 * catalog name is set, or we dont support catalogs.
351 * @return the current catalog name or null
352 * @exception SQLException if a database access error occurs
354 public String getCatalog() throws SQLException
360 * You can call this method to try to change the transaction
361 * isolation level using one of the TRANSACTION_* values.
363 * <B>Note:</B> setTransactionIsolation cannot be called while
364 * in the middle of a transaction
366 * @param level one of the TRANSACTION_* isolation values with
367 * the exception of TRANSACTION_NONE; some databases may
368 * not support other values
369 * @exception SQLException if a database access error occurs
370 * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
372 public void setTransactionIsolation(int level) throws SQLException
374 String q = "SET TRANSACTION ISOLATION LEVEL";
378 case java.sql.Connection.TRANSACTION_READ_COMMITTED:
379 ExecSQL(q + " READ COMMITTED");
382 case java.sql.Connection.TRANSACTION_SERIALIZABLE:
383 ExecSQL(q + " SERIALIZABLE");
387 throw new PSQLException("postgresql.con.isolevel",new Integer(level));
392 * Get this Connection's current transaction isolation mode.
394 * @return the current TRANSACTION_* mode value
395 * @exception SQLException if a database access error occurs
397 public int getTransactionIsolation() throws SQLException
399 ExecSQL("show xactisolevel");
401 SQLWarning w = getWarnings();
403 if (w.getMessage().indexOf("READ COMMITTED") != -1) return java.sql.Connection.TRANSACTION_READ_COMMITTED; else
404 if (w.getMessage().indexOf("READ UNCOMMITTED") != -1) return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; else
405 if (w.getMessage().indexOf("REPEATABLE READ") != -1) return java.sql.Connection.TRANSACTION_REPEATABLE_READ; else
406 if (w.getMessage().indexOf("SERIALIZABLE") != -1) return java.sql.Connection.TRANSACTION_SERIALIZABLE;
408 return java.sql.Connection.TRANSACTION_READ_COMMITTED;
412 * The first warning reported by calls on this Connection is
415 * <B>Note:</B> Sebsequent warnings will be changed to this
418 * @return the first SQLWarning or null
419 * @exception SQLException if a database access error occurs
421 public SQLWarning getWarnings() throws SQLException
427 * After this call, getWarnings returns null until a new warning
428 * is reported for this connection.
430 * @exception SQLException if a database access error occurs
432 public void clearWarnings() throws SQLException
438 * This overides the method in org.postgresql.Connection and returns a
441 protected java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat,Field[] fields, Vector tuples, String status, int updateCount, int insertOID) throws SQLException
443 // In 7.1 we now test concurrency to see which class to return. If we are not working with a
444 // Statement then default to a normal ResultSet object.
446 if(stat.getResultSetConcurrency()==java.sql.ResultSet.CONCUR_UPDATABLE)
447 return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID);
450 return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID);
457 public java.util.Map getTypeMap() throws SQLException
464 public void setTypeMap(java.util.Map map) throws SQLException
471 * This overides the standard internal getObject method so that we can
472 * check the jdbc2 type map first
474 * @return PGobject for this type, and set to value
475 * @exception SQLException if value is not correct for this type
476 * @see org.postgresql.util.Serialize
478 public Object getObject(String type,String value) throws SQLException
481 SQLData d = (SQLData) typemap.get(type);
483 // Handle the type (requires SQLInput & SQLOutput classes to be implemented)
484 throw org.postgresql.Driver.notImplemented();
488 // Default to the original method
489 return super.getObject(type,value);
493 // ***********************************************************************