mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-25 12:04:21 +01:00
Merge 'bindings/java: Implement returning updated counts and version information ' from Kim Seon Woo
### Purpose - Do some minor nits - Implement logic that returns updated count when running executeUpdate - Implement version related functions ### Reference - https://github.com/tursodatabase/limbo/issues/615 Closes #1086
This commit is contained in:
@@ -270,6 +270,23 @@ pub extern "system" fn Java_tech_turso_core_LimboStatement_bindBlob<'local>(
|
||||
SQLITE_OK
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_tech_turso_core_LimboStatement_totalChanges<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
obj: JObject<'local>,
|
||||
stmt_ptr: jlong,
|
||||
) -> jlong {
|
||||
let stmt = match to_limbo_statement(stmt_ptr) {
|
||||
Ok(stmt) => stmt,
|
||||
Err(e) => {
|
||||
set_err_msg_and_throw_exception(&mut env, obj, SQLITE_ERROR, e.to_string());
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
stmt.connection.conn.total_changes()
|
||||
}
|
||||
|
||||
/// Converts an optional `JObject` into Java's `LimboStepResult`.
|
||||
///
|
||||
/// This function takes an optional `JObject` and converts it into a Java object
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import tech.turso.annotations.Nullable;
|
||||
import tech.turso.annotations.SkipNullableCheck;
|
||||
import tech.turso.core.LimboPropertiesHolder;
|
||||
import tech.turso.jdbc4.JDBC4Connection;
|
||||
import tech.turso.utils.Logger;
|
||||
import tech.turso.utils.LoggerFactory;
|
||||
@@ -57,14 +58,12 @@ public final class JDBC implements Driver {
|
||||
|
||||
@Override
|
||||
public int getMajorVersion() {
|
||||
// TODO
|
||||
return 0;
|
||||
return Integer.parseInt(LimboPropertiesHolder.getDriverVersion().split("\\.")[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinorVersion() {
|
||||
// TODO
|
||||
return 0;
|
||||
return Integer.parseInt(LimboPropertiesHolder.getDriverVersion().split("\\.")[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package tech.turso.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import tech.turso.jdbc4.JDBC4DatabaseMetaData;
|
||||
import tech.turso.utils.Logger;
|
||||
import tech.turso.utils.LoggerFactory;
|
||||
|
||||
public class LimboPropertiesHolder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LimboPropertiesHolder.class);
|
||||
|
||||
private static String driverName = "";
|
||||
private static String driverVersion = "";
|
||||
|
||||
static {
|
||||
try (InputStream limboJdbcPropStream =
|
||||
JDBC4DatabaseMetaData.class.getClassLoader().getResourceAsStream("limbo-jdbc.properties")) {
|
||||
if (limboJdbcPropStream == null) {
|
||||
throw new IOException("Cannot load limbo-jdbc.properties from jar");
|
||||
}
|
||||
|
||||
final Properties properties = new Properties();
|
||||
properties.load(limboJdbcPropStream);
|
||||
driverName = properties.getProperty("driverName");
|
||||
driverVersion = properties.getProperty("driverVersion");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load driverName and driverVersion");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDriverName() {
|
||||
return driverName;
|
||||
}
|
||||
|
||||
public static String getDriverVersion() {
|
||||
return driverVersion;
|
||||
}
|
||||
}
|
||||
@@ -214,6 +214,21 @@ public final class LimboStatement {
|
||||
private native int bindBlob(long statementPointer, int position, byte[] value)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns total number of changes.
|
||||
*
|
||||
* @throws SQLException If a database access error occurs
|
||||
*/
|
||||
public long totalChanges() throws SQLException {
|
||||
final long result = totalChanges(statementPointer);
|
||||
if (result == -1) {
|
||||
throw new SQLException("Exception while retrieving total number of changes");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private native long totalChanges(long statementPointer) throws SQLException;
|
||||
/**
|
||||
* Checks if the statement is closed.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package tech.turso.jdbc4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -9,9 +7,9 @@ import java.sql.ResultSet;
|
||||
import java.sql.RowIdLifetime;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Properties;
|
||||
import tech.turso.annotations.Nullable;
|
||||
import tech.turso.annotations.SkipNullableCheck;
|
||||
import tech.turso.core.LimboPropertiesHolder;
|
||||
import tech.turso.utils.Logger;
|
||||
import tech.turso.utils.LoggerFactory;
|
||||
|
||||
@@ -19,9 +17,6 @@ public final class JDBC4DatabaseMetaData implements DatabaseMetaData {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JDBC4DatabaseMetaData.class);
|
||||
|
||||
private static String driverName = "";
|
||||
private static String driverVersion = "";
|
||||
|
||||
private final JDBC4Connection connection;
|
||||
@Nullable private PreparedStatement getTables = null;
|
||||
@Nullable private PreparedStatement getTableTypes = null;
|
||||
@@ -41,22 +36,6 @@ public final class JDBC4DatabaseMetaData implements DatabaseMetaData {
|
||||
@Nullable private PreparedStatement getVersionColumns = null;
|
||||
@Nullable private PreparedStatement getColumnPrivileges = null;
|
||||
|
||||
static {
|
||||
try (InputStream limboJdbcPropStream =
|
||||
JDBC4DatabaseMetaData.class.getClassLoader().getResourceAsStream("limbo-jdbc.properties")) {
|
||||
if (limboJdbcPropStream == null) {
|
||||
throw new IOException("Cannot load limbo-jdbc.properties from jar");
|
||||
}
|
||||
|
||||
final Properties properties = new Properties();
|
||||
properties.load(limboJdbcPropStream);
|
||||
driverName = properties.getProperty("driverName");
|
||||
driverVersion = properties.getProperty("driverVersion");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load driverName and driverVersion");
|
||||
}
|
||||
}
|
||||
|
||||
public JDBC4DatabaseMetaData(JDBC4Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
@@ -120,22 +99,22 @@ public final class JDBC4DatabaseMetaData implements DatabaseMetaData {
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
return driverName;
|
||||
return LimboPropertiesHolder.getDriverName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverVersion() {
|
||||
return driverVersion;
|
||||
return LimboPropertiesHolder.getDriverVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMajorVersion() {
|
||||
return Integer.parseInt(driverVersion.split("\\.")[0]);
|
||||
return Integer.parseInt(getDriverVersion().split("\\.")[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMinorVersion() {
|
||||
return Integer.parseInt(driverVersion.split("\\.")[1]);
|
||||
return Integer.parseInt(getDriverVersion().split("\\.")[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,8 +28,6 @@ public class JDBC4Statement implements Statement {
|
||||
private final int resultSetHoldability;
|
||||
|
||||
private int queryTimeoutSeconds;
|
||||
private long updateCount;
|
||||
private boolean exhaustedResults = false;
|
||||
|
||||
private ReentrantLock connectionLock = new ReentrantLock();
|
||||
|
||||
@@ -74,14 +72,14 @@ public class JDBC4Statement implements Statement {
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
execute(sql);
|
||||
final long previousTotalChanges = statement == null ? 0L : statement.totalChanges();
|
||||
|
||||
execute(sql);
|
||||
requireNonNull(statement, "statement should not be null after running execute method");
|
||||
final LimboResultSet resultSet = statement.getResultSet();
|
||||
resultSet.consumeAll();
|
||||
|
||||
// TODO: return update count;
|
||||
return 0;
|
||||
return (int) (statement.totalChanges() - previousTotalChanges);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,7 +174,6 @@ public class JDBC4Statement implements Statement {
|
||||
statement = connection.prepare(sql);
|
||||
final boolean result = statement.execute();
|
||||
updateGeneratedKeys();
|
||||
exhaustedResults = false;
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package tech.turso;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
@@ -30,4 +32,22 @@ class JDBCTest {
|
||||
assertThat(connection).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void retrieve_version() {
|
||||
assertDoesNotThrow(() -> DriverManager.getDriver("jdbc:sqlite:").getMajorVersion());
|
||||
assertDoesNotThrow(() -> DriverManager.getDriver("jdbc:sqlite:").getMinorVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
void all_driver_property_info_should_have_a_description() throws Exception {
|
||||
Driver driver = DriverManager.getDriver("jdbc:sqlite:");
|
||||
assertThat(driver.getPropertyInfo(null, null))
|
||||
.allSatisfy((info) -> assertThat(info.description).isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void return_null_when_protocol_can_not_be_handled() throws Exception {
|
||||
assertThat(JDBC.createConnection("jdbc:unknownprotocol:", null)).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.turso.jdbc4;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -70,4 +71,30 @@ class JDBC4StatementTest {
|
||||
stmt.close();
|
||||
assertThrows(SQLException.class, () -> stmt.execute("SELECT 1;"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void execute_update_should_return_number_of_inserted_elements() throws Exception {
|
||||
assertThat(stmt.executeUpdate("CREATE TABLE s1 (c1);")).isEqualTo(0);
|
||||
assertThat(stmt.executeUpdate("INSERT INTO s1 VALUES (0);")).isEqualTo(1);
|
||||
assertThat(stmt.executeUpdate("INSERT INTO s1 VALUES (1), (2);")).isEqualTo(2);
|
||||
assertThat(stmt.executeUpdate("INSERT INTO s1 VALUES (3), (4), (5);")).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Limbo update not yet supported")
|
||||
void execute_update_should_return_number_of_updated_elements() throws Exception {
|
||||
assertThat(stmt.executeUpdate("CREATE TABLE s1 (c1);")).isEqualTo(0);
|
||||
assertThat(stmt.executeUpdate("INSERT INTO s1 VALUES (1), (2), (3);")).isEqualTo(3);
|
||||
|
||||
assertThat(stmt.executeUpdate("UPDATE s1 SET c1 = 0;")).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Limbo delete has a bug")
|
||||
void execute_update_should_return_number_of_deleted_elements() throws Exception {
|
||||
assertThat(stmt.executeUpdate("CREATE TABLE s1 (c1);")).isEqualTo(0);
|
||||
assertThat(stmt.executeUpdate("INSERT INTO s1 VALUES (1), (2), (3);")).isEqualTo(3);
|
||||
|
||||
assertThat(stmt.executeUpdate("DELETE FROM s1")).isEqualTo(3);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user