Mercurial > hg > monetdb-java
changeset 284:e5b99c929a2d
Improve setSchema(String schema) by checking also on empty name.
Improve setSchema(String schema) and getSchema() by checking on null to prevent NPE's
Reduce indentation in executeQuery(String[] templ, String query).
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 25 Jul 2019 15:35:37 +0200 (2019-07-25) |
parents | 92e882feea95 |
children | 637899bda602 |
files | src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java |
diffstat | 1 files changed, 151 insertions(+), 165 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java @@ -110,8 +110,8 @@ public class MonetConnection /** The stack of warnings for this Connection object */ private SQLWarning warnings = null; - /** The Connection specific mapping of user defined types to Java - * types */ + + /** The Connection specific mapping of user defined types to Java types */ private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() { private static final long serialVersionUID = 1L; { @@ -1318,7 +1318,7 @@ public class MonetConnection if (closed) return false; - // ping db using query: select 1; + // ping monetdb server using query: select 1; Statement stmt = null; ResultSet rs = null; boolean isValid = false; @@ -1521,14 +1521,21 @@ public class MonetConnection public void setSchema(String schema) throws SQLException { if (closed) throw new SQLException("Cannot call on closed Connection", "M1M20"); - if (schema == null) + if (schema == null || schema.isEmpty()) throw new SQLException("Missing schema name", "M1M05"); - Statement st = createStatement(); + Statement st = null; try { - st.execute("SET SCHEMA \"" + schema + "\""); + st = createStatement(); + if (st != null) + st.execute("SET SCHEMA \"" + schema + "\""); + // do not catch any Exception, just let it propagate } finally { - st.close(); + if (st != null) { + try { + st.close(); + } catch (SQLException e) { /* ignore */ } + } } } @@ -1545,19 +1552,33 @@ public class MonetConnection if (closed) throw new SQLException("Cannot call on closed Connection", "M1M20"); - String cur_schema; - Statement st = createStatement(); + String cur_schema = null; + Statement st = null; ResultSet rs = null; try { - rs = st.executeQuery("SELECT CURRENT_SCHEMA"); - if (!rs.next()) - throw new SQLException("Row expected", "02000"); - cur_schema = rs.getString(1); + st = createStatement(); + if (st != null) { + rs = st.executeQuery("SELECT CURRENT_SCHEMA"); + if (rs != null) { + if (rs.next()) + cur_schema = rs.getString(1); + } + } + // do not catch any Exception, just let it propagate } finally { - if (rs != null) - rs.close(); - st.close(); + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { /* ignore */ } + } + if (st != null) { + try { + st.close(); + } catch (SQLException e) { /* ignore */ } + } } + if (cur_schema == null) + throw new SQLException("Failed to fetch schema name", "02000"); return cur_schema; } @@ -2731,169 +2752,134 @@ public class MonetConnection int linetype = in.getLineType(); Response res = null; while (linetype != BufferedMCLReader.PROMPT) { - // each response should start with a start of header - // (or error) + // each response should start with a start of header (or error) switch (linetype) { - case BufferedMCLReader.SOHEADER: - // make the response object, and fill it - try { - switch (sohp.parse(tmpLine)) { - case StartOfHeaderParser.Q_PARSE: - throw new MCLParseException("Q_PARSE header not allowed here", 1); - case StartOfHeaderParser.Q_TABLE: - case StartOfHeaderParser.Q_PREPARE: { - int id = sohp.getNextAsInt(); - int tuplecount = sohp.getNextAsInt(); - int columncount = sohp.getNextAsInt(); - int rowcount = sohp.getNextAsInt(); - // enforce the maxrows setting - if (maxrows != 0 && tuplecount > maxrows) - tuplecount = maxrows; - res = new ResultSetResponse( - id, - tuplecount, - columncount, - rowcount, - this, - seqnr - ); - // only add this resultset to - // the hashmap if it can possibly - // have an additional datablock - if (rowcount < tuplecount) { - if (rsresponses == null) - rsresponses = new HashMap<Integer, ResultSetResponse>(); - rsresponses.put( - Integer.valueOf(id), - (ResultSetResponse) res + case BufferedMCLReader.SOHEADER: + // make the response object, and fill it + try { + switch (sohp.parse(tmpLine)) { + case StartOfHeaderParser.Q_PARSE: + throw new MCLParseException("Q_PARSE header not allowed here", 1); + case StartOfHeaderParser.Q_TABLE: + case StartOfHeaderParser.Q_PREPARE: { + int id = sohp.getNextAsInt(); + int tuplecount = sohp.getNextAsInt(); + int columncount = sohp.getNextAsInt(); + int rowcount = sohp.getNextAsInt(); + // enforce the maxrows setting + if (maxrows != 0 && tuplecount > maxrows) + tuplecount = maxrows; + res = new ResultSetResponse(id, tuplecount, columncount, rowcount, this, seqnr); + // only add this resultset to the hashmap if it can possibly have an additional datablock + if (rowcount < tuplecount) { + if (rsresponses == null) + rsresponses = new HashMap<Integer, ResultSetResponse>(); + rsresponses.put(Integer.valueOf(id), (ResultSetResponse) res); + } + } break; + case StartOfHeaderParser.Q_UPDATE: + res = new UpdateResponse(sohp.getNextAsInt(), // count + sohp.getNextAsString() // key-id ); - } - } break; - case StartOfHeaderParser.Q_UPDATE: - res = new UpdateResponse( - sohp.getNextAsInt(), // count - sohp.getNextAsString() // key-id - ); + break; + case StartOfHeaderParser.Q_SCHEMA: + res = new SchemaResponse(); + break; + case StartOfHeaderParser.Q_TRANS: + boolean ac = sohp.getNextAsString().equals("t") ? true : false; + if (autoCommit && ac) { + addWarning("Server enabled auto commit mode " + + "while local state already was auto commit.", "01M11"); + } + autoCommit = ac; + res = new AutoCommitResponse(ac); + break; + case StartOfHeaderParser.Q_BLOCK: { + // a new block of results for a response... + int id = sohp.getNextAsInt(); + sohp.getNextAsInt(); // columncount + int rowcount = sohp.getNextAsInt(); + int offset = sohp.getNextAsInt(); + ResultSetResponse t = rsresponses.get(Integer.valueOf(id)); + if (t == null) { + error = "M0M12!no ResultSetResponse with id " + id + " found"; break; - case StartOfHeaderParser.Q_SCHEMA: - res = new SchemaResponse(); - break; - case StartOfHeaderParser.Q_TRANS: - boolean ac = sohp.getNextAsString().equals("t") ? true : false; - if (autoCommit && ac) { - addWarning("Server enabled auto commit " + - "mode while local state " + - "already was auto commit.", "01M11" - ); - } - autoCommit = ac; - res = new AutoCommitResponse(ac); - break; - case StartOfHeaderParser.Q_BLOCK: { - // a new block of results for a - // response... - int id = sohp.getNextAsInt(); - sohp.getNextAsInt(); // columncount - int rowcount = sohp.getNextAsInt(); - int offset = sohp.getNextAsInt(); - ResultSetResponse t = - rsresponses.get(Integer.valueOf(id)); - if (t == null) { - error = "M0M12!no ResultSetResponse with id " + id + " found"; - break; - } + } + DataBlockResponse r = new DataBlockResponse(rowcount, t.getRSType() == ResultSet.TYPE_FORWARD_ONLY); + t.addDataBlockResponse(offset, r); + res = r; + } break; + } // end of switch (sohp.parse(tmpLine)) + } catch (MCLParseException e) { + error = "M0M10!error while parsing start of header:\n" + + e.getMessage() + + " found: '" + tmpLine.charAt(e.getErrorOffset()) + "'" + + " in: \"" + tmpLine + "\"" + + " at pos: " + e.getErrorOffset(); + // flush all the rest + in.waitForPrompt(); + linetype = in.getLineType(); + break; + } - DataBlockResponse r = - new DataBlockResponse( - rowcount, // rowcount - t.getRSType() == ResultSet.TYPE_FORWARD_ONLY - ); + // immediately handle errors after parsing the header (res may be null) + if (error != null) { + in.waitForPrompt(); + linetype = in.getLineType(); + break; + } - t.addDataBlockResponse(offset, r); - res = r; - } break; - } - } catch (MCLParseException e) { - error = "M0M10!error while parsing start of header:\n" + - e.getMessage() + - " found: '" + tmpLine.charAt(e.getErrorOffset()) + "'" + - " in: \"" + tmpLine + "\"" + - " at pos: " + e.getErrorOffset(); - // flush all the rest + // here we have a res object, which we can start filling + while (res.wantsMore()) { + error = res.addLine(in.readLine(), in.getLineType()); + if (error != null) { + // right, some protocol violation, + // skip the rest of the result + error = "M0M10!" + error; in.waitForPrompt(); linetype = in.getLineType(); break; } - - // immediately handle errors after parsing - // the header (res may be null) - if (error != null) { - in.waitForPrompt(); - linetype = in.getLineType(); - break; - } + } + if (error != null) + break; - // here we have a res object, which - // we can start filling - while (res.wantsMore()) { - error = res.addLine( - in.readLine(), - in.getLineType() - ); - if (error != null) { - // right, some protocol violation, - // skip the rest of the result - error = "M0M10!" + error; - in.waitForPrompt(); - linetype = in.getLineType(); - break; - } - } - if (error != null) - break; - // it is of no use to store - // DataBlockReponses, you never want to - // retrieve them directly anyway - if (!(res instanceof DataBlockResponse)) - responses.add(res); + // it is of no use to store DataBlockReponses, you never want to + // retrieve them directly anyway + if (!(res instanceof DataBlockResponse)) + responses.add(res); - // read the next line (can be prompt, new - // result, error, etc.) before we start the - // loop over - tmpLine = in.readLine(); - linetype = in.getLineType(); + // read the next line (can be prompt, new result, error, etc.) + // before we start the loop over + tmpLine = in.readLine(); + linetype = in.getLineType(); break; - case BufferedMCLReader.INFO: - addWarning(tmpLine.substring(1), "01000"); - - // read the next line (can be prompt, new - // result, error, etc.) before we start the - // loop over - tmpLine = in.readLine(); - linetype = in.getLineType(); + case BufferedMCLReader.INFO: + addWarning(tmpLine.substring(1), "01000"); + // read the next line (can be prompt, new result, error, etc.) + // before we start the loop over + tmpLine = in.readLine(); + linetype = in.getLineType(); break; - default: // Yeah... in Java this is correct! - // we have something we don't - // expect/understand, let's make it an error - // message - tmpLine = "!M0M10!protocol violation, unexpected line: " + tmpLine; - // don't break; fall through... - case BufferedMCLReader.ERROR: - // read everything till the prompt (should be - // error) we don't know if we ignore some - // garbage here... but the log should reveal - // that - error = in.waitForPrompt(); - linetype = in.getLineType(); - if (error != null) { - error = tmpLine.substring(1) + "\n" + error; - } else { - error = tmpLine.substring(1); - } + default: // Yeah... in Java this is correct! + // we have something we don't expect/understand, let's make it an error message + tmpLine = "!M0M10!protocol violation, unexpected line: " + tmpLine; + // don't break; fall through... + case BufferedMCLReader.ERROR: + // read everything till the prompt (should be + // error) we don't know if we ignore some + // garbage here... but the log should reveal that + error = in.waitForPrompt(); + linetype = in.getLineType(); + if (error != null) { + error = tmpLine.substring(1) + "\n" + error; + } else { + error = tmpLine.substring(1); + } break; - } - } - } + } // end of switch (linetype) + } // end of while (linetype != BufferedMCLReader.PROMPT) + } // end of synchronized (server) // if we used the sendThread, make sure it has finished if (sendThreadInUse) {