diff --git a/Cargo.lock b/Cargo.lock index 8a3dcb2f..31a2f82f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "addr2line" version = "0.17.0" @@ -396,7 +386,7 @@ dependencies = [ "clap_lex", "indexmap", "once_cell", - "strsim 0.10.0", + "strsim", "termcolor", "textwrap 0.16.0", ] @@ -561,8 +551,8 @@ name = "cozo_java" version = "0.1.3" dependencies = [ "cozo", + "jni", "lazy_static", - "robusta_jni", ] [[package]] @@ -726,41 +716,6 @@ dependencies = [ "syn", ] -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "deflate" version = "1.0.0" @@ -829,16 +784,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "backtrace", - "version_check", -] - [[package]] name = "fail" version = "0.4.0" @@ -1310,12 +1255,6 @@ dependencies = [ "cxx-build", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.3.0" @@ -1389,15 +1328,15 @@ checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jni" -version = "0.17.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36bcc950632e48b86da402c5c077590583da5ac0d480103611d5374e7c967a3c" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" dependencies = [ "cesu8", "combine", - "error-chain", "jni-sys", "log", + "thiserror", "walkdir", ] @@ -2479,33 +2418,6 @@ dependencies = [ "rmp", ] -[[package]] -name = "robusta-codegen" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66a33c846c7b892c2fd20ff58ba34859e6d83e491d51ce94f678cc7157ad774" -dependencies = [ - "Inflector", - "darling", - "proc-macro-error", - "proc-macro2", - "quote", - "rand 0.7.3", - "syn", -] - -[[package]] -name = "robusta_jni" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61f3ca304f439f93ae5f59f2fe65f4c2693b253c7656dc242c061996a4b01f8" -dependencies = [ - "jni", - "paste", - "robusta-codegen", - "static_assertions", -] - [[package]] name = "rouille" version = "3.6.1" @@ -2838,12 +2750,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" diff --git a/cozo-lib-java/.gitignore b/cozo-lib-java/.gitignore new file mode 100644 index 00000000..5241a722 --- /dev/null +++ b/cozo-lib-java/.gitignore @@ -0,0 +1 @@ +*.class \ No newline at end of file diff --git a/cozo-lib-java/Cargo.toml b/cozo-lib-java/Cargo.toml index 62328778..7ec5c17b 100644 --- a/cozo-lib-java/Cargo.toml +++ b/cozo-lib-java/Cargo.toml @@ -19,7 +19,7 @@ io-uring = ["cozo/io-uring"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -robusta_jni = "0.2.0" +jni = "0.20.0" # , features = ["compact"] -cozo = { version = "0.1.3", path = "../cozo-core", default_features = false } +cozo = { version = "0.1.3", path = "../cozo-core", default_features = false, features = ["compact"] } lazy_static = "1.4.0" diff --git a/cozo-lib-java/CozoJavaBridge.java b/cozo-lib-java/CozoJavaBridge.java new file mode 100644 index 00000000..0d6b5f56 --- /dev/null +++ b/cozo-lib-java/CozoJavaBridge.java @@ -0,0 +1,19 @@ +package org.cozodb; + +public class CozoJavaBridge { + private static native int openDb(String kind, String path); + private static native boolean closeDb(int id); + private static native String runQuery(int id, String script, String params); + private static native String exportRelations(int id, String rel); + private static native String importRelations(int id, String data); + private static native String backup(int id, String file); + private static native String restore(int id, String file); + + static { + System.loadLibrary("cozo_java"); + } + + public static void main(String[] args) { + System.out.println("OK"); + } +} \ No newline at end of file diff --git a/cozo-lib-java/build.sh b/cozo-lib-java/build.sh index c90852d9..57ee9031 100755 --- a/cozo-lib-java/build.sh +++ b/cozo-lib-java/build.sh @@ -1,10 +1,6 @@ #!/usr/bin/env bash -export ANDROID_HOME=/Users/$USER/Library/Android/sdk -export NDK_HOME=/Users/$USER/Library/Android/sdk/ndk/23.1.7779620/ -export PATH=$PATH:$HOME/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/ -export CC=aarch64-linux-android23-clang -export CXX=aarch64-linux-android23-clang++ -export LD=$HOME/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/ld -export LD_LIBRARY_PATH=/Users/zh217/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/26 -cargo build --release -p cozo_c --target=aarch64-linux-android \ No newline at end of file +cross build -p cozo_java --release --target=aarch64-linux-android +cross build -p cozo_java --release --target=armv7-linux-androideabi +cross build -p cozo_java --release --target=i686-linux-android +cross build -p cozo_java --release --target=x86_64-linux-android \ No newline at end of file diff --git a/cozo-lib-java/org_cozodb_CozoJavaBridge.h b/cozo-lib-java/org_cozodb_CozoJavaBridge.h new file mode 100644 index 00000000..420f4a44 --- /dev/null +++ b/cozo-lib-java/org_cozodb_CozoJavaBridge.h @@ -0,0 +1,69 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_cozodb_CozoJavaBridge */ + +#ifndef _Included_org_cozodb_CozoJavaBridge +#define _Included_org_cozodb_CozoJavaBridge +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_cozodb_CozoJavaBridge + * Method: openDb + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_cozodb_CozoJavaBridge_openDb + (JNIEnv *, jclass, jstring, jstring); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: closeDb + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_cozodb_CozoJavaBridge_closeDb + (JNIEnv *, jclass, jint); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: runQuery + * Signature: (ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_runQuery + (JNIEnv *, jclass, jint, jstring, jstring); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: exportRelations + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_exportRelations + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: importRelations + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_importRelations + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: backup + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_backup + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: org_cozodb_CozoJavaBridge + * Method: restore + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_restore + (JNIEnv *, jclass, jint, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/cozo-lib-java/src/lib.rs b/cozo-lib-java/src/lib.rs index 31ce0768..7e7cc3a8 100644 --- a/cozo-lib-java/src/lib.rs +++ b/cozo-lib-java/src/lib.rs @@ -6,13 +6,13 @@ * You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::BTreeMap; -use std::sync::atomic::AtomicI32; +use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::Mutex; +use jni::objects::{JClass, JString}; +use jni::sys::{jboolean, jint, jstring}; +use jni::JNIEnv; use lazy_static::lazy_static; -use robusta_jni::bridge; -use robusta_jni::jni::errors::Error as JniError; -use robusta_jni::jni::errors::Result as JniResult; use cozo::*; @@ -29,76 +29,133 @@ lazy_static! { }; } -fn get_db(id: i32) -> JniResult { - let db_ref = { - let dbs = HANDLES.dbs.lock().unwrap(); - dbs.get(&id).cloned() - }; - db_ref.ok_or_else(|| JniError::from("database already closed")) +fn get_db(id: i32) -> Option { + let dbs = HANDLES.dbs.lock().unwrap(); + dbs.get(&id).cloned() } -#[bridge] -mod jni { - use std::sync::atomic::Ordering; - - use robusta_jni::convert::{IntoJavaValue, Signature, TryFromJavaValue, TryIntoJavaValue}; - use robusta_jni::jni::errors::Error as JniError; - use robusta_jni::jni::errors::Result as JniResult; - use robusta_jni::jni::objects::AutoLocal; +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_openDb( + env: JNIEnv, + _class: JClass, + kind: JString, + path: JString, +) -> jint { + let kind: String = env.get_string(kind).unwrap().into(); + let path: String = env.get_string(path).unwrap().into(); + let id = match DbInstance::new(&kind, &path, Default::default()) { + Ok(db) => { + let id = HANDLES.current.fetch_add(1, Ordering::AcqRel); + let mut dbs = HANDLES.dbs.lock().unwrap(); + dbs.insert(id, db); + id + } + Err(err) => { + eprintln!("{:?}", err); + -1 + } + }; + id +} - use cozo::*; +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_closeDb( + _env: JNIEnv, + _class: JClass, + id: jint, +) -> jboolean { + let db = { + let mut dbs = HANDLES.dbs.lock().unwrap(); + dbs.remove(&id) + }; + db.is_some().into() +} - use crate::{get_db, HANDLES}; +const DB_NOT_FOUND: &str = r#"{"ok":false,"message":"database not found"}"#; - #[derive(Signature, TryIntoJavaValue, IntoJavaValue, TryFromJavaValue)] - #[package(org.cozodb)] - pub struct CozoDb<'env: 'borrow, 'borrow> { - #[instance] - raw: AutoLocal<'env, 'borrow>, +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_runQuery( + env: JNIEnv, + _class: JClass, + id: jint, + script: JString, + params_str: JString, +) -> jstring { + let script: String = env.get_string(script).unwrap().into(); + let params_str: String = env.get_string(params_str).unwrap().into(); + match get_db(id) { + None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), + Some(db) => { + let res = db.run_script_str(&script, ¶ms_str); + env.new_string(res).unwrap().into_raw() + } } +} - impl<'env: 'borrow, 'borrow> CozoDb<'env, 'borrow> { - pub extern "jni" fn openDb(kind: String, path: String) -> JniResult { - match DbInstance::new(&kind, &path, Default::default()) { - Ok(db) => { - let id = HANDLES.current.fetch_add(1, Ordering::AcqRel); - let mut dbs = HANDLES.dbs.lock().unwrap(); - dbs.insert(id, db); - Ok(id) - } - Err(err) => Err(JniError::from(format!("{:?}", err))), - } - } - pub extern "jni" fn closeDb(id: i32) -> JniResult { - let db = { - let mut dbs = HANDLES.dbs.lock().unwrap(); - dbs.remove(&id) - }; - Ok(db.is_some()) +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_exportRelations( + env: JNIEnv, + _class: JClass, + id: jint, + rel: JString, +) -> jstring { + let rel: String = env.get_string(rel).unwrap().into(); + match get_db(id) { + None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), + Some(db) => { + let res = db.export_relations_str(&rel); + env.new_string(res).unwrap().into_raw() } - pub extern "jni" fn runQuery( - id: i32, - script: String, - params_str: String, - ) -> JniResult { - let db = get_db(id)?; - Ok(db.run_script_str(&script, ¶ms_str)) - } - pub extern "jni" fn exportRelations(id: i32, relations_str: String) -> JniResult { - let db = get_db(id)?; - Ok(db.export_relations_str(&relations_str)) - } - pub extern "jni" fn importRelation(id: i32, data: String) -> JniResult { - let db = get_db(id)?; - Ok(db.import_relation_str(&data)) + } +} + +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_importRelations( + env: JNIEnv, + _class: JClass, + id: jint, + data: JString, +) -> jstring { + let data: String = env.get_string(data).unwrap().into(); + match get_db(id) { + None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), + Some(db) => { + let res = db.import_relation_str(&data); + env.new_string(res).unwrap().into_raw() } - pub extern "jni" fn backup(id: i32, out_file: String) -> JniResult { - let db = get_db(id)?; - Ok(db.backup_db_str(&out_file)) + } +} + +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_backup( + env: JNIEnv, + _class: JClass, + id: jint, + file: JString, +) -> jstring { + let file: String = env.get_string(file).unwrap().into(); + match get_db(id) { + None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), + Some(db) => { + let res = db.backup_db_str(&file); + env.new_string(res).unwrap().into_raw() } - pub extern "jni" fn restore(id: i32, in_file: String) -> JniResult { - let db = get_db(id)?; - Ok(db.restore_backup_str(&in_file)) + } +} + +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_restore( + env: JNIEnv, + _class: JClass, + id: jint, + file: JString, +) -> jstring { + let file: String = env.get_string(file).unwrap().into(); + match get_db(id) { + None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), + Some(db) => { + let res = db.restore_backup_str(&file); + env.new_string(res).unwrap().into_raw() } } }