comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java @ 7:b3ca1157be73

Improve DatabaseMetaData.getDatabaseProductVersion() to never return a null String. This prevents runtime NullPointerException in getTables() and getTableTypes(). Also improved error reporting when JDBC driver failed to fetch the value of environment variable monet_version as reported in bug 4038. It will now throw an SQLException with the error message.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 29 Sep 2016 13:02:21 +0200 (2016-09-29)
parents a5a898f6886c
children 6e48d0fae766
comparison
equal deleted inserted replaced
6:2165c6f838fe 7:b3ca1157be73
25 * @author Fabian Groffen, Martin van Dinther 25 * @author Fabian Groffen, Martin van Dinther
26 * @version 0.6 26 * @version 0.6
27 */ 27 */
28 public class MonetDatabaseMetaData extends MonetWrapper implements DatabaseMetaData { 28 public class MonetDatabaseMetaData extends MonetWrapper implements DatabaseMetaData {
29 private Connection con; 29 private Connection con;
30
31 // Internal cache for 3 server environment values
30 private String env_current_user; 32 private String env_current_user;
31 private String env_monet_version; 33 private String env_monet_version;
32 private String env_max_clients; 34 private String env_max_clients;
33 35
34 public MonetDatabaseMetaData(Connection parent) { 36 public MonetDatabaseMetaData(Connection parent) {
35 con = parent; 37 con = parent;
36 } 38 }
37 39
38 /** 40 /**
39 * Internal cache for 3 environment values retrieved from the 41 * Utility method to fetch some server environment values combined in one query for efficiency.
40 * server, to avoid querying the server over and over again. 42 * We currently fetch the env values of: current_user, monet_version and max_clients.
41 * Once a value is read, it is kept in the private env_* variables for reuse. 43 * We cache them locally such that we do not need to query the server again and again.
42 * We currently only need the env values of: current_user, monet_version and max_clients. 44 */
43 */ 45 private synchronized void getEnvValues() throws SQLException {
44 private synchronized void getEnvValues() {
45 Statement st = null; 46 Statement st = null;
46 ResultSet rs = null; 47 ResultSet rs = null;
47 try { 48 try {
48 st = con.createStatement(); 49 st = con.createStatement();
49 rs = st.executeQuery( 50 rs = st.executeQuery(
63 if ("max_clients".equals(prop)) { 64 if ("max_clients".equals(prop)) {
64 env_max_clients = value; 65 env_max_clients = value;
65 } 66 }
66 } 67 }
67 } 68 }
68 } catch (SQLException e) { 69 /* do not catch SQLException here, as we want to know it when it fails */
69 // ignore
70 } finally { 70 } finally {
71 if (rs != null) { 71 if (rs != null) {
72 try { 72 try {
73 rs.close(); 73 rs.close();
74 } catch (SQLException e) { /* ignore */ } 74 } catch (SQLException e) { /* ignore */ }
222 */ 222 */
223 @Override 223 @Override
224 public String getDatabaseProductVersion() throws SQLException { 224 public String getDatabaseProductVersion() throws SQLException {
225 if (env_monet_version == null) 225 if (env_monet_version == null)
226 getEnvValues(); 226 getEnvValues();
227 return env_monet_version; 227 // always return a valid String to prevent NPE in getTables() and getTableTypes()
228 return (env_monet_version != null) ? env_monet_version : "";
228 } 229 }
229 230
230 /** 231 /**
231 * What is the name of this JDBC driver? 232 * What is the name of this JDBC driver?
232 * 233 *
1406 * number here. 1407 * number here.
1407 * 1408 *
1408 * @return the maximum number of connections 1409 * @return the maximum number of connections
1409 */ 1410 */
1410 @Override 1411 @Override
1411 public int getMaxConnections() { 1412 public int getMaxConnections() throws SQLException {
1412 if (env_max_clients == null) 1413 if (env_max_clients == null)
1413 getEnvValues(); 1414 getEnvValues();
1414 1415
1415 int max_clients = 16; 1416 int max_clients = 16;
1416 if (env_max_clients != null) { 1417 if (env_max_clients != null) {
3609 getEnvValues(); 3610 getEnvValues();
3610 int major = 0; 3611 int major = 0;
3611 if (env_monet_version != null) { 3612 if (env_monet_version != null) {
3612 try { 3613 try {
3613 int start = env_monet_version.indexOf("."); 3614 int start = env_monet_version.indexOf(".");
3614 major = Integer.parseInt(env_monet_version.substring(0, start)); 3615 major = Integer.parseInt((start >= 0) ? env_monet_version.substring(0, start) : env_monet_version);
3615 } catch (NumberFormatException e) { 3616 } catch (NumberFormatException e) {
3616 // ignore 3617 // ignore
3617 } 3618 }
3618 } 3619 }
3619 return major; 3620 return major;
3631 getEnvValues(); 3632 getEnvValues();
3632 int minor = 0; 3633 int minor = 0;
3633 if (env_monet_version != null) { 3634 if (env_monet_version != null) {
3634 try { 3635 try {
3635 int start = env_monet_version.indexOf("."); 3636 int start = env_monet_version.indexOf(".");
3636 int end = env_monet_version.indexOf(".", start + 1); 3637 if (start >= 0) {
3637 minor = Integer.parseInt(env_monet_version.substring(start + 1, end)); 3638 start++;
3639 int end = env_monet_version.indexOf(".", start);
3640 minor = Integer.parseInt((end > 0) ? env_monet_version.substring(start, end) : env_monet_version.substring(start));
3641 }
3638 } catch (NumberFormatException e) { 3642 } catch (NumberFormatException e) {
3639 // ignore 3643 // ignore
3640 } 3644 }
3641 } 3645 }
3642 return minor; 3646 return minor;