import org.postgresql.core.Encoding;
/**
- * $Id: Connection.java,v 1.21 2001/07/30 14:51:19 momjian Exp $
+ * $Id: Connection.java,v 1.22 2001/08/04 19:32:04 momjian Exp $
*
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
* JDBC2 versions of the Connection class.
*/
private Encoding encoding = Encoding.defaultEncoding();
+ private String dbVersionLong;
+ private String dbVersionNumber;
+
public boolean CONNECTION_OK = true;
public boolean CONNECTION_BAD = false;
// used, so we denote this with 'UNKNOWN'.
final String encodingQuery =
- "select case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
+ "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
// Set datestyle and fetch db encoding in a single call, to avoid making
// more than one round trip to the backend during connection startup.
java.sql.ResultSet resultSet =
- ExecSQL("set datestyle to 'ISO'; " + encodingQuery);
+ ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
if (! resultSet.next()) {
throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
}
- dbEncoding = resultSet.getString(1);
+ dbVersionLong = resultSet.getString(1);
+ dbEncoding = resultSet.getString(2);
encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
// Initialise object handling
if (autoCommit)
ExecSQL("end");
else {
- ExecSQL("begin");
- doIsolationLevel();
+ ExecSQL("begin; " + getIsolationLevelSQL());
}
this.autoCommit = autoCommit;
}
public void commit() throws SQLException {
if (autoCommit)
return;
- ExecSQL("commit");
- autoCommit = true;
- ExecSQL("begin");
- doIsolationLevel();
- autoCommit = false;
+ ExecSQL("commit; begin; " + getIsolationLevelSQL());
}
/**
public void rollback() throws SQLException {
if (autoCommit)
return;
- ExecSQL("rollback");
- autoCommit = true;
- ExecSQL("begin");
- doIsolationLevel();
- autoCommit = false;
+ ExecSQL("rollback; begin; " + getIsolationLevelSQL());
}
/**
/**
* You can call this method to try to change the transaction
* isolation level using one of the TRANSACTION_* values.
- *
+ *
* <B>Note:</B> setTransactionIsolation cannot be called while
* in the middle of a transaction
*
* @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
*/
public void setTransactionIsolation(int level) throws SQLException {
- isolationLevel = level;
- doIsolationLevel();
+ //In 7.1 and later versions of the server it is possible using
+ //the "set session" command to set this once for all future txns
+ //however in 7.0 and prior versions it is necessary to set it in
+ //each transaction, thus adding complexity below.
+ //When we decide to drop support for servers older than 7.1
+ //this can be simplified
+ isolationLevel = level;
+ String isolationLevelSQL;
+ switch(isolationLevel) {
+ case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+ if (haveMinimumServerVersion("7.1")) {
+ isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED";
+ } else {
+ isolationLevelSQL = getIsolationLevelSQL();
+ }
+ break;
+
+ case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+ if (haveMinimumServerVersion("7.1")) {
+ isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE";
+ } else {
+ isolationLevelSQL = getIsolationLevelSQL();
+ }
+ break;
+
+ default:
+ throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel));
+ }
+ ExecSQL(isolationLevelSQL);
}
/**
* Helper method used by setTransactionIsolation(), commit(), rollback()
- * and setAutoCommit(). This sets the current isolation level.
+ * and setAutoCommit(). This returns the SQL string needed to
+ * set the isolation level for a transaction. In 7.1 and later it
+ * is possible to set a default isolation level that applies to all
+ * future transactions, this method is only necesary for 7.0 and older
+ * servers, and should be removed when support for these older
+ * servers are dropped
*/
- protected void doIsolationLevel() throws SQLException {
+ protected String getIsolationLevelSQL() throws SQLException {
+ //7.1 and higher servers have a default specified so
+ //no additional SQL is required to set the isolation level
+ if (haveMinimumServerVersion("7.1")) {
+ return "";
+ }
String q = "SET TRANSACTION ISOLATION LEVEL";
switch(isolationLevel) {
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
- ExecSQL(q + " READ COMMITTED");
- return;
+ q = q + " READ COMMITTED";
+ break;
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
- ExecSQL(q + " SERIALIZABLE");
- return;
+ q = q + " SERIALIZABLE";
+ break;
default:
throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel));
}
+ return q;
}
/**
*/
public void setCatalog(String catalog) throws SQLException
{
- if(catalog!=null && !catalog.equals(PG_DATABASE)) {
- close();
- Properties info=new Properties();
- info.setProperty("user", PG_USER);
- info.setProperty("password", PG_PASSWORD);
- openConnection(PG_HOST, PG_PORT, info, catalog, this_url, this_driver);
- }
+ //no-op
}
/**
return sql;
}
+ /**
+ * What is the version of the server
+ *
+ * @return the database version
+ * @exception SQLException if a database access error occurs
+ */
+ public String getDBVersionNumber() throws SQLException
+ {
+ if(dbVersionNumber == null) {
+ StringTokenizer versionParts = new StringTokenizer(dbVersionLong);
+ versionParts.nextToken(); /* "PostgreSQL" */
+ dbVersionNumber = versionParts.nextToken(); /* "X.Y.Z" */
+ }
+ return dbVersionNumber;
+ }
+
+ public boolean haveMinimumServerVersion(String ver) throws SQLException
+ {
+ if (getDBVersionNumber().compareTo(ver)>=0)
+ return true;
+ else
+ return false;
+ }
+
+
+
}
+
private static final byte defaultRemarks[]="no remarks".getBytes();
- private boolean haveMinimumServerVersion(String ver) throws SQLException
- {
- if (getDatabaseProductVersion().compareTo(ver)>=0)
- return true;
- else
- return false;
- }
-
-
public DatabaseMetaData(Connection conn)
{
this.connection = conn;
*/
public boolean nullsAreSortedHigh() throws SQLException
{
- return haveMinimumServerVersion("7.2");
+ return connection.haveMinimumServerVersion("7.2");
}
/**
*/
public boolean nullsAreSortedAtEnd() throws SQLException
{
- return ! haveMinimumServerVersion("7.2");
+ return ! connection.haveMinimumServerVersion("7.2");
}
/**
*/
public String getDatabaseProductVersion() throws SQLException
{
- java.sql.ResultSet resultSet = connection.ExecSQL("select version()");
- resultSet.next();
-
- StringTokenizer versionParts = new StringTokenizer(resultSet.getString(1));
- versionParts.nextToken(); /* "PostgreSQL" */
- String versionNumber = versionParts.nextToken(); /* "X.Y.Z" */
-
- return versionNumber;
+ return connection.getDBVersionNumber();
}
/**
*/
public boolean supportsOrderByUnrelated() throws SQLException
{
- return haveMinimumServerVersion("6.4");
+ return connection.haveMinimumServerVersion("6.4");
}
/**
*/
public boolean supportsGroupByUnrelated() throws SQLException
{
- return haveMinimumServerVersion("6.4");
+ return connection.haveMinimumServerVersion("6.4");
}
/**
*/
public boolean supportsLikeEscapeClause() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsOuterJoins() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsFullOuterJoins() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsSelectForUpdate() throws SQLException
{
- return haveMinimumServerVersion("6.5");
+ return connection.haveMinimumServerVersion("6.5");
}
/**
*/
public boolean supportsCorrelatedSubqueries() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsUnionAll() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public int getMaxRowSize() throws SQLException
{
- if (haveMinimumServerVersion("7.1"))
+ if (connection.haveMinimumServerVersion("7.1"))
return 1073741824; // 1 GB
else
return 8192; // XXX could be altered
*/
public int getMaxStatementLength() throws SQLException
{
- if (haveMinimumServerVersion("7.0"))
+ if (connection.haveMinimumServerVersion("7.0"))
return 0; // actually whatever fits in size_t
else
return 16384;
private static final byte defaultRemarks[]="no remarks".getBytes();
- private boolean haveMinimumServerVersion(String ver) throws SQLException
- {
- if (getDatabaseProductVersion().compareTo(ver)>=0)
- return true;
- else
- return false;
- }
-
-
public DatabaseMetaData(Connection conn)
{
this.connection = conn;
*/
public boolean nullsAreSortedHigh() throws SQLException
{
- return haveMinimumServerVersion("7.2");
+ return connection.haveMinimumServerVersion("7.2");
}
/**
*/
public boolean nullsAreSortedAtEnd() throws SQLException
{
- return ! haveMinimumServerVersion("7.2");
+ return ! connection.haveMinimumServerVersion("7.2");
}
/**
*/
public String getDatabaseProductVersion() throws SQLException
{
- java.sql.ResultSet resultSet = connection.ExecSQL("select version()");
- resultSet.next();
-
- StringTokenizer versionParts = new StringTokenizer(resultSet.getString(1));
- versionParts.nextToken(); /* "PostgreSQL" */
- String versionNumber = versionParts.nextToken(); /* "X.Y.Z" */
-
- return versionNumber;
+ return connection.getDBVersionNumber();
}
/**
*/
public boolean supportsOrderByUnrelated() throws SQLException
{
- return haveMinimumServerVersion("6.4");
+ return connection.haveMinimumServerVersion("6.4");
}
/**
*/
public boolean supportsGroupByUnrelated() throws SQLException
{
- return haveMinimumServerVersion("6.4");
+ return connection.haveMinimumServerVersion("6.4");
}
/**
*/
public boolean supportsLikeEscapeClause() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsOuterJoins() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsFullOuterJoins() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsSelectForUpdate() throws SQLException
{
- return haveMinimumServerVersion("6.5");
+ return connection.haveMinimumServerVersion("6.5");
}
/**
*/
public boolean supportsCorrelatedSubqueries() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public boolean supportsUnionAll() throws SQLException
{
- return haveMinimumServerVersion("7.1");
+ return connection.haveMinimumServerVersion("7.1");
}
/**
*/
public int getMaxRowSize() throws SQLException
{
- if (haveMinimumServerVersion("7.1"))
+ if (connection.haveMinimumServerVersion("7.1"))
return 1073741824; // 1 GB
else
return 8192; // XXX could be altered
*/
public int getMaxStatementLength() throws SQLException
{
- if (haveMinimumServerVersion("7.0"))
+ if (connection.haveMinimumServerVersion("7.0"))
return 0; // actually whatever fits in size_t
else
return 16384;