Skip to content

Commit

Permalink
net-sf-ucanaccess-fork: Add connection builder
Browse files Browse the repository at this point in the history
  • Loading branch information
spannm committed Nov 14, 2023
1 parent 8520ee4 commit 082483f
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 134 deletions.
3 changes: 1 addition & 2 deletions src/main/java/net/ucanaccess/console/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ public static void main(String[] args) throws Exception {
noMem = size > 30000000 ? ";memory=false" : "";
}

conn = DriverManager.getConnection("jdbc:ucanaccess://" + fl.getAbsolutePath() + passwordEntry + noMem,
props);
conn = DriverManager.getConnection("jdbc:ucanaccess://" + fl.getAbsolutePath() + passwordEntry + noMem, props);

SQLWarning sqlw = conn.getWarnings();
while (sqlw != null) {
Expand Down
97 changes: 97 additions & 0 deletions src/main/java/net/ucanaccess/jdbc/UcanaccessConnectionBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package net.ucanaccess.jdbc;

import net.ucanaccess.util.Try;

import java.sql.DriverManager;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* A build for Ucanaccess database urls and connections.
*/
public final class UcanaccessConnectionBuilder {

private String user = "ucanaccess";
private String password;
private String dbPath;
private boolean ignoreCase;
private long inactivityTimeout = -1;
private String columnOrder;
private Map<String, Object> addParms = new LinkedHashMap<>();

public UcanaccessConnectionBuilder withUser(String _user) {
user = _user;
return this;
}

public UcanaccessConnectionBuilder withPassword(String _password) {
password = _password;
return this;
}

public UcanaccessConnectionBuilder withoutUserPass() {
user = "";
password = "";
return this;
}

public UcanaccessConnectionBuilder withDbPath(String _dbPath) {
dbPath = _dbPath;
return this;
}

public UcanaccessConnectionBuilder withIgnoreCase(boolean _ignoreCase) {
ignoreCase = _ignoreCase;
return this;
}

public UcanaccessConnectionBuilder withInactivityTimeout(long _inactivityTimeout) {
inactivityTimeout = _inactivityTimeout;
return this;
}

public UcanaccessConnectionBuilder withColumnOrder(String _columnOrder) {
columnOrder = _columnOrder;
return this;
}

public UcanaccessConnectionBuilder withParm(String _key, Object _value) {
Objects.requireNonNull(_key, "Key required");
Objects.requireNonNull(_value, "Value required");
addParms.put(_key, _value);
return this;
}

public String buildUrl() {
Objects.requireNonNull(dbPath, "Database path required");

String url = UcanaccessDriver.URL_PREFIX + dbPath;

if (ignoreCase) {
url += ";ignoreCase=" + ignoreCase;
}
if (inactivityTimeout > -1) {
url += ";inactivityTimeout=" + inactivityTimeout;
} else {
url += ";immediatelyReleaseResources=true";
}
if (columnOrder != null) {
url += ";columnOrder=" + columnOrder;
}
if (!addParms.isEmpty()) {
url += ";" + addParms.entrySet().stream().map(e -> e.getKey() + '=' + e.getValue()).collect(Collectors.joining(";"));
}
return url;
}

public UcanaccessConnection build() {
Try.catching(() -> Class.forName(UcanaccessDriver.class.getName()))
.orThrow(UcanaccessRuntimeException::new);

return Try.catching(() -> DriverManager.getConnection(buildUrl(), user, password))
.map(UcanaccessConnection.class::cast).orThrow();
}

}
12 changes: 6 additions & 6 deletions src/test/java/net/ucanaccess/jdbc/BigintTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.junit.jupiter.params.provider.EnumSource.Mode;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

Expand All @@ -29,14 +28,15 @@ void testBigintInsert(AccessVersion _accessVersion) throws Exception {

ucanaccess.close();

String connUrl = UcanaccessDriver.URL_PREFIX + accdbPath + ";immediatelyReleaseResources=true";

try (Connection cnxn = DriverManager.getConnection(connUrl);
Statement st2 = cnxn.createStatement();
ResultSet rs = st2.executeQuery("SELECT x FROM table1 WHERE entry='3 billion'")) {
try (Connection conn = buildConnection()
.withDbPath(accdbPath)
.withParm("immediatelyReleaseResources", true).build();
Statement st2 = conn.createStatement();
ResultSet rs = st2.executeQuery("SELECT x FROM table1 WHERE entry='3 billion'")) {
rs.next();
Long actual = rs.getLong("x");
assertEquals(expected, actual);
}
}

}
7 changes: 6 additions & 1 deletion src/test/java/net/ucanaccess/jdbc/ColumnOrderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ protected String getAccessPath() {
return TEST_DB_DIR + "columnOrder.accdb";
}

@Override
protected UcanaccessConnectionBuilder buildConnection() {
return super.buildConnection()
.withColumnOrder("display");
}

@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("net.ucanaccess.test.AccessVersion#getDefaultAccessVersion()")
void testColumnOrder1(AccessVersion _accessVersion) throws Exception {
init(_accessVersion);

setColumnOrder("display");
try (Connection uca = createUcanaccessConnection();
PreparedStatement ps = uca.prepareStatement("INSERT INTO t1 values (?,?,?)")) {
ps.setInt(3, 3);
Expand Down
9 changes: 5 additions & 4 deletions src/test/java/net/ucanaccess/jdbc/ConcatNullsFalseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@

class ConcatNullsFalseTest extends UcanaccessBaseTest {

ConcatNullsFalseTest() {
appendToJdbcURL(";concatnulls=false");
}

@Override
protected String getAccessPath() {
return TEST_DB_DIR + "badDb.accdb";
}

protected UcanaccessConnectionBuilder buildConnection() {
return super.buildConnection()
.withParm("concatnulls", false);
}

@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("net.ucanaccess.test.AccessVersion#getDefaultAccessVersion()")
void testConcat(AccessVersion _accessVersion) throws Exception {
Expand Down
16 changes: 9 additions & 7 deletions src/test/java/net/ucanaccess/jdbc/ConcatNullsTrueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@

class ConcatNullsTrueTest extends UcanaccessBaseTest {

ConcatNullsTrueTest() {
// By default, any null value will cause the function to return null.
// If the property is set false, then NULL values are replaced with empty strings.
// see: http://hsqldb.org/doc/guide/builtinfunctions-chapt.html
appendToJdbcURL(";concatnulls=true");
}

@Override
protected String getAccessPath() {
return TEST_DB_DIR + "badDb.accdb";
}

@Override
protected UcanaccessConnectionBuilder buildConnection() {
// By default, any null value will cause the function to return null.
// If the property is set false, then NULL values are replaced with empty strings.
// see: http://hsqldb.org/doc/guide/builtinfunctions-chapt.html
return super.buildConnection()
.withParm("concatnulls", true);
}

@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("net.ucanaccess.test.AccessVersion#getDefaultAccessVersion()")
void testConcat(AccessVersion _accessVersion) throws Exception {
Expand Down
25 changes: 15 additions & 10 deletions src/test/java/net/ucanaccess/jdbc/CreateDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.junit.jupiter.params.provider.EnumSource;

import java.io.File;
import java.sql.DriverManager;
import java.sql.Statement;

class CreateDatabaseTest extends UcanaccessBaseTest {
Expand All @@ -19,20 +18,26 @@ void testNewDatabase(AccessVersion _accessVersion) throws Exception {
File fileMdb = createTempFileName(getClass().getSimpleName());
fileMdb.deleteOnExit();

String url = UcanaccessDriver.URL_PREFIX + fileMdb.getAbsolutePath() + ";immediatelyReleaseResources=true;newDatabaseVersion=" + getFileFormat().name();
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
UcanaccessConnection conn = buildConnection()
.withDbPath(fileMdb.getAbsolutePath())
.withUser("")
.withPassword("")
.withParm("immediatelyReleaseResources", true)
.withParm("newDatabaseVersion", getFileFormat().name())
.build();

UcanaccessConnection ucanaccessConnection = (UcanaccessConnection) DriverManager.getConnection(url, "", "");
assertNotNull(ucanaccessConnection);
assertNotNull(conn);
ucanaccess.close();
ucanaccess = ucanaccessConnection;
ucanaccess = conn;

getLogger().info("Database file successfully created: {}", fileMdb.getAbsolutePath());

try (Statement st = ucanaccessConnection.createStatement()) {
st.execute("CREATE TABLE AAA (baaaa text(3) PRIMARY KEY, A long default 3, C text(4))");
st.execute("INSERT INTO AAA(baaaa, c) VALUES ('33A','G' )");
st.execute("INSERT INTO AAA VALUES ('33B',111,'G' )");

try (Statement st = conn.createStatement()) {
executeStatements(st,
"CREATE TABLE AAA (baaaa TEXT(3) PRIMARY KEY, A LONG DEFAULT 3, C TEXT(4))",
"INSERT INTO AAA(baaaa, c) VALUES ('33A','G' )",
"INSERT INTO AAA VALUES ('33B',111,'G' )");
}
dumpQueryResult("SELECT * FROM AAA");
}
Expand Down
14 changes: 8 additions & 6 deletions src/test/java/net/ucanaccess/jdbc/ExceptionCodeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Locale;
Expand Down Expand Up @@ -53,11 +52,14 @@ void testGenException(AccessVersion _accessVersion) {
@ParameterizedTest(name = "[{index}] {0}")
@EnumSource(value = AccessVersion.class)
void testGException(AccessVersion _accessVersion) {
assertThatThrownBy(() -> DriverManager.getConnection(UcanaccessDriver.URL_PREFIX + "kuso_yaro"))
.isInstanceOf(UcanaccessSQLException.class)
.hasMessageContaining("given file does not exist")
.hasFieldOrPropertyWithValue("ErrorCode", IUcanaccessErrorCodes.UCANACCESS_GENERIC_ERROR)
.hasFieldOrPropertyWithValue("SQLState", String.valueOf(IUcanaccessErrorCodes.UCANACCESS_GENERIC_ERROR));
assertThatThrownBy(() -> buildConnection()
.withDbPath("kuso_yaro")
.withUser("")
.build())
.isInstanceOf(UcanaccessSQLException.class)
.hasMessageContaining("given file does not exist")
.hasFieldOrPropertyWithValue("ErrorCode", IUcanaccessErrorCodes.UCANACCESS_GENERIC_ERROR)
.hasFieldOrPropertyWithValue("SQLState", String.valueOf(IUcanaccessErrorCodes.UCANACCESS_GENERIC_ERROR));
}

}
20 changes: 12 additions & 8 deletions src/test/java/net/ucanaccess/jdbc/ExternalResourcesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import org.junit.jupiter.params.provider.MethodSource;

import java.io.File;
import java.sql.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

class ExternalResourcesTest extends UcanaccessBaseTest {

Expand All @@ -15,17 +17,19 @@ class ExternalResourcesTest extends UcanaccessBaseTest {
void testLinks(AccessVersion _accessVersion) throws SQLException, ClassNotFoundException {
init(_accessVersion);

Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");

File main = copyResourceToTempFile(TEST_DB_DIR + "main.mdb");
File linkee1 = copyResourceToTempFile(TEST_DB_DIR + "linkee1.mdb");
File linkee2 = copyResourceToTempFile(TEST_DB_DIR + "linkee2.mdb");
String url = UcanaccessDriver.URL_PREFIX + main.getAbsolutePath() + ";immediatelyreleaseresources=true"
+ ";remap=c:\\db\\linkee1.mdb|" + linkee1.getAbsolutePath() + "&c:\\db\\linkee2.mdb|"
+ linkee2.getAbsolutePath();
getLogger().info("Database url: {}", url);

try (Connection conn = DriverManager.getConnection(url, "", "");
UcanaccessConnectionBuilder bldr = buildConnection()
.withDbPath(main.getAbsolutePath())
.withUser("")
.withPassword("")
.withParm("immediatelyReleaseResources", true)
.withParm("remap", "c:\\db\\linkee1.mdb|" + linkee1.getAbsolutePath() + "&c:\\db\\linkee2.mdb|" + linkee2.getAbsolutePath());
getLogger().info("Database url: {}", bldr.buildUrl());

try (Connection conn = bldr.build();
Statement st = conn.createStatement()) {

dumpQueryResult(() -> st.executeQuery("SELECT * FROM table1"));
Expand Down
8 changes: 3 additions & 5 deletions src/test/java/net/ucanaccess/jdbc/FolderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLWarning;

Expand All @@ -23,12 +22,11 @@ void testFolderContent(AccessVersion _accessVersion) throws SQLException, ClassN
return;
}

Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");

File folder = new File(folderPath);
for (File fl : folder.listFiles()) {
String url = UcanaccessDriver.URL_PREFIX + fl.getAbsolutePath();
Connection conn = DriverManager.getConnection(url);
Connection conn = buildConnection()
.withDbPath(fl.getAbsolutePath())
.build();
SQLWarning sqlw = conn.getWarnings();
getLogger().info("open {}", fl.getAbsolutePath());
while (sqlw != null) {
Expand Down
7 changes: 6 additions & 1 deletion src/test/java/net/ucanaccess/jdbc/MemoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ protected void init(AccessVersion _accessVersion) throws SQLException {
super.init(_accessVersion);
getLogger().debug("Thread.activeCount (setup): " + Thread.activeCount());

setInactivityTimeout(1000L);
executeStatements("CREATE TABLE memm(id LONG PRIMARY KEY, A LONG, C TEXT, D TEXT)");
}

@Override
protected UcanaccessConnectionBuilder buildConnection() {
return super.buildConnection()
.withInactivityTimeout(1000L);
}

@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("net.ucanaccess.test.AccessVersion#getDefaultAccessVersion()")
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/net/ucanaccess/jdbc/MultiThreadAccessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void afterEachTest() throws SQLException {
}

void crud() throws SQLException {
try (Connection conn = createUcanaccessConnection(dbPath)) {
try (Connection conn = buildConnection().withDbPath(dbPath).build()) {
conn.setAutoCommit(false);
Statement st = conn.createStatement();
intVal++;
Expand All @@ -43,7 +43,7 @@ void crud() throws SQLException {
}

void crudPS() throws SQLException {
try (Connection conn = createUcanaccessConnection(dbPath)) {
try (Connection conn = buildConnection().withDbPath(dbPath).build()) {
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("INSERT INTO " + tableName + " (id,descr) VALUES(?, ?)");
ps.setInt(1, ++intVal);
Expand All @@ -57,7 +57,7 @@ void crudPS() throws SQLException {
}

void crudUpdatableRS() throws SQLException {
try (Connection conn = createUcanaccessConnection(dbPath)) {
try (Connection conn = buildConnection().withDbPath(dbPath).build()) {
conn.setAutoCommit(false);
Statement st = conn.createStatement();
st.execute("INSERT INTO " + tableName + " (id,descr) VALUES(" + (++intVal) + " ,'" + Thread.currentThread() + "')");
Expand Down Expand Up @@ -89,7 +89,7 @@ void testMultiThread(AccessVersion _accessVersion) throws SQLException, IOExcept
for (Thread t : threads) {
Try.catching(() -> t.join()).orIgnore();
}
ucanaccess = createUcanaccessConnection(dbPath);
ucanaccess = buildConnection().withDbPath(dbPath).build();
dumpQueryResult("SELECT * FROM " + tableName + " ORDER BY id");

checkQuery("SELECT * FROM " + tableName + " ORDER BY id");
Expand Down
Loading

0 comments on commit 082483f

Please sign in to comment.