comparison src/main/java/org/monetdb/jdbc/MonetConnection.java @ 551:5ce6a942aff3 onclient

Last minute API fix: 'int offset' -> 'long linesToSkip' Int -> long because there might be many lines Offset -> linesToSkip to save users some work. The COPY INTO statement has an OFFSET modifier which is 1-based but also allows 0. This means both 0 and 1 mean 'upload the whole file' and any N > 1 means skip N-1 lines and upload the rest. To avoid having to deal with this over and over in every implementation of MonetConnection.UploadHandler#handleUpload(), parameter 'offset' has been replaced with 'linesToSkip' where the adjustment has already been performed.
author Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
date Tue, 14 Sep 2021 10:52:04 +0200 (2021-09-14)
parents eb7ecfbb48f2
children 7b320303b579
comparison
equal deleted inserted replaced
550:c5cf3f00c4c5 551:5ce6a942aff3
3211 // }}} 3211 // }}}
3212 3212
3213 private String handleTransfer(String transferCommand) throws IOException { 3213 private String handleTransfer(String transferCommand) throws IOException {
3214 String[] parts = transferCommand.split(" ", 3); 3214 String[] parts = transferCommand.split(" ", 3);
3215 if (transferCommand.startsWith("r ") && parts.length == 3) { 3215 if (transferCommand.startsWith("r ") && parts.length == 3) {
3216 final int offset; 3216 final long offset;
3217 try { 3217 try {
3218 offset = Integer.parseInt(parts[1]); 3218 offset = Long.parseLong(parts[1]);
3219 } catch (NumberFormatException e) { 3219 } catch (NumberFormatException e) {
3220 return e.toString(); 3220 return e.toString();
3221 } 3221 }
3222 return handleUpload(parts[2], true, offset); 3222 return handleUpload(parts[2], true, offset);
3223 } else if (transferCommand.startsWith("rb ")) { 3223 } else if (transferCommand.startsWith("rb ")) {
3227 } else { 3227 } else {
3228 return "JDBC does not support this file transfer yet: " + transferCommand; 3228 return "JDBC does not support this file transfer yet: " + transferCommand;
3229 } 3229 }
3230 } 3230 }
3231 3231
3232 private String handleUpload(String path, boolean textMode, int offset) throws IOException { 3232 private String handleUpload(String path, boolean textMode, long offset) throws IOException {
3233 if (uploadHandler == null) { 3233 if (uploadHandler == null) {
3234 return "No file upload handler has been registered with the JDBC driver"; 3234 return "No file upload handler has been registered with the JDBC driver";
3235 } 3235 }
3236 3236
3237 long linesToSkip = offset >= 1 ? offset - 1 : 0;
3237 Upload handle = new Upload(server); 3238 Upload handle = new Upload(server);
3238 boolean wasFaking = server.setInsertFakePrompts(false); 3239 boolean wasFaking = server.setInsertFakePrompts(false);
3239 try { 3240 try {
3240 uploadHandler.handleUpload(handle, path, textMode, offset); 3241 uploadHandler.handleUpload(handle, path, textMode, linesToSkip);
3241 if (!handle.hasBeenUsed()) { 3242 if (!handle.hasBeenUsed()) {
3242 String message = String.format("Call to %s.handleUpload for path '%s' sent neither data nor an error message", 3243 String message = String.format("Call to %s.handleUpload for path '%s' sent neither data nor an error message",
3243 uploadHandler.getClass().getCanonicalName(), path); 3244 uploadHandler.getClass().getCanonicalName(), path);
3244 throw new IOException(message); 3245 throw new IOException(message);
3245 } 3246 }
3278 public static interface UploadHandler { 3279 public static interface UploadHandler {
3279 /** 3280 /**
3280 * Called if the server sends a request to read file data. 3281 * Called if the server sends a request to read file data.
3281 * 3282 *
3282 * Use the given handle to receive data or send errors to the server. 3283 * Use the given handle to receive data or send errors to the server.
3283 * 3284 * @param handle Handle to communicate with the server
3284 * @param handle Handle to communicate with the server
3285 * @param name Name of the file the server would like to read. Make sure 3285 * @param name Name of the file the server would like to read. Make sure
3286 * to validate this before reading from the file system 3286 * to validate this before reading from the file system
3287 * @param textMode Whether this is text or binary data. 3287 * @param textMode Whether this is text or binary data.
3288 * @param offset line number of the first line to upload. Both 0 and 1 3288 * @param linesToSkip In text mode, number of initial lines to skip.
3289 * mean 'upload the whole file', 2 means 'skip line 1', 3289 * 0 means upload everything, 1 means skip the first line, etc.
3290 * etc. 3290 * Note: this is different from the OFFSET option of the COPY INTO,
3291 */ 3291 * where both 0 and 1 mean 'upload everything'
3292 void handleUpload(Upload handle, String name, boolean textMode, int offset) throws IOException; 3292 */
3293 void handleUpload(Upload handle, String name, boolean textMode, long linesToSkip) throws IOException;
3293 } 3294 }
3294 3295
3295 /** 3296 /**
3296 * Callback for receiving files with COPY ON CLIENT 3297 * Callback for receiving files with COPY ON CLIENT
3297 * 3298 *
3411 } 3412 }
3412 3413
3413 /** 3414 /**
3414 * Read data from the given buffered reader and send it to the server 3415 * Read data from the given buffered reader and send it to the server
3415 * @param reader reader to read from 3416 * @param reader reader to read from
3416 * @param offset start uploading at line {@code offset}. Value 0 and 1 3417 * @param linesToSkip start uploading at line {@code offset}. Value 0 and 1
3417 * both mean upload the whole file, value 2 means skip the first line, etc.q 3418 * both mean upload the whole file, value 2 means skip the first line, etc.q
3418 * @throws IOException 3419 * @throws IOException
3419 */ 3420 */
3420 public void uploadFrom(BufferedReader reader, int offset) throws IOException { 3421 public void uploadFrom(BufferedReader reader, long linesToSkip) throws IOException {
3421 // we're 1-based but also accept 0 3422 for (int i = 0; i < linesToSkip; i++) {
3422 if (offset > 0) {
3423 offset -= 1;
3424 }
3425
3426 for (int i = 0; i < offset; i++) {
3427 String line = reader.readLine(); 3423 String line = reader.readLine();
3428 if (line == null) { 3424 if (line == null) {
3429 return; 3425 return;
3430 } 3426 }
3431 } 3427 }