Changeset: 784259e85d8f for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=784259e85d8f Modified Files: java/embedded/org_monetdb_embedded_MonetDBEmbedded.c java/embedded/src/main/java/org/monetdb/embedded/MonetDBEmbedded.java java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java Branch: embedded-java Log Message:
Ensuring only one instance can be instantiated from the same JVM - If another one in the same dir is attempted to be started the method siply returns true. - If one is attempted to be started in a different dir, it throws an exception. diffs (228 lines): diff --git a/java/embedded/org_monetdb_embedded_MonetDBEmbedded.c b/java/embedded/org_monetdb_embedded_MonetDBEmbedded.c --- a/java/embedded/org_monetdb_embedded_MonetDBEmbedded.c +++ b/java/embedded/org_monetdb_embedded_MonetDBEmbedded.c @@ -13,6 +13,9 @@ #include "res_table.h" #include "mal_type.h" +bool running = false; +char *runningDirectory; + JNIEXPORT jboolean JNICALL Java_org_monetdb_embedded_MonetDBEmbedded_startupWrapper (JNIEnv *env, jobject object, jstring directory, jboolean silent) { (void)object; @@ -20,9 +23,25 @@ JNIEXPORT jboolean JNICALL Java_org_mone char *directory_string = strdup(directory_string_tmp); unsigned char silent_char = 'n'; char *err; - + jclass exClass = (*env)->FindClass(env, "java/io/IOException"); // Release the directory string (*env)->ReleaseStringUTFChars(env, directory, directory_string_tmp); + + // Check if we already have a running db + if (running) { + if (strcmp(directory_string, runningDirectory) == 0) { + return true; + } + // Throw a Java exception + if (exClass == NULL) { + // Cloud not find the exception class, just return empty object + return false; + } + err = "A database is already working in another directory. Only a single embedded MonetDB process can be started in the same JVM"; + (*env)->ThrowNew(env, exClass, err); + return false; + } + // Set the silent flag based on passed boolean value if (silent) { silent_char = 'y'; @@ -31,9 +50,6 @@ JNIEXPORT jboolean JNICALL Java_org_mone err = monetdb_startup(directory_string, silent_char); // Checking for errors if (err != NULL) { - jclass exClass = (*env)->FindClass(env, "java/io/IOException"); - - // Clean up the result data if (exClass == NULL) { // Cloud not find the exception class, just return empty object return false; @@ -42,6 +58,9 @@ JNIEXPORT jboolean JNICALL Java_org_mone return false; } + // set the flags + running = true; + runningDirectory = directory_string; return true; } diff --git a/java/embedded/src/main/java/org/monetdb/embedded/MonetDBEmbedded.java b/java/embedded/src/main/java/org/monetdb/embedded/MonetDBEmbedded.java --- a/java/embedded/src/main/java/org/monetdb/embedded/MonetDBEmbedded.java +++ b/java/embedded/src/main/java/org/monetdb/embedded/MonetDBEmbedded.java @@ -18,6 +18,7 @@ import org.monetdb.embedded.result.Embed * Embedded version of MonetDB. * Communication between Java and native C is done via JNI. * + * <br/><strong>Note</strong>: You can have only one embedded MonetDB database running per JVM process. */ public class MonetDBEmbedded { /** @@ -27,24 +28,31 @@ public class MonetDBEmbedded { /** * The working directory for MonetDB. */ - private File directory; - private boolean silentFlag; + private final File databaseDirectory; + /** + * Silent flag for database startup + */ + private final boolean silentFlag; /** - * You can instantiate multiple object, - * just make sure they are assigned different directories. - * - * @param directory Database directory - * @param silentFlag Silent flag for logging messages + * @param databaseDirectory Database directory */ - public MonetDBEmbedded(File directory, boolean silentFlag) { + public MonetDBEmbedded(final File databaseDirectory) { + this(databaseDirectory, true); + } + + /** + * @param databaseDirectory Database directory + * @param silentFlag Silent flag + */ + public MonetDBEmbedded(final File databaseDirectory, final boolean silentFlag) { // Load the embedded library (and its dependencies) System.loadLibrary("embedded_java"); - if (!directory.isDirectory()) { - throw new IllegalArgumentException(directory + " is not a directory"); + if (!databaseDirectory.isDirectory()) { + throw new IllegalArgumentException(databaseDirectory + " is not a directory"); } - this.directory = directory; + this.databaseDirectory = databaseDirectory; this.silentFlag = silentFlag; } @@ -64,9 +72,9 @@ public class MonetDBEmbedded { * @return {@code True} if the was started successfully or is already running, otherwise {@code False}. * @throws IOException Database startup failure */ - public boolean run() throws IOException { + public boolean start() throws IOException { if (!running) { - if (startupWrapper(directory.getAbsolutePath(), silentFlag)){ + if (startupWrapper(databaseDirectory.getAbsolutePath(), silentFlag)){ running = true; } } @@ -95,7 +103,7 @@ public class MonetDBEmbedded { /** * Start the embedded database up. * - * @param direcrory Database directory + * @param dir Database directory * @param silent Silent flag * @return Startup status code */ diff --git a/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java b/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java --- a/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java +++ b/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java @@ -34,6 +34,11 @@ public class EmbeddedQueryResult impleme * The number of columns in the query result. */ private int numberOfColumns; + /** + * Pointer to the native result set. + * We need to keep it around for getting columns. + * The native result set is kept until the {@link close()} is called. + */ private long resultPointer; public EmbeddedQueryResult(String[] columnNames, String[] columnTypes, int numberOfColumns, long resultPointer) { diff --git a/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java b/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java --- a/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java +++ b/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java @@ -34,7 +34,7 @@ public class EmbeddedTest { Integer.valueOf(34), Long.valueOf(45l), Float.valueOf(5.6f), - Double.valueOf(6.7), + Double.valueOf(6.7) }; static Object[] charTypeTestValues = new Object[]{ @@ -51,8 +51,8 @@ public class EmbeddedTest { final Path directoryPath = Files.createTempDirectory("monetdbtest"); datbaseDirectory = directoryPath.toFile(); - db = new MonetDBEmbedded(datbaseDirectory, false); - db.run(); + db = new MonetDBEmbedded(datbaseDirectory); + db.start(); db.query("CREATE TABLE test (id integer, val integer);"); db.query("INSERT INTO test VALUES (0, " + testValues[0] + "), (1, " + testValues[1] + "), (2, " + testValues[2] + "), (3, " + testValues[3] + ");"); @@ -73,18 +73,6 @@ public class EmbeddedTest { } @Test - public void restartExistingDatabaseTest() throws IOException, SQLException { - MonetDBEmbedded restartedDB = new MonetDBEmbedded(datbaseDirectory, false); - restartedDB.run(); - - try (EmbeddedQueryResult result = restartedDB.query("SELECT * FROM test;")) { - assertEquals(4, result.getColumn(1).columnSize()); - assertEquals(Integer.valueOf(20), result.getColumn(1).getValue(1)); - assertEquals(null, result.getColumn(1).getValue(3)); - } - } - - @Test public void iteratorTest() throws IOException, SQLException { try (EmbeddedQueryResult result = db.query("SELECT * FROM test;")) { @@ -198,20 +186,24 @@ public class EmbeddedTest { } @Test - public void newDatabaseTest() throws IOException, SQLException { - final Path tempDirectoryPath = Files.createTempDirectory("monetdbtest_new"); - final File newDirectory = tempDirectoryPath.toFile(); - - MonetDBEmbedded newDB = new MonetDBEmbedded(newDirectory, false); - newDB.run(); - - newDB.query("CREATE TABLE test (id integer, val integer);"); - newDB.query("INSERT INTO test VALUES (1, 10), (2, 20), (3, 30), (4, null);"); - - try (EmbeddedQueryResult result = newDB.query("SELECT * FROM world;")) { + public void newObjectWithSameDatabaseDirectoryTest() throws IOException, SQLException { + MonetDBEmbedded sameDB = new MonetDBEmbedded(datbaseDirectory, false); + // This is technically a no-op + sameDB.start(); + + try (EmbeddedQueryResult result = sameDB.query("SELECT * FROM test;")) { assertEquals(4, result.getColumn(1).columnSize()); assertEquals(Integer.valueOf(20), result.getColumn(1).getValue(1)); assertEquals(null, result.getColumn(1).getValue(3)); } } + + @Test(expected=IOException.class) + public void newDatabaseTest() throws IOException { + final Path tempDirectoryPath = Files.createTempDirectory("monetdbtest_new"); + final File newDirectory = tempDirectoryPath.toFile(); + + MonetDBEmbedded newDB = new MonetDBEmbedded(newDirectory); + newDB.start(); + } } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list