improve import_relations API

main
Ziyang Hu 2 years ago
parent d12b34e745
commit 458e6c4106

@ -220,8 +220,8 @@ impl DbInstance {
} }
} }
/// Export relations to JSON-encoded string /// Export relations to JSON-encoded string
pub fn export_relations_str(&self, relations_str: &str) -> String { pub fn export_relations_str(&self, data: &str) -> String {
match self.export_relations_str_inner(relations_str) { match self.export_relations_str_inner(data) {
Ok(s) => { Ok(s) => {
let ret = json!({"ok": true, "data": s}); let ret = json!({"ok": true, "data": s});
format!("{}", ret) format!("{}", ret)
@ -232,8 +232,8 @@ impl DbInstance {
} }
} }
} }
fn export_relations_str_inner(&self, relations_str: &str) -> Result<JsonValue> { fn export_relations_str_inner(&self, data: &str) -> Result<JsonValue> {
let j_val: JsonValue = serde_json::from_str(relations_str).into_diagnostic()?; let j_val: JsonValue = serde_json::from_str(data).into_diagnostic()?;
let relations = j_val let relations = j_val
.get("relations") .get("relations")
.ok_or_else(|| miette!("field 'relations' expected"))?; .ok_or_else(|| miette!("field 'relations' expected"))?;

@ -61,8 +61,8 @@ char *cozo_run_query(int32_t db_id, const char *script_raw, const char *params_r
* *
* Returns a UTF-8-encoded C-string indicating the result that **must** be freed with `cozo_free_str`. * Returns a UTF-8-encoded C-string indicating the result that **must** be freed with `cozo_free_str`.
*/ */
char *cozo_import_relation(int32_t db_id, char *cozo_import_relations(int32_t db_id,
const char *json_payload); const char *json_payload);
/** /**
* Export relations into JSON * Export relations into JSON

@ -143,7 +143,7 @@ pub unsafe extern "C" fn cozo_run_query(
/// `json_payload`: a UTF-8 encoded JSON payload, see the manual for the expected fields. /// `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`. /// Returns a UTF-8-encoded C-string indicating the result that **must** be freed with `cozo_free_str`.
pub unsafe extern "C" fn cozo_import_relation( pub unsafe extern "C" fn cozo_import_relations(
db_id: i32, db_id: i32,
json_payload: *const c_char, json_payload: *const c_char,
) -> *mut c_char { ) -> *mut c_char {
@ -165,7 +165,7 @@ pub unsafe extern "C" fn cozo_import_relation(
Ok(p) => p, Ok(p) => p,
Err(err) => return CString::new(format!("{}", err)).unwrap().into_raw(), Err(err) => return CString::new(format!("{}", err)).unwrap().into_raw(),
}; };
CString::new(db.import_relation_str(data)) CString::new(db.import_relations_str(data))
.unwrap() .unwrap()
.into_raw() .into_raw()
} }

@ -120,7 +120,7 @@ pub extern "system" fn Java_org_cozodb_CozoJavaBridge_importRelations(
match get_db(id) { match get_db(id) {
None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(), None => env.new_string(DB_NOT_FOUND).unwrap().into_raw(),
Some(db) => { Some(db) => {
let res = db.import_relation_str(&data); let res = db.import_relations_str(&data);
env.new_string(res).unwrap().into_raw() env.new_string(res).unwrap().into_raw()
} }
} }

@ -48,10 +48,10 @@ class CozoDb {
}) })
} }
importRelation(relation, data) { importRelations(data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const rels_str = JSON.stringify({relation, data}); const rels_str = JSON.stringify(data);
native.import_relation(rels_str, (result_str) => { native.import_relations(rels_str, (result_str) => {
const result = JSON.parse(result_str); const result = JSON.parse(result_str);
if (result.ok) { if (result.ok) {
resolve(result) resolve(result)

@ -199,7 +199,7 @@ fn export_relations(mut cx: FunctionContext) -> JsResult<JsUndefined> {
Ok(cx.undefined()) Ok(cx.undefined())
} }
fn import_relation(mut cx: FunctionContext) -> JsResult<JsUndefined> { fn import_relations(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let id = cx.argument::<JsNumber>(0)?.value(&mut cx) as u32; let id = cx.argument::<JsNumber>(0)?.value(&mut cx) as u32;
let db = { let db = {
let db_ref = { let db_ref = {
@ -222,7 +222,7 @@ fn import_relation(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let channel = cx.channel(); let channel = cx.channel();
std::thread::spawn(move || { std::thread::spawn(move || {
let result = db.import_relation_str(&data); let result = db.import_relations_str(&data);
channel.send(move |mut cx| { channel.send(move |mut cx| {
let callback = callback.into_inner(&mut cx); let callback = callback.into_inner(&mut cx);
let this = cx.undefined(); let this = cx.undefined();
@ -244,6 +244,6 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("backup_db", backup_db)?; cx.export_function("backup_db", backup_db)?;
cx.export_function("restore_db", restore_db)?; cx.export_function("restore_db", restore_db)?;
cx.export_function("export_relations", export_relations)?; cx.export_function("export_relations", export_relations)?;
cx.export_function("import_relation", import_relation)?; cx.export_function("import_relations", import_relations)?;
Ok(()) Ok(())
} }

@ -34,16 +34,16 @@ impl CozoDbPy {
DB_CLOSED_MSG.to_string() DB_CLOSED_MSG.to_string()
} }
} }
pub fn export_relations(&self, py: Python<'_>, rels: &str) -> String { pub fn export_relations(&self, py: Python<'_>, data: &str) -> String {
if let Some(db) = &self.db { if let Some(db) = &self.db {
py.allow_threads(|| db.export_relations_str(rels)) py.allow_threads(|| db.export_relations_str(data))
} else { } else {
DB_CLOSED_MSG.to_string() DB_CLOSED_MSG.to_string()
} }
} }
pub fn import_relation(&self, py: Python<'_>, data: &str) -> String { pub fn import_relations(&self, py: Python<'_>, data: &str) -> String {
if let Some(db) = &self.db { if let Some(db) = &self.db {
py.allow_threads(|| db.import_relation_str(data)) py.allow_threads(|| db.import_relations_str(data))
} else { } else {
DB_CLOSED_MSG.to_string() DB_CLOSED_MSG.to_string()
} }

@ -17,8 +17,8 @@ mod ffi {
#[swift_bridge(associated_to = DbInstance)] #[swift_bridge(associated_to = DbInstance)]
fn run_script_str(&self, payload: &str, params: &str) -> String; fn run_script_str(&self, payload: &str, params: &str) -> String;
fn export_relations_str(&self, relations_str: &str) -> String; fn export_relations_str(&self, data: &str) -> String;
fn import_relation_str(&self, data: &str) -> String; fn import_relations_str(&self, data: &str) -> String;
fn backup_db_str(&self, out_file: &str) -> String; fn backup_db_str(&self, out_file: &str) -> String;
fn restore_backup_str(&self, in_file: &str) -> String; fn restore_backup_str(&self, in_file: &str) -> String;
} }

@ -38,10 +38,10 @@ impl CozoDb {
pub fn run(&self, script: &str, params: &str) -> String { pub fn run(&self, script: &str, params: &str) -> String {
self.db.run_script_str(script, params) self.db.run_script_str(script, params)
} }
pub fn export_relations(&self, rels: &str) -> String { pub fn export_relations(&self, data: &str) -> String {
self.db.export_relations_str(rels) self.db.export_relations_str(data)
} }
pub fn import_relation(&self, data: &str) -> String { pub fn import_relations(&self, data: &str) -> String {
self.db.import_relation_str(data) self.db.import_relations_str(data)
} }
} }

@ -88,7 +88,10 @@ fn main() {
} else { } else {
format!("{}:{}", args.bind, args.port) format!("{}:{}", args.bind, args.port)
}; };
println!("Database ({} backend) web API running at http://{}", args.kind, addr); println!(
"Database ({} backend) web API running at http://{}",
args.kind, addr
);
rouille::start_server(addr, move |request| { rouille::start_server(addr, move |request| {
let now = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S%.6f"); let now = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S%.6f");
let log_ok = |req: &Request, _resp: &Response, elap: std::time::Duration| { let log_ok = |req: &Request, _resp: &Response, elap: std::time::Duration| {
@ -134,7 +137,11 @@ fn main() {
Some(t) Some(t)
} }
}); });
let result = db.export_relations(relations); let as_objects = match request.get_param("as_objects") {
Some(s) => !s.is_empty(),
None => false
};
let result = db.export_relations(relations, as_objects);
match result { match result {
Ok(s) => { Ok(s) => {
let ret = json!({"ok": true, "data": s}); let ret = json!({"ok": true, "data": s});
@ -146,17 +153,19 @@ fn main() {
} }
} }
}, },
(PUT) (/import/{relation: String}) => { (PUT) (/import) => {
check_auth!(request, auth_guard); check_auth!(request, auth_guard);
#[derive(serde_derive::Serialize, serde_derive::Deserialize)] let payload: serde_json::Value = try_or_400!(rouille::input::json_input(request));
struct ImportPayload { let payload = match payload.as_object() {
data: Vec<serde_json::Value>, Some(o) => o,
} None => {
let ret = json!({"ok": false, "message": "bad import format"});
let payload: ImportPayload = try_or_400!(rouille::input::json_input(request)); return Response::json(&ret).with_status_code(400)
}
};
let result = db.import_relation(&relation, &payload.data); let result = db.import_relations(payload);
match result { match result {
Ok(()) => { Ok(()) => {

Loading…
Cancel
Save