Changeset: efba5d427a89 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=efba5d427a89
Modified Files:
java/SQLSTATEs
java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
java/src/nl/cwi/monetdb/jdbc/MonetDataSource.java
java/src/nl/cwi/monetdb/jdbc/MonetDriver.java.in
java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
Branch: Dec2011
Log Message:
JDBC: first bunch of JDBC 4.1 changes
All 4.1 (Java 7) changes are backwards compatible with 4.0 (Java 6), so
even though support is incomplete at the moment, we can still
compile/test it with Java 6.
diffs (truncated from 321 to 300 lines):
diff --git a/java/SQLSTATEs b/java/SQLSTATEs
--- a/java/SQLSTATEs
+++ b/java/SQLSTATEs
@@ -34,6 +34,7 @@ 3BM30 autocommit mode active
2DM30 autocommit mode active
42M31 user/role already exists
42M32 user/role not found
+08M33 connection timeout
TODO:
JDBC 4.1 suggests the following SQLException subclass mapping:
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -24,6 +24,9 @@ import java.util.*;
import java.io.*;
import java.nio.*;
import java.security.*;
+import java.util.concurrent.Executor;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
import nl.cwi.monetdb.mcl.io.*;
import nl.cwi.monetdb.mcl.net.*;
import nl.cwi.monetdb.mcl.parser.*;
@@ -170,7 +173,6 @@ public class MonetConnection extends Mon
if (hash != null) server.setHash(hash);
if (database != null) server.setDatabase(database);
server.setLanguage(language);
- server.setSoTimeout(sockTimeout);
// we're debugging here... uhm, should be off in real life
if (debug) {
@@ -202,6 +204,10 @@ public class MonetConnection extends Mon
}
}
+ // apply NetworkTimeout value from legacy (pre 4.1)
driver
+ // so_timeout calls
+ server.setSoTimeout(sockTimeout);
+
in = server.getReader();
out = server.getWriter();
@@ -214,7 +220,6 @@ public class MonetConnection extends Mon
throw new SQLException(e.getMessage(), "08001");
}
-
// we seem to have managed to log in, let's store the
// language used
if ("sql".equals(language)) {
@@ -1227,6 +1232,123 @@ public class MonetConnection extends Mon
(closed ? "connected" : "disconnected"));
}
+ //== 1.7 methods (JDBC 4.1)
+
+ /**
+ * Sets the given schema name to access.
+ *
+ * @param schema the name of a schema in which to work
+ * @throws SQLException if a database access error occurs or this
+ * method is called on a closed connection
+ */
+ public void setSchema(String schema) throws SQLException {
+ if (closed)
+ throw new SQLException("Cannot call on closed
Connection", "M1M20");
+ createStatement().executeUpdate("SET SCHEMA = \"" + schema +
"\"");
+ }
+
+ /**
+ * Retrieves this Connection object's current schema name.
+ *
+ * @return the current schema name or null if there is none
+ * @throws SQLException if a database access error occurs or this
+ * method is called on a closed connection
+ */
+ public String getSchema() throws SQLException {
+ if (closed)
+ throw new SQLException("Cannot call on closed
Connection", "M1M20");
+ ResultSet rs = createStatement().executeQuery("SELECT
CURRENT_SCHEMA");
+ if (!rs.next())
+ throw new SQLException("Row expected", "02000");
+ return(rs.getString(1));
+ }
+
+ /**
+ * Terminates an open connection. Calling abort results in:
+ * * The connection marked as closed
+ * * Closes any physical connection to the database
+ * * Releases resources used by the connection
+ * * Insures that any thread that is currently accessing the
+ * connection will either progress to completion or throw an
+ * SQLException.
+ * Calling abort marks the connection closed and releases any
+ * resources. Calling abort on a closed connection is a no-op.
+ *
+ * @param executor The Executor implementation which will be used by
+ * abort
+ * @throws SQLException if a database access error occurs or the
+ * executor is null
+ * @throws SecurityException if a security manager exists and
+ * its checkPermission method denies calling abort
+ */
+ public void abort(Executor executor) throws SQLException {
+ if (closed)
+ return;
+ if (executor == null)
+ throw new SQLException("executor is null", "M1M05");
+ // this is really the simplest thing to do, it destroys
+ // everything (in particular the server connection)
+ close();
+ }
+
+ /**
+ * Sets the maximum period a Connection or objects created from the
+ * Connection will wait for the database to reply to any one
+ * request. If any request remains unanswered, the waiting method
+ * will return with a SQLException, and the Connection or objects
+ * created from the Connection will be marked as closed. Any
+ * subsequent use of the objects, with the exception of the close,
+ * isClosed or Connection.isValid methods, will result in a
+ * SQLException.
+ *
+ * @param executor The Executor implementation which will be used by
+ * setNetworkTimeout
+ * @param milliseconds The time in milliseconds to wait for the
+ * database operation to complete
+ * @throws SQLException if a database access error occurs, this
+ * method is called on a closed connection, the executor is
+ * null, or the value specified for seconds is less than 0.
+ * @throws SQLException if a database access error occurs or
+ * this method is called on a closed Connection
+ */
+ public void setNetworkTimeout(Executor executor, int millis)
+ throws SQLException
+ {
+ if (closed)
+ throw new SQLException("Cannot call on closed
Connection", "M1M20");
+ if (executor == null)
+ throw new SQLException("executor is null", "M1M05");
+ if (millis < 0)
+ throw new SQLException("milliseconds is less than
zero", "M1M05");
+
+ try {
+ server.setSoTimeout(millis);
+ } catch (SocketException e) {
+ throw new SQLException(e.getMessage(), "08000");
+ }
+ }
+
+ /**
+ * Retrieves the number of milliseconds the driver will wait for a
+ * database request to complete. If the limit is exceeded, a
+ * SQLException is thrown.
+ *
+ * @return the current timeout limit in milliseconds; zero means
+ * there is no limit
+ * @throws SQLException if a database access error occurs or
+ * this method is called on a closed Connection
+ */
+ public int getNetworkTimeout() throws SQLException {
+ if (closed)
+ throw new SQLException("Cannot call on closed
Connection", "M1M20");
+
+ try {
+ return(server.getSoTimeout());
+ } catch (SocketException e) {
+ throw new SQLException(e.getMessage(), "08000");
+ }
+ }
+
//== end methods of interface Connection
/**
@@ -1256,6 +1378,9 @@ public class MonetConnection extends Mon
if (error != null)
throw new
SQLException(error.substring(6),
error.substring(0, 5));
+ } catch (SocketTimeoutException e) {
+ close(); // JDBC 4.1 semantics: abort()
+ throw new SQLException("connection timed out",
"08M33");
} catch (IOException e) {
throw new SQLException(e.getMessage(), "08000");
}
@@ -1283,6 +1408,9 @@ public class MonetConnection extends Mon
if (error != null)
throw new
SQLException(error.substring(6),
error.substring(0, 5));
+ } catch (SocketTimeoutException e) {
+ close(); // JDBC 4.1 semantics, abort()
+ throw new SQLException("connection timed out",
"08M33");
} catch (IOException e) {
throw new SQLException(e.getMessage(), "08000");
}
@@ -2362,6 +2490,9 @@ public class MonetConnection extends Mon
}
throw ret;
}
+ } catch (SocketTimeoutException e) {
+ close(); // JDBC 4.1 semantics, abort()
+ throw new SQLException("connection timed out",
"08M33");
} catch (IOException e) {
closed = true;
throw new SQLException(e.getMessage() + "
(mserver still alive?)", "08000");
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetDataSource.java
b/java/src/nl/cwi/monetdb/jdbc/MonetDataSource.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetDataSource.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetDataSource.java
@@ -23,6 +23,7 @@ import java.sql.*;
import javax.sql.*;
import java.util.*;
import java.io.*;
+import java.util.logging.Logger;
/**
* A DataSource suitable for the MonetDB database.
@@ -202,4 +203,20 @@ public class MonetDataSource extends Mon
public void setDescription(String description) {
this.description = description;
}
+
+ /**
+ * Return the parent Logger of all the Loggers used by this data
+ * source. This should be the Logger farthest from the root Logger
+ * that is still an ancestor of all of the Loggers used by this data
+ * source. Configuring this Logger will affect all of the log
+ * messages generated by the data source. In the worst case, this
+ * may be the root Logger.
+ *
+ * @return the parent Logger for this data source
+ * @throws SQLFeatureNotSupportedException if the data source does
+ * not use java.util.logging
+ */
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ throw new SQLFeatureNotSupportedException("java.util.logging
not in use", "0A000");
+ }
}
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetDriver.java.in
b/java/src/nl/cwi/monetdb/jdbc/MonetDriver.java.in
--- a/java/src/nl/cwi/monetdb/jdbc/MonetDriver.java.in
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetDriver.java.in
@@ -22,6 +22,7 @@ package nl.cwi.monetdb.jdbc;
import java.sql.*;
import java.util.*;
import java.net.*;
+import java.util.logging.Logger;
/**
* A Driver suitable for the MonetDB database.
@@ -243,7 +244,7 @@ final public class MonetDriver implement
prop = new DriverPropertyInfo("so_timeout", "0");
prop.required = false;
- prop.description = "Defines the maximum time to wait in
milliseconds on a blocking read socket call";
+ prop.description = "Defines the maximum time to wait in
milliseconds on a blocking read socket call (this corresponds to the
Connection.setNetworkTimeout() method introduced in JDBC 4.1)";
props.add(prop);
DriverPropertyInfo[] dpi = new DriverPropertyInfo[props.size()];
@@ -352,4 +353,20 @@ final public class MonetDriver implement
public static String getDriverVersion() {
return("" + DRIVERMAJOR + "." + DRIVERMINOR + " (" +
DRIVERVERSIONSUFFIX + ")");
}
+
+ /**
+ * Return the parent Logger of all the Loggers used by this data
+ * source. This should be the Logger farthest from the root Logger
+ * that is still an ancestor of all of the Loggers used by this data
+ * source. Configuring this Logger will affect all of the log
+ * messages generated by the data source. In the worst case, this
+ * may be the root Logger.
+ *
+ * @return the parent Logger for this data source
+ * @throws SQLFeatureNotSupportedException if the data source does
+ * not use java.util.logging
+ */
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ throw new SQLFeatureNotSupportedException("java.util.logging
not in use", "0A000");
+ }
}
diff --git a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
--- a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
+++ b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
@@ -119,9 +119,6 @@ public final class MapiSocket {
/** A short in two bytes for holding the block size in bytes */
private byte[] blklen = new byte[2];
- /** SO_TIMEOUT value for the underlying java.net.Socket */
- private int sockTimeout = 0;
-
/**
* Constructs a new MapiSocket.
*/
@@ -200,8 +197,18 @@ public final class MapiSocket {
* @param timeout The specified timeout, in milliseconds. A timeout
* of zero is interpreted as an infinite timeout.
*/
- public void setSoTimeout(int s) {
- this.sockTimeout = s;
+ public void setSoTimeout(int s) throws SocketException {
+ // limit time to wait on blocking operations (0 = indefinite)
+ con.setSoTimeout(s);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list