Mercurial > hg > monetdb-java
changeset 656:c6fe5dfecafc
Refactor HandshakeOptions
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Fri, 09 Sep 2022 12:25:23 +0200 (2022-09-09) |
parents | 2ded26c5a679 |
children | 8476d6f4378f |
files | src/main/java/org/monetdb/jdbc/MonetConnection.java src/main/java/org/monetdb/mcl/net/HandshakeOptions.java src/main/java/org/monetdb/mcl/net/MapiSocket.java |
diffstat | 3 files changed, 75 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java @@ -37,6 +37,7 @@ import org.monetdb.mcl.io.BufferedMCLRea import org.monetdb.mcl.io.BufferedMCLWriter; import org.monetdb.mcl.io.LineType; import org.monetdb.mcl.net.HandshakeOptions; +import org.monetdb.mcl.net.HandshakeOptions.Setting; import org.monetdb.mcl.net.MapiSocket; import org.monetdb.mcl.parser.HeaderLineParser; import org.monetdb.mcl.parser.MCLParseException; @@ -287,8 +288,8 @@ public class MonetConnection int offsetMillis = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET); int offsetSeconds = offsetMillis / 1000; final HandshakeOptions handshakeOptions = new HandshakeOptions(); - handshakeOptions.setTimeZone(offsetSeconds); - handshakeOptions.setReplySize(defaultFetchSize); + handshakeOptions.set(Setting.TimeZone, offsetSeconds); + handshakeOptions.set(Setting.ReplySize, defaultFetchSize); server.setHandshakeOptions(handshakeOptions); // we're debugging here... uhm, should be off in real life @@ -370,11 +371,18 @@ public class MonetConnection lang = LANG_UNKNOWN; } - if (!handshakeOptions.mustSendReplySize()) { - // Initially, it had to be sent. If it no more needs to be sent now, - // it must have been sent during the auth challenge/response. - // Record the value it was set to. - this.curReplySize = handshakeOptions.getReplySize(); + // The reply size is checked before every query and adjusted if + // necessary. Update our current belief of what the server is set to. + if (handshakeOptions.wasSentInHandshake(HandshakeOptions.Setting.ReplySize)) { + this.curReplySize = handshakeOptions.get(HandshakeOptions.Setting.ReplySize); + } + + for (Setting setting : new Setting[] { Setting.SizeHeader }) { + if (handshakeOptions.mustSend(setting)) { + Integer value = handshakeOptions.get(setting); // guaranteed by mustSend to be non-null + String command = String.format("%s %d", setting.getXCommand(), value); + sendControlCommand(command); + } } // the following initialisers are only valid when the language is SQL... @@ -383,10 +391,10 @@ public class MonetConnection setAutoCommit(true); // set our time zone on the server, if we haven't already - if (handshakeOptions.mustSendTimeZone()) { + if (handshakeOptions.mustSend(Setting.TimeZone)) { final StringBuilder tz = new StringBuilder(64); tz.append("SET TIME ZONE INTERVAL '"); - int offsetMinutes = handshakeOptions.getTimeZone() / 60; + int offsetMinutes = handshakeOptions.get(Setting.TimeZone) / 60; if (offsetMinutes < 0) { tz.append('-'); offsetMinutes = -offsetMinutes; // make it positive
--- a/src/main/java/org/monetdb/mcl/net/HandshakeOptions.java +++ b/src/main/java/org/monetdb/mcl/net/HandshakeOptions.java @@ -8,98 +8,96 @@ package org.monetdb.mcl.net; +import java.util.HashMap; +import java.util.Map; + /** Keep track of MAPI handshake options. * * Recent server versions (from 2021) allow you to send configuration information during * the authentication handshake so no additional round trips are necessary * when that has completed. * - * This class keeps track of the options to send, and whether they have already - * been sent. + * This class keeps track of the values themselves, and also of whether or not they should still be sent. */ final public class HandshakeOptions { - - // public Boolean autoCommit; - int replySize; - // public Integer ColumnarProtocol; - int timeZone; + HashMap<Setting,Integer> options = new HashMap<>(); + int handshakeLevel = 0; - boolean mustSendReplySize; - boolean mustSendTimeZone; - - public int getReplySize() { - return replySize; + public void set(Setting setting, int value) { + options.put(setting, value); } - public void setReplySize(int replySize) { - this.replySize = replySize; - this.mustSendReplySize = true; + public Integer get(Setting setting) { + return options.get(setting); } - public boolean mustSendReplySize() { - return mustSendReplySize; + public boolean wasSentInHandshake(Setting setting) { + return setting.isSupported(this.handshakeLevel); } - public void mustSendReplySize(boolean mustSendReplySize) { - this.mustSendReplySize = mustSendReplySize; - } - - public int getTimeZone() { - return timeZone; - } - - public void setTimeZone(int timeZone) { - this.timeZone = timeZone; - this.mustSendTimeZone = true; + public boolean mustSend(Setting setting) { + if (wasSentInHandshake(setting)) { + return false; + } + Integer value = options.get(setting); + return value != null && value != setting.defaultValue; } - public boolean mustSendTimeZone() { - return mustSendTimeZone; - } - - public void mustSendTimeZone(boolean mustSendTimeZone) { - this.mustSendTimeZone = mustSendTimeZone; - } + public String formatHandshakeResponse(int serverLevel) { + StringBuilder opts = new StringBuilder(100); - public String formatResponse(int serverLevel) { - StringBuilder opts = new StringBuilder(100); - if (mustSendReplySize()) { - formatOption(opts, Level.ReplySize, serverLevel, replySize); - mustSendReplySize(false); + for (Map.Entry<Setting, Integer> entry: options.entrySet()) { + Setting setting = entry.getKey(); + Integer value = entry.getValue(); + if (setting.isSupported(serverLevel)) { + if (opts.length() > 0) { + opts.append(","); + } + opts.append(setting.field); + opts.append("="); + opts.append(value); + } } - if (mustSendTimeZone()) { - formatOption(opts, Level.TimeZone, serverLevel, timeZone); - mustSendTimeZone(false); - } + + this.handshakeLevel = serverLevel; return opts.toString(); } - private void formatOption(StringBuilder opts, Level level, int serverLevel, int value) { - if (!level.isSupported(serverLevel)) - return; - if (opts.length() > 0) { - opts.append(","); - } - opts.append(level.field); - opts.append("="); - opts.append(value); - } - - public enum Level { - ReplySize("reply_size", 2), - TimeZone("time_zone", 5); + public enum Setting { + AutoCommit("auto_commit", 1, 1), + ReplySize("reply_size", 2, 100), + SizeHeader("size_header", "sizeheader", 3, 0), + // ColumnarProtocol("columnar_protocol", 4), + TimeZone("time_zone", 5, 0), + ; private final int level; private final String field; + private final String xcommand; + private final int defaultValue; - Level(String field, int level) { + Setting(String field, int level, int defaultValue) { + this(field, field, level, defaultValue); + } + + Setting(String field, String xcommand, int level, int defaultValue) { this.field = field; + this.xcommand = xcommand; this.level = level; + this.defaultValue = defaultValue; } public boolean isSupported(int serverLevel) { return this.level < serverLevel; } + + public String getXCommand() { + return xcommand; + } + + public Integer getDefaultValue() { + return defaultValue; + } } }
--- a/src/main/java/org/monetdb/mcl/net/MapiSocket.java +++ b/src/main/java/org/monetdb/mcl/net/MapiSocket.java @@ -562,7 +562,7 @@ public class MapiSocket { /* cannot (yet } catch (NumberFormatException e) { throw new MCLParseException("Invalid handshake level: " + chaltok[6]); } - response += handshakeOptions.formatResponse(level); + response += handshakeOptions.formatHandshakeResponse(level); break; } }