mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-25 03:54:21 +01:00
Implement JDBC4ResultSEt.java's next() method
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package org.github.tursodatabase.core;
|
||||
|
||||
import org.github.tursodatabase.annotations.Nullable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
@@ -21,9 +23,11 @@ public class LimboResultSet {
|
||||
private long maxRows;
|
||||
// number of current row, starts at 1 (0 is used to represent loading data)
|
||||
private int row = 0;
|
||||
|
||||
private boolean pastLastRow = false;
|
||||
|
||||
@Nullable
|
||||
private LimboStepResult lastResult;
|
||||
|
||||
public static LimboResultSet of(LimboStatement statement) {
|
||||
return new LimboResultSet(statement);
|
||||
}
|
||||
@@ -33,6 +37,14 @@ public class LimboResultSet {
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cursor forward one row from its current position. A {@link LimboResultSet} cursor is initially positioned
|
||||
* before the first fow; the first call to the method <code>next</code> makes the first row the current row; the second call
|
||||
* makes the second row the current row, and so on.
|
||||
* When a call to the <code>next</code> method returns <code>false</code>, the cursor is positioned after the last row.
|
||||
* <p>
|
||||
* Note that limbo only supports <code>ResultSet.TYPE_FORWARD_ONLY</code>, which means that the cursor can only move forward.
|
||||
*/
|
||||
public boolean next() throws SQLException {
|
||||
if (!open || isEmptyResultSet || pastLastRow) {
|
||||
return false; // completed ResultSet
|
||||
@@ -42,10 +54,9 @@ public class LimboResultSet {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// int statusCode = this.statement.step();
|
||||
this.statement.step();
|
||||
return true;
|
||||
lastResult = this.statement.step();
|
||||
pastLastRow = lastResult == null || lastResult.isDone();
|
||||
return !pastLastRow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,21 +25,20 @@ public class LimboStatement {
|
||||
this.resultSet = LimboResultSet.of(this);
|
||||
}
|
||||
|
||||
public LimboResultSet resultSet() {
|
||||
public LimboResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public void execute() throws SQLException {
|
||||
LimboResultSet result = LimboResultSet.of(this);
|
||||
|
||||
// at least, run query minimally
|
||||
result.next();
|
||||
resultSet.next();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LimboStepResult step() throws SQLException {
|
||||
return step(this.statementPointer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private native LimboStepResult step(long stmtPointer) throws SQLException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.github.tursodatabase.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.github.tursodatabase.annotations.NativeInvocation;
|
||||
|
||||
/**
|
||||
@@ -22,4 +24,16 @@ public class LimboStepResult {
|
||||
this.stepResultId = stepResultId;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return stepResultId == STEP_RESULT_ID_DONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LimboStepResult{" +
|
||||
"stepResultId=" + stepResultId +
|
||||
", result=" + Arrays.toString(result) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ public class JDBC4ResultSet implements ResultSet {
|
||||
|
||||
@Override
|
||||
public boolean next() throws SQLException {
|
||||
// TODO
|
||||
return false;
|
||||
return resultSet.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package org.github.tursodatabase.jdbc4;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
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.LimboStatement;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class JDBC4Statement implements Statement {
|
||||
|
||||
private final LimboConnection connection;
|
||||
@@ -28,10 +34,12 @@ public class JDBC4Statement implements Statement {
|
||||
private ReentrantLock connectionLock = new ReentrantLock();
|
||||
|
||||
public JDBC4Statement(LimboConnection connection) {
|
||||
this(connection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
||||
this(connection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
|
||||
ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
||||
}
|
||||
|
||||
public JDBC4Statement(LimboConnection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
|
||||
public JDBC4Statement(LimboConnection connection, int resultSetType, int resultSetConcurrency,
|
||||
int resultSetHoldability) {
|
||||
this.connection = connection;
|
||||
this.resultSetType = resultSetType;
|
||||
this.resultSetConcurrency = resultSetConcurrency;
|
||||
@@ -121,6 +129,17 @@ public class JDBC4Statement implements Statement {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>execute</code> method executes an SQL statement and indicates the
|
||||
* form of the first result. You must then use the methods
|
||||
* <code>getResultSet</code> or <code>getUpdateCount</code>
|
||||
* to retrieve the result, and <code>getMoreResults</code> to
|
||||
* move to any subsequent result(s).
|
||||
*
|
||||
* @return <code>true</code> if the first result is a <code>ResultSet</code>
|
||||
* object; <code>false</code> if it is an update count or there are
|
||||
* no results
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
internalClose();
|
||||
@@ -133,8 +152,8 @@ public class JDBC4Statement implements Statement {
|
||||
statement.execute();
|
||||
updateGeneratedKeys();
|
||||
exhaustedResults = false;
|
||||
// TODO: determine whether
|
||||
return true;
|
||||
// return !result.isEmpty();
|
||||
} finally {
|
||||
connectionLock.unlock();
|
||||
}
|
||||
@@ -143,10 +162,9 @@ public class JDBC4Statement implements Statement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SkipNullableCheck
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
// TODO
|
||||
return null;
|
||||
requireNonNull(statement, "statement is null");
|
||||
return new JDBC4ResultSet(statement.getResultSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,7 +307,7 @@ public class JDBC4Statement implements Statement {
|
||||
|
||||
@Override
|
||||
public void closeOnCompletion() throws SQLException {
|
||||
if (closed) throw new SQLException("statement is closed");
|
||||
if (closed) {throw new SQLException("statement is closed");}
|
||||
closeOnCompletion = true;
|
||||
}
|
||||
|
||||
@@ -298,7 +316,7 @@ public class JDBC4Statement implements Statement {
|
||||
*/
|
||||
@Override
|
||||
public boolean isCloseOnCompletion() throws SQLException {
|
||||
if (closed) throw new SQLException("statement is closed");
|
||||
if (closed) {throw new SQLException("statement is closed");}
|
||||
return closeOnCompletion;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public class LimboExceptionUtils {
|
||||
/**
|
||||
* Throws formatted SQLException with error code and message.
|
||||
*
|
||||
* @param errorCode Error code.
|
||||
* @param errorCode Error code.
|
||||
* @param errorMessageBytes Error message.
|
||||
*/
|
||||
public static void throwLimboException(int errorCode, byte[] errorMessageBytes) throws SQLException {
|
||||
@@ -23,10 +23,11 @@ public class LimboExceptionUtils {
|
||||
/**
|
||||
* Throws formatted SQLException with error code and message.
|
||||
*
|
||||
* @param errorCode Error code.
|
||||
* @param errorCode Error code.
|
||||
* @param errorMessage Error message.
|
||||
*/
|
||||
public static LimboException buildLimboException(int errorCode, @Nullable String errorMessage) throws SQLException {
|
||||
public static LimboException buildLimboException(int errorCode, @Nullable String errorMessage)
|
||||
throws SQLException {
|
||||
LimboErrorCode code = LimboErrorCode.getErrorCode(errorCode);
|
||||
String msg;
|
||||
if (code == LimboErrorCode.UNKNOWN_ERROR) {
|
||||
@@ -37,4 +38,18 @@ public class LimboExceptionUtils {
|
||||
|
||||
return new LimboException(msg, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the provided object is not null.
|
||||
*
|
||||
* @param object the object to check for nullity
|
||||
* @param message the message to include in the exception if the object is null
|
||||
*
|
||||
* @throws IllegalArgumentException if the provided object is null
|
||||
*/
|
||||
public static void requireNonNull(Object object, String message) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ public class IntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Doesn't work on workflow. Need investigation.")
|
||||
void create_table_multi_inserts_select() throws Exception {
|
||||
Statement stmt = createDefaultStatement();
|
||||
stmt.execute("CREATE TABLE users (id INT PRIMARY KEY, username TEXT);");
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.github.tursodatabase.jdbc4;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.github.tursodatabase.TestUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class JDBC4ResultSetTest {
|
||||
|
||||
private Statement stmt;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
String filePath = TestUtils.createTempFile();
|
||||
String url = "jdbc:sqlite:" + filePath;
|
||||
final JDBC4Connection connection = new JDBC4Connection(url, filePath, new Properties());
|
||||
stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
|
||||
ResultSet.CONCUR_READ_ONLY,
|
||||
ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void invoking_next_before_the_last_row_should_return_true() throws Exception {
|
||||
stmt.execute("CREATE TABLE users (id INT PRIMARY KEY, username TEXT);");
|
||||
stmt.execute("INSERT INTO users VALUES (1, 'sinwoo');");
|
||||
stmt.execute("INSERT INTO users VALUES (2, 'seonwoo');");
|
||||
|
||||
// first call to next occur internally
|
||||
stmt.execute("SELECT * FROM users");
|
||||
ResultSet resultSet = stmt.getResultSet();
|
||||
|
||||
assertTrue(resultSet.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
void invoking_next_after_the_last_row_should_return_false() throws Exception {
|
||||
stmt.execute("CREATE TABLE users (id INT PRIMARY KEY, username TEXT);");
|
||||
stmt.execute("INSERT INTO users VALUES (1, 'sinwoo');");
|
||||
stmt.execute("INSERT INTO users VALUES (2, 'seonwoo');");
|
||||
|
||||
// first call to next occur internally
|
||||
stmt.execute("SELECT * FROM users");
|
||||
ResultSet resultSet = stmt.getResultSet();
|
||||
|
||||
while (resultSet.next()) {
|
||||
// this loop will break when resultSet returns false
|
||||
}
|
||||
|
||||
// if the previous call to next() returned false, consecutive call to next() should return false as well
|
||||
assertFalse(resultSet.next());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user