Mercurial > hg > monetdb-java
comparison src/main/java/org/monetdb/jdbc/MonetConnection.java @ 620:5ab170ddc66a
Some small improvements
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Wed, 19 Jan 2022 21:30:10 +0100 (2022-01-19) |
parents | 15eb17b911a5 |
children | 1c3cdf0667d7 |
comparison
equal
deleted
inserted
replaced
619:ffc2fc8e82ec | 620:5ab170ddc66a |
---|---|
3142 tmpLine = in.readLine(); | 3142 tmpLine = in.readLine(); |
3143 linetype = in.getLineType(); | 3143 linetype = in.getLineType(); |
3144 break; | 3144 break; |
3145 case FILETRANSFER: | 3145 case FILETRANSFER: |
3146 // Consume the command | 3146 // Consume the command |
3147 String transferCommand = in.readLine(); | 3147 final String transferCommand = in.readLine(); |
3148 // Consume the fake prompt inserted by MapiSocket. | 3148 // Consume the fake prompt inserted by MapiSocket. |
3149 String dummy = in.readLine(); | 3149 in.readLine(); |
3150 // Handle the request | 3150 // Handle the request |
3151 if (transferCommand != null) | 3151 if (transferCommand != null) |
3152 error = handleTransfer(transferCommand); | 3152 error = handleTransfer(transferCommand); |
3153 else | 3153 else |
3154 error = "Protocol violation, expected transfer command, got nothing"; | 3154 error = "Protocol violation, expected transfer command, got nothing"; |
3225 } else if (transferCommand.startsWith("rb ")) { | 3225 } else if (transferCommand.startsWith("rb ")) { |
3226 return handleUpload(transferCommand.substring(3), false, 0); | 3226 return handleUpload(transferCommand.substring(3), false, 0); |
3227 } else if (transferCommand.startsWith("w ")) { | 3227 } else if (transferCommand.startsWith("w ")) { |
3228 return handleDownload(transferCommand.substring(2), true); | 3228 return handleDownload(transferCommand.substring(2), true); |
3229 } else if (transferCommand.startsWith("wb ")) { | 3229 } else if (transferCommand.startsWith("wb ")) { |
3230 return handleDownload(transferCommand.substring(2), false); | 3230 return handleDownload(transferCommand.substring(3), false); |
3231 } | 3231 } |
3232 return "JDBC does not support this file transfer yet: " + transferCommand; | 3232 return "JDBC does not support this file transfer yet: " + transferCommand; |
3233 } | 3233 } |
3234 | 3234 |
3235 private String handleUpload(final String path, final boolean textMode, final long offset) throws IOException { | 3235 private String handleUpload(final String path, final boolean textMode, final long offset) throws IOException { |
3243 try { | 3243 try { |
3244 uploadHandler.handleUpload(handle, path, textMode, linesToSkip); | 3244 uploadHandler.handleUpload(handle, path, textMode, linesToSkip); |
3245 if (!handle.hasBeenUsed()) { | 3245 if (!handle.hasBeenUsed()) { |
3246 throw new IOException("Call to " + uploadHandler.getClass().getCanonicalName() + ".handleUpload for path '" + path + "' sent neither data nor an error message"); | 3246 throw new IOException("Call to " + uploadHandler.getClass().getCanonicalName() + ".handleUpload for path '" + path + "' sent neither data nor an error message"); |
3247 } | 3247 } |
3248 } finally { | |
3248 handle.close(); | 3249 handle.close(); |
3249 } finally { | |
3250 server.setInsertFakePrompts(wasFaking); | 3250 server.setInsertFakePrompts(wasFaking); |
3251 } | 3251 } |
3252 return handle.getError(); | 3252 return handle.getError(); |
3253 } | 3253 } |
3254 | 3254 |
3255 private String handleDownload(final String path, boolean textMode) throws IOException { | 3255 private String handleDownload(final String path, final boolean textMode) throws IOException { |
3256 if (downloadHandler == null) { | 3256 if (downloadHandler == null) { |
3257 return "No file download handler has been registered with the JDBC driver"; | 3257 return "No file download handler has been registered with the JDBC driver"; |
3258 } | 3258 } |
3259 | 3259 |
3260 final Download handle = new Download(server, textMode); | 3260 final Download handle = new Download(server, textMode); |
3280 public interface UploadHandler { | 3280 public interface UploadHandler { |
3281 /** | 3281 /** |
3282 * Called if the server sends a request to read file data. | 3282 * Called if the server sends a request to read file data. |
3283 * | 3283 * |
3284 * Use the given handle to receive data or send errors to the server. | 3284 * Use the given handle to receive data or send errors to the server. |
3285 * @param handle Handle to communicate with the server | 3285 * |
3286 * @param handle Handle to communicate with the server | |
3286 * @param name Name of the file the server would like to read. Make sure | 3287 * @param name Name of the file the server would like to read. Make sure |
3287 * to validate this before reading from the file system | 3288 * to validate this before reading from the file system |
3288 * @param textMode Whether to open the file as text or binary data. | 3289 * @param textMode Whether to open the file as text or binary data. |
3289 * @param linesToSkip In text mode, number of initial lines to skip. | 3290 * @param linesToSkip In text mode, number of initial lines to skip. |
3290 * 0 means upload everything, 1 means skip the first line, etc. | 3291 * 0 means upload everything, 1 means skip the first line, etc. |
3313 * Called if the server sends a request to write a file. | 3314 * Called if the server sends a request to write a file. |
3314 * | 3315 * |
3315 * Use the given handle to send data or errors to the server. | 3316 * Use the given handle to send data or errors to the server. |
3316 * | 3317 * |
3317 * @param handle Handle to communicate with the server | 3318 * @param handle Handle to communicate with the server |
3318 * @param name Name of the file the server would like to write. Make sure to validate this before writing to | 3319 * @param name Name of the file the server would like to write. Make sure |
3319 * the file system | 3320 * to validate this before writing to the file system |
3320 * @param textMode Whether this is text or binary data. | 3321 * @param textMode Whether this is text or binary data. |
3321 */ | 3322 */ |
3322 void handleDownload(Download handle, String name, boolean textMode) throws IOException; | 3323 void handleDownload(Download handle, String name, boolean textMode) throws IOException; |
3323 } | 3324 } |
3324 | 3325 |
3420 | 3421 |
3421 /** | 3422 /** |
3422 * Read data from the given buffered reader and send it to the server | 3423 * Read data from the given buffered reader and send it to the server |
3423 * @param reader reader to read from | 3424 * @param reader reader to read from |
3424 * @param linesToSkip start uploading at line {@code offset}. Value 0 and 1 | 3425 * @param linesToSkip start uploading at line {@code offset}. Value 0 and 1 |
3425 * both mean upload the whole file, value 2 means skip the first line, etc.q | 3426 * both mean upload the whole file, value 2 means skip the first line, etc. |
3426 */ | 3427 */ |
3427 public void uploadFrom(final BufferedReader reader, final long linesToSkip) throws IOException { | 3428 public void uploadFrom(final BufferedReader reader, final long linesToSkip) throws IOException { |
3428 for (int i = 0; i < linesToSkip; i++) { | 3429 for (int i = 0; i < linesToSkip; i++) { |
3429 String line = reader.readLine(); | 3430 String line = reader.readLine(); |
3430 if (line == null) { | 3431 if (line == null) { |
3492 * {@link IOException} but this will terminate the connection. | 3493 * {@link IOException} but this will terminate the connection. |
3493 * | 3494 * |
3494 * Note: as of MonetDB version Jul2021 the server always terminates the connection | 3495 * Note: as of MonetDB version Jul2021 the server always terminates the connection |
3495 * when this error is used. This will probably change in the future. | 3496 * when this error is used. This will probably change in the future. |
3496 */ | 3497 */ |
3497 public void sendError(String errorMessage) throws IOException { | 3498 public void sendError(final String errorMessage) throws IOException { |
3498 if (error != null) { | 3499 if (error != null) { |
3499 throw new IOException("another error has already been sent: " + error); | 3500 throw new IOException("another error has already been sent: " + error); |
3500 } | 3501 } |
3501 error = errorMessage; | 3502 error = errorMessage; |
3502 } | 3503 } |
3542 final InputStream s = getStream(); | 3543 final InputStream s = getStream(); |
3543 final InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8); | 3544 final InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8); |
3544 final char[] buffer = new char[65536]; | 3545 final char[] buffer = new char[65536]; |
3545 while (true) { | 3546 while (true) { |
3546 final int nread = r.read(buffer); | 3547 final int nread = r.read(buffer); |
3547 if (nread < 0) | 3548 if (nread < 0) { |
3548 break; | 3549 break; |
3550 } | |
3549 writer.write(buffer, 0, nread); | 3551 writer.write(buffer, 0, nread); |
3550 } | 3552 } |
3551 } | 3553 } |
3552 | 3554 |
3553 /** | 3555 /** |
3554 * @return true if data has been received or an error has been sent. | 3556 * @return true if data has been received or an error has been sent. |
3555 */ | 3557 */ |
3556 public boolean hasBeenUsed() { | 3558 public boolean hasBeenUsed() { |
3557 return error != null || stream != null; | 3559 return stream != null || error != null; |
3558 } | 3560 } |
3559 | 3561 |
3560 /** | 3562 /** |
3561 * @return the error that was sent, if any | 3563 * @return the error that was sent, if any |
3562 */ | 3564 */ |
3581 /** | 3583 /** |
3582 * Set the line endings used in the stream returned by {@link Download#getStream()} | 3584 * Set the line endings used in the stream returned by {@link Download#getStream()} |
3583 * @param sep separator to use | 3585 * @param sep separator to use |
3584 * @throws IllegalArgumentException if sep is neither "\n" nor "\r\n" | 3586 * @throws IllegalArgumentException if sep is neither "\n" nor "\r\n" |
3585 */ | 3587 */ |
3586 public void setLineSeparator(String sep) { | 3588 public void setLineSeparator(final String sep) { |
3587 if ("\n".equals(sep)) { | 3589 if ("\n".equals(sep)) { |
3588 prependCr = false; | 3590 prependCr = false; |
3589 } else if ("\r\n".equals(sep)) { | 3591 } else if ("\r\n".equals(sep)) { |
3590 prependCr = true; | 3592 prependCr = true; |
3591 } else { | 3593 } else { |
3592 throw new IllegalArgumentException("sep must be \n or \r\n"); | 3594 throw new IllegalArgumentException("sep must be \\n or \\r\\n"); |
3593 } | 3595 } |
3594 } | 3596 } |
3595 } | 3597 } |
3596 | 3598 |
3597 public static class StripCrLfStream extends FilterOutputStream { | 3599 public static class StripCrLfStream extends FilterOutputStream { |
3604 public boolean pending() { | 3606 public boolean pending() { |
3605 return this.crPending; | 3607 return this.crPending; |
3606 } | 3608 } |
3607 | 3609 |
3608 @Override | 3610 @Override |
3609 public void write(int b) throws IOException { | 3611 public void write(final int b) throws IOException { |
3610 if (crPending && b != '\n') { | 3612 if (crPending && b != '\n') { |
3611 out.write('\r'); | 3613 out.write('\r'); |
3612 } | 3614 } |
3613 if (b != '\r') { | 3615 if (b != '\r') { |
3614 out.write(b); | 3616 out.write(b); |
3615 crPending = false; | 3617 crPending = false; |
3616 } else { | 3618 } else { |
3617 crPending = true; | 3619 crPending = true; |
3618 } | 3620 } |
3619 } | 3621 } |
3620 | 3622 |
3621 @Override | 3623 @Override |
3622 public void write(byte[] b) throws IOException { | 3624 public void write(final byte[] b) throws IOException { |
3623 this.write(b, 0, b.length); | 3625 this.write(b, 0, b.length); |
3624 } | 3626 } |
3625 | 3627 |
3626 @Override | 3628 @Override |
3627 public void write(byte[] b, int off, int len) throws IOException { | 3629 public void write(final byte[] b, int off, int len) throws IOException { |
3628 if (len == 0) { | 3630 if (len == 0) { |
3629 return; | 3631 return; |
3630 } | 3632 } |
3631 if (crPending && b[0] != '\n') { | 3633 if (crPending && b[0] != '\n') { |
3632 out.write('\r'); | 3634 out.write('\r'); |