java module
parent
659ee3bb2f
commit
b49c5a1cab
@ -0,0 +1,25 @@
|
|||||||
|
### Java template
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "cozo_java"
|
||||||
|
version = "0.1.1"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
robusta_jni = "0.2.0"
|
||||||
|
cozo = { version = "0.1.1", path = ".." }
|
||||||
|
miette = { version = "=5.3.0", features = ["fancy"] }
|
||||||
|
serde_json = "1.0.81"
|
||||||
|
lazy_static = "1.4.0"
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.cozodb;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class CozoDb {
|
||||||
|
private static native int openDb(String path);
|
||||||
|
private static native boolean closeDb(int id);
|
||||||
|
private static native String runQuery(int id, String script, String params);
|
||||||
|
|
||||||
|
private int dbId;
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("cozo_java");
|
||||||
|
}
|
||||||
|
|
||||||
|
CozoDb(String path) {
|
||||||
|
this.dbId = CozoDb.openDb(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
String query(String script, String params) {
|
||||||
|
return CozoDb.runQuery(this.dbId, script, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean close() {
|
||||||
|
return CozoDb.closeDb(this.dbId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
CozoDb db = new CozoDb("_test_db");
|
||||||
|
System.out.println(db);
|
||||||
|
System.out.println(db.query("?[] <- [[1, 2, 3]]", "{}"));
|
||||||
|
try {
|
||||||
|
System.out.println(db.query("?[z] <- [[1, 2, 3]]", "{}"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = e.getMessage().substring("JNI call error!. Cause: ".length());
|
||||||
|
System.out.println(msg);
|
||||||
|
}
|
||||||
|
System.out.println(db.close());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022, The Cozo Project Authors. Licensed under MIT/Apache-2.0/BSD-3-Clause.
|
||||||
|
*/
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::atomic::AtomicI32;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use robusta_jni::bridge;
|
||||||
|
|
||||||
|
use cozo::Db;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Handles {
|
||||||
|
current: AtomicI32,
|
||||||
|
dbs: Mutex<BTreeMap<i32, Db>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref HANDLES: Handles = Handles::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bridge]
|
||||||
|
mod jni {
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
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;
|
||||||
|
|
||||||
|
use cozo::Db;
|
||||||
|
|
||||||
|
use crate::HANDLES;
|
||||||
|
|
||||||
|
#[derive(Signature, TryIntoJavaValue, IntoJavaValue, TryFromJavaValue)]
|
||||||
|
#[package(org.cozodb)]
|
||||||
|
pub struct CozoDb<'env: 'borrow, 'borrow> {
|
||||||
|
#[instance]
|
||||||
|
raw: AutoLocal<'env, 'borrow>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'env: 'borrow, 'borrow> CozoDb<'env, 'borrow> {
|
||||||
|
pub extern "jni" fn openDb(path: String) -> JniResult<i32> {
|
||||||
|
match Db::new(path) {
|
||||||
|
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<bool> {
|
||||||
|
let db = {
|
||||||
|
let mut dbs = HANDLES.dbs.lock().unwrap();
|
||||||
|
dbs.remove(&id)
|
||||||
|
};
|
||||||
|
Ok(db.is_some())
|
||||||
|
}
|
||||||
|
pub extern "jni" fn runQuery(
|
||||||
|
id: i32,
|
||||||
|
script: String,
|
||||||
|
params_str: String,
|
||||||
|
) -> JniResult<String> {
|
||||||
|
let db = {
|
||||||
|
let db_ref = {
|
||||||
|
let dbs = HANDLES.dbs.lock().unwrap();
|
||||||
|
dbs.get(&id).cloned()
|
||||||
|
};
|
||||||
|
let db = db_ref.ok_or_else(|| JniError::from("database already closed"))?;
|
||||||
|
db
|
||||||
|
};
|
||||||
|
let params_map: serde_json::Value = serde_json::from_str(¶ms_str)
|
||||||
|
.map_err(|_| JniError::from("the given params argument is not valid JSON"))?;
|
||||||
|
|
||||||
|
let params_arg: BTreeMap<_, _> = match params_map {
|
||||||
|
serde_json::Value::Object(m) => m.into_iter().collect(),
|
||||||
|
_ => {
|
||||||
|
return Err(JniError::from(
|
||||||
|
"the given params argument is not a JSON map",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let result = db.run_script(&script, ¶ms_arg);
|
||||||
|
match result {
|
||||||
|
Ok(json) => Ok(json.to_string()),
|
||||||
|
Err(err) => Err(JniError::from(format!("{:?}", err))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue