comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in @ 93:eeb71f7d36bf embedded

Fixed a bug on the JDBC MAPI connection from the old code! Fixed the connection properties for an JDBC Embedded connection. To start a JDBC Embedded connection, the user must start the embedded database beforehand with the method MonetDBEmbeddedDatabase.StartDatabase().
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Fri, 06 Jan 2017 12:36:33 +0000 (2017-01-06)
parents 6f74e01c57da
children 64530632dc2a
comparison
equal deleted inserted replaced
91:6f74e01c57da 93:eeb71f7d36bf
146 prop = new DriverPropertyInfo("hash", ""); 146 prop = new DriverPropertyInfo("hash", "");
147 prop.required = false; 147 prop.required = false;
148 prop.description = "Force the use of the given hash algorithm during challenge response (one of SHA1, MD5, plain)"; 148 prop.description = "Force the use of the given hash algorithm during challenge response (one of SHA1, MD5, plain)";
149 props.add(prop); 149 props.add(prop);
150 150
151 prop = new DriverPropertyInfo("host", "localhost");
152 prop.required = false;
153 prop.description = "The MonetDB server hostname (MAPI connection only)";
154 props.add(prop);
155
156 prop = new DriverPropertyInfo("port", PORT);
157 prop.required = false;
158 prop.description = "The port to connect to the MonetDB server (MAPI connection only)";
159 props.add(prop);
160
161 prop = new DriverPropertyInfo("so_timeout", "0");
162 prop.required = false;
163 prop.description = "Defines the maximum time to wait in milliseconds on a blocking read socket call (MAPI connection only)"; // this corresponds to the Connection.setNetworkTimeout() method introduced in JDBC 4.1
164 props.add(prop);
165
166 prop = new DriverPropertyInfo("database", "");
167 prop.required = false;
168 prop.description = "The database name to connect (MAPI connection only)";
169 props.add(prop);
170
171 prop = new DriverPropertyInfo("follow_redirects", "true");
172 prop.required = false;
173 prop.description = "Whether redirects issued by the server should be followed (MAPI connection only)";
174 props.add(prop);
175
176 prop = new DriverPropertyInfo("treat_blob_as_binary", "false");
177 prop.required = false;
178 prop.description = "Whether BLOBs on the server should be treated as LONGVARBINARY types, thus mapped to byte[] (MAPI connection only)";
179 props.add(prop);
180
181 prop = new DriverPropertyInfo("treat_clob_as_longvarchar", "false");
182 prop.required = false;
183 prop.description = "Whether CLOBs on the server should be treated as LONGVARCHAR types, thus mapped to String (MAPI connection only)";
184 props.add(prop);
185
151 prop = new DriverPropertyInfo("language", "sql"); 186 prop = new DriverPropertyInfo("language", "sql");
152 prop.required = false; 187 prop.required = false;
153 prop.description = "What language to use for MonetDB conversations (experts only)"; 188 prop.description = "What language to use for MonetDB conversations (experts only)";
154 props.add(prop); 189 props.add(prop);
155 190
156 prop = new DriverPropertyInfo("follow_redirects", "true");
157 prop.required = false;
158 prop.description = "Whether redirects issued by the server should be followed (MAPI connection only)";
159 props.add(prop);
160
161 prop = new DriverPropertyInfo("treat_blob_as_binary", "false");
162 prop.required = false;
163 prop.description = "Whether BLOBs on the server should be treated as BINARY types, thus mapped to byte[] (MAPI connection only)";
164 props.add(prop);
165
166 prop = new DriverPropertyInfo("treat_clob_as_longvarchar", "false");
167 prop.required = false;
168 prop.description = "Whether CLOBs on the server should be treated as LONGVARCHAR types, thus mapped to String (MAPI connection only)";
169 props.add(prop);
170
171 prop = new DriverPropertyInfo("so_timeout", "0");
172 prop.required = false;
173 prop.description = "Defines the maximum time to wait in milliseconds on a blocking read socket call (MAPI connection only)"; // this corresponds to the Connection.setNetworkTimeout() method introduced in JDBC 4.1
174 props.add(prop);
175
176 prop = new DriverPropertyInfo("embedded", "false"); 191 prop = new DriverPropertyInfo("embedded", "false");
177 prop.required = false; 192 prop.required = false;
178 prop.description = "Whether or not to use an embedded MonetDB connection"; 193 prop.description = "Whether or not to use an embedded MonetDB connection";
179 props.add(prop);
180
181 prop = new DriverPropertyInfo("directory", "");
182 prop.required = false;
183 prop.description = "The directory of the database farm (Embedded connection only)";
184 props.add(prop); 194 props.add(prop);
185 195
186 DriverPropertyInfo[] dpi = new DriverPropertyInfo[props.size()]; 196 DriverPropertyInfo[] dpi = new DriverPropertyInfo[props.size()];
187 return props.toArray(dpi); 197 return props.toArray(dpi);
188 } 198 }
402 IllegalArgumentException { 412 IllegalArgumentException {
403 MonetConnection res; 413 MonetConnection res;
404 414
405 boolean isEmbedded = Boolean.parseBoolean(props.getProperty("embedded", "false")); 415 boolean isEmbedded = Boolean.parseBoolean(props.getProperty("embedded", "false"));
406 String language = props.getProperty("language", "sql"); 416 String language = props.getProperty("language", "sql");
407 String username = props.getProperty("user", null); 417 String username = props.getProperty("user");
408 String password = props.getProperty("password", null); 418 String password = props.getProperty("password");
409 String database = props.getProperty("database");
410 if (database == null || database.trim().isEmpty())
411 throw new IllegalArgumentException("database should not be null or empty");
412 String hash = props.getProperty("hash"); 419 String hash = props.getProperty("hash");
413 int sockTimeout = 0; 420 int sockTimeout = 0;
414 421
415 //instantiate the connection 422 if(isEmbedded) { //instantiate the connection
416 if(isEmbedded) {
417 String directory = props.getProperty("directory");
418 if (directory == null || directory.trim().isEmpty())
419 throw new IllegalArgumentException("directory should not be null or empty");
420 try { 423 try {
421 if(EmbeddedConnectionClass == null) { 424 if(EmbeddedConnectionClass == null) {
422 EmbeddedConnectionClass = Class.forName("nl.cwi.monetdb.embedded.jdbc.EmbeddedConnection"); 425 EmbeddedConnectionClass = Class.forName("nl.cwi.monetdb.embedded.jdbc.EmbeddedConnection");
423 } 426 }
424 if(EmbeddedConnectionClass == null) { //if it's still null then there is a problem 427 if(EmbeddedConnectionClass == null) { //if it's still null then there is a problem
425 throw new SQLException("EmbeddedConnection Class not found!"); 428 throw new SQLException("EmbeddedConnection Class not found!");
426 } 429 }
427 res = (MonetConnection) EmbeddedConnectionClass 430 res = (MonetConnection) EmbeddedConnectionClass
428 .getDeclaredConstructor(Properties.class, String.class, String.class, String.class, String.class) 431 .getDeclaredConstructor(Properties.class, String.class, String.class)
429 .newInstance(props, database, hash, language, directory); 432 .newInstance(props, hash, language);
430 } catch (InvocationTargetException | InstantiationException | IllegalAccessException | 433 } catch (InvocationTargetException | InstantiationException | IllegalAccessException |
431 NoSuchMethodException | ClassNotFoundException e) { 434 NoSuchMethodException | ClassNotFoundException e) {
432 throw new SQLException(e); 435 throw new SQLException(e);
433 } 436 }
434 } else { 437 } else {
437 throw new IllegalArgumentException("hostname should not be null or empty"); 440 throw new IllegalArgumentException("hostname should not be null or empty");
438 if (username == null || username.trim().isEmpty()) 441 if (username == null || username.trim().isEmpty())
439 throw new IllegalArgumentException("user should not be null or empty"); 442 throw new IllegalArgumentException("user should not be null or empty");
440 if (password == null || password.trim().isEmpty()) 443 if (password == null || password.trim().isEmpty())
441 throw new IllegalArgumentException("password should not be null or empty"); 444 throw new IllegalArgumentException("password should not be null or empty");
445 String database = props.getProperty("database");
446 if (database == null || database.trim().isEmpty())
447 throw new IllegalArgumentException("database should not be null or empty");
442 448
443 boolean blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary", "false")); 449 boolean blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary", "false"));
444 boolean clobIsLongChar = Boolean.valueOf(props.getProperty("treat_clob_as_longvarchar", "false")); 450 boolean clobIsLongChar = Boolean.valueOf(props.getProperty("treat_clob_as_longvarchar", "false"));
445 451
446 boolean negative1 = false, failedparse1 = false; 452 boolean negative1 = false, failedparse1 = false;
470 negative2 = true; 476 negative2 = true;
471 sockTimeout = 0; 477 sockTimeout = 0;
472 props.setProperty("so_timeout", "0"); 478 props.setProperty("so_timeout", "0");
473 } 479 }
474 try { 480 try {
475 res = new MapiConnection(props, database, hash, language, blobIsBinary, clobIsLongChar, hostname, port); 481 res = new MapiConnection(props, hash, language, blobIsBinary, clobIsLongChar, hostname, port, database);
476 } catch (IOException e) { 482 } catch (IOException e) {
477 throw new SQLException(e); 483 throw new SQLException(e);
478 } 484 }
479 if(failedparse1) { 485 if(failedparse1) {
480 res.addWarning("Unable to parse port number from: " + port, "M1M05"); 486 res.addWarning("Unable to parse port number from: " + port, "M1M05");
489 res.addWarning("Negative socket timeout not allowed. Value ignored", "M1M05"); 495 res.addWarning("Negative socket timeout not allowed. Value ignored", "M1M05");
490 } 496 }
491 res.setSoTimeout(sockTimeout); 497 res.setSoTimeout(sockTimeout);
492 } 498 }
493 499
494 try { 500 try { //atempt to connect and authenticate the user
495 List<String> warnings = res.connect(username, password); 501 List<String> warnings = res.connect(username, password);
496 if(warnings != null) { 502 if(warnings != null) {
497 for (String warning : warnings) { 503 for (String warning : warnings) {
498 res.addWarning(warning, "01M02"); 504 res.addWarning(warning, "01M02");
499 } 505 }
506 if(!isEmbedded) { 512 if(!isEmbedded) {
507 MapiConnection con = (MapiConnection) res; 513 MapiConnection con = (MapiConnection) res;
508 throw new SQLException("Unable to connect (" + con.getHostname() + ":" 514 throw new SQLException("Unable to connect (" + con.getHostname() + ":"
509 + con.getPort() + "): " + e.getMessage(), "08006"); 515 + con.getPort() + "): " + e.getMessage(), "08006");
510 } else { 516 } else {
511 try { 517 throw new SQLException("Unable to connect: " + e.getMessage(), "08006");
512 java.lang.reflect.Method method = EmbeddedConnectionClass.getMethod("getDirectory");
513 String directory = (String) method.invoke(EmbeddedConnectionClass.cast(res));
514 throw new SQLException("Unable to start the farm on the directory: " + directory +
515 " Details:" + e.getMessage(), "08006");
516 } catch (NoSuchMethodException | SecurityException | IllegalArgumentException |
517 IllegalAccessException | InvocationTargetException ex) {
518 throw new SQLException(e.getMessage());
519 }
520 } 518 }
521 } catch (ProtocolException e) { 519 } catch (ProtocolException e) {
522 throw new SQLException(e.getMessage(), "08001"); 520 throw new SQLException(e.getMessage(), "08001");
523 } catch (MCLException e) { 521 } catch (MCLException e) {
524 String[] connex = e.getMessage().split("\n"); 522 String[] connex = e.getMessage().split("\n");
527 sqle.setNextException(new SQLException(connex[1], "08001")); 525 sqle.setNextException(new SQLException(connex[1], "08001"));
528 } 526 }
529 throw sqle; 527 throw sqle;
530 } 528 }
531 529
532 //set the timezone 530 if (!isEmbedded && res.getLanguage() == MapiLanguage.LANG_SQL) { //set the timezone only in the MAPI connection
533 if (res.getLanguage() == MapiLanguage.LANG_SQL) {
534 // enable auto commit 531 // enable auto commit
535 res.setAutoCommit(true); 532 res.setAutoCommit(true);
536 // set our time zone on the server 533 // set our time zone on the server
537 Calendar cal = Calendar.getInstance(); 534 Calendar cal = Calendar.getInstance();
538 int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET); 535 int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);