diff --git a/bindings/java/src/main/java/org/github/tursodatabase/LimboConnection.java b/bindings/java/src/main/java/org/github/tursodatabase/LimboConnection.java index 5bc88a5ca..38af814eb 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/LimboConnection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/LimboConnection.java @@ -1,7 +1,7 @@ package org.github.tursodatabase; import org.github.tursodatabase.core.AbstractDB; -import org.github.tursodatabase.core.LimboDB; +import org.github.tursodatabase.core.LimboDBFactory; import java.sql.Connection; import java.sql.ResultSet; @@ -47,20 +47,7 @@ public abstract class LimboConnection implements Connection { } private static AbstractDB open(String url, String fileName, Properties properties) throws SQLException { - if (fileName.isEmpty()) { - throw new IllegalArgumentException("fileName should not be empty"); - } - - final AbstractDB database; - try { - LimboDB.load(); - database = LimboDB.create(url, fileName); - } catch (Exception e) { - throw new SQLException("Error opening connection", e); - } - - database.open(0); - return database; + return LimboDBFactory.open(url, fileName, properties); } protected void checkOpen() throws SQLException { diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDBFactory.java b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDBFactory.java new file mode 100644 index 000000000..d5275cb6a --- /dev/null +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDBFactory.java @@ -0,0 +1,47 @@ +package org.github.tursodatabase.core; + +import java.sql.SQLException; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Factory class for managing and creating instances of {@link LimboDB}. + * This class ensures that multiple instances of {@link LimboDB} with the same URL are not created. + */ +public class LimboDBFactory { + + private static final ConcurrentHashMap databaseHolder = new ConcurrentHashMap<>(); + + /** + * If a database with the same URL already exists, it returns the existing instance. + * Otherwise, it creates a new instance and stores it in the database holder. + * + * @param url the URL of the database + * @param fileName the path to the database file + * @param properties additional properties for the database connection + * @return an instance of {@link LimboDB} + * @throws SQLException if there is an error opening the connection + * @throws IllegalArgumentException if the fileName is empty + */ + public static LimboDB open(String url, String fileName, Properties properties) throws SQLException { + if (databaseHolder.containsKey(url)) { + return databaseHolder.get(url); + } + + if (fileName.isEmpty()) { + throw new IllegalArgumentException("fileName should not be empty"); + } + + final LimboDB database; + try { + LimboDB.load(); + database = LimboDB.create(url, fileName); + } catch (Exception e) { + throw new SQLException("Error opening connection", e); + } + + database.open(0); + databaseHolder.put(url, database); + return database; + } +} diff --git a/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBFactoryTest.java b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBFactoryTest.java new file mode 100644 index 000000000..bc3150f2c --- /dev/null +++ b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBFactoryTest.java @@ -0,0 +1,32 @@ +package org.github.tursodatabase.core; + +import org.github.tursodatabase.TestUtils; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +class LimboDBFactoryTest { + + @Test + void single_database_should_be_created_when_urls_are_same() throws Exception { + String filePath = TestUtils.createTempFile(); + String url = "jdbc:sqlite:" + filePath; + LimboDB db1 = LimboDBFactory.open(url, filePath, new Properties()); + LimboDB db2 = LimboDBFactory.open(url, filePath, new Properties()); + assertEquals(db1, db2); + } + + @Test + void multiple_databases_should_be_created_when_urls_differ() throws Exception { + String filePath1 = TestUtils.createTempFile(); + String filePath2 = TestUtils.createTempFile(); + String url1 = "jdbc:sqlite:" + filePath1; + String url2 = "jdbc:sqlite:" + filePath2; + LimboDB db1 = LimboDBFactory.open(url1, filePath1, new Properties()); + LimboDB db2 = LimboDBFactory.open(url2, filePath2, new Properties()); + assertNotEquals(db1, db2); + } +}