From dcee278e280194b5bd2218ab585f26e1a40bd966 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Thu, 24 Nov 2022 21:45:58 +0800 Subject: [PATCH] add method import_from_backup --- Cargo.lock | 2 +- cozo-lib-c/cozo_c.h | 10 ++++++ cozo-lib-c/src/lib.rs | 35 +++++++++++++++++++++ cozo-lib-java/CozoJavaBridge.java | 1 + cozo-lib-java/org_cozodb_CozoJavaBridge.h | 8 +++++ cozo-lib-java/src/lib.rs | 17 ++++++++++ cozo-lib-nodejs/src/lib.rs | 38 +++++++++++++++++++++++ cozo-lib-python/Cargo.toml | 2 +- cozo-lib-python/src/lib.rs | 7 +++++ cozo-lib-swift/src/lib.rs | 1 + 10 files changed, 119 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0616c3f3..c06f6a15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -587,7 +587,7 @@ dependencies = [ ] [[package]] -name = "cozo_py_module" +name = "cozo_py" version = "0.2.0" dependencies = [ "cozo", diff --git a/cozo-lib-c/cozo_c.h b/cozo-lib-c/cozo_c.h index c6b563f5..85cf336e 100644 --- a/cozo-lib-c/cozo_c.h +++ b/cozo-lib-c/cozo_c.h @@ -97,6 +97,16 @@ char *cozo_backup(int32_t db_id, char *cozo_restore(int32_t db_id, const char *in_path); +/** + * Import data into a relation + * `db_id`: the ID representing the database. + * `json_payload`: a UTF-8 encoded JSON payload, see the manual for the expected fields. + * + * Returns a UTF-8-encoded C-string indicating the result that **must** be freed with `cozo_free_str`. + */ +char *import_from_backup(int32_t db_id, + const char *json_payload); + /** * Free any C-string returned from the Cozo C API. * Must be called exactly once for each returned C-string. diff --git a/cozo-lib-c/src/lib.rs b/cozo-lib-c/src/lib.rs index e1f01208..af30dd0b 100644 --- a/cozo-lib-c/src/lib.rs +++ b/cozo-lib-c/src/lib.rs @@ -264,6 +264,41 @@ pub unsafe extern "C" fn cozo_restore(db_id: i32, in_path: *const c_char) -> *mu .into_raw() } +#[no_mangle] +/// Import data into a relation +/// `db_id`: the ID representing the database. +/// `json_payload`: a UTF-8 encoded JSON payload, see the manual for the expected fields. +/// +/// Returns a UTF-8-encoded C-string indicating the result that **must** be freed with `cozo_free_str`. +pub unsafe extern "C" fn import_from_backup( + db_id: i32, + json_payload: *const c_char, +) -> *mut c_char { + let db = { + let db_ref = { + let dbs = HANDLES.dbs.lock().unwrap(); + dbs.get(&db_id).cloned() + }; + match db_ref { + None => { + return CString::new(r##"{"ok":false,"message":"database closed"}"##) + .unwrap() + .into_raw(); + } + Some(db) => db, + } + }; + + let data = match CStr::from_ptr(json_payload).to_str() { + Ok(p) => p, + Err(err) => return CString::new(format!("{}", err)).unwrap().into_raw(), + }; + + CString::new(db.import_from_backup_str(data)) + .unwrap() + .into_raw() +} + /// Free any C-string returned from the Cozo C API. /// Must be called exactly once for each returned C-string. /// diff --git a/cozo-lib-java/CozoJavaBridge.java b/cozo-lib-java/CozoJavaBridge.java index 0d6b5f56..fb3b37eb 100644 --- a/cozo-lib-java/CozoJavaBridge.java +++ b/cozo-lib-java/CozoJavaBridge.java @@ -8,6 +8,7 @@ public class CozoJavaBridge { 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); + private static native String importFromBackup(int id, String data); static { System.loadLibrary("cozo_java"); diff --git a/cozo-lib-java/org_cozodb_CozoJavaBridge.h b/cozo-lib-java/org_cozodb_CozoJavaBridge.h index 420f4a44..018f6bb4 100644 --- a/cozo-lib-java/org_cozodb_CozoJavaBridge.h +++ b/cozo-lib-java/org_cozodb_CozoJavaBridge.h @@ -63,6 +63,14 @@ JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_backup JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_restore (JNIEnv *, jclass, jint, jstring); +/* + * Class: org_cozodb_CozoJavaBridge + * Method: importFromBackup + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cozodb_CozoJavaBridge_importFromBackup + (JNIEnv *, jclass, jint, jstring); + #ifdef __cplusplus } #endif diff --git a/cozo-lib-java/src/lib.rs b/cozo-lib-java/src/lib.rs index 07802e17..5feb4396 100644 --- a/cozo-lib-java/src/lib.rs +++ b/cozo-lib-java/src/lib.rs @@ -159,3 +159,20 @@ pub extern "system" fn Java_org_cozodb_CozoJavaBridge_restore( } } } + +#[no_mangle] +pub extern "system" fn Java_org_cozodb_CozoJavaBridge_importFromBackup( + 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_from_backup_str(&data); + env.new_string(res).unwrap().into_raw() + } + } +} \ No newline at end of file diff --git a/cozo-lib-nodejs/src/lib.rs b/cozo-lib-nodejs/src/lib.rs index 8b23a07c..da7ce44c 100644 --- a/cozo-lib-nodejs/src/lib.rs +++ b/cozo-lib-nodejs/src/lib.rs @@ -236,6 +236,43 @@ fn import_relations(mut cx: FunctionContext) -> JsResult { Ok(cx.undefined()) } +fn import_from_backup(mut cx: FunctionContext) -> JsResult { + let id = cx.argument::(0)?.value(&mut cx) as u32; + let db = { + let db_ref = { + let dbs = HANDLES.dbs.lock().unwrap(); + dbs.get(&id).cloned() + }; + match db_ref { + None => { + let s = cx.string("database already closed"); + cx.throw(s)? + } + Some(db) => db, + } + }; + + let data = cx.argument::(1)?.value(&mut cx); + + let callback = cx.argument::(2)?.root(&mut cx); + + let channel = cx.channel(); + + std::thread::spawn(move || { + let result = db.import_from_backup_str(&data); + channel.send(move |mut cx| { + let callback = callback.into_inner(&mut cx); + let this = cx.undefined(); + let json_str = cx.string(result); + callback.call(&mut cx, this, vec![json_str.upcast()])?; + + Ok(()) + }); + }); + + Ok(cx.undefined()) +} + #[neon::main] fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("open_db", open_db)?; @@ -245,5 +282,6 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("restore_db", restore_db)?; cx.export_function("export_relations", export_relations)?; cx.export_function("import_relations", import_relations)?; + cx.export_function("import_from_backup", import_from_backup)?; Ok(()) } diff --git a/cozo-lib-python/Cargo.toml b/cozo-lib-python/Cargo.toml index 5ee824b5..549f3dac 100644 --- a/cozo-lib-python/Cargo.toml +++ b/cozo-lib-python/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cozo_py_module" +name = "cozo_py" version = "0.2.0" edition = "2021" description = "Cozo database for python" diff --git a/cozo-lib-python/src/lib.rs b/cozo-lib-python/src/lib.rs index 15789cea..385c82a0 100644 --- a/cozo-lib-python/src/lib.rs +++ b/cozo-lib-python/src/lib.rs @@ -62,6 +62,13 @@ impl CozoDbPy { DB_CLOSED_MSG.to_string() } } + pub fn import_from_backup(&self, py: Python<'_>, data: &str) -> String { + if let Some(db) = &self.db { + py.allow_threads(|| db.import_from_backup_str(data)) + } else { + DB_CLOSED_MSG.to_string() + } + } pub fn close(&mut self) -> bool { self.db.take().is_some() } diff --git a/cozo-lib-swift/src/lib.rs b/cozo-lib-swift/src/lib.rs index 2ae1dfe9..9ea3859d 100644 --- a/cozo-lib-swift/src/lib.rs +++ b/cozo-lib-swift/src/lib.rs @@ -21,6 +21,7 @@ mod ffi { fn import_relations_str(&self, data: &str) -> String; fn backup_db_str(&self, out_file: &str) -> String; fn restore_backup_str(&self, in_file: &str) -> String; + fn import_from_backup_str(&self, data: &str) -> String; } }