Mercurial > hg > monetdb-java
changeset 93:eeb71f7d36bf embedded
Fixed a bug on the JDBC MAPI connection from the old code! Fixed the connection properties for an JDBC Embedded connection. To start a JDBC Embedded connection, the user must start the embedded database beforehand with the method MonetDBEmbeddedDatabase.StartDatabase().
author | Pedro Ferreira <pedro.ferreira@monetdbsolutions.com> |
---|---|
date | Fri, 06 Jan 2017 12:36:33 +0000 (2017-01-06) |
parents | 6f74e01c57da |
children | 4bb4e988164d |
files | example/MJDBCTest.java example/SQLcopyinto.java src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java src/main/java/nl/cwi/monetdb/merovingian/Control.java src/main/java/nl/cwi/monetdb/util/Extract.java src/main/java/nl/cwi/monetdb/util/SQLRestore.java |
diffstat | 13 files changed, 83 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/example/MJDBCTest.java +++ b/example/MJDBCTest.java @@ -17,8 +17,7 @@ import java.sql.*; */ public class MJDBCTest { public static void main(String[] args) throws Exception { - // make sure the driver is loaded - Class.forName("nl.cwi.monetdb.jdbc.MonetDriver"); + //Class.forName("nl.cwi.monetdb.jdbc.MonetDriver"); // turn on debugging (disabled) //nl.cwi.monetdb.jdbc.MonetConnection.setDebug(true); Connection con = DriverManager.getConnection("jdbc:monetdb://localhost/notused", "monetdb", "monetdb");
--- a/example/SQLcopyinto.java +++ b/example/SQLcopyinto.java @@ -43,7 +43,7 @@ public class SQLcopyinto { // of course also be done simultaneously with the JDBC // connection being kept connected - MapiConnection server = new MapiConnection(null, "database",null, "sql", true,"localhost", 50000 ); + MapiConnection server = new MapiConnection(null, null, "sql", false, true,"localhost", 50000, "database"); try { List warning = server.connect("monetdb", "monetdb");
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java @@ -54,8 +54,6 @@ public abstract class MonetConnection ex protected final Properties conn_props; /** The language to connect with */ protected IMonetDBLanguage language; - /** The database to connect to */ - protected String database; /** Authentication hash method */ protected final String hash; /** An optional thread that is used for sending large queries */ @@ -79,7 +77,7 @@ public abstract class MonetConnection ex private Map<Statement,?> statements = new WeakHashMap<Statement, Object>(); /** The number of results we receive from the server at once */ private int curReplySize = -1; // the server by default uses -1 (all) - /** Whether or not BLOB is mapped to BINARY within the driver */ + /** Whether or not BLOB is mapped to LONGVARBINARY within the driver */ private final boolean blobIsBinary; /** Whether or not CLOB is mapped to LONGVARCHAR within the driver */ private final boolean clobIsLongChar; @@ -93,10 +91,9 @@ public abstract class MonetConnection ex * * @throws IOException if an error occurs */ - public MonetConnection(Properties props, String database, String hash, IMonetDBLanguage language, - boolean blobIsBinary, boolean clobIsLongChar) throws IOException { + public MonetConnection(Properties props, String hash, IMonetDBLanguage language, boolean blobIsBinary, + boolean clobIsLongChar) throws IOException { this.conn_props = props; - this.database = database; this.hash = hash; this.language = language; this.blobIsBinary = blobIsBinary; @@ -800,7 +797,7 @@ public abstract class MonetConnection ex */ @Override public String toString() { - return "MonetDB Connection (" + this.getJDBCURL() + ") " + (closed ? "connected" : "disconnected"); + return "MonetDB Connection (" + this.getJDBCURL() + ") " + (closed ? "disconnected" : "connected"); } //== Java 1.6 methods (JDBC 4.0) @@ -1068,8 +1065,8 @@ public abstract class MonetConnection ex // only set value for supported property names if (name.equals("host") || name.equals("port") || name.equals("user") || name.equals("password") || name.equals("database") || name.equals("language") || name.equals("so_timeout") || - name.equals("debug") || name.equals("hash") || name.equals("treat_blob_as_binary") || - name.equals("treat_clob_as_longvarchar") || name.equals("embedded") || name.equals("directory")) { + name.equals("hash") || name.equals("treat_blob_as_binary") || name.equals("follow_redirects") || + name.equals("treat_clob_as_longvarchar") || name.equals("embedded")) { conn_props.setProperty(name, value); } else { addWarning("setClientInfo: " + name + "is not a recognised property", "01M07");
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java @@ -35,7 +35,7 @@ public class MonetDataSource extends Mon private String description = "MonetDB database"; private String url = "jdbc:monetdb://localhost/"; private int loginTimeout; - private String embeddedDirectory; + private boolean isEmbedded; private final MonetDriver driver = new MonetDriver(); // the following properties are also standard: @@ -73,9 +73,8 @@ public class MonetDataSource extends Mon if (loginTimeout > 0) { props.put("so_timeout", Integer.toString(loginTimeout)); } - if(embeddedDirectory != null) { + if(isEmbedded) { props.put("embedded", "true"); - props.put("directory", embeddedDirectory); } return driver.connect(url, props); } @@ -160,7 +159,7 @@ public class MonetDataSource extends Mon * * @param url the connection URL */ - public void setDatabaseName(String url) { + public void setURL(String url) { this.url = url; } @@ -183,21 +182,21 @@ public class MonetDataSource extends Mon } /** - * Gets the embedded connection directory. If null, then a MAPI connection will be created instead. + * Gets the embedded connection directory. If not, then a MAPI connection will be created instead. * - * @return The embedded connection directory String. If null, then a MAPI connection will be created instead. + * @return If the connection will be embedded. If not, then a MAPI connection will be created instead. */ - public String getEmbeddedDirectory() { - return embeddedDirectory; + public boolean isEmbedded() { + return isEmbedded; } /** - * Sets the embedded connection directory, thus making the connection embedded. + * Sets the connection to be embedded * - * @param embeddedDirectory The embedded connection directory to set + * @param isEmbedded A boolean to indicate if the connection will be embedded */ - public void setEmbeddedDirectory(String embeddedDirectory) { - this.embeddedDirectory = embeddedDirectory; + public void setIsEmbedded(boolean isEmbedded) { + this.isEmbedded = isEmbedded; } /**
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in @@ -148,9 +148,24 @@ final public class MonetDriver implement prop.description = "Force the use of the given hash algorithm during challenge response (one of SHA1, MD5, plain)"; props.add(prop); - prop = new DriverPropertyInfo("language", "sql"); + prop = new DriverPropertyInfo("host", "localhost"); + prop.required = false; + prop.description = "The MonetDB server hostname (MAPI connection only)"; + props.add(prop); + + prop = new DriverPropertyInfo("port", PORT); prop.required = false; - prop.description = "What language to use for MonetDB conversations (experts only)"; + prop.description = "The port to connect to the MonetDB server (MAPI connection only)"; + props.add(prop); + + prop = new DriverPropertyInfo("so_timeout", "0"); + prop.required = false; + prop.description = "Defines the maximum time to wait in milliseconds on a blocking read socket call (MAPI connection only)"; // this corresponds to the Connection.setNetworkTimeout() method introduced in JDBC 4.1 + props.add(prop); + + prop = new DriverPropertyInfo("database", ""); + prop.required = false; + prop.description = "The database name to connect (MAPI connection only)"; props.add(prop); prop = new DriverPropertyInfo("follow_redirects", "true"); @@ -160,7 +175,7 @@ final public class MonetDriver implement prop = new DriverPropertyInfo("treat_blob_as_binary", "false"); prop.required = false; - prop.description = "Whether BLOBs on the server should be treated as BINARY types, thus mapped to byte[] (MAPI connection only)"; + prop.description = "Whether BLOBs on the server should be treated as LONGVARBINARY types, thus mapped to byte[] (MAPI connection only)"; props.add(prop); prop = new DriverPropertyInfo("treat_clob_as_longvarchar", "false"); @@ -168,9 +183,9 @@ final public class MonetDriver implement prop.description = "Whether CLOBs on the server should be treated as LONGVARCHAR types, thus mapped to String (MAPI connection only)"; props.add(prop); - prop = new DriverPropertyInfo("so_timeout", "0"); + prop = new DriverPropertyInfo("language", "sql"); prop.required = false; - prop.description = "Defines the maximum time to wait in milliseconds on a blocking read socket call (MAPI connection only)"; // this corresponds to the Connection.setNetworkTimeout() method introduced in JDBC 4.1 + prop.description = "What language to use for MonetDB conversations (experts only)"; props.add(prop); prop = new DriverPropertyInfo("embedded", "false"); @@ -178,11 +193,6 @@ final public class MonetDriver implement prop.description = "Whether or not to use an embedded MonetDB connection"; props.add(prop); - prop = new DriverPropertyInfo("directory", ""); - prop.required = false; - prop.description = "The directory of the database farm (Embedded connection only)"; - props.add(prop); - DriverPropertyInfo[] dpi = new DriverPropertyInfo[props.size()]; return props.toArray(dpi); } @@ -404,19 +414,12 @@ final public class MonetDriver implement boolean isEmbedded = Boolean.parseBoolean(props.getProperty("embedded", "false")); String language = props.getProperty("language", "sql"); - String username = props.getProperty("user", null); - String password = props.getProperty("password", null); - String database = props.getProperty("database"); - if (database == null || database.trim().isEmpty()) - throw new IllegalArgumentException("database should not be null or empty"); + String username = props.getProperty("user"); + String password = props.getProperty("password"); String hash = props.getProperty("hash"); int sockTimeout = 0; - //instantiate the connection - if(isEmbedded) { - String directory = props.getProperty("directory"); - if (directory == null || directory.trim().isEmpty()) - throw new IllegalArgumentException("directory should not be null or empty"); + if(isEmbedded) { //instantiate the connection try { if(EmbeddedConnectionClass == null) { EmbeddedConnectionClass = Class.forName("nl.cwi.monetdb.embedded.jdbc.EmbeddedConnection"); @@ -425,8 +428,8 @@ final public class MonetDriver implement throw new SQLException("EmbeddedConnection Class not found!"); } res = (MonetConnection) EmbeddedConnectionClass - .getDeclaredConstructor(Properties.class, String.class, String.class, String.class, String.class) - .newInstance(props, database, hash, language, directory); + .getDeclaredConstructor(Properties.class, String.class, String.class) + .newInstance(props, hash, language); } catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException e) { throw new SQLException(e); @@ -439,6 +442,9 @@ final public class MonetDriver implement throw new IllegalArgumentException("user should not be null or empty"); if (password == null || password.trim().isEmpty()) throw new IllegalArgumentException("password should not be null or empty"); + String database = props.getProperty("database"); + if (database == null || database.trim().isEmpty()) + throw new IllegalArgumentException("database should not be null or empty"); boolean blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary", "false")); boolean clobIsLongChar = Boolean.valueOf(props.getProperty("treat_clob_as_longvarchar", "false")); @@ -472,7 +478,7 @@ final public class MonetDriver implement props.setProperty("so_timeout", "0"); } try { - res = new MapiConnection(props, database, hash, language, blobIsBinary, clobIsLongChar, hostname, port); + res = new MapiConnection(props, hash, language, blobIsBinary, clobIsLongChar, hostname, port, database); } catch (IOException e) { throw new SQLException(e); } @@ -491,7 +497,7 @@ final public class MonetDriver implement res.setSoTimeout(sockTimeout); } - try { + try { //atempt to connect and authenticate the user List<String> warnings = res.connect(username, password); if(warnings != null) { for (String warning : warnings) { @@ -508,15 +514,7 @@ final public class MonetDriver implement throw new SQLException("Unable to connect (" + con.getHostname() + ":" + con.getPort() + "): " + e.getMessage(), "08006"); } else { - try { - java.lang.reflect.Method method = EmbeddedConnectionClass.getMethod("getDirectory"); - String directory = (String) method.invoke(EmbeddedConnectionClass.cast(res)); - throw new SQLException("Unable to start the farm on the directory: " + directory + - " Details:" + e.getMessage(), "08006"); - } catch (NoSuchMethodException | SecurityException | IllegalArgumentException | - IllegalAccessException | InvocationTargetException ex) { - throw new SQLException(e.getMessage()); - } + throw new SQLException("Unable to connect: " + e.getMessage(), "08006"); } } catch (ProtocolException e) { throw new SQLException(e.getMessage(), "08001"); @@ -529,8 +527,7 @@ final public class MonetDriver implement throw sqle; } - //set the timezone - if (res.getLanguage() == MapiLanguage.LANG_SQL) { + if (!isEmbedded && res.getLanguage() == MapiLanguage.LANG_SQL) { //set the timezone only in the MAPI connection // enable auto commit res.setAutoCommit(true); // set our time zone on the server
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java @@ -3257,22 +3257,6 @@ public class MonetResultSet extends Mone //== end methods of interface ResultSet /** - * Adds a warning to the pile of warnings this ResultSet object has. If - * there were no warnings (or clearWarnings was called) this warning will - * be the first, otherwise this warning will get appended to the current - * warning. - * - * @param reason the warning message - */ - private void addWarning(String reason, String sqlstate) { - if (warnings == null) { - warnings = new SQLWarning(reason, sqlstate); - } else { - warnings.setNextWarning(new SQLWarning(reason, sqlstate)); - } - } - - /** * Small helper method that formats the "Invalid Column Index number ..." message * and creates a new SQLException object whose SQLState is set to "M1M05". *
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java +++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java @@ -44,14 +44,17 @@ public class MapiConnection extends Mone private int ttl = 10; /** Protocol version of the connection */ private int version; + /** The database to connect to */ + private String database; /** Endianness of the server */ private ByteOrder serverEndianness; - public MapiConnection(Properties props, String database, String hash, String language, boolean blobIsBinary, - boolean clobIsLongChar, String hostname, int port) throws IOException { - super(props, database, hash, MapiLanguage.GetLanguageFromString(language), blobIsBinary, clobIsLongChar); + public MapiConnection(Properties props, String hash, String language, boolean blobIsBinary, + boolean clobIsLongChar, String hostname, int port, String database) throws IOException { + super(props, hash, MapiLanguage.GetLanguageFromString(language), blobIsBinary, clobIsLongChar); this.hostname = hostname; this.port = port; + this.database = database; } public String getHostname() { @@ -62,6 +65,10 @@ public class MapiConnection extends Mone return port; } + public String getDatabase() { + return database; + } + public boolean isFollowRedirects() { return followRedirects; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java @@ -83,9 +83,7 @@ public class OldMapiProtocol extends Abs @Override public StarterHeaders getNextStarterHeader() { - StarterHeaders res = OldMapiStartOfHeaderParser.GetNextStartHeaderOnOldMapi(this); - this.lineBuffer.position(this.lineBuffer.position() + 1); - return res; + return OldMapiStartOfHeaderParser.GetNextStartHeaderOnOldMapi(this); } @Override @@ -135,7 +133,7 @@ public class OldMapiProtocol extends Abs public int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] data, boolean[][] nulls) throws ProtocolException { OldMapiTupleLineParser.OldMapiParseTupleLine(firstLineNumber, this.lineBuffer, - this.tupleLineBuilder, typesMap, data, nulls[firstLineNumber]); + this.tupleLineBuilder, typesMap, data, nulls); return firstLineNumber; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java @@ -21,9 +21,11 @@ final class OldMapiStartOfHeaderParser { break; case '1': res = StarterHeaders.Q_TABLE; + protocol.lineBuffer.get(); break; case '2': res = StarterHeaders.Q_UPDATE; + protocol.lineBuffer.get(); break; case '3': res = StarterHeaders.Q_SCHEMA; @@ -33,9 +35,11 @@ final class OldMapiStartOfHeaderParser { break; case '5': res = StarterHeaders.Q_PREPARE; + protocol.lineBuffer.get(); break; case '6': res = StarterHeaders.Q_BLOCK; + protocol.lineBuffer.get(); break; default: res = StarterHeaders.Q_UNKNOWN; @@ -51,11 +55,13 @@ final class OldMapiStartOfHeaderParser { if (currentPointer >= limit) { throw new ProtocolException("unexpected end of string", currentPointer - 1); } - int tmp; + int tmp = 0, negative = 1;; char chr = array[currentPointer++]; // note: don't use Character.isDigit() here, because we only want ISO-LATIN-1 digits if (chr >= '0' && chr <= '9') { tmp = (int)chr - (int)'0'; + } else if(chr == '-') { + negative = -1; } else { throw new ProtocolException("expected a digit", currentPointer - 1); } @@ -72,6 +78,7 @@ final class OldMapiStartOfHeaderParser { throw new ProtocolException("expected a digit", currentPointer - 1); } } + tmp *= negative; protocol.lineBuffer.position(currentPointer); return tmp; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java @@ -54,7 +54,7 @@ final class OldMapiTupleLineParser { } static int OldMapiParseTupleLine(int lineNumber, CharBuffer lineBuffer, StringBuilder helper, int[] typesMap, - Object[] values, boolean[] nulls) throws ProtocolException { + Object[] values, boolean[][] nulls) throws ProtocolException { int len = lineBuffer.limit(); char[] array = lineBuffer.array(); @@ -151,13 +151,13 @@ final class OldMapiTupleLineParser { } // put the unescaped string in the right place OldMapiStringToJavaObjectConverter(helper.toString(), lineNumber, values[column], typesMap[column]); - nulls[column] = false; + nulls[column][lineNumber] = false; } else if ((i - 1) - cursor == 4 && CharIndexOf(array, array.length, NULL_STRING, NULL_STRING.length) == cursor) { SetNullValue(lineNumber, values[column], typesMap[column]); - nulls[column] = true; + nulls[column][lineNumber] = true; } else { OldMapiStringToJavaObjectConverter(new String(array, cursor, i - 1 - cursor), lineNumber, values[column], typesMap[column]); - nulls[column] = false; + nulls[column][lineNumber] = false; } column++; cursor = i + 1; @@ -197,10 +197,10 @@ final class OldMapiTupleLineParser { ((short[]) columnArray)[lineNumber] = Short.parseShort(toParse); break; case Types.INTEGER: - ((int[]) columnArray)[lineNumber] = Integer.parseInt(toParse); + ((int[]) columnArray)[lineNumber] = Integer.parseInt(toParse.replace(".", "")); //intervals :( break; case Types.BIGINT: - ((long[]) columnArray)[lineNumber] = Long.parseLong(toParse); + ((long[]) columnArray)[lineNumber] = Long.parseLong(toParse.replace(".", "")); //intervals :( break; case Types.REAL: ((float[]) columnArray)[lineNumber] = Float.parseFloat(toParse);
--- a/src/main/java/nl/cwi/monetdb/merovingian/Control.java +++ b/src/main/java/nl/cwi/monetdb/merovingian/Control.java @@ -98,7 +98,7 @@ public class Control { private List<String> sendCommand(String database, String command, boolean hasOutput) throws MerovingianException, IOException { - MapiConnection server = new MapiConnection(null, "merovingian",null, "control", false, true, host, port ); + MapiConnection server = new MapiConnection(null, null, "control", false, true, host, port, "merovingian"); AbstractProtocol protocol = server.getProtocol(); try { server.connect("monetdb", passphrase);
--- a/src/main/java/nl/cwi/monetdb/util/Extract.java +++ b/src/main/java/nl/cwi/monetdb/util/Extract.java @@ -17,8 +17,7 @@ import java.io.InputStreamReader; /** - * This file contains a function to extract files from its including Jar - * package. + * This file contains a function to extract files from its including Jar package. * * @author Ying Zhang <Y.Zhang@cwi.nl> * @version 0.1 @@ -28,15 +27,12 @@ public class Extract { private static final int DEFAULT_BUFSIZE = 16386; /** - * Extracts a file from the Jar package which includes this class to - * the given destination - * @param fromFile The file to extract, including it absolute path - * inside its including Jar package. + * Extracts a file from the Jar package which includes this class to the given destination + * @param fromFile The file to extract, including it absolute path inside its including Jar package. * @param toFile Destination for the extracted file * @throws FileNotFoundException If the file to extract can not be * found in its including Jar package. - * @throws IOException If any error happens during - * creating/reading/writing files. + * @throws IOException If any error happens during creating/reading/writing files. */ public static void extractFile(String fromFile, String toFile) throws FileNotFoundException, IOException { char[] cbuf = new char[DEFAULT_BUFSIZE];
--- a/src/main/java/nl/cwi/monetdb/util/SQLRestore.java +++ b/src/main/java/nl/cwi/monetdb/util/SQLRestore.java @@ -102,7 +102,7 @@ public class SQLRestore { * @throws IOException */ public void restore(File source) throws IOException { - MapiConnection server = new MapiConnection(null, _dbName,null, "sql", false, true, _host, _port ); + MapiConnection server = new MapiConnection(null,null, "sql", false, true, _host, _port, _dbName); try { server.connect(_user, _password);