Changeset: 778959b2e0a4 for monetdb-java URL: https://dev.monetdb.org/hg/monetdb-java/rev/778959b2e0a4 Added Files: src/main/java/org/monetdb/mcl/net/ClientInfo.java Modified Files: src/main/java/org/monetdb/jdbc/MonetConnection.java src/main/java/org/monetdb/mcl/net/MapiSocket.java src/main/java/org/monetdb/mcl/net/Parameter.java src/main/java/org/monetdb/mcl/net/Target.java tests/javaspecific.md Branch: default Log Message:
Send ClientInfo on startup Configurable through the client_info=bool, client_application=NAME, client_remark=MESSAGE properties. diffs (271 lines): diff --git a/src/main/java/org/monetdb/jdbc/MonetConnection.java b/src/main/java/org/monetdb/jdbc/MonetConnection.java --- a/src/main/java/org/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java @@ -224,6 +224,11 @@ public class MonetConnection throw sqle; } + // send any clientinfo + if (server.hasClientInfo()) { + sendControlCommand("clientinfo " + server.getClientInfo().format()); + } + // Now take care of any options not handled during the handshake curReplySize = defaultFetchSize; if (lang == LANG_SQL) { diff --git a/src/main/java/org/monetdb/mcl/net/ClientInfo.java b/src/main/java/org/monetdb/mcl/net/ClientInfo.java new file mode 100644 --- /dev/null +++ b/src/main/java/org/monetdb/mcl/net/ClientInfo.java @@ -0,0 +1,74 @@ +package org.monetdb.mcl.net; + +import org.monetdb.jdbc.MonetDriver; + +import java.sql.ClientInfoStatus; +import java.sql.SQLClientInfoException; +import java.util.Collections; +import java.util.Map; +import java.util.Properties; + +public class ClientInfo { + private static final String defaultHostname = findHostname(); + + private static final String defaultClientLibrary = findClientLibrary(); + + private static final int defaultPid = findPid(); + + private final Properties props; + + public ClientInfo() { + props = new Properties(); + props.setProperty("ClientHostname", defaultHostname); + props.setProperty("ClientLibrary", defaultClientLibrary); + props.setProperty("ClientPid", "" + defaultPid); + props.setProperty("ApplicationName", ""); + props.setProperty("ClientRemark", ""); + } + + private static String findHostname() { + return "my host"; + } + + private static int findPid() { + return 42; + } + + private static String findClientLibrary() { + return "monetdb-java " + MonetDriver.getDriverVersion(); + } + + public String format() { + StringBuilder builder = new StringBuilder(200); + for (String name : props.stringPropertyNames()) { + String value = props.getProperty(name); + builder.append(name); + builder.append('='); + builder.append(value); + builder.append('\n'); + } + return builder.toString(); + } + + public Properties get() { + Properties ret = new Properties(); + ret.putAll(props); + return ret; + } + + public boolean set(String name, String value) throws SQLClientInfoException { + if (value == null) + value = ""; + if (value.contains("\n")) { + Map<String, ClientInfoStatus> map = Collections.singletonMap(name, ClientInfoStatus.REASON_VALUE_INVALID); + throw new SQLClientInfoException(map); + } + if (props.containsKey(name)) { + props.setProperty(name, value); + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/org/monetdb/mcl/net/MapiSocket.java b/src/main/java/org/monetdb/mcl/net/MapiSocket.java --- a/src/main/java/org/monetdb/mcl/net/MapiSocket.java +++ b/src/main/java/org/monetdb/mcl/net/MapiSocket.java @@ -25,6 +25,7 @@ import java.net.*; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.sql.SQLClientInfoException; import java.util.*; import javax.net.ssl.SSLException; @@ -117,6 +118,7 @@ public final class MapiSocket { private BufferedMCLWriter writer; /** protocol version of the connection */ private int version; + private ClientInfo clientInfo; /** Whether we should follow redirects. * Not sure why this needs to be separate @@ -497,6 +499,17 @@ public final class MapiSocket { String optionsPart = parts.length > 6 ? parts[6] : null; // String binaryPart = parts.length > 7 ? parts[7] : null; + if (parts.length > 9 && target.isClientInfo()) { + clientInfo = new ClientInfo(); + try { + clientInfo.set("ApplicationName", target.getClientApplication()); + clientInfo.set("ClientRemark", target.getClientRemark()); + } catch (SQLClientInfoException e) { + String keys = String.join(", ", e.getFailedProperties().keySet()); + throw new MCLException("Could not set ClientInfo properties: " + keys, e); + } + } + String userResponse; String password = target.getPassword(); if (serverTypePart.equals("merovingian") && !target.getLanguage().equals("control")) { @@ -771,6 +784,15 @@ public final class MapiSocket { return target.isDebug(); } + public boolean hasClientInfo() { + return clientInfo != null; + } + + public ClientInfo getClientInfo() { + if (clientInfo == null) + clientInfo = new ClientInfo(); + return clientInfo; + } /** * Inner class that is used to write data on a normal stream as a diff --git a/src/main/java/org/monetdb/mcl/net/Parameter.java b/src/main/java/org/monetdb/mcl/net/Parameter.java --- a/src/main/java/org/monetdb/mcl/net/Parameter.java +++ b/src/main/java/org/monetdb/mcl/net/Parameter.java @@ -45,6 +45,10 @@ public enum Parameter { SO_TIMEOUT("so_timeout", ParameterType.Int, 0, "abort if network I/O does not complete in this many milliseconds, 0 means no timeout", false), CLOB_AS_VARCHAR("treat_clob_as_varchar", ParameterType.Bool, true, "return CLOB/TEXT data as type VARCHAR instead of type CLOB", false), BLOB_AS_BINARY("treat_blob_as_binary", ParameterType.Bool, true, "return BLOB data as type BINARY instead of type BLOB", false), + + CLIENT_INFO("client_info", ParameterType.Bool, true, "whether to send ClientInfo when connecting", false), + CLIENT_APPLICATION("client_application", ParameterType.Str, "", "application name to send in ClientInfo", false), + CLIENT_REMARK("client_remark", ParameterType.Str, "", "application name to send in ClientInfo", false), ; public final String name; @@ -117,6 +121,12 @@ public enum Parameter { return CLOB_AS_VARCHAR; case "treat_blob_as_binary": return BLOB_AS_BINARY; + case "client_info": + return CLIENT_INFO; + case "client_application": + return CLIENT_APPLICATION; + case "client_remark": + return CLIENT_REMARK; default: return null; } diff --git a/src/main/java/org/monetdb/mcl/net/Target.java b/src/main/java/org/monetdb/mcl/net/Target.java --- a/src/main/java/org/monetdb/mcl/net/Target.java +++ b/src/main/java/org/monetdb/mcl/net/Target.java @@ -46,6 +46,9 @@ public class Target { private int soTimeout = 0; private boolean treatClobAsVarchar = true; private boolean treatBlobAsBinary = true; + private boolean clientInfo = true; + private String clientApplication = ""; + private String clientRemark = ""; private boolean userWasSet = false; private boolean passwordWasSet = false; private Validated validated = null; @@ -202,6 +205,15 @@ public class Target { case BLOB_AS_BINARY: setTreatBlobAsBinary((boolean) value); break; + case CLIENT_INFO: + setClientInfo((boolean) value); + break; + case CLIENT_APPLICATION: + setClientApplication((String) value); + break; + case CLIENT_REMARK: + setClientRemark((String) value); + break; default: throw new IllegalStateException("unreachable -- missing case: " + parm.name); @@ -269,6 +281,12 @@ public class Target { return treatClobAsVarchar; case BLOB_AS_BINARY: return treatBlobAsBinary; + case CLIENT_INFO: + return clientInfo; + case CLIENT_APPLICATION: + return clientApplication; + case CLIENT_REMARK: + return clientRemark; default: throw new IllegalStateException("unreachable -- missing case"); } @@ -510,6 +528,30 @@ public class Target { validated = null; } + public boolean isClientInfo() { + return clientInfo; + } + + public void setClientInfo(boolean clientInfo) { + this.clientInfo = clientInfo; + } + + public String getClientApplication() { + return clientApplication; + } + + public void setClientApplication(String clientApplication) { + this.clientApplication = clientApplication; + } + + public String getClientRemark() { + return clientRemark; + } + + public void setClientRemark(String clientRemark) { + this.clientRemark = clientRemark; + } + public Validated validate() throws ValidationError { if (validated == null) validated = new Validated(); diff --git a/tests/javaspecific.md b/tests/javaspecific.md --- a/tests/javaspecific.md +++ b/tests/javaspecific.md @@ -28,3 +28,20 @@ EXPECT treat_blob_as_binary=false ACCEPT monetdb://?treat_blob_as_binary=yes EXPECT treat_blob_as_binary=on ``` + +```test +ONLY jdbc +EXPECT client_info=true +EXPECT client_application= +EXPECT client_remark= +``` + +```test +ONLY jdbc +SET client_info=false +SET client_application=myapp +SET client_remark=a remark +EXPECT client_info=false +EXPECT client_application=myapp +EXPECT client_remark=a remark +``` _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org