From d047a24a32ef5653e4ea9ae1c8cacd93b6ad0bb2 Mon Sep 17 00:00:00 2001 From: Piotr Sarna Date: Wed, 10 May 2023 12:09:06 +0200 Subject: [PATCH] bindings: expose reading from the database The results are returned as a CString for now. --- core/mvcc/bindings/c/include/mvcc.h | 5 +++ core/mvcc/bindings/c/src/errors.rs | 1 + core/mvcc/bindings/c/src/lib.rs | 50 +++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/core/mvcc/bindings/c/include/mvcc.h b/core/mvcc/bindings/c/include/mvcc.h index aea8beb23..b30f1cf4a 100644 --- a/core/mvcc/bindings/c/include/mvcc.h +++ b/core/mvcc/bindings/c/include/mvcc.h @@ -5,6 +5,7 @@ typedef enum { MVCC_OK = 0, + MVCC_IO_ERROR_READ = 266, MVCC_IO_ERROR_WRITE = 778, } MVCCError; @@ -22,6 +23,10 @@ void MVCCDatabaseClose(MVCCDatabaseRef db); MVCCError MVCCDatabaseInsert(MVCCDatabaseRef db, uint64_t id, const void *value_ptr, uintptr_t value_len); +MVCCError MVCCDatabaseRead(MVCCDatabaseRef db, uint64_t id, char **value_ptr, int64_t *value_len); + +void MVCCFreeStr(void *ptr); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/core/mvcc/bindings/c/src/errors.rs b/core/mvcc/bindings/c/src/errors.rs index 8b40ad2ba..65a174b50 100644 --- a/core/mvcc/bindings/c/src/errors.rs +++ b/core/mvcc/bindings/c/src/errors.rs @@ -1,5 +1,6 @@ #[repr(C)] pub enum MVCCError { MVCC_OK = 0, + MVCC_IO_ERROR_READ = 266, MVCC_IO_ERROR_WRITE = 778, } diff --git a/core/mvcc/bindings/c/src/lib.rs b/core/mvcc/bindings/c/src/lib.rs index 2f2529cb2..f995be1ea 100644 --- a/core/mvcc/bindings/c/src/lib.rs +++ b/core/mvcc/bindings/c/src/lib.rs @@ -93,3 +93,53 @@ pub unsafe extern "C" fn MVCCDatabaseInsert( } } } + +#[no_mangle] +pub unsafe extern "C" fn MVCCDatabaseRead( + db: MVCCDatabaseRef, + id: u64, + value_ptr: *mut *mut std::ffi::c_char, + value_len: *mut i64, +) -> MVCCError { + let db = db.get_ref(); + let (db, runtime) = (&db.db, &db.runtime); + + match runtime.block_on(async move { + let tx = db.begin_tx().await; + let maybe_row = db.read(tx, id).await?; + match maybe_row { + Some(row) => { + tracing::debug!("Found row {row:?}"); + let str_len = row.data.len() + 1; + let value = std::ffi::CString::new(row.data.as_bytes()).map_err(|e| { + mvcc_rs::errors::DatabaseError::Io(format!( + "Failed to transform read data into CString: {e}" + )) + })?; + unsafe { + *value_ptr = value.into_raw(); + *value_len = str_len as i64; + } + } + None => unsafe { *value_len = -1 }, + }; + Ok::<(), mvcc_rs::errors::DatabaseError>(()) + }) { + Ok(_) => { + tracing::debug!("MVCCDatabaseRead: success"); + MVCCError::MVCC_OK + } + Err(e) => { + tracing::error!("MVCCDatabaseRead: {e}"); + MVCCError::MVCC_IO_ERROR_READ + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn MVCCFreeStr(ptr: *mut std::ffi::c_void) { + if ptr.is_null() { + return; + } + let _ = std::ffi::CString::from_raw(ptr as *mut std::ffi::c_char); +}