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