mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-05 01:04:22 +01:00
Remove the tight coupling(using inheritance) between LimboXXX and JDBCXXX and favor composition instead
This commit is contained in:
@@ -10,6 +10,6 @@ import java.lang.annotation.Target;
|
||||
* Annotation to mark methods that are called by native functions.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
public @interface NativeInvocation {
|
||||
}
|
||||
|
||||
@@ -79,13 +79,13 @@ public abstract class LimboConnection implements Connection {
|
||||
* @return Pointer to statement.
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public long prepare(String sql) throws SQLException {
|
||||
public LimboStatement prepare(String sql) throws SQLException {
|
||||
logger.trace("DriverManager [{}] [SQLite EXEC] {}", Thread.currentThread().getName(), sql);
|
||||
byte[] sqlBytes = stringToUtf8ByteArray(sql);
|
||||
if (sqlBytes == null) {
|
||||
throw new SQLException("Failed to convert " + sql + " into bytes");
|
||||
}
|
||||
return prepareUtf8(connectionPtr, sqlBytes);
|
||||
return new LimboStatement(prepareUtf8(connectionPtr, sqlBytes));
|
||||
}
|
||||
|
||||
private native long prepareUtf8(long connectionPtr, byte[] sqlUtf8) throws SQLException;
|
||||
|
||||
@@ -3,25 +3,51 @@ package org.github.tursodatabase.core;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* JDBC ResultSet.
|
||||
* A table of data representing limbo database result set, which is generated by executing a statement that queries the
|
||||
* database.
|
||||
* <p>
|
||||
* A {@link LimboResultSet} object is automatically closed when the {@link LimboStatement} object that generated it is
|
||||
* closed or re-executed.
|
||||
*/
|
||||
public abstract class LimboResultSet {
|
||||
public class LimboResultSet {
|
||||
|
||||
protected final LimboStatement statement;
|
||||
private final LimboStatement statement;
|
||||
|
||||
// Whether the result set does not have any rows.
|
||||
protected boolean isEmptyResultSet = false;
|
||||
private boolean isEmptyResultSet = false;
|
||||
// If the result set is open. Doesn't mean it has results.
|
||||
private boolean open = false;
|
||||
// Maximum number of rows as set by the statement
|
||||
protected long maxRows;
|
||||
private long maxRows;
|
||||
// number of current row, starts at 1 (0 is used to represent loading data)
|
||||
protected int row = 0;
|
||||
private int row = 0;
|
||||
|
||||
protected LimboResultSet(LimboStatement statement) {
|
||||
private boolean pastLastRow = false;
|
||||
|
||||
public static LimboResultSet of(LimboStatement statement) {
|
||||
return new LimboResultSet(statement);
|
||||
}
|
||||
|
||||
private LimboResultSet(LimboStatement statement) {
|
||||
this.open = true;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
public boolean next() throws SQLException {
|
||||
if (!open || isEmptyResultSet || pastLastRow) {
|
||||
return false; // completed ResultSet
|
||||
}
|
||||
|
||||
if (maxRows != 0 && row == maxRows) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// int statusCode = this.statement.step();
|
||||
this.statement.step();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the status of the result set.
|
||||
*
|
||||
@@ -34,7 +60,7 @@ public abstract class LimboResultSet {
|
||||
/**
|
||||
* @throws SQLException if not {@link #open}
|
||||
*/
|
||||
protected void checkOpen() throws SQLException {
|
||||
public void checkOpen() throws SQLException {
|
||||
if (!open) {
|
||||
throw new SQLException("ResultSet closed");
|
||||
}
|
||||
|
||||
@@ -2,58 +2,45 @@ package org.github.tursodatabase.core;
|
||||
|
||||
import org.github.tursodatabase.annotations.NativeInvocation;
|
||||
import org.github.tursodatabase.annotations.Nullable;
|
||||
import org.github.tursodatabase.jdbc4.JDBC4ResultSet;
|
||||
import org.github.tursodatabase.utils.LimboExceptionUtils;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class LimboStatement {
|
||||
/**
|
||||
* By default, only one <code>resultSet</code> object per <code>LimboStatement</code> can be open at the same time.
|
||||
* Therefore, if the reading of one <code>resultSet</code> object is interleaved with the reading of another, each must
|
||||
* have been generated by different <code>LimboStatement</code> objects. All execution method in the <code>LimboStatement</code>
|
||||
* implicitly close the current <code>resultSet</code> object of the statement if an open one exists.
|
||||
*/
|
||||
public class LimboStatement {
|
||||
|
||||
protected final LimboConnection connection;
|
||||
protected final LimboResultSet resultSet;
|
||||
private final long statementPointer;
|
||||
private final LimboResultSet resultSet;
|
||||
|
||||
@Nullable
|
||||
protected String sql = null;
|
||||
|
||||
protected LimboStatement(LimboConnection connection) {
|
||||
this.connection = connection;
|
||||
this.resultSet = new JDBC4ResultSet(this);
|
||||
public LimboStatement(long statementPointer) {
|
||||
this.statementPointer = statementPointer;
|
||||
this.resultSet = LimboResultSet.of(this);
|
||||
}
|
||||
|
||||
protected void internalClose() throws SQLException {
|
||||
// TODO
|
||||
public LimboResultSet resultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
protected void clearGeneratedKeys() throws SQLException {
|
||||
// TODO
|
||||
public void execute() throws SQLException {
|
||||
LimboResultSet result = LimboResultSet.of(this);
|
||||
|
||||
// at least, run query minimally
|
||||
result.next();
|
||||
}
|
||||
|
||||
protected void updateGeneratedKeys() throws SQLException {
|
||||
// TODO
|
||||
public LimboStepResult step() throws SQLException {
|
||||
return step(this.statementPointer);
|
||||
}
|
||||
|
||||
// TODO: associate the result with CoreResultSet
|
||||
// TODO: we can make this async!!
|
||||
// TODO: distinguish queries that return result or doesn't return result
|
||||
protected List<Object[]> execute(long stmtPointer) throws SQLException {
|
||||
List<Object[]> result = new ArrayList<>();
|
||||
while (true) {
|
||||
Object[] stepResult = step(stmtPointer);
|
||||
if (stepResult != null) {
|
||||
for (int i = 0; i < stepResult.length; i++) {
|
||||
System.out.println("stepResult" + i + ": " + stepResult[i]);
|
||||
}
|
||||
}
|
||||
if (stepResult == null) break;
|
||||
result.add(stepResult);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private native Object[] step(long stmtPointer) throws SQLException;
|
||||
private native LimboStepResult step(long stmtPointer) throws SQLException;
|
||||
|
||||
/**
|
||||
* Throws formatted SQLException with error code and message.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.github.tursodatabase.core;
|
||||
|
||||
import org.github.tursodatabase.annotations.NativeInvocation;
|
||||
|
||||
/**
|
||||
* Represents the step result of limbo's statement's step function.
|
||||
*/
|
||||
public class LimboStepResult {
|
||||
public static final int STEP_RESULT_ID_ROW = 10;
|
||||
public static final int STEP_RESULT_ID_IO = 20;
|
||||
public static final int STEP_RESULT_ID_DONE = 30;
|
||||
public static final int STEP_RESULT_ID_INTERRUPT = 40;
|
||||
public static final int STEP_RESULT_ID_BUSY = 50;
|
||||
public static final int STEP_RESULT_ID_ERROR = 60;
|
||||
|
||||
// Identifier for limbo's StepResult
|
||||
private final int stepResultId;
|
||||
private final Object[] result;
|
||||
|
||||
@NativeInvocation
|
||||
public LimboStepResult(int stepResultId, Object[] result) {
|
||||
this.stepResultId = stepResultId;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.github.tursodatabase.jdbc4;
|
||||
|
||||
import org.github.tursodatabase.annotations.SkipNullableCheck;
|
||||
import org.github.tursodatabase.core.LimboResultSet;
|
||||
import org.github.tursodatabase.core.LimboStatement;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
@@ -12,10 +11,12 @@ import java.sql.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
public class JDBC4ResultSet extends LimboResultSet implements ResultSet {
|
||||
public class JDBC4ResultSet implements ResultSet {
|
||||
|
||||
public JDBC4ResultSet(LimboStatement statement) {
|
||||
super(statement);
|
||||
private final LimboResultSet resultSet;
|
||||
|
||||
public JDBC4ResultSet(LimboResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package org.github.tursodatabase.jdbc4;
|
||||
|
||||
import org.github.tursodatabase.annotations.Nullable;
|
||||
import org.github.tursodatabase.annotations.SkipNullableCheck;
|
||||
import org.github.tursodatabase.core.LimboConnection;
|
||||
import org.github.tursodatabase.core.LimboStatement;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link Statement} interface for JDBC 4.
|
||||
*/
|
||||
public class JDBC4Statement extends LimboStatement implements Statement {
|
||||
public class JDBC4Statement implements Statement {
|
||||
|
||||
private final LimboConnection connection;
|
||||
@Nullable
|
||||
private LimboStatement statement = null;
|
||||
|
||||
private boolean closed;
|
||||
private boolean closeOnCompletion;
|
||||
@@ -32,7 +32,7 @@ public class JDBC4Statement extends LimboStatement implements Statement {
|
||||
}
|
||||
|
||||
public JDBC4Statement(LimboConnection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
|
||||
super(connection);
|
||||
this.connection = connection;
|
||||
this.resultSetType = resultSetType;
|
||||
this.resultSetConcurrency = resultSetConcurrency;
|
||||
this.resultSetHoldability = resultSetHoldability;
|
||||
@@ -129,11 +129,12 @@ public class JDBC4Statement extends LimboStatement implements Statement {
|
||||
() -> {
|
||||
try {
|
||||
connectionLock.lock();
|
||||
final long stmtPointer = connection.prepare(sql);
|
||||
List<Object[]> result = execute(stmtPointer);
|
||||
statement = connection.prepare(sql);
|
||||
statement.execute();
|
||||
updateGeneratedKeys();
|
||||
exhaustedResults = false;
|
||||
return !result.isEmpty();
|
||||
return true;
|
||||
// return !result.isEmpty();
|
||||
} finally {
|
||||
connectionLock.unlock();
|
||||
}
|
||||
@@ -314,6 +315,18 @@ public class JDBC4Statement extends LimboStatement implements Statement {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void internalClose() throws SQLException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
protected void clearGeneratedKeys() throws SQLException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
protected void updateGeneratedKeys() throws SQLException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
private <T> T withConnectionTimeout(SQLCallable<T> callable) throws SQLException {
|
||||
final int originalBusyTimeoutMillis = connection.getBusyTimeout();
|
||||
if (queryTimeoutSeconds > 0) {
|
||||
|
||||
Reference in New Issue
Block a user