From f31044e8a3a6e6792d28e9b330093bb44b120a6f Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 21 May 2023 12:57:37 +0100 Subject: [PATCH] tabledb work --- veilid-flutter/lib/veilid_encoding.dart | 6 +++++ veilid-flutter/lib/veilid_ffi.dart | 26 ++++++++++----------- veilid-flutter/lib/veilid_js.dart | 12 ++++------ veilid-flutter/lib/veilid_table_db.dart | 18 +++++++++++++-- veilid-flutter/rust/src/dart_ffi.rs | 28 +++++++++++++---------- veilid-wasm/src/lib.rs | 30 +++++++++++++------------ 6 files changed, 71 insertions(+), 49 deletions(-) diff --git a/veilid-flutter/lib/veilid_encoding.dart b/veilid-flutter/lib/veilid_encoding.dart index 9d56b58d..9ef54f14 100644 --- a/veilid-flutter/lib/veilid_encoding.dart +++ b/veilid-flutter/lib/veilid_encoding.dart @@ -14,6 +14,12 @@ Uint8List base64UrlNoPadDecode(String source) { return base64.decode(source); } +Uint8List base64UrlNoPadDecodeDynamic(dynamic source) { + source = source as String; + source = base64.normalize(source); + return base64.decode(source); +} + abstract class EncodedString { late String contents; EncodedString(String s) { diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index f461bd46..5f17e7ec 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -148,9 +148,9 @@ typedef _DeleteTableDbDart = void Function(int, Pointer); // fn table_db_get_column_count(id: u32) -> u32 typedef _TableDbGetColumnCountC = Uint32 Function(Uint32); typedef _TableDbGetColumnCountDart = int Function(int); -// fn table_db_get_keys(id: u32, col: u32) -> *mut c_char -typedef _TableDbGetKeysC = Pointer Function(Uint32, Uint32); -typedef _TableDbGetKeysDart = Pointer Function(int, int); +// fn table_db_get_keys(port: i64, id: u32, col: u32) +typedef _TableDbGetKeysC = Pointer Function(Uint64, Uint32, Uint32); +typedef _TableDbGetKeysDart = Pointer Function(int, int, int); // fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr) typedef _TableDbStoreC = Void Function( Int64, Uint32, Uint32, Pointer, Pointer); @@ -834,15 +834,15 @@ class VeilidTableDBFFI extends VeilidTableDB { } @override - List getKeys(int col) { - final s = _tdb.ffi._tableDbGetKeys(_tdb.id, col); - if (s.address == nullptr.address) { - throw VeilidAPIExceptionInternal("No db for id"); - } - String ja = s.toDartString(); - _tdb.ffi._freeString(s); - List jarr = jsonDecode(ja); - return jarr.map((e) => base64UrlNoPadDecode(e)).toList(); + Future> getKeys(int col) { + final recvPort = ReceivePort("veilid_table_db_get_keys"); + final sendPort = recvPort.sendPort; + + _tdb.ffi._tableDbGetKeys(sendPort.nativePort, _tdb.id, col); + + return processFutureJson( + jsonListConstructor(base64UrlNoPadDecodeDynamic), + recvPort.first); } @override @@ -888,7 +888,7 @@ class VeilidTableDBFFI extends VeilidTableDB { } @override - Future delete(int col, Uint8List key) { + Future delete(int col, Uint8List key) { final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8(); final recvPort = ReceivePort("veilid_table_db_delete"); diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index cd1c590a..8a323516 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -399,13 +399,9 @@ class VeilidTableDBJS extends VeilidTableDB { } @override - List getKeys(int col) { - String? s = js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id, col]); - if (s == null) { - throw VeilidAPIExceptionInternal("No db for id"); - } - List jarr = jsonDecode(s); - return jarr.map((e) => base64UrlNoPadDecode(e)).toList(); + Future> getKeys(int col) async { + return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode( + await js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id, col]))); } @override @@ -437,7 +433,7 @@ class VeilidTableDBJS extends VeilidTableDB { } @override - Future delete(int col, Uint8List key) { + Future delete(int col, Uint8List key) { final encodedKey = base64UrlNoPadEncode(key); return _wrapApiPromise(js_util diff --git a/veilid-flutter/lib/veilid_table_db.dart b/veilid-flutter/lib/veilid_table_db.dart index 4790988d..84923fd0 100644 --- a/veilid-flutter/lib/veilid_table_db.dart +++ b/veilid-flutter/lib/veilid_table_db.dart @@ -25,11 +25,11 @@ abstract class VeilidTableDBTransaction { abstract class VeilidTableDB { int getColumnCount(); - List getKeys(int col); + Future> getKeys(int col); VeilidTableDBTransaction transact(); Future store(int col, Uint8List key, Uint8List value); Future load(int col, Uint8List key); - Future delete(int col, Uint8List key); + Future delete(int col, Uint8List key); Future storeJson(int col, Uint8List key, Object? object, {Object? Function(Object? nonEncodable)? toEncodable}) { @@ -56,4 +56,18 @@ abstract class VeilidTableDB { {Object? Function(Object? key, Object? value)? reviver}) { return loadJson(col, utf8.encoder.convert(key), reviver: reviver); } + + Future deleteJson(int col, Uint8List key, + {Object? Function(Object? key, Object? value)? reviver}) async { + var s = await delete(col, key); + if (s == null) { + return null; + } + return jsonDecode(utf8.decode(s, allowMalformed: false), reviver: reviver); + } + + Future deleteStringJson(int col, String key, + {Object? Function(Object? key, Object? value)? reviver}) { + return deleteJson(col, utf8.encoder.convert(key), reviver: reviver); + } } diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index ed1cf5b8..bc1502aa 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -781,17 +781,20 @@ pub extern "C" fn table_db_get_column_count(id: u32) -> u32 { } #[no_mangle] -pub extern "C" fn table_db_get_keys(id: u32, col: u32) -> *mut c_char { - let table_dbs = TABLE_DBS.lock(); - let Some(table_db) = table_dbs.get(&id) else { - return std::ptr::null_mut(); - }; xxx continue here and run all tests - let Ok(keys) = table_db.clone().get_keys(col) else { - return std::ptr::null_mut(); - }; - let keys: Vec = keys.into_iter().map(|k| BASE64URL_NOPAD.encode(&k)).collect(); - let out = veilid_core::serialize_json(keys); - out.into_ffi_value() +pub extern "C" fn table_db_get_keys(port: i64, id: u32, col: u32) { + DartIsolateWrapper::new(port).spawn_result_json(async move { + let table_db = { + let table_dbs = TABLE_DBS.lock(); + let Some(table_db) = table_dbs.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_get_keys", "id", id)); + }; + table_db.clone() + }; + + let keys = table_db.get_keys(col).await.map_err(veilid_core::VeilidAPIError::generic)?; + let out: Vec = keys.into_iter().map(|k| BASE64URL_NOPAD.encode(&k)).collect(); + APIResult::Ok(out) + }); } fn add_table_db_transaction(tdbt: veilid_core::TableDBTransaction) -> u32 { @@ -957,7 +960,7 @@ pub extern "C" fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr) { table_db.clone() }; - let out = table_db.load(col, &key).map_err(veilid_core::VeilidAPIError::generic)?; + let out = table_db.load(col, &key).await.map_err(veilid_core::VeilidAPIError::generic)?; let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); APIResult::Ok(out) }); @@ -982,6 +985,7 @@ pub extern "C" fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr) { }; let out = table_db.delete(col, &key).await.map_err(veilid_core::VeilidAPIError::generic)?; + let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); APIResult::Ok(out) }); } diff --git a/veilid-wasm/src/lib.rs b/veilid-wasm/src/lib.rs index 80703dd9..ef1e6fa3 100644 --- a/veilid-wasm/src/lib.rs +++ b/veilid-wasm/src/lib.rs @@ -717,20 +717,21 @@ pub fn table_db_get_column_count(id: u32) -> u32 { } #[wasm_bindgen()] -pub fn table_db_get_keys(id: u32, col: u32) -> Option { - let table_dbs = (*TABLE_DBS).borrow(); - let Some(table_db) = table_dbs.get(&id) else { - return None; - }; - let Ok(keys) = table_db.clone().get_keys(col) else { - return None; - }; - let keys: Vec = keys - .into_iter() - .map(|k| data_encoding::BASE64URL_NOPAD.encode(&k)) - .collect(); - let out = veilid_core::serialize_json(keys); - Some(out) +pub fn table_db_get_keys(id: u32, col: u32) -> Promise { + wrap_api_future_json(async move { + let table_dbs = (*TABLE_DBS).borrow(); + let Some(table_db) = table_dbs.get(&id) else { + return None; + }; + let Ok(keys) = table_db.clone().get_keys(col) else { + return None; + }; + let out: Vec = keys + .into_iter() + .map(|k| data_encoding::BASE64URL_NOPAD.encode(&k)) + .collect(); + APIResult::Ok(Some(out)) + }); } fn add_table_db_transaction(tdbt: veilid_core::TableDBTransaction) -> u32 { @@ -903,6 +904,7 @@ pub fn table_db_delete(id: u32, col: u32, key: String) -> Promise { .delete(col, &key) .await .map_err(veilid_core::VeilidAPIError::generic)?; + let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); APIResult::Ok(out) }) }