Mercurial > hg > monetdb-java
comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in @ 295:003ae6d881db
Add "final" keyword to method arguments and local variables where possible.
It discovered some bugs in the MonetStatement constructor (changed the argument instead of object variable) which are fixed now.
See also https://en.wikipedia.org/wiki/Final_(Java)
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 01 Aug 2019 20:18:43 +0200 (2019-08-01) |
parents | 2d62ca1f758b |
children | 55330e40cbf1 |
comparison
equal
deleted
inserted
replaced
294:894abb249de1 | 295:003ae6d881db |
---|---|
7 */ | 7 */ |
8 | 8 |
9 package nl.cwi.monetdb.jdbc; | 9 package nl.cwi.monetdb.jdbc; |
10 | 10 |
11 import java.net.URI; | 11 import java.net.URI; |
12 import java.net.URISyntaxException; | |
13 import java.sql.Connection; | 12 import java.sql.Connection; |
14 import java.sql.Driver; | 13 import java.sql.Driver; |
15 import java.sql.DriverManager; | 14 import java.sql.DriverManager; |
16 import java.sql.DriverPropertyInfo; | 15 import java.sql.DriverPropertyInfo; |
17 import java.sql.SQLException; | 16 import java.sql.SQLException; |
18 import java.sql.SQLFeatureNotSupportedException; | 17 import java.sql.SQLFeatureNotSupportedException; |
19 import java.sql.SQLNonTransientConnectionException; | |
20 import java.sql.Types; | 18 import java.sql.Types; |
21 import java.util.ArrayList; | |
22 import java.util.List; | |
23 import java.util.Map.Entry; | 19 import java.util.Map.Entry; |
24 import java.util.Properties; | 20 import java.util.Properties; |
25 import java.util.logging.Logger; | |
26 | 21 |
27 /** | 22 /** |
28 * A Driver suitable for the MonetDB database. | 23 * A Driver suitable for the MonetDB database. |
29 * | 24 * |
30 * This driver will be used by the DriverManager to determine if an URL | 25 * This driver will be used by the DriverManager to determine if an URL |
54 /** Minor version of this driver */ | 49 /** Minor version of this driver */ |
55 private static final int DRIVERMINOR = @JDBC_MINOR@; | 50 private static final int DRIVERMINOR = @JDBC_MINOR@; |
56 /** Version suffix string */ | 51 /** Version suffix string */ |
57 private static final String DRIVERVERSIONSUFFIX = | 52 private static final String DRIVERVERSIONSUFFIX = |
58 "@JDBC_VER_SUFFIX@ based on MCL v@MCL_MAJOR@.@MCL_MINOR@"; | 53 "@JDBC_VER_SUFFIX@ based on MCL v@MCL_MAJOR@.@MCL_MINOR@"; |
59 // We're not fully compliant, but what we support is compliant | |
60 /** Whether this driver is JDBC compliant or not */ | |
61 private static final boolean MONETJDBCCOMPLIANT = false; | |
62 | 54 |
63 /** MonetDB default port to connect to */ | 55 /** MonetDB default port to connect to */ |
64 private static final String PORT = "@JDBC_DEF_PORT@"; | 56 private static final String PORT = "@JDBC_DEF_PORT@"; |
65 | 57 |
66 | 58 |
83 * | 75 * |
84 * @param url the URL of the database | 76 * @param url the URL of the database |
85 * @return true if this driver understands the given URL; false otherwise | 77 * @return true if this driver understands the given URL; false otherwise |
86 */ | 78 */ |
87 @Override | 79 @Override |
88 public boolean acceptsURL(String url) { | 80 public boolean acceptsURL(final String url) { |
89 return url != null && url.startsWith(MONETURL); | 81 return url != null && url.startsWith(MONETURL); |
90 } | 82 } |
91 | 83 |
92 /** | 84 /** |
93 * Attempts to make a database connection to the given URL. The driver | 85 * Attempts to make a database connection to the given URL. The driver |
109 * should be included | 101 * should be included |
110 * @return a Connection object that represents a connection to the URL | 102 * @return a Connection object that represents a connection to the URL |
111 * @throws SQLException if a database access error occurs | 103 * @throws SQLException if a database access error occurs |
112 */ | 104 */ |
113 @Override | 105 @Override |
114 public Connection connect(String url, Properties info) | 106 public Connection connect(final String url, Properties info) |
115 throws SQLException | 107 throws SQLException |
116 { | 108 { |
117 // url should be of style jdbc:monetdb://<host>/<database> | 109 // url should be of style jdbc:monetdb://<host>/<database> |
118 if (!acceptsURL(url)) | 110 if (!acceptsURL(url)) |
119 return null; | 111 return null; |
120 | 112 |
121 Properties props = new Properties(); | 113 final Properties props = new Properties(); |
122 // set the optional properties and their defaults here | 114 // set the optional properties and their defaults here |
123 props.put("port", PORT); | 115 props.put("port", PORT); |
124 props.put("debug", "false"); | 116 props.put("debug", "false"); |
125 props.put("language", "sql"); // mal, sql, <future> | 117 props.put("language", "sql"); // mal, sql, <future> |
126 props.put("so_timeout", "0"); | 118 props.put("so_timeout", "0"); |
128 if (info != null) | 120 if (info != null) |
129 props.putAll(info); | 121 props.putAll(info); |
130 info = props; | 122 info = props; |
131 | 123 |
132 // remove leading "jdbc:" so the rest is a valid hierarchical URI | 124 // remove leading "jdbc:" so the rest is a valid hierarchical URI |
133 URI uri; | 125 final URI uri; |
134 try { | 126 try { |
135 uri = new URI(url.substring(5)); | 127 uri = new URI(url.substring(5)); |
136 } catch (URISyntaxException e) { | 128 } catch (java.net.URISyntaxException e) { |
137 return null; | 129 return null; |
138 } | 130 } |
139 | 131 |
140 String uri_host = uri.getHost(); | 132 final String uri_host = uri.getHost(); |
141 if (uri_host == null) | 133 if (uri_host == null) |
142 return null; | 134 return null; |
143 info.put("host", uri_host); | 135 info.put("host", uri_host); |
144 | 136 |
145 int uri_port = uri.getPort(); | 137 int uri_port = uri.getPort(); |
152 uri_path = uri_path.substring(1).trim(); | 144 uri_path = uri_path.substring(1).trim(); |
153 if (!uri_path.isEmpty()) | 145 if (!uri_path.isEmpty()) |
154 info.put("database", uri_path); | 146 info.put("database", uri_path); |
155 } | 147 } |
156 | 148 |
157 String uri_query = uri.getQuery(); | 149 final String uri_query = uri.getQuery(); |
158 if (uri_query != null) { | 150 if (uri_query != null) { |
159 int pos; | 151 int pos; |
160 // handle additional connection properties separated by the & character | 152 // handle additional connection properties separated by the & character |
161 String args[] = uri_query.split("&"); | 153 final String args[] = uri_query.split("&"); |
162 for (int i = 0; i < args.length; i++) { | 154 for (int i = 0; i < args.length; i++) { |
163 pos = args[i].indexOf('='); | 155 pos = args[i].indexOf('='); |
164 if (pos > 0) | 156 if (pos > 0) |
165 info.put(args[i].substring(0, pos), args[i].substring(pos + 1)); | 157 info.put(args[i].substring(0, pos), args[i].substring(pos + 1)); |
166 } | 158 } |
206 * @return an array of DriverPropertyInfo objects describing possible | 198 * @return an array of DriverPropertyInfo objects describing possible |
207 * properties. This array may be an empty array if no properties | 199 * properties. This array may be an empty array if no properties |
208 * are required. | 200 * are required. |
209 */ | 201 */ |
210 @Override | 202 @Override |
211 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { | 203 public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) { |
212 if (!acceptsURL(url)) | 204 if (!acceptsURL(url)) |
213 return null; | 205 return null; |
214 | 206 |
215 String[] boolean_choices = new String[] { "true", "false" }; | 207 final String[] boolean_choices = new String[] { "true", "false" }; |
216 String[] language_choices = new String[] { "sql", "mal" }; | 208 final String[] language_choices = new String[] { "sql", "mal" }; |
217 String[] hash_choices = new String[] { "SHA512", "SHA384", "SHA256", "SHA1", "MD5" }; | 209 final String[] hash_choices = new String[] { "SHA512", "SHA384", "SHA256", "SHA1", "MD5" }; |
218 DriverPropertyInfo[] dpi = new DriverPropertyInfo[9]; // we currently support 9 connection properties | 210 final DriverPropertyInfo[] dpi = new DriverPropertyInfo[9]; // we currently support 9 connection properties |
219 | 211 |
220 DriverPropertyInfo prop = new DriverPropertyInfo("user", info != null ? info.getProperty("user") : null); | 212 DriverPropertyInfo prop = new DriverPropertyInfo("user", info != null ? info.getProperty("user") : null); |
221 prop.required = true; | 213 prop.required = true; |
222 prop.description = "The user loginname to use when authenticating on the database server"; | 214 prop.description = "The user loginname to use when authenticating on the database server"; |
223 dpi[0] = prop; | 215 dpi[0] = prop; |
296 * | 288 * |
297 * @return true if this driver is JDBC Compliant; false otherwise | 289 * @return true if this driver is JDBC Compliant; false otherwise |
298 */ | 290 */ |
299 @Override | 291 @Override |
300 public boolean jdbcCompliant() { | 292 public boolean jdbcCompliant() { |
301 return MONETJDBCCOMPLIANT; | 293 // We're not fully JDBC compliant, but what we support is compliant |
294 return false; | |
302 } | 295 } |
303 | 296 |
304 /** | 297 /** |
305 * Return the parent Logger of all the Loggers used by this data source. | 298 * Return the parent Logger of all the Loggers used by this data source. |
306 * This should be the Logger farthest from the root Logger that is | 299 * This should be the Logger farthest from the root Logger that is |
313 * @throws SQLFeatureNotSupportedException if the data source does | 306 * @throws SQLFeatureNotSupportedException if the data source does |
314 * not use java.util.logging | 307 * not use java.util.logging |
315 * @since 1.7 | 308 * @since 1.7 |
316 */ | 309 */ |
317 @Override | 310 @Override |
318 public Logger getParentLogger() throws SQLFeatureNotSupportedException { | 311 public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { |
319 throw MonetWrapper.newSQLFeatureNotSupportedException("getParentLogger"); | 312 throw MonetWrapper.newSQLFeatureNotSupportedException("getParentLogger"); |
320 } | 313 } |
321 | 314 |
322 //== end methods of interface driver | 315 //== end methods of interface driver |
323 | 316 |
324 | 317 |
325 /** A static Map containing the mapping between MonetDB types and Java SQL types */ | 318 /** A static Map containing the mapping between MonetDB types and Java SQL types */ |
326 /* use SELECT sqlname, * FROM sys.types order by 1, id; to view all MonetDB types */ | 319 /* use SELECT sqlname, * FROM sys.types order by 1, id; to view all MonetDB types */ |
327 /* see http://docs.oracle.com/javase/7/docs/api/java/sql/Types.html to view all supported java SQL types */ | 320 /* see http://docs.oracle.com/javase/7/docs/api/java/sql/Types.html to view all supported java SQL types */ |
328 private static java.util.Map<String, Integer> typeMap = new java.util.HashMap<String, Integer>(); | 321 private static final java.util.Map<String, Integer> typeMap = new java.util.HashMap<String, Integer>(); |
329 static { | 322 static { |
330 // fill the typeMap once | 323 // fill the typeMap once |
331 // typeMap.put("any", Integer.valueOf(Types.???)); | 324 // typeMap.put("any", Integer.valueOf(Types.???)); |
332 typeMap.put("bigint", Integer.valueOf(Types.BIGINT)); | 325 typeMap.put("bigint", Integer.valueOf(Types.BIGINT)); |
333 typeMap.put("blob", Integer.valueOf(Types.BLOB)); | 326 typeMap.put("blob", Integer.valueOf(Types.BLOB)); |
369 * | 362 * |
370 * @param type the SQL data type name as used by MonetDB | 363 * @param type the SQL data type name as used by MonetDB |
371 * @return the matching java.sql.Types constant or | 364 * @return the matching java.sql.Types constant or |
372 * java.sql.Types.OTHER if nothing matched the given type name | 365 * java.sql.Types.OTHER if nothing matched the given type name |
373 */ | 366 */ |
374 static int getJdbcSQLType(String type) { | 367 static final int getJdbcSQLType(final String type) { |
375 // find the column type name in the typeMap | 368 // find the column type name in the typeMap |
376 Integer tp = typeMap.get(type); | 369 final Integer tp = typeMap.get(type); |
377 if (tp != null) { | 370 if (tp != null) { |
378 return tp.intValue(); | 371 return tp.intValue(); |
379 } | 372 } |
380 // When type name is not found in the map, for instance | 373 // When type name is not found in the map, for instance |
381 // when it is a new type (not yet added in the above typeMap) or | 374 // when it is a new type (not yet added in the above typeMap) or |
392 * @param column a String representing the value that should be evaluated | 385 * @param column a String representing the value that should be evaluated |
393 * in the SQL CASE statement | 386 * in the SQL CASE statement |
394 * @return a SQL CASE statement | 387 * @return a SQL CASE statement |
395 */ | 388 */ |
396 private static String TypeMapppingSQL = null; // cache to optimise getSQLTypeMap() | 389 private static String TypeMapppingSQL = null; // cache to optimise getSQLTypeMap() |
397 static String getSQLTypeMap(String column) { | 390 static final String getSQLTypeMap(final String column) { |
398 if (TypeMapppingSQL == null) { | 391 if (TypeMapppingSQL == null) { |
399 // first time, compose TypeMappping SQL string | 392 // first time, compose TypeMappping SQL string |
400 StringBuilder val = new StringBuilder((typeMap.size() * (7 + 7 + 7 + 4)) + 14); | 393 final StringBuilder val = new StringBuilder((typeMap.size() * (7 + 7 + 7 + 4)) + 14); |
401 for (Entry<String, Integer> entry : typeMap.entrySet()) { | 394 for (Entry<String, Integer> entry : typeMap.entrySet()) { |
402 val.append(" WHEN '").append(entry.getKey()).append("' THEN ").append(entry.getValue().toString()); | 395 val.append(" WHEN '").append(entry.getKey()).append("' THEN ").append(entry.getValue().toString()); |
403 } | 396 } |
404 val.append(" ELSE ").append(Types.OTHER).append(" END"); | 397 val.append(" ELSE ").append(Types.OTHER).append(" END"); |
405 // as the typeMap is static, cache this SQL part for all next calls | 398 // as the typeMap is static, cache this SQL part for all next calls |
408 return "CASE " + column + TypeMapppingSQL; | 401 return "CASE " + column + TypeMapppingSQL; |
409 } | 402 } |
410 | 403 |
411 /** | 404 /** |
412 * Returns a touched up identifying version string of this driver. | 405 * Returns a touched up identifying version string of this driver. |
413 * | 406 * It is made public as it is called from nl/cwi/monetdb/client/JdbcClient.java |
414 * @return the version string | 407 * @return the version string |
415 */ | 408 */ |
416 public static String getDriverVersion() { | 409 public static final String getDriverVersion() { |
417 return DRIVERMAJOR + "." + DRIVERMINOR + " (" + DRIVERVERSIONSUFFIX + ")"; | 410 return DRIVERMAJOR + "." + DRIVERMINOR + " (" + DRIVERVERSIONSUFFIX + ")"; |
418 } | 411 } |
419 | 412 |
420 static int getDriverMajorVersion() { | 413 static final int getDriverMajorVersion() { |
421 return DRIVERMAJOR; | 414 return DRIVERMAJOR; |
422 } | 415 } |
423 | 416 |
424 static int getDriverMinorVersion() { | 417 static final int getDriverMinorVersion() { |
425 return DRIVERMINOR; | 418 return DRIVERMINOR; |
426 } | 419 } |
427 } | 420 } |