Changeset: c2bf983dc79b for monetdb-java
URL: https://dev.monetdb.org/hg/monetdb-java/rev/c2bf983dc79b
Modified Files:
        ChangeLog
        src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
Branch: default
Log Message:

Implemented Connection methods: getClientInfo(name) and getClientInfo().
They used to return null and empty Properties object.

Improved robustness and error reporting when processing property values in 
Connection constructor.

Added @since 1.6 and @since 1.7 tags for methods introduced in those java 
versions.

Rearranged place of 1.6 and 1.7 methods implementation code to match the order
as used in http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html
The 1.6 (JDBC 4.0) and 1.7 (JDBC 4.1) methods are now listed at the end of the 
source file.

Removed unneeded trailing spaces (mostly in comment lines)


diffs (truncated from 1418 to 300 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
 # ChangeLog file for java
 # This file is updated with Maddlog
 
+* Thu Nov 10 2016 Martin van Dinther <[email protected]>
+- Implemented Connection methods: getClientInfo(name) and getClientInfo().
+  They used to return null and empty Properties object.
+  Method Connection.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT) now
+  throws an SQLFeatureNotSupportedException.
+
 * Thu Oct 13 2016 Martin van Dinther <[email protected]>
 - Corrected implementation of java.sql.Wrapper methods isWrapperFor()
   and unwrap().  They now properly return expected results instead of
diff --git a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java 
b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -12,22 +12,16 @@ import java.io.File;
 import java.io.IOException;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
-import java.sql.Array;
-import java.sql.Blob;
 import java.sql.CallableStatement;
-import java.sql.Clob;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
-import java.sql.NClob;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLWarning;
-import java.sql.SQLXML;
 import java.sql.Savepoint;
 import java.sql.Statement;
-import java.sql.Struct;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.HashMap;
@@ -53,40 +47,45 @@ import nl.cwi.monetdb.mcl.parser.StartOf
 
 /**
  * A {@link Connection} suitable for the MonetDB database.
- * 
+ *
  * This connection represents a connection (session) to a MonetDB
  * database. SQL statements are executed and results are returned within
  * the context of a connection. This Connection object holds a physical
  * connection to the MonetDB database.
- * 
+ *
  * A Connection object's database should able to provide information
  * describing its tables, its supported SQL grammar, its stored
  * procedures, the capabilities of this connection, and so on. This
  * information is obtained with the getMetaData method.
- * 
+ *
  * Note: By default a Connection object is in auto-commit mode, which
  * means that it automatically commits changes after executing each
  * statement. If auto-commit mode has been disabled, the method commit
  * must be called explicitly in order to commit changes; otherwise,
  * database changes will not be saved.
- * 
+ *
  * The current state of this connection is that it nearly implements the
  * whole Connection interface.
  *
  * @author Fabian Groffen
- * @version 1.2
+ * @author Martin van Dinther
+ * @version 1.3
  */
 public class MonetConnection extends MonetWrapper implements Connection {
+       /** the successful processed input properties */
+       private final Properties conn_props = new Properties();
+
        /** The hostname to connect to */
        private final String hostname;
        /** The port to connect on the host to */
-       private final int port;
+       private int port = 0;
        /** The database to use (currently not used) */
        private final String database;
        /** The username to use when authenticating */
        private final String username;
        /** The password to use when authenticating */
        private final String password;
+
        /** A connection to mserver5 using a TCP socket */
        private final MapiSocket server;
        /** The Reader from the server */
@@ -107,9 +106,7 @@ public class MonetConnection extends Mon
        private SQLWarning warnings = null;
        /** The Connection specific mapping of user defined types to Java
         * types */
-       private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() 
{/**
-                * 
-                */
+       private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() {
                private static final long serialVersionUID = 1L;
                {
                        put("inet", INET.class);
@@ -125,10 +122,11 @@ public class MonetConnection extends Mon
        /** The number of results we receive from the server at once */
        private int curReplySize = -1;  // the server by default uses -1 (all)
 
-       /** A template to apply to each query (like pre and post fixes) */
-       String[] queryTempl;
-       /** A template to apply to each command (like pre and post fixes) */
-       String[] commandTempl;
+       /** A template to apply to each query (like pre and post fixes), filled 
in constructor */
+       final String[] queryTempl = new String[3]; // pre, post, sep
+
+       /** A template to apply to each command (like pre and post fixes), 
filled in constructor */
+       final String[] commandTempl = new String[3]; // pre, post, sep
 
        /** the SQL language */
        final static int LANG_SQL = 0;
@@ -149,57 +147,99 @@ public class MonetConnection extends Mon
         * createStatement() call.  This constructor is only accessible to
         * classes from the jdbc package.
         *
-        * @param props a Property hashtable holding the properties needed for
-        *              connecting
+        * @param props a Property hashtable holding the properties needed for 
connecting
         * @throws SQLException if a database error occurs
         * @throws IllegalArgumentException is one of the arguments is null or 
empty
         */
        MonetConnection(Properties props)
                throws SQLException, IllegalArgumentException
        {
+               // get supported property values from the props argument.
+               // When a value is found add it to the internal conn_props list 
for use by getClientInfo().
                this.hostname = props.getProperty("host");
-               int port;
-               try {
-                       port = Integer.parseInt(props.getProperty("port"));
-               } catch (NumberFormatException e) {
-                       port = 0;
+               if (this.hostname != null)
+                       conn_props.setProperty("host", this.hostname);
+
+               String port_prop = props.getProperty("port");
+               if (port_prop != null) {
+                       try {
+                               this.port = Integer.parseInt(port_prop);
+                       } catch (NumberFormatException e) {
+                               addWarning("Unable to parse port number from: " 
+ port_prop, "M1M05");
+                       }
+                       conn_props.setProperty("port", 
Integer.toString(this.port));
                }
-               this.port = port;
+
                this.database = props.getProperty("database");
+               if (this.database != null)
+                       conn_props.setProperty("database", this.database);
+
                this.username = props.getProperty("user");
+               if (this.username != null)
+                       conn_props.setProperty("user", this.username);
+
                this.password = props.getProperty("password");
+               if (this.password != null)
+                       conn_props.setProperty("password", this.password);
+
                String language = props.getProperty("language");
-               boolean debug = 
Boolean.valueOf(props.getProperty("debug")).booleanValue();
-               String hash = props.getProperty("hash");
-               blobIsBinary = 
Boolean.valueOf(props.getProperty("treat_blob_as_binary")).booleanValue();
-               int sockTimeout = 0;
-               try {
-                       sockTimeout = 
Integer.parseInt(props.getProperty("so_timeout"));
-               } catch (NumberFormatException e) {
-                       sockTimeout = 0;
-               }
-               // check input arguments
-               if (hostname == null || hostname.trim().isEmpty())
-                       throw new IllegalArgumentException("hostname should not 
be null or empty");
-               if (port == 0)
-                       throw new IllegalArgumentException("port should not be 
0");
-               if (username == null || username.trim().isEmpty())
-                       throw new IllegalArgumentException("user should not be 
null or empty");
-               if (password == null || password.trim().isEmpty())
-                       throw new IllegalArgumentException("password should not 
be null or empty");
-               if (language == null || language.trim().isEmpty()) {
-                       language = "sql";
-                       addWarning("No language given, defaulting to 'sql'", 
"M1M05");
+               if (language != null)
+                       conn_props.setProperty("language", language);
+
+               boolean debug = false;
+               String debug_prop = props.getProperty("debug");
+               if (debug_prop != null) {
+                       debug = Boolean.parseBoolean(debug_prop);
+                       conn_props.setProperty("debug", 
Boolean.toString(debug));
                }
 
-               // initialise query templates (filled later, but needed below)
-               queryTempl = new String[3]; // pre, post, sep
-               commandTempl = new String[3]; // pre, post, sep
+               String hash = props.getProperty("hash");
+               if (hash != null)
+                       conn_props.setProperty("hash", hash);
+
+               String blobIsBinary_prop = 
props.getProperty("treat_blob_as_binary");
+               if (blobIsBinary_prop != null) {
+                       blobIsBinary = Boolean.parseBoolean(blobIsBinary_prop);
+                       conn_props.setProperty("treat_blob_as_binary", 
Boolean.toString(blobIsBinary));
+               } else {
+                       blobIsBinary = false;
+               }
+
+               int sockTimeout = 0;
+               String so_timeout_prop = props.getProperty("so_timeout");
+               if (so_timeout_prop != null) {
+                       try {
+                               sockTimeout = Integer.parseInt(so_timeout_prop);
+                               if (sockTimeout < 0) {
+                                       addWarning("Negative socket timeout not 
allowed. Value ignored", "M1M05");
+                                       sockTimeout = 0;
+                               }
+                       } catch (NumberFormatException e) {
+                               addWarning("Unable to parse socket timeout 
number from: " + so_timeout_prop, "M1M05");
+                       }
+                       conn_props.setProperty("so_timeout", 
Integer.toString(sockTimeout));
+               }
+
+               // check mandatory input arguments
+               if (hostname == null || hostname.isEmpty())
+                       throw new IllegalArgumentException("Missing or empty 
host name");
+               if (port <= 0)
+                       throw new IllegalArgumentException("Invalid port 
number. It should not be " + (port < 0 ? "negative" : "0"));
+               if (username == null || username.isEmpty())
+                       throw new IllegalArgumentException("Missing or empty 
user name");
+               if (password == null || password.isEmpty())
+                       throw new IllegalArgumentException("Missing or empty 
password");
+               if (language == null || language.isEmpty()) {
+                       // fallback to default language: sql
+                       language = "sql";
+                       addWarning("No language specified, defaulting to 
'sql'", "M1M05");
+               }
 
                server = new MapiSocket();
-
-               if (hash != null) server.setHash(hash);
-               if (database != null) server.setDatabase(database);
+               if (hash != null)
+                       server.setHash(hash);
+               if (database != null)
+                       server.setDatabase(database);
                server.setLanguage(language);
 
                // we're debugging here... uhm, should be off in real life
@@ -209,7 +249,8 @@ public class MonetConnection extends Mon
                                        System.currentTimeMillis() + ".log");
                                File f = new File(fname);
                                int ext = fname.lastIndexOf('.');
-                               if (ext < 0) ext = fname.length();
+                               if (ext < 0)
+                                       ext = fname.length();
                                String pre = fname.substring(0, ext);
                                String suf = fname.substring(ext);
 
@@ -224,12 +265,11 @@ public class MonetConnection extends Mon
                }
 
                try {
-                       List<String> warnings = 
-                               server.connect(hostname, port, username, 
password);
+                       List<String> warnings = server.connect(hostname, port, 
username, password);
                        for (String warning : warnings) {
                                addWarning(warning, "01M02");
                        }
-                       
+
                        // apply NetworkTimeout value from legacy (pre 4.1) 
driver
                        // so_timeout calls
                        server.setSoTimeout(sockTimeout);
@@ -239,7 +279,7 @@ public class MonetConnection extends Mon
 
                        String error = in.waitForPrompt();
                        if (error != null)
-                               throw new SQLException(error.substring(6), 
"08001");
+                               throw new SQLException((error.length() > 6) ? 
error.substring(6) : error, "08001");
                } catch (IOException e) {
                        throw new SQLException("Unable to connect (" + hostname 
+ ":" + port + "): " + e.getMessage(), "08006");
                } catch (MCLParseException e) {
@@ -254,17 +294,10 @@ public class MonetConnection extends Mon
                }
 
                // we seem to have managed to log in, let's store the
-               // language used
+               // language used and language specific query templates
                if ("sql".equals(language)) {
                        lang = LANG_SQL;
-               } else if ("mal".equals(language)) {
-                       lang = LANG_MAL;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to