Changeset: 5540793628d6 for monetdb-java
URL: https://dev.monetdb.org/hg/monetdb-java?cmd=changeset;node=5540793628d6
Modified Files:
        src/main/java/org/monetdb/jdbc/MonetConnection.java
        src/main/java/org/monetdb/jdbc/MonetStatement.java
Branch: default
Log Message:

Improve code when setting query timeout. It used to call the 
sys.settimeout(bigint) which is deprecated as of release Jun2020 (11.37.7) and 
replaced by new sys.setquerytimeout(int).
As the server call was done from two places MonetConnection.isValid() and 
MonetStatement.internalExecute(), I created a single utlity method which is now 
called instead.


diffs (254 lines):

diff --git a/src/main/java/org/monetdb/jdbc/MonetConnection.java 
b/src/main/java/org/monetdb/jdbc/MonetConnection.java
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java
@@ -142,7 +142,7 @@ public class MonetConnection
        private boolean treatClobAsVarChar = true;
 
        /** The last set query timeout on the server as used by Statement, 
PreparedStatement and CallableStatement */
-       protected int lastSetQueryTimeout = 0;  // 0 means no timeout, which is 
the default on the server
+       protected int lastSetQueryTimeout;      // 0 means no timeout, which is 
the default on the server
 
 
        /**
@@ -1311,7 +1311,7 @@ public class MonetConnection
                                }
                        }
                } catch (SQLException se) {
-                       String msg = se.getMessage();
+                       final String msg = se.getMessage();
                        // System.out.println(se.getSQLState() + " 
Con.isValid(): " + msg);
                        if (msg != null && msg.equalsIgnoreCase("Current 
transaction is aborted (please ROLLBACK)")) {
                                // Must use equalsIgnoreCase() here because up 
to Jul2017 release 'Current' was 'current' so with lowercase c.
@@ -1321,22 +1321,18 @@ public class MonetConnection
                        }
                        /* ignore stmt errors/exceptions, we are only testing 
if the connection is still alive and usable */
                } finally {
+                       closeResultsetStatement(rs, stmt);
                        /* when changed, reset the original server timeout 
value on the server */
                        if (timeout > 0 && original_timeout != 
this.lastSetQueryTimeout) {
                                this.lastSetQueryTimeout = original_timeout;
-                               Statement stmt2 = null;
                                try {
                                        /* we have to set in the server 
explicitly, because the test 'queryTimeout != connection.lastSetQueryTimeout' 
                                           on 
MonetStatement.internalExecute(sql) won't pass and the server won't be set back 
*/
-                                       stmt2 = this.createStatement();
-                                       stmt2.execute("CALL 
\"sys\".\"settimeout\"(" + this.lastSetQueryTimeout + ")");
+                                       setQueryTimeout(original_timeout);
                                } catch (SQLException se) {
                                        /* ignore stmt errors/exceptions, we 
are only testing if the connection is still alive and usable */
-                               } finally {
-                                       closeResultsetStatement(null, stmt2);
                                }
                        }
-                       closeResultsetStatement(rs, stmt);
                }
                return isValid;
        }
@@ -1636,6 +1632,43 @@ public class MonetConnection
        //== internal helper methods which do not belong to the JDBC interface
 
        /**
+        * Local helper method to test whether the Connection object is closed
+        * When closed it throws an SQLException
+        */
+       private void checkNotClosed() throws SQLException {
+               if (closed)
+                       throw new SQLException("Connection is closed", "M1M20");
+       }
+
+       /**
+        * Utility method to call sys.setquerytimeout(int); procedure on the 
connected server.
+        * It is called from: MonetConnection.isValid() and 
MonetStatement.internalExecute()
+        */
+       void setQueryTimeout(final int millis) throws SQLException {
+               if (millis < 0)
+                       throw new SQLException("query timeout milliseconds is 
less than zero", "M1M05");
+
+               checkNotClosed();
+               Statement st = null;
+               try {
+                       // as of release Jun2020 (11.37.7) the function 
sys.settimeout(bigint) is deprecated and replaced by new 
sys.setquerytimeout(int)
+                       final boolean postJun2020 = (getDatabaseMajorVersion() 
>=11) && (getDatabaseMinorVersion() >= 37);
+                       final String callstmt = postJun2020 ? "CALL 
sys.\"setquerytimeout\"(" + millis + ")"
+                                                           : "CALL 
sys.\"settimeout\"(" + millis + ")";
+                       // for debug: System.out.println("Before: " + callstmt);
+                       st = createStatement();
+                       st.execute(callstmt);
+                       // for debug: System.out.println("After : " + callstmt);
+
+                       this.lastSetQueryTimeout = millis;
+               }
+               /* do not catch SQLException here, as we want to know it when 
it fails */
+               finally {
+                       closeResultsetStatement(null, st);
+               }
+       }
+
+       /**
         * @return whether the JDBC BLOB type should be mapped to VARBINARY 
type.
         * This allows generic JDBC programs to fetch Blob data via getBytes()
         * instead of getBlob() and Blob.getBinaryStream() to reduce overhead.
@@ -1656,15 +1689,6 @@ public class MonetConnection
        }
 
        /**
-        * Local helper method to test whether the Connection object is closed
-        * When closed it throws an SQLException
-        */
-       private void checkNotClosed() throws SQLException {
-               if (closed)
-                       throw new SQLException("Connection is closed", "M1M20");
-       }
-
-       /**
         * @return the MonetDB JDBC Connection URL (without user name and 
password).
         * It is called from: getURL()in MonetDatabaseMetaData
         */
@@ -1699,8 +1723,6 @@ public class MonetConnection
        private String env_current_user;
        private String env_monet_version;
        private int maxConnections;
-       private int databaseMajorVersion;
-       private int databaseMinorVersion;
 
        /**
         * Utility method to fetch 3 mserver environment values combined in one 
query for efficiency.
@@ -1757,6 +1779,17 @@ public class MonetConnection
        }
 
        /**
+        * @return the maximum number of active connections possible at one 
time;
+        * a result of zero means that there is no limit or the limit is not 
known
+        * It is called from: MonetDatabaseMetaData
+        */
+       int getMaxConnections() throws SQLException {
+               if (maxConnections == 0)
+                       getEnvValues();
+               return maxConnections;
+       }
+
+       /**
         * @return the MonetDB Database Server version string.
         * It is called from: MonetDatabaseMetaData
         */
@@ -1769,9 +1802,11 @@ public class MonetConnection
                return "";
        }
 
+       private int databaseMajorVersion;
        /**
         * @return the MonetDB Database Server major version number.
-        * It is called from: MonetDatabaseMetaData
+        * The number is extracted from the env_monet_version the first time 
and cached for next calls.
+        * It is called from: MonetDatabaseMetaData and MonetConnection
         */
        int getDatabaseMajorVersion() throws SQLException {
                if (databaseMajorVersion == 0) {
@@ -1790,9 +1825,11 @@ public class MonetConnection
                return databaseMajorVersion;
        }
 
+       private int databaseMinorVersion;
        /**
         * @return the MonetDB Database Server minor version number.
-        * It is called from: MonetDatabaseMetaData
+        * The number is extracted from the env_monet_version the first time 
and cached for next calls.
+        * It is called from: MonetDatabaseMetaData and MonetConnection
         */
        int getDatabaseMinorVersion() throws SQLException {
                if (databaseMinorVersion == 0) {
@@ -1815,17 +1852,6 @@ public class MonetConnection
                return databaseMinorVersion;
        }
 
-       /**
-        * @return the maximum number of active connections possible at one 
time;
-        * a result of zero means that there is no limit or the limit is not 
known
-        * It is called from: MonetDatabaseMetaData
-        */
-       int getMaxConnections() throws SQLException {
-               if (maxConnections == 0)
-                       getEnvValues();
-               return maxConnections;
-       }
-
 
        // Internal cache for determining if system table sys.privilege_codes 
(new as of Jul2017 release) exists on connected server
        private boolean queriedPrivilege_codesTable = false;
@@ -2090,17 +2116,17 @@ public class MonetConnection
                 *  if we close this Response */
                private boolean destroyOnClose;
                /** the offset to be used on Xexport queries */
-               private int blockOffset = 0;
+               private int blockOffset;
 
                /** A parser for header lines */
                private final HeaderLineParser hlp;
 
                /** A boolean array telling whether the headers are set or not 
*/
                private final boolean[] isSet;
-               private static final int NAMES  = 0;
-               private static final int TYPES  = 1;
-               private static final int TABLES = 2;
-               private static final int LENS   = 3;
+               private static final int NAMES  = 0;
+               private static final int TYPES  = 1;
+               private static final int TABLES = 2;
+               private static final int LENS   = 3;
 
 
                /**
diff --git a/src/main/java/org/monetdb/jdbc/MonetStatement.java 
b/src/main/java/org/monetdb/jdbc/MonetStatement.java
--- a/src/main/java/org/monetdb/jdbc/MonetStatement.java
+++ b/src/main/java/org/monetdb/jdbc/MonetStatement.java
@@ -62,11 +62,11 @@ public class MonetStatement
        /** Whether this Statement should be closed if the last ResultSet 
closes */
        private boolean closeOnCompletion = false;
        /** The timeout (in sec) for the query to return, 0 means no timeout */
-       private int queryTimeout = 0;
+       private int queryTimeout;
        /** The size of the blocks of results to ask for at the server */
-       private int fetchSize = 0;
+       private int fetchSize;
        /** The maximum number of rows to return in a ResultSet, 0 indicates 
unlimited */
-       private long maxRows = 0;
+       private long maxRows;
        /** The type of ResultSet to produce; i.e. forward only, random access 
*/
        private int resultSetType = MonetResultSet.DEF_RESULTSETTYPE;
        /** The suggested direction of fetching data (implemented but not used) 
*/
@@ -75,8 +75,8 @@ public class MonetStatement
        private int resultSetConcurrency = MonetResultSet.DEF_CONCURRENCY;
 
        /** A List to hold all queries of a batch */
-       private ArrayList<String> batch = null;
-       private ReentrantLock batchLock = null;
+       private ArrayList<String> batch;
+       private ReentrantLock batchLock;
 
 
        /**
@@ -431,23 +431,7 @@ public class MonetStatement
 
                if (queryTimeout != connection.lastSetQueryTimeout) {
                        // set requested/changed queryTimeout on the server 
side first
-                       Statement st = null;
-                       try {
-                               st = connection.createStatement();
-                               final String callstmt = "CALL 
\"sys\".\"settimeout\"(" + queryTimeout + ")";
-                               // for debug: System.out.println("Before: " + 
callstmt);
-                               st.execute(callstmt);
-                               // for debug: System.out.println("After : " + 
callstmt);
-                               connection.lastSetQueryTimeout = queryTimeout;
-                       }
-                       /* do not catch SQLException here, as we want to know 
it when it fails */
-                       finally {
-                               if (st != null) {
-                                       try {
-                                                st.close();
-                                       } catch (SQLException e) { /* ignore */ 
}
-                               }
-                       }
+                       connection.setQueryTimeout(queryTimeout);
                }
 
                // create a container for the result
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to