Refactor to use composition instead of inheritance

- Update JDBC4Connection to implement Connection directly
- JDBC4Connection holds LimboConnection as a member field
This commit is contained in:
김선우
2025-02-07 15:37:37 +09:00
parent 400dd6dd42
commit 7409779be7
7 changed files with 48 additions and 74 deletions

View File

@@ -5,7 +5,6 @@ import java.util.Locale;
import java.util.Properties;
import org.github.tursodatabase.annotations.Nullable;
import org.github.tursodatabase.annotations.SkipNullableCheck;
import org.github.tursodatabase.core.LimboConnection;
import org.github.tursodatabase.jdbc4.JDBC4Connection;
import org.github.tursodatabase.utils.Logger;
import org.github.tursodatabase.utils.LoggerFactory;
@@ -24,7 +23,7 @@ public class JDBC implements Driver {
}
@Nullable
public static LimboConnection createConnection(String url, Properties properties)
public static JDBC4Connection createConnection(String url, Properties properties)
throws SQLException {
if (!isValidURL(url)) return null;

View File

@@ -2,7 +2,6 @@ package org.github.tursodatabase.core;
import static org.github.tursodatabase.utils.ByteArrayUtils.stringToUtf8ByteArray;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
@@ -11,7 +10,7 @@ import org.github.tursodatabase.utils.LimboExceptionUtils;
import org.github.tursodatabase.utils.Logger;
import org.github.tursodatabase.utils.LoggerFactory;
public abstract class LimboConnection implements Connection {
public class LimboConnection {
private static final Logger logger = LoggerFactory.getLogger(LimboConnection.class);
private final long connectionPtr;
@@ -38,11 +37,10 @@ public abstract class LimboConnection implements Connection {
return LimboDBFactory.open(url, filePath, properties);
}
protected void checkOpen() throws SQLException {
public void checkOpen() throws SQLException {
if (isClosed()) throw new SQLException("database connection closed");
}
@Override
public void close() throws SQLException {
if (isClosed()) {
return;
@@ -53,7 +51,6 @@ public abstract class LimboConnection implements Connection {
private native void _close(long connectionPtr);
@Override
public boolean isClosed() throws SQLException {
return closed;
}
@@ -80,14 +77,7 @@ public abstract class LimboConnection implements Connection {
private native long prepareUtf8(long connectionPtr, byte[] sqlUtf8) throws SQLException;
/** @return busy timeout in milliseconds. */
public int getBusyTimeout() {
// TODO: add support for busyTimeout
return 0;
}
// TODO: check whether this is still valid for limbo
/**
* Checks whether the type, concurrency, and holdability settings for a {@link ResultSet} are
* supported by the SQLite interface. Supported settings are:
@@ -102,7 +92,7 @@ public abstract class LimboConnection implements Connection {
* @param resultSetConcurrency the concurrency setting.
* @param resultSetHoldability the holdability setting.
*/
protected void checkCursor(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
public void checkCursor(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
throw new SQLException("SQLite only supports TYPE_FORWARD_ONLY cursors");
@@ -115,10 +105,6 @@ public abstract class LimboConnection implements Connection {
}
}
public void setBusyTimeout(int busyTimeout) {
// TODO: add support for busy timeout
}
/**
* Throws formatted SQLException with error code and message.
*

View File

@@ -7,15 +7,22 @@ import java.util.Properties;
import java.util.concurrent.Executor;
import org.github.tursodatabase.annotations.SkipNullableCheck;
import org.github.tursodatabase.core.LimboConnection;
import org.github.tursodatabase.core.LimboStatement;
public class JDBC4Connection extends LimboConnection {
public class JDBC4Connection implements Connection {
private final LimboConnection connection;
public JDBC4Connection(String url, String filePath) throws SQLException {
super(url, filePath);
this.connection = new LimboConnection(url, filePath);
}
public JDBC4Connection(String url, String filePath, Properties properties) throws SQLException {
super(url, filePath, properties);
this.connection = new LimboConnection(url, filePath, properties);
}
public LimboStatement prepare(String sql) throws SQLException {
return connection.prepare(sql);
}
@Override
@@ -33,8 +40,8 @@ public class JDBC4Connection extends LimboConnection {
@Override
public Statement createStatement(
int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
checkOpen();
checkCursor(resultSetType, resultSetConcurrency, resultSetHoldability);
connection.checkOpen();
connection.checkCursor(resultSetType, resultSetConcurrency, resultSetHoldability);
return new JDBC4Statement(this);
}
@@ -81,12 +88,12 @@ public class JDBC4Connection extends LimboConnection {
@Override
public void close() throws SQLException {
super.close();
connection.close();
}
@Override
public boolean isClosed() throws SQLException {
return super.isClosed();
return connection.isClosed();
}
@Override
@@ -351,4 +358,14 @@ public class JDBC4Connection extends LimboConnection {
// TODO
return false;
}
public void setBusyTimeout(int busyTimeout) {
// TODO: add support for busy timeout
}
/** @return busy timeout in milliseconds. */
public int getBusyTimeout() {
// TODO: add support for busyTimeout
return 0;
}
}

View File

@@ -23,13 +23,12 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import org.github.tursodatabase.annotations.SkipNullableCheck;
import org.github.tursodatabase.core.LimboConnection;
public class JDBC4PreparedStatement extends JDBC4Statement implements PreparedStatement {
private final String sql;
public JDBC4PreparedStatement(LimboConnection connection, String sql) throws SQLException {
public JDBC4PreparedStatement(JDBC4Connection connection, String sql) throws SQLException {
super(connection);
this.sql = sql;

View File

@@ -10,13 +10,12 @@ import java.sql.Statement;
import java.util.concurrent.locks.ReentrantLock;
import org.github.tursodatabase.annotations.Nullable;
import org.github.tursodatabase.annotations.SkipNullableCheck;
import org.github.tursodatabase.core.LimboConnection;
import org.github.tursodatabase.core.LimboResultSet;
import org.github.tursodatabase.core.LimboStatement;
public class JDBC4Statement implements Statement {
private final LimboConnection connection;
private final JDBC4Connection connection;
@Nullable protected LimboStatement statement = null;
// Because JDBC4Statement has different life cycle in compared to LimboStatement, let's use this
@@ -34,7 +33,7 @@ public class JDBC4Statement implements Statement {
private ReentrantLock connectionLock = new ReentrantLock();
public JDBC4Statement(LimboConnection connection) {
public JDBC4Statement(JDBC4Connection connection) {
this(
connection,
ResultSet.TYPE_FORWARD_ONLY,
@@ -43,7 +42,7 @@ public class JDBC4Statement implements Statement {
}
public JDBC4Statement(
LimboConnection connection,
JDBC4Connection connection,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) {

View File

@@ -6,21 +6,21 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.github.tursodatabase.core.LimboConnection;
import org.github.tursodatabase.jdbc4.JDBC4Connection;
import org.junit.jupiter.api.Test;
class JDBCTest {
@Test
void null_is_returned_when_invalid_url_is_passed() throws Exception {
LimboConnection connection = JDBC.createConnection("jdbc:invalid:xxx", new Properties());
JDBC4Connection connection = JDBC.createConnection("jdbc:invalid:xxx", new Properties());
assertThat(connection).isNull();
}
@Test
void non_null_connection_is_returned_when_valid_url_is_passed() throws Exception {
String fileUrl = TestUtils.createTempFile();
LimboConnection connection = JDBC.createConnection("jdbc:sqlite:" + fileUrl, new Properties());
JDBC4Connection connection = JDBC.createConnection("jdbc:sqlite:" + fileUrl, new Properties());
assertThat(connection).isNotNull();
}