Mercurial > hg > monetdb-java
diff src/main/java/org/monetdb/jdbc/MonetConnection.java @ 700:940e266eeccd
Refactor BufferedMCLReader
It used to inherit from BufferedReader but there is no reason for that.
Also, it used to have a method readLine() which
- returned the line read
- stored the linetype
In the new setup we have a method advance() which reads
a line and stores both it and its type.
This makes the code more regular and makes it possible to
peek ahead without consuming.
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Thu, 08 Dec 2022 15:59:17 +0100 (2022-12-08) |
parents | 68422d7f3961 |
children | f89882b07614 |
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java @@ -343,7 +343,7 @@ public class MonetConnection in = server.getReader(); out = server.getWriter(); - final String error = in.waitForPrompt(); + final String error = in.discardRemainder(); if (error != null) throw new SQLNonTransientConnectionException((error.length() > 6) ? error.substring(6) : error, "08001"); } catch (java.net.UnknownHostException e) { @@ -2138,7 +2138,7 @@ public class MonetConnection out.writeLine(queryTempl[0] + command + queryTempl[1]); else out.writeLine(commandTempl[0] + command + commandTempl[1]); - final String error = in.waitForPrompt(); + final String error = in.discardRemainder(); if (error != null) throw new SQLException(error.substring(6), error.substring(0, 5)); } catch (SocketTimeoutException e) { @@ -3131,7 +3131,7 @@ public class MonetConnection // have the prompt it is possible (and most likely) that we // already have the prompt and do not have to skip any // lines. Ignore errors from previous result sets. - in.waitForPrompt(); + in.discardRemainder(); // {{{ set reply size /** @@ -3158,16 +3158,15 @@ public class MonetConnection out.writeLine(templ[0] + query + templ[1]); // go for new results - String tmpLine = in.readLine(); - LineType linetype = in.getLineType(); + in.advance(); Response res = null; - while (linetype != LineType.PROMPT) { + while (in.getLineType() != LineType.PROMPT) { // each response should start with a start of header (or error) - switch (linetype) { + switch (in.getLineType()) { case SOHEADER: // make the response object, and fill it try { - switch (sohp.parse(tmpLine)) { + switch (sohp.parse(in.getLine())) { case StartOfHeaderParser.Q_PARSE: throw new MCLParseException("Q_PARSE header not allowed here", 1); case StartOfHeaderParser.Q_TABLE: @@ -3228,31 +3227,29 @@ public class MonetConnection final int offset = e.getErrorOffset(); error = "M0M10!error while parsing start of header:\n" + e.getMessage() + - " found: '" + tmpLine.charAt(offset) + - "' in: \"" + tmpLine + + " found: '" + in.getLine().charAt(offset) + + "' in: \"" + in.getLine() + "\" at pos: " + offset; // flush all the rest - in.waitForPrompt(); - linetype = in.getLineType(); + in.discardRemainder(); break; } // immediately handle errors after parsing the header (res may be null) if (error != null) { - in.waitForPrompt(); - linetype = in.getLineType(); + in.discardRemainder(); break; } // here we have a res object, which we can start filling while (res.wantsMore()) { - error = res.addLine(in.readLine(), in.getLineType()); + in.advance(); + error = res.addLine(in.getLine(), in.getLineType()); if (error != null) { // right, some protocol violation, // skip the rest of the result error = "M0M10!" + error; - in.waitForPrompt(); - linetype = in.getLineType(); + in.discardRemainder(); break; } } @@ -3266,21 +3263,20 @@ public class MonetConnection // read the next line (can be prompt, new result, error, etc.) // before we start the loop over - tmpLine = in.readLine(); - linetype = in.getLineType(); + in.advance(); break; case INFO: - addWarning(tmpLine.substring(1), "01000"); + addWarning(in.getLine().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(); + in.advance(); break; case FILETRANSFER: // Consume the command - final String transferCommand = in.readLine(); + in.advance(); + final String transferCommand = in.getLine(); // Consume the fake prompt inserted by MapiSocket. - in.readLine(); + in.advance(); // Handle the request if (transferCommand != null) error = handleTransfer(transferCommand); @@ -3289,27 +3285,21 @@ public class MonetConnection // Then prepare for the next iteration if (error != null) { out.writeLine(error + "\n"); - error = in.waitForPrompt(); + error = in.discardRemainder(); } else { - tmpLine = in.readLine(); + in.advance(); } - linetype = in.getLineType(); break; - default: // Yeah... in Java this is correct! + default: // we have something we don't expect/understand, let's make it an error message - tmpLine = "!M0M10!protocol violation, unexpected " + linetype + " line: " + tmpLine; - // don't break; fall through... + String msg = "M0M10!protocol violation, unexpected " + in.getLineType() + " line: " + in.getLine(); + error = in.discardRemainder(msg); + break; case 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); - } + error = in.discardRemainder(in.getLine().substring(1)); break; } // end of switch (linetype) } // end of while (linetype != LineType.PROMPT)