Mercurial > hg > monetdb-java
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 |