comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in @ 172:60063c67f9e7 embedded

Merged with default
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Tue, 19 Sep 2017 13:49:34 +0200 (2017-09-19)
parents 477c4de0eda2 d6abd1ffffbb
children 89c285fc0a49
comparison
equal deleted inserted replaced
171:0f95fee3cf29 172:60063c67f9e7
13 import nl.cwi.monetdb.mcl.connection.mapi.MapiLanguage; 13 import nl.cwi.monetdb.mcl.connection.mapi.MapiLanguage;
14 import nl.cwi.monetdb.mcl.protocol.ProtocolException; 14 import nl.cwi.monetdb.mcl.protocol.ProtocolException;
15 15
16 import java.io.IOException; 16 import java.io.IOException;
17 import java.lang.reflect.InvocationTargetException; 17 import java.lang.reflect.InvocationTargetException;
18 import java.net.SocketException;
18 import java.net.URI; 19 import java.net.URI;
19 import java.net.URISyntaxException; 20 import java.net.URISyntaxException;
20 import java.sql.Connection; 21 import java.sql.Connection;
21 import java.sql.Driver; 22 import java.sql.Driver;
22 import java.sql.DriverManager; 23 import java.sql.DriverManager;
23 import java.sql.DriverPropertyInfo; 24 import java.sql.DriverPropertyInfo;
24 import java.sql.SQLException; 25 import java.sql.SQLException;
25 import java.sql.SQLFeatureNotSupportedException; 26 import java.sql.SQLFeatureNotSupportedException;
27 import java.sql.SQLNonTransientConnectionException;
26 import java.sql.Types; 28 import java.sql.Types;
27 import java.util.*; 29 import java.util.*;
28 import java.util.Map.Entry; 30 import java.util.Map.Entry;
29 import java.util.logging.Logger; 31 import java.util.logging.Logger;
30 32
89 * subprotocol specified in the URL and false if they do not. 91 * subprotocol specified in the URL and false if they do not.
90 * 92 *
91 * @param url the URL of the database 93 * @param url the URL of the database
92 * @return true if this driver understands the given URL; false otherwise 94 * @return true if this driver understands the given URL; false otherwise
93 */ 95 */
96 @Override
94 public boolean acceptsURL(String url) { 97 public boolean acceptsURL(String url) {
95 return url != null && url.startsWith(MONETURL); 98 return url != null && url.startsWith(MONETURL);
96 } 99 }
97 100
98 /** 101 /**
99 * Retrieves the driver's major version number. Initially this should be 1. 102 * Retrieves the driver's major version number. Initially this should be 1.
100 * 103 *
101 * @return this driver's major version number 104 * @return this driver's major version number
102 */ 105 */
106 @Override
103 public int getMajorVersion() { 107 public int getMajorVersion() {
104 return DRIVERMAJOR; 108 return DRIVERMAJOR;
105 } 109 }
106 110
107 /** 111 /**
108 * Gets the driver's minor version number. Initially this should be 0. 112 * Gets the driver's minor version number. Initially this should be 0.
109 * 113 *
110 * @return this driver's minor version number 114 * @return this driver's minor version number
111 */ 115 */
116 @Override
112 public int getMinorVersion() { 117 public int getMinorVersion() {
113 return DRIVERMINOR; 118 return DRIVERMINOR;
114 } 119 }
115 120
116 /** 121 /**
126 * @param url the URL of the database to which to connect 131 * @param url the URL of the database to which to connect
127 * @param info a proposed list of tag/value pairs that will be sent on connect open 132 * @param info a proposed list of tag/value pairs that will be sent on connect open
128 * @return an array of DriverPropertyInfo objects describing possible properties. This array may be an empty array 133 * @return an array of DriverPropertyInfo objects describing possible properties. This array may be an empty array
129 * if no properties are required. 134 * if no properties are required.
130 */ 135 */
136 @Override
131 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { 137 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
132 if (!acceptsURL(url)) 138 if (!acceptsURL(url))
133 return null; 139 return null;
134 140
135 List<DriverPropertyInfo> props = new ArrayList<>(); 141 List<DriverPropertyInfo> props = new ArrayList<>();
194 * such as document information retrieval where a SQL implementation may not 200 * such as document information retrieval where a SQL implementation may not
195 * be feasible. 201 * be feasible.
196 * 202 *
197 * @return true if this driver is JDBC Compliant; false otherwise 203 * @return true if this driver is JDBC Compliant; false otherwise
198 */ 204 */
205 @Override
199 public boolean jdbcCompliant() { 206 public boolean jdbcCompliant() {
200 return MONETJDBCCOMPLIANT; 207 return MONETJDBCCOMPLIANT;
201 } 208 }
202 209
203 //== end methods of interface driver 210 //== end methods of interface driver
300 public static int getDriverMinorVersion() { 307 public static int getDriverMinorVersion() {
301 return DRIVERMINOR; 308 return DRIVERMINOR;
302 } 309 }
303 310
304 /** 311 /**
305 * Return the parent Logger of all the Loggers used by this data 312 * Return the parent Logger of all the Loggers used by this data source.
306 * source. This should be the Logger farthest from the root Logger 313 * This should be the Logger farthest from the root Logger that is
307 * that is still an ancestor of all of the Loggers used by this data 314 * still an ancestor of all of the Loggers used by this data source.
308 * source. Configuring this Logger will affect all of the log 315 * Configuring this Logger will affect all of the log messages
309 * messages generated by the data source. In the worst case, this 316 * generated by the data source. In the worst case, this may be the root Logger.
310 * may be the root Logger.
311 * 317 *
312 * @return the parent Logger for this data source 318 * @return the parent Logger for this data source
313 * @throws SQLFeatureNotSupportedException if the data source does not use java.util.logging 319 * @throws SQLFeatureNotSupportedException if the data source does not use java.util.logging
314 */ 320 * @since 1.7
321 */
322 @Override
315 public Logger getParentLogger() throws SQLFeatureNotSupportedException { 323 public Logger getParentLogger() throws SQLFeatureNotSupportedException {
316 throw new SQLFeatureNotSupportedException("java.util.logging not in use", "0A000"); 324 throw new SQLFeatureNotSupportedException("java.util.logging not in use", "0A000");
317 } 325 }
318 326
319 /** 327 /**
329 * The java.util.Properties argument can be used to pass arbitrary string 337 * The java.util.Properties argument can be used to pass arbitrary string
330 * tag/value pairs as connection arguments. Normally at least "user" and 338 * tag/value pairs as connection arguments. Normally at least "user" and
331 * "password" properties should be included in the Properties object. 339 * "password" properties should be included in the Properties object.
332 * 340 *
333 * @param url the URL of the database to which to connect 341 * @param url the URL of the database to which to connect
334 * @param info a list of arbitrary string tag/value pairs as connection 342 * @param info a list of arbitrary string tag/value pairs as connection arguments. Normally at least a "user" and
335 * arguments. Normally at least a "user" and "password" property 343 * "password" property should be included
336 * should be included
337 * @return a Connection object that represents a connection to the URL 344 * @return a Connection object that represents a connection to the URL
338 * @throws SQLException if a database access error occurs 345 * @throws SQLException if a database access error occurs
339 */ 346 */
340 public Connection connect(String url, Properties info) throws SQLException { 347 public Connection connect(String url, Properties info) throws SQLException {
341 int tmp; 348 int tmp;
413 if (directory != null && (directory.trim().isEmpty() || directory.equals(":memory:"))) 420 if (directory != null && (directory.trim().isEmpty() || directory.equals(":memory:")))
414 directory = null; 421 directory = null;
415 if(embeddedConnectionClass == null) { 422 if(embeddedConnectionClass == null) {
416 embeddedConnectionClass = Class.forName("nl.cwi.monetdb.embedded.jdbc.EmbeddedConnection"); 423 embeddedConnectionClass = Class.forName("nl.cwi.monetdb.embedded.jdbc.EmbeddedConnection");
417 if(embeddedConnectionClass == null) { //if it is still null then there is a problem! 424 if(embeddedConnectionClass == null) { //if it is still null then there is a problem!
418 throw new SQLException("EmbeddedConnection Class not found! Please add monetdb-java-lite jar to the CLASSPATH"); 425 throw new SQLNonTransientConnectionException("EmbeddedConnection Class not found! Please add monetdb-java-lite jar to the CLASSPATH");
419 } 426 }
420 } 427 }
421 res = (MonetConnection) embeddedConnectionClass 428 res = (MonetConnection) embeddedConnectionClass
422 .getDeclaredConstructor(Properties.class, String.class, String.class, String.class) 429 .getDeclaredConstructor(Properties.class, String.class, String.class, String.class)
423 .newInstance(props, hash, language, directory); 430 .newInstance(props, hash, language, directory);
424 } catch (InvocationTargetException | InstantiationException | IllegalAccessException | 431 } catch (InvocationTargetException | InstantiationException | IllegalAccessException |
425 NoSuchMethodException | ClassNotFoundException e) { 432 NoSuchMethodException | ClassNotFoundException e) {
426 throw new SQLException(e); 433 throw new SQLNonTransientConnectionException(e);
427 } 434 }
428 } else { 435 } else {
429 String hostname = props.getProperty("host"); 436 String hostname = props.getProperty("host");
430 if (hostname == null || hostname.trim().isEmpty()) 437 if (hostname == null || hostname.trim().isEmpty())
431 throw new IllegalArgumentException("hostname should not be null or empty"); 438 throw new IllegalArgumentException("hostname should not be null or empty");
466 if (sockTimeout < 0) { 473 if (sockTimeout < 0) {
467 negative2 = true; 474 negative2 = true;
468 sockTimeout = 0; 475 sockTimeout = 0;
469 props.setProperty("so_timeout", "0"); 476 props.setProperty("so_timeout", "0");
470 } 477 }
471 try { 478 res = new MapiConnection(props, hash, language, blobIsBinary, clobIsLongChar, hostname, port, database);
472 res = new MapiConnection(props, hash, language, blobIsBinary, clobIsLongChar, hostname, port, database);
473 } catch (IOException e) {
474 throw new SQLException(e);
475 }
476 if(failedparse1) { 479 if(failedparse1) {
477 res.addWarning("Unable to parse port number from: " + port, "M1M05"); 480 res.addWarning("Unable to parse port number from: " + port, "M1M05");
478 } 481 }
479 if(negative1) { 482 if(negative1) {
480 res.addWarning("Negative port not allowed. Value ignored", "M1M05"); 483 res.addWarning("Negative port not allowed. Value ignored", "M1M05");
483 res.addWarning("Unable to parse socket timeout number from: " + timeout, "M1M05"); 486 res.addWarning("Unable to parse socket timeout number from: " + timeout, "M1M05");
484 } 487 }
485 if(negative2) { 488 if(negative2) {
486 res.addWarning("Negative socket timeout not allowed. Value ignored", "M1M05"); 489 res.addWarning("Negative socket timeout not allowed. Value ignored", "M1M05");
487 } 490 }
488 res.setSoTimeout(sockTimeout); 491 try {
492 res.setSoTimeout(sockTimeout);
493 } catch(SocketException ex) {
494 res.addWarning("Failed to set socket timeout: " + ex.getMessage(), "M1M05");
495 }
489 } 496 }
490 497
491 try { //attempt to connect and authenticate the user 498 try { //attempt to connect and authenticate the user
492 List<String> warnings = res.connect(username, password); 499 List<String> warnings = res.connect(username, password);
493 if(warnings != null) { 500 if(warnings != null) {
503 if(!isEmbedded) { 510 if(!isEmbedded) {
504 MapiConnection con = (MapiConnection) res; 511 MapiConnection con = (MapiConnection) res;
505 throw new SQLException("Unable to connect (" + con.getHostname() + ":" 512 throw new SQLException("Unable to connect (" + con.getHostname() + ":"
506 + con.getPort() + "): " + e.getMessage(), "08006"); 513 + con.getPort() + "): " + e.getMessage(), "08006");
507 } else { 514 } else {
508 throw new SQLException("Unable to connect: " + e.getMessage(), "08006"); 515 throw new SQLNonTransientConnectionException("Unable to connect: " + e.getMessage(), "08006");
509 } 516 }
510 } catch (ProtocolException e) { 517 } catch (ProtocolException e) {
511 throw new SQLException(e.getMessage(), "08001"); 518 throw new SQLNonTransientConnectionException(e.getMessage(), "08001");
512 } catch (MCLException e) { 519 } catch (MCLException e) {
513 String[] connex = e.getMessage().split("\n"); 520 String[] connex = e.getMessage().split("\n");
514 SQLException sqle = new SQLException(connex[0], "08001", e); 521 SQLException sqle = new SQLNonTransientConnectionException(connex[0], "08001", e);
515 for (int i = 1; i < connex.length; i++) { 522 for (int i = 1; i < connex.length; i++) {
516 sqle.setNextException(new SQLException(connex[1], "08001")); 523 sqle.setNextException(new SQLNonTransientConnectionException(connex[1], "08001"));
517 } 524 }
518 throw sqle; 525 throw sqle;
519 } 526 }
520 527
521 if (!isEmbedded && res.getLanguage() == MapiLanguage.LANG_SQL) { //set the timezone only in the MAPI connection 528 if (!isEmbedded && res.getLanguage() == MapiLanguage.LANG_SQL) { //set the timezone only in the MAPI connection