Mercurial > hg > monetdb-java
changeset 576:095e896f9d7a onclient
Updated comments. Improved code. Added final keywords
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Wed, 06 Oct 2021 22:48:11 +0200 (2021-10-06) |
parents | 08c9918177b2 |
children | 6ab9168ef8e1 |
files | src/main/java/org/monetdb/jdbc/MonetConnection.java src/main/java/org/monetdb/mcl/net/MapiSocket.java src/main/java/org/monetdb/util/FileTransferHandler.java |
diffstat | 3 files changed, 93 insertions(+), 91 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java @@ -68,7 +68,7 @@ import org.monetdb.mcl.parser.StartOfHea * * @author Fabian Groffen * @author Martin van Dinther - * @version 1.6 + * @version 1.7 */ public class MonetConnection extends MonetWrapper @@ -1238,7 +1238,6 @@ public class MonetConnection throw newSQLFeatureNotSupportedException("createArrayOf"); } - /** * Constructs an object that implements the Clob interface. The * object returned initially contains no data. The setAsciiStream, @@ -1674,8 +1673,9 @@ public class MonetConnection //== internal helper methods which do not belong to the JDBC interface - /** Handlers for ON CLIENT requests */ + /** Handler for COPY ... INTO ... FROM 'data-file-name' ON CLIENT requests */ private UploadHandler uploadHandler; + /** Handler for COPY ... INTO 'data-file-name' ON CLIENT requests */ private DownloadHandler downloadHandler; /** @@ -1683,7 +1683,7 @@ public class MonetConnection * * @param uploadHandler the handler to register, or null to deregister */ - public void setUploadHandler(UploadHandler uploadHandler) { + public void setUploadHandler(final UploadHandler uploadHandler) { this.uploadHandler = uploadHandler; } @@ -1693,12 +1693,13 @@ public class MonetConnection public UploadHandler getUploadHandler() { return uploadHandler; } + /** * Registers a {@link DownloadHandler} to support for example COPY select_result INTO 'data.csv' ON CLIENT * * @param downloadHandler the handler to register, or null to deregister */ - public void setDownloadHandler(DownloadHandler downloadHandler) { + public void setDownloadHandler(final DownloadHandler downloadHandler) { this.downloadHandler = downloadHandler; } @@ -3020,8 +3021,7 @@ public class MonetConnection // }}} set reply size // send query to the server - String queryLine = templ[0] + query + templ[1]; - out.writeLine(queryLine); + out.writeLine(templ[0] + query + templ[1]); // go for new results String tmpLine = in.readLine(); @@ -3210,9 +3210,9 @@ public class MonetConnection } // }}} - private String handleTransfer(String transferCommand) throws IOException { + private String handleTransfer(final String transferCommand) throws IOException { if (transferCommand.startsWith("r ")) { - String[] parts = transferCommand.split(" ", 3); + final String[] parts = transferCommand.split(" ", 3); if (parts.length == 3) { final long offset; try { @@ -3230,19 +3230,18 @@ public class MonetConnection return "JDBC does not support this file transfer yet: " + transferCommand; } - private String handleUpload(String path, boolean textMode, long offset) throws IOException { + private String handleUpload(final String path, final boolean textMode, final long offset) throws IOException { if (uploadHandler == null) { return "No file upload handler has been registered with the JDBC driver"; } - long linesToSkip = offset >= 1 ? offset - 1 : 0; - Upload handle = new Upload(server, uploadHandler::uploadCancelled); - boolean wasFaking = server.setInsertFakePrompts(false); + final long linesToSkip = offset >= 1 ? offset - 1 : 0; + final Upload handle = new Upload(server, uploadHandler::uploadCancelled); + final boolean wasFaking = server.setInsertFakePrompts(false); try { uploadHandler.handleUpload(handle, path, textMode, linesToSkip); if (!handle.hasBeenUsed()) { - String message = "Call to " + uploadHandler.getClass().getCanonicalName() + ".handleUpload for path '" + path + "' sent neither data nor an error message"; - throw new IOException(message); + throw new IOException("Call to " + uploadHandler.getClass().getCanonicalName() + ".handleUpload for path '" + path + "' sent neither data nor an error message"); } handle.close(); } finally { @@ -3251,17 +3250,16 @@ public class MonetConnection return handle.getError(); } - private String handleDownload(String path) throws IOException { + private String handleDownload(final String path) throws IOException { if (downloadHandler == null) { return "No file download handler has been registered with the JDBC driver"; } - Download handle = new Download(server); + final Download handle = new Download(server); try { downloadHandler.handleDownload(handle, path, true); if (!handle.hasBeenUsed()) { - String message = "Call to " + downloadHandler.getClass().getSimpleName() + ".handleDownload sent neither data nor error"; - handle.sendError(message); + handle.sendError("Call to " + downloadHandler.getClass().getSimpleName() + ".handleDownload sent neither data nor error"); } } finally { handle.close(); @@ -3270,9 +3268,11 @@ public class MonetConnection } /** - * Callback for sending files for COPY ON CLIENT + * Callback for sending files for COPY INTO "table" FROM 'file-name' ON CLIENT commands * * To be registered with {@link MonetConnection#setUploadHandler(UploadHandler)} + * + * An example implementation can be found at ../util/FileTransferHandler.java */ public interface UploadHandler { @@ -3300,9 +3300,11 @@ public class MonetConnection } /** - * Callback for receiving files with COPY ON CLIENT + * Callback for receiving files from COPY .. INTO 'file-name' ON CLIENT commands * * To be registered with {@link MonetConnection#setDownloadHandler(DownloadHandler)} + * + * An example implementation can be found at ../util/FileTransferHandler.java */ public interface DownloadHandler { /** @@ -3344,7 +3346,7 @@ public class MonetConnection * {@link IOException} but this will terminate the connection. * @param errorMessage error message to send */ - public void sendError(String errorMessage) throws IOException { + public void sendError(final String errorMessage) throws IOException { if (error != null) { throw new IOException("another error has already been sent: " + error); } @@ -3355,7 +3357,7 @@ public class MonetConnection * After every {@code chunkSize} bytes, the server gets the opportunity to * terminate the upload. */ - public void setChunkSize(int chunkSize) { + public void setChunkSize(final int chunkSize) { this.customChunkSize = chunkSize; } @@ -3370,7 +3372,7 @@ public class MonetConnection } if (print == null) { try { - MapiSocket.UploadStream up = customChunkSize >= 0 ? server.uploadStream(customChunkSize) : server.uploadStream(); + final MapiSocket.UploadStream up = customChunkSize >= 0 ? server.uploadStream(customChunkSize) : server.uploadStream(); up.setCancellationCallback(cancellationCallback); print = new PrintStream(up, false, "UTF-8"); up.write('\n'); @@ -3400,9 +3402,9 @@ public class MonetConnection * * For text mode uploads, the data MUST be validly UTF-8 encoded. */ - public void uploadFrom(InputStream inputStream) throws IOException { - OutputStream s = getStream(); - byte[] buffer = new byte[64 * 1024]; + public void uploadFrom(final InputStream inputStream) throws IOException { + final OutputStream s = getStream(); + final byte[] buffer = new byte[64 * 1024]; while (true) { int nread = inputStream.read(buffer); if (nread < 0) { @@ -3418,7 +3420,7 @@ public class MonetConnection * @param linesToSkip start uploading at line {@code offset}. Value 0 and 1 * both mean upload the whole file, value 2 means skip the first line, etc.q */ - public void uploadFrom(BufferedReader reader, long linesToSkip) throws IOException { + public void uploadFrom(final BufferedReader reader, final long linesToSkip) throws IOException { for (int i = 0; i < linesToSkip; i++) { String line = reader.readLine(); if (line == null) { @@ -3429,15 +3431,14 @@ public class MonetConnection uploadFrom(reader); } - /** * Read data from the given buffered reader and send it to the server * @param reader reader to read from */ - public void uploadFrom(Reader reader) throws IOException { - OutputStream s = getStream(); - OutputStreamWriter writer = new OutputStreamWriter(s, StandardCharsets.UTF_8); - char[] buffer = new char[64 * 1024]; + public void uploadFrom(final Reader reader) throws IOException { + final OutputStream s = getStream(); + final OutputStreamWriter writer = new OutputStreamWriter(s, StandardCharsets.UTF_8); + final char[] buffer = new char[64 * 1024]; while (true) { int nread = reader.read(buffer, 0, buffer.length); if (nread < 0) { @@ -3448,9 +3449,13 @@ public class MonetConnection } } + /** + * Close opened {@link PrintStream}. + */ public void close() { if (print != null) { print.close(); + print = null; } } } @@ -3463,8 +3468,6 @@ public class MonetConnection private MapiSocket.DownloadStream stream = null; private String error = null; - boolean closed = false; - Download(MapiSocket server) { this.server = server; } @@ -3508,13 +3511,14 @@ public class MonetConnection /** * Write the data from the server to the given {@link OutputStream}. */ - public void downloadTo(OutputStream stream) throws IOException { - InputStream s = getStream(); - byte[] buffer = new byte[65536]; + public void downloadTo(final OutputStream stream) throws IOException { + final InputStream s = getStream(); + final byte[] buffer = new byte[65536]; while (true) { int nread = s.read(buffer); - if (nread < 0) + if (nread < 0) { break; + } stream.write(buffer, 0, nread); } } @@ -3522,7 +3526,6 @@ public class MonetConnection /** * @return true if data has been received or an error has been sent. */ - public boolean hasBeenUsed() { return error != null || stream != null; } @@ -3530,18 +3533,22 @@ public class MonetConnection /** * @return the error that was sent, if any */ - public String getError() { return error; } - public void close() throws IOException { - if (closed) { - return; + + /** + * Close opened stream. + */ + public void close() { + if (stream != null) { + try { + stream.close(); + stream = null; + } catch (IOException e) { + /* ignore close error */ + } } - if (stream != null) { - stream.close(); - } - closed = true; } } }
--- a/src/main/java/org/monetdb/mcl/net/MapiSocket.java +++ b/src/main/java/org/monetdb/mcl/net/MapiSocket.java @@ -81,7 +81,7 @@ import org.monetdb.mcl.parser.MCLParseEx * geared towards the format of the data. * * @author Fabian Groffen - * @version 4.1 + * @version 4.2 * @see org.monetdb.mcl.io.BufferedMCLReader * @see org.monetdb.mcl.io.BufferedMCLWriter */ @@ -431,6 +431,7 @@ public class MapiSocket { /* cannot (yet * @param language the language to use * @param database the database to connect to * @param hash the hash method(s) to use, or NULL for all supported hashes + * @return the response string for the server */ private String getChallengeResponse( final String chalstr, @@ -549,10 +550,9 @@ public class MapiSocket { /* cannot (yet + username + ":" + pwhash + ":" + language + ":" - + (database == null ? "" : database) + ":"; - response += "FILETRANS:"; + + (database == null ? "" : database) + ":" + + "FILETRANS:"; // this capability is added in monetdb-jdbc-3.2.jre8.jar if (chaltok.length > 6) { - // if supported, send handshake options for (String part : chaltok[6].split(",")) { if (part.startsWith("sql=") && handshakeOptions != null) { @@ -568,7 +568,6 @@ public class MapiSocket { /* cannot (yet } // this ':' delimits the handshake options field. response += ":"; - } return response; default: @@ -599,7 +598,6 @@ public class MapiSocket { /* cannot (yet : (char) ('0' + n); } - /** * Returns an InputStream that reads from this open connection on * the MapiSocket. @@ -735,6 +733,7 @@ public class MapiSocket { /* cannot (yet return fromMonet.setInsertFakePrompts(b); } + /** * Inner class that is used to write data on a normal stream as a * blocked stream. A call to the flush() method will write a @@ -1218,10 +1217,11 @@ public class MapiSocket { /* cannot (yet super.finalize(); } + /** * Stream of data sent to the server - * - * Building block for {@link org.monetdb.jdbc.MonetConnection.UploadHandler}. + * + * Building block for {@link org.monetdb.jdbc.MonetConnection.UploadHandler}. * * An UploadStream has a chunk size. Every chunk size bytes, the server gets * the opportunity to abort the upload. @@ -1236,7 +1236,7 @@ public class MapiSocket { /* cannot (yet private Runnable cancellationCallback = null; /** Create an UploadStream with the given chunk size */ - UploadStream(int chunkSize) { + UploadStream(final int chunkSize) { super(toMonet); if (chunkSize <= 0) { throw new IllegalArgumentException("chunk size must be positive"); @@ -1255,12 +1255,12 @@ public class MapiSocket { /* cannot (yet /** Set a callback to be invoked if the server cancels the upload */ - public void setCancellationCallback(Runnable cancellationCallback) { + public void setCancellationCallback(final Runnable cancellationCallback) { this.cancellationCallback = cancellationCallback; } @Override - public void write(int b) throws IOException { + public void write(final int b) throws IOException { if (serverCancelled) { // We have already thrown an exception and apparently that has been ignored. // Probably because they're calling print methods instead of write. @@ -1273,12 +1273,12 @@ public class MapiSocket { /* cannot (yet } @Override - public void write(byte[] b) throws IOException { + public void write(final byte[] b) throws IOException { write(b, 0, b.length); } @Override - public void write(byte[] b, int off, int len) throws IOException { + public void write(final byte[] b, int off, int len) throws IOException { if (serverCancelled) { // We have already thrown an exception and apparently that has been ignored. // Probably because they're calling print methods instead of write. @@ -1320,17 +1320,17 @@ public class MapiSocket { /* cannot (yet } // send empty block out.flush(); - LineType acknowledgement = readPrompt(); + final LineType acknowledgement = readPrompt(); if (acknowledgement != LineType.FILETRANSFER) { throw new IOException("Expected server to acknowledge end of file"); } } - private void closeAfterServerCancelled() throws IOException { + private void closeAfterServerCancelled() { // nothing to do here, we have already read the error prompt. } - private void wrote(int i) { + private void wrote(final int i) { chunkLeft -= i; } @@ -1344,7 +1344,7 @@ public class MapiSocket { /* cannot (yet private void flushAndReadPrompt() throws IOException { out.flush(); chunkLeft = chunkSize; - LineType lineType = readPrompt(); + final LineType lineType = readPrompt(); switch (lineType) { case MORE: return; @@ -1362,22 +1362,21 @@ public class MapiSocket { /* cannot (yet } private LineType readPrompt() throws IOException { - int nread = fromMonet.read(promptBuffer); + final int nread = fromMonet.read(promptBuffer); if (nread != promptBuffer.length || promptBuffer[promptBuffer.length - 1] != '\n') { throw new IOException("server return incomplete prompt"); } - LineType lineType = LineType.classify(promptBuffer); - return lineType; + return LineType.classify(promptBuffer); } } + /** * Stream of data received from the server - * - * Building block for {@link org.monetdb.jdbc.MonetConnection.DownloadHandler}. + * + * Building block for {@link org.monetdb.jdbc.MonetConnection.DownloadHandler}. */ public static class DownloadStream extends InputStream { - private final BlockInputStream.Raw rawIn; private final OutputStream out; private boolean endBlockSeen = false; @@ -1391,7 +1390,7 @@ public class MapiSocket { /* cannot (yet void nextBlock() throws IOException { if (endBlockSeen || closed) return; - int ret = rawIn.readBlock(); + final int ret = rawIn.readBlock(); if (ret < 0 || rawIn.wasEndBlock()) { endBlockSeen = true; } @@ -1414,8 +1413,8 @@ public class MapiSocket { /* cannot (yet @Override public int read() throws IOException { - byte[] buf = { 0 }; - int nread = read(buf, 0, 1); + final byte[] buf = { 0 }; + final int nread = read(buf, 0, 1); if (nread == 1) return buf[0]; else @@ -1423,8 +1422,8 @@ public class MapiSocket { /* cannot (yet } @Override - public int read(byte[] b, int off, int len) throws IOException { - int origOff = off; + public int read(final byte[] b, int off, int len) throws IOException { + final int origOff = off; while (len > 0) { int chunk = Integer.min(len, rawIn.getLength() - rawIn.getPosition()); if (chunk > 0) {
--- a/src/main/java/org/monetdb/util/FileTransferHandler.java +++ b/src/main/java/org/monetdb/util/FileTransferHandler.java @@ -10,9 +10,7 @@ package org.monetdb.util; import org.monetdb.jdbc.MonetConnection; -import java.io.BufferedReader; import java.io.IOException; -import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; @@ -21,7 +19,7 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; /** - * Sample implement of ON CLIENT handling + * Sample implementation of COPY ... INTO 'file-name' ON CLIENT handling * * Can be registered with {@link MonetConnection#setUploadHandler(MonetConnection.UploadHandler)} * and {@link MonetConnection#setDownloadHandler(MonetConnection.DownloadHandler)}. @@ -37,7 +35,7 @@ public class FileTransferHandler impleme * @param dir directory to read and write files from * @param utf8Encoded set this to true if all files in the directory are known to be utf-8 encoded. */ - public FileTransferHandler(Path dir, boolean utf8Encoded) { + public FileTransferHandler(final Path dir, final boolean utf8Encoded) { root = dir.toAbsolutePath().normalize(); this.utf8Encoded = utf8Encoded; } @@ -48,12 +46,12 @@ public class FileTransferHandler impleme * @param dir directory to read and write files from * @param utf8Encoded set this to true if all files in the directory are known to be utf-8 encoded. */ - public FileTransferHandler(String dir, boolean utf8Encoded) { + public FileTransferHandler(final String dir, final boolean utf8Encoded) { this(FileSystems.getDefault().getPath(dir), utf8Encoded); } - public void handleUpload(MonetConnection.Upload handle, String name, boolean textMode, long linesToSkip) throws IOException { - Path path = root.resolve(name).normalize(); + public void handleUpload(final MonetConnection.Upload handle, final String name, final boolean textMode, final long linesToSkip) throws IOException { + final Path path = root.resolve(name).normalize(); if (!path.startsWith(root)) { handle.sendError("File is not in upload directory"); return; @@ -63,16 +61,15 @@ public class FileTransferHandler impleme return; } if (textMode && (linesToSkip > 0 || !utf8Encoded)) { - Charset encoding = utf8Encoded ? StandardCharsets.UTF_8 : Charset.defaultCharset(); - BufferedReader reader = Files.newBufferedReader(path, encoding); - handle.uploadFrom(reader, linesToSkip); + final Charset encoding = utf8Encoded ? StandardCharsets.UTF_8 : Charset.defaultCharset(); + handle.uploadFrom(Files.newBufferedReader(path, encoding), linesToSkip); } else { handle.uploadFrom(Files.newInputStream(path)); } } - public void handleDownload(MonetConnection.Download handle, String name, boolean textMode) throws IOException { - Path path = root.resolve(name).normalize(); + public void handleDownload(final MonetConnection.Download handle, final String name, final boolean textMode) throws IOException { + final Path path = root.resolve(name).normalize(); if (!path.startsWith(root)) { handle.sendError("File is not in download directory"); return; @@ -81,7 +78,6 @@ public class FileTransferHandler impleme handle.sendError("File already exists: " + name); return; } - OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW); - handle.downloadTo(outputStream); + handle.downloadTo(Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)); } -} \ No newline at end of file +}