Group "pointer to struct" and "struct to pointer" functions

This commit is contained in:
김선우
2025-01-17 23:56:45 +09:00
parent 9765eaba52
commit f6ec2252cf
5 changed files with 121 additions and 56 deletions

View File

@@ -1,4 +1,5 @@
mod connection;
mod errors;
mod limbo_connection;
mod limbo_db;
mod limbo_statement;
mod utils;

View File

@@ -2,6 +2,7 @@ use crate::errors::{
LimboError, Result, LIMBO_ETC, LIMBO_FAILED_TO_PARSE_BYTE_ARRAY,
LIMBO_FAILED_TO_PREPARE_STATEMENT,
};
use crate::limbo_statement::CoreStatement;
use crate::utils::utf8_byte_arr_to_str;
use jni::objects::{JByteArray, JClass, JObject};
use jni::sys::jlong;
@@ -10,11 +11,30 @@ use std::rc::Rc;
#[allow(dead_code)]
#[derive(Clone)]
pub struct Connection {
pub struct LimboConnection {
pub(crate) conn: Rc<limbo_core::Connection>,
pub(crate) io: Rc<dyn limbo_core::IO>,
}
impl LimboConnection {
pub fn to_ptr(self) -> jlong {
Box::into_raw(Box::new(self)) as jlong
}
#[allow(dead_code)]
pub fn drop(ptr: jlong) {
let _boxed = unsafe { Box::from_raw(ptr as *mut LimboConnection) };
}
}
pub fn to_limbo_connection(ptr: jlong) -> Result<&'static mut LimboConnection> {
if ptr == 0 {
Err(LimboError::InvalidConnectionPointer)
} else {
unsafe { Ok(&mut *(ptr as *mut LimboConnection)) }
}
}
/// Returns a pointer to a `Cursor` object.
///
/// The Java application will pass this pointer to native functions,
@@ -36,7 +56,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboConnection_prepar
connection_ptr: jlong,
sql_bytes: JByteArray<'local>,
) -> jlong {
let connection = match to_connection(connection_ptr) {
let connection = match to_limbo_connection(connection_ptr) {
Ok(conn) => conn,
Err(e) => {
set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string());
@@ -58,7 +78,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboConnection_prepar
};
match connection.conn.prepare(sql) {
Ok(stmt) => Box::into_raw(Box::new(stmt)) as jlong,
Ok(stmt) => CoreStatement::new(stmt).to_ptr(),
Err(e) => {
set_err_msg_and_throw_exception(
&mut env,
@@ -87,15 +107,7 @@ pub unsafe extern "system" fn Java_org_github_tursodatabase_limbo_Connection_clo
_class: JClass<'local>,
connection_ptr: jlong,
) {
let _boxed_connection = Box::from_raw(connection_ptr as *mut Connection);
}
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 Connection)) }
}
LimboConnection::drop(connection_ptr);
}
fn set_err_msg_and_throw_exception<'local>(

View File

@@ -1,5 +1,5 @@
use crate::connection::Connection;
use crate::errors::{LimboError, Result, LIMBO_ETC};
use crate::limbo_connection::LimboConnection;
use jni::objects::{JByteArray, JObject};
use jni::sys::{jint, jlong};
use jni::JNIEnv;
@@ -7,6 +7,33 @@ use limbo_core::Database;
use std::rc::Rc;
use std::sync::Arc;
struct LimboDB {
db: Arc<Database>,
}
impl LimboDB {
pub fn new(db: Arc<Database>) -> Self {
LimboDB { db }
}
pub fn to_ptr(self) -> jlong {
Box::into_raw(Box::new(self)) as jlong
}
#[allow(dead_code)]
pub fn drop(ptr: jlong) {
let _boxed = unsafe { Box::from_raw(ptr as *mut LimboDB) };
}
}
fn to_limbo_db(ptr: jlong) -> Result<&'static mut LimboDB> {
if ptr == 0 {
Err(LimboError::InvalidDatabasePointer)
} else {
unsafe { Ok(&mut *(ptr as *mut LimboDB)) }
}
}
#[no_mangle]
#[allow(clippy::arc_with_non_send_sync)]
pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'local>(
@@ -48,7 +75,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_openUtf8<'loca
}
};
Box::into_raw(Box::new(db)) as jlong
LimboDB::new(db).to_ptr()
}
#[no_mangle]
@@ -58,7 +85,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca
file_path_byte_arr: JByteArray<'local>,
db_pointer: jlong,
) -> jlong {
let db = match to_db(db_pointer) {
let db = match to_limbo_db(db_pointer) {
Ok(db) => db,
Err(e) => {
set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string());
@@ -99,20 +126,12 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca
}
},
};
let conn = Connection {
conn: db.connect(),
let conn = LimboConnection {
conn: db.db.connect(),
io,
};
Box::into_raw(Box::new(conn)) as jlong
}
pub fn to_db(db_pointer: jlong) -> Result<&'static mut Arc<Database>> {
if db_pointer == 0 {
Err(LimboError::InvalidDatabasePointer)
} else {
unsafe { Ok(&mut *(db_pointer as *mut Arc<Database>)) }
}
conn.to_ptr()
}
#[no_mangle]

View File

@@ -0,0 +1,61 @@
use crate::errors::LimboError;
use crate::errors::Result;
use jni::objects::{JObject, JValue};
use jni::sys::jlong;
use jni::JNIEnv;
use limbo_core::Statement;
pub struct CoreStatement {
pub(crate) stmt: Statement,
}
impl CoreStatement {
pub fn to_ptr(self) -> jlong {
Box::into_raw(Box::new(self)) as jlong
}
pub fn new(stmt: Statement) -> Self {
CoreStatement { stmt }
}
#[allow(dead_code)]
pub fn drop(ptr: jlong) {
let _boxed = unsafe { Box::from_raw(ptr as *mut CoreStatement) };
}
}
pub fn to_statement(ptr: jlong) -> Result<&'static mut CoreStatement> {
if ptr == 0 {
Err(LimboError::InvalidConnectionPointer)
} else {
unsafe { Ok(&mut *(ptr as *mut CoreStatement)) }
}
}
#[allow(dead_code)]
fn row_to_obj_array<'local>(
env: &mut JNIEnv<'local>,
row: &limbo_core::Row,
) -> Result<JObject<'local>> {
let obj_array =
env.new_object_array(row.values.len() as i32, "java/lang/Object", JObject::null())?;
for (i, value) in row.values.iter().enumerate() {
let obj = match value {
limbo_core::Value::Null => JObject::null(),
limbo_core::Value::Integer(i) => {
env.new_object("java/lang/Long", "(J)V", &[JValue::Long(*i)])?
}
limbo_core::Value::Float(f) => {
env.new_object("java/lang/Double", "(D)V", &[JValue::Double(*f)])?
}
limbo_core::Value::Text(s) => env.new_string(s)?.into(),
limbo_core::Value::Blob(b) => env.byte_array_from_slice(b)?.into(),
};
if let Err(e) = env.set_object_array_element(&obj_array, i as i32, obj) {
eprintln!("Error on parsing row: {:?}", e);
}
}
Ok(obj_array.into())
}

View File

@@ -1,35 +1,7 @@
use crate::errors::LimboError;
use jni::objects::{JByteArray, JObject, JValue};
use jni::objects::JByteArray;
use jni::JNIEnv;
#[allow(dead_code)]
pub(crate) fn row_to_obj_array<'local>(
env: &mut JNIEnv<'local>,
row: &limbo_core::Row,
) -> Result<JObject<'local>, LimboError> {
let obj_array =
env.new_object_array(row.values.len() as i32, "java/lang/Object", JObject::null())?;
for (i, value) in row.values.iter().enumerate() {
let obj = match value {
limbo_core::Value::Null => JObject::null(),
limbo_core::Value::Integer(i) => {
env.new_object("java/lang/Long", "(J)V", &[JValue::Long(*i)])?
}
limbo_core::Value::Float(f) => {
env.new_object("java/lang/Double", "(D)V", &[JValue::Double(*f)])?
}
limbo_core::Value::Text(s) => env.new_string(s)?.into(),
limbo_core::Value::Blob(b) => env.byte_array_from_slice(b)?.into(),
};
if let Err(e) = env.set_object_array_element(&obj_array, i as i32, obj) {
eprintln!("Error on parsing row: {:?}", e);
}
}
Ok(obj_array.into())
}
pub(crate) fn utf8_byte_arr_to_str(
env: &JNIEnv,
bytes: JByteArray,