diff --git a/bindings/java/build.gradle.kts b/bindings/java/build.gradle.kts index 2a4b7b8a8..cf8d25c3e 100644 --- a/bindings/java/build.gradle.kts +++ b/bindings/java/build.gradle.kts @@ -20,8 +20,8 @@ repositories { } dependencies { - implementation("ch.qos.logback:logback-classic:1.5.16") - implementation("ch.qos.logback:logback-core:1.5.16") + implementation("ch.qos.logback:logback-classic:1.2.13") + implementation("ch.qos.logback:logback-core:1.2.13") errorprone("com.uber.nullaway:nullaway:0.10.26") // maximum version which supports java 8 errorprone("com.google.errorprone:error_prone_core:2.10.0") // maximum version which supports java 8 diff --git a/bindings/java/rs_src/connection.rs b/bindings/java/rs_src/connection.rs index d4a492d40..df5ab867a 100644 --- a/bindings/java/rs_src/connection.rs +++ b/bindings/java/rs_src/connection.rs @@ -7,13 +7,12 @@ use jni::objects::{JByteArray, JClass, JObject}; use jni::sys::jlong; use jni::JNIEnv; use std::rc::Rc; -use std::sync::Arc; #[allow(dead_code)] #[derive(Clone)] pub struct Connection { pub(crate) conn: Rc, - pub(crate) io: Arc, + pub(crate) io: Rc, } /// Returns a pointer to a `Cursor` object. @@ -31,7 +30,7 @@ pub struct Connection { /// /// A `jlong` representing the pointer to the newly created `Cursor` object. #[no_mangle] -pub extern "system" fn Java_org_github_tursodatabase_limbo_LimboConnection_prepareUtf8<'local>( +pub extern "system" fn Java_org_github_tursodatabase_core_LimboConnection_prepareUtf8<'local>( mut env: JNIEnv<'local>, obj: JObject<'local>, connection_ptr: jlong, @@ -91,11 +90,11 @@ pub unsafe extern "system" fn Java_org_github_tursodatabase_limbo_Connection_clo let _boxed_connection = Box::from_raw(connection_ptr as *mut Connection); } -fn to_connection(connection_ptr: jlong) -> Result<&'static mut Rc> { +fn to_connection(connection_ptr: jlong) -> Result<&'static mut Connection> { if connection_ptr == 0 { Err(LimboError::InvalidConnectionPointer) } else { - unsafe { Ok(&mut *(connection_ptr as *mut Rc)) } + unsafe { Ok(&mut *(connection_ptr as *mut Connection)) } } } diff --git a/bindings/java/rs_src/limbo_db.rs b/bindings/java/rs_src/limbo_db.rs index bd1ad5082..9bcdf0c58 100644 --- a/bindings/java/rs_src/limbo_db.rs +++ b/bindings/java/rs_src/limbo_db.rs @@ -1,13 +1,12 @@ use crate::connection::Connection; -use crate::errors::{LimboError, Result}; +use crate::errors::{LimboError, Result, LIMBO_ETC}; use jni::objects::{JByteArray, JObject}; use jni::sys::{jint, jlong}; use jni::JNIEnv; use limbo_core::Database; +use std::rc::Rc; use std::sync::Arc; -const ERROR_CODE_ETC: i32 = 9999; - #[no_mangle] #[allow(clippy::arc_with_non_send_sync)] pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'local>( @@ -19,7 +18,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'loca let io = match limbo_core::PlatformIO::new() { Ok(io) => Arc::new(io), Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return -1; } }; @@ -31,12 +30,12 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'loca Ok(bytes) => match String::from_utf8(bytes) { Ok(s) => s, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return -1; } }, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return -1; } }; @@ -44,7 +43,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'loca let db = match Database::open_file(io.clone(), &path) { Ok(db) => db, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return -1; } }; @@ -53,7 +52,6 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'loca } #[no_mangle] -#[allow(clippy::arc_with_non_send_sync)] pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'local>( mut env: JNIEnv<'local>, obj: JObject<'local>, @@ -63,7 +61,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca let db = match to_db(db_pointer) { Ok(db) => db, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return 0; } }; @@ -75,28 +73,28 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca Ok(bytes) => match String::from_utf8(bytes) { Ok(s) => s, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return 0; } }, Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return 0; } }; - let io: Arc = match path.as_str() { + let io: Rc = match path.as_str() { ":memory:" => match limbo_core::MemoryIO::new() { - Ok(io) => Arc::new(io), + Ok(io) => Rc::new(io), Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return 0; } }, _ => match limbo_core::PlatformIO::new() { - Ok(io) => Arc::new(io), + Ok(io) => Rc::new(io), Err(e) => { - set_err_msg_and_throw_exception(&mut env, obj, ERROR_CODE_ETC, e.to_string()); + set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string()); return 0; } }, @@ -109,7 +107,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca Box::into_raw(Box::new(conn)) as jlong } -fn to_db(db_pointer: jlong) -> Result<&'static mut Arc> { +pub fn to_db(db_pointer: jlong) -> Result<&'static mut Arc> { if db_pointer == 0 { Err(LimboError::InvalidDatabasePointer) } else { diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java b/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java index ce8bfadd4..7ec33edcc 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java @@ -78,31 +78,6 @@ public abstract class AbstractDB { */ public abstract long connect() throws SQLException; -// /** -// * Compiles an SQL statement. -// * -// * @param stmt The SQL statement to compile. -// * @throws SQLException if a database access error occurs. -// */ -// public final void prepare(CoreStatement stmt) throws SQLException { -// if (stmt.sql == null) { -// throw new SQLException("Statement must not be null"); -// } -// -// // TODO: check whether closing the pointer and replacing stamt.pointer should work atomically using locks etc -// final SafeStatementPointer pointer = stmt.getStmtPointer(); -// if (pointer != null) { -// pointer.close(); -// } -// -// final SafeStatementPointer newPointer = stmt.connection.prepare(stmt.sql); -// stmt.setStmtPointer(newPointer); -// final boolean added = statementPointerSet.add(newPointer); -// if (!added) { -// throw new IllegalStateException("The pointer is already added to statements set"); -// } -// } - /** * Destroys a statement. * diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java index c3eacdb21..8bf5bfcb2 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java @@ -93,7 +93,7 @@ public final class LimboDB extends AbstractDB { byte[] filePathBytes = stringToUtf8ByteArray(filePath); if (filePathBytes == null) { - throw LimboExceptionUtils.buildLimboException(LimboErrorCode.LIMBO_ETC.code, "File name cannot be converted to byteArray. File name: " + filePath); + throw LimboExceptionUtils.buildLimboException(LimboErrorCode.LIMBO_ETC.code, "File path cannot be converted to byteArray. File name: " + filePath); } dbPointer = openUtf8(filePathBytes, openFlags); @@ -102,7 +102,11 @@ public final class LimboDB extends AbstractDB { @Override public long connect() throws SQLException { - return connect0(ByteArrayUtils.stringToUtf8ByteArray(filePath), dbPointer); + byte[] filePathBytes = stringToUtf8ByteArray(filePath); + if (filePathBytes == null) { + throw LimboExceptionUtils.buildLimboException(LimboErrorCode.LIMBO_ETC.code, "File path cannot be converted to byteArray. File name: " + filePath); + } + return connect0(filePathBytes, dbPointer); } private native long connect0(byte[] path, long databasePtr) throws SQLException; diff --git a/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java b/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java index 6c39f1c3d..b52164e7c 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java @@ -1,6 +1,7 @@ package org.github.tursodatabase.jdbc4; import org.github.tursodatabase.TestUtils; +import org.github.tursodatabase.core.LimboConnection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -55,4 +56,12 @@ class JDBC4ConnectionTest { connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, -1); }); } + + @Test + void prepare_simple_create_table() throws Exception { + String filePath = TestUtils.createTempFile(); + String url = "jdbc:sqlite:" + filePath; + LimboConnection connection = new JDBC4Connection(url, filePath); + connection.prepare("CREATE TABLE users (id INT PRIMARY KEY, username TEXT)"); + } }