diff --git a/bindings/java/README.md b/bindings/java/README.md index 051833325..32631275d 100644 --- a/bindings/java/README.md +++ b/bindings/java/README.md @@ -4,15 +4,17 @@ The Limbo JDBC driver is a library for accessing and creating Limbo database fil ## Project Status -The project is actively developed. Feel free to open issues and contribute. +The project is actively developed. Feel free to open issues and contribute. To view related works, visit this [issue](https://github.com/tursodatabase/limbo/issues/615). -## How to use +## How to use -Currently, we have not published to the maven central. Instead, you can locally build the jar and deploy it to maven local to use it. +Currently, we have not published to the maven central. Instead, you can locally build the jar and deploy it to +maven local to use it. + +### Build jar and publish to maven local -### Build jar and publish to maven local ```shell $ cd bindings/java @@ -23,44 +25,16 @@ $ make macos_x86 $ make publish_local ``` -Now you can use the dependency as follows: +Now you can use the dependency as follows: + ```kotlin dependencies { - implementation("org.github.tursodatabase:limbo:0.0.1-SNAPSHOT") + implementation("org.github.tursodatabase:limbo:0.0.1-SNAPSHOT") } ``` -## Development +## Code style -### How to Run Tests - -To run tests, use the following command: - -```shell -$ make test -``` - -### Code Formatting - -To unify Java's formatting style, we use Spotless. To apply the formatting style, run: - -```shell -$ make lint_apply -``` - -To apply the formatting style for Rust, run the following command: - -```shell -$ cargo fmt -``` - -## Concepts - -Note that this project is actively developed, so the concepts might change in the future. - -- `LimboDB` represents a Limbo database. -- `LimboConnection` represents a connection to `LimboDB`. Multiple `LimboConnections` can be created on the same - `LimboDB`. -- `LimboStatement` represents a Limbo database statement. Multiple `LimboStatements` can be created on the same - `LimboConnection`. -- `LimboResultSet` represents the result of `LimboStatement` execution. It is one-to-one mapped to `LimboStatement`. +- Favor composition over inheritance. For example, `JDBC4Connection` doesn't implement `LimboConnection`. Instead, + it includes `LimboConnection` as a field. This approach allows us to preserve the characteristics of Limbo using + `LimboConnection` easily while maintaining interoperability with the Java world using `JDBC4Connection`. diff --git a/bindings/java/src/main/java/org/github/tursodatabase/JDBC.java b/bindings/java/src/main/java/org/github/tursodatabase/JDBC.java index ee8ae206b..444629ee2 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/JDBC.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/JDBC.java @@ -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; diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java index 639a2be56..597029ce9 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java @@ -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. * diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index d5b73e627..aac34e755 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -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; + } } diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java index f109cb647..fa487f014 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java @@ -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; diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java index 729134a44..260b7cbcb 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java @@ -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) { diff --git a/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java b/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java index c28ff7cb3..79e98176d 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java @@ -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(); }