nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

commit 627945923baa0ea683333919bdb21a467291b664
parent c7e4303f88b9d9584485d3795d60cc4218f9300c
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 14 Dec 2023 11:59:25 -0800

rust: initial api for Ndb and NdbConfig

This is the start of our rust library for nostrdb. Implement idiomatic
interfaces for Ndb and NdbConfig.

Changelog-Added: Add initial rust library

Diffstat:
Mnostrdb.c | 2+-
Mnostrdb.h | 2+-
Mrust/Cargo.toml | 4+++-
Arust/src/config.rs | 43+++++++++++++++++++++++++++++++++++++++++++
Arust/src/error.rs | 3+++
Mrust/src/lib.rs | 32++++----------------------------
Arust/src/ndb.rs | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arust/src/result.rs | 3+++
8 files changed, 119 insertions(+), 31 deletions(-)

diff --git a/nostrdb.c b/nostrdb.c @@ -3147,7 +3147,7 @@ static int ndb_run_migrations(struct ndb *ndb) return 1; } -int ndb_init(struct ndb **pndb, const char *filename, struct ndb_config *config) +int ndb_init(struct ndb **pndb, const char *filename, const struct ndb_config *config) { struct ndb *ndb; //MDB_dbi ind_id; // TODO: ind_pk, etc diff --git a/nostrdb.h b/nostrdb.h @@ -295,7 +295,7 @@ int ndb_decode_key(const char *secstr, struct ndb_keypair *keypair); int ndb_note_verify(void *secp_ctx, unsigned char pubkey[32], unsigned char id[32], unsigned char signature[64]); // NDB -int ndb_init(struct ndb **ndb, const char *dbdir, struct ndb_config *); +int ndb_init(struct ndb **ndb, const char *dbdir, const struct ndb_config *); int ndb_db_version(struct ndb *ndb); int ndb_process_event(struct ndb *, const char *json, int len); int ndb_process_events(struct ndb *, const char *ldjson, size_t len); diff --git a/rust/Cargo.toml b/rust/Cargo.toml @@ -6,7 +6,9 @@ build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +libc = "0.2.151" + [build-dependencies] bindgen = "0.69.1" cc = "1.0" - diff --git a/rust/src/config.rs b/rust/src/config.rs @@ -0,0 +1,43 @@ +use crate::bindings; + +// The Rust wrapper for ndb_config +pub struct NdbConfig { + pub config: bindings::ndb_config, +} + +impl NdbConfig { + // Constructor + pub fn new() -> Self { + let mut config = bindings::ndb_config { + filter_context: std::ptr::null_mut(), + ingest_filter: None, + flags: 0, + ingester_threads: 0, + mapsize: 0, + }; + + unsafe { + bindings::ndb_default_config(&mut config); + } + + NdbConfig { config } + } + + // Example setter methods + pub fn set_flags(&mut self, flags: i32) -> &mut Self { + self.config.flags = flags; + self + } + + pub fn set_ingester_threads(&mut self, threads: i32) -> &mut Self { + self.config.ingester_threads = threads; + self + } + + // Add other setter methods as needed + + // Internal method to get a raw pointer to the config, used in Ndb + pub fn as_ptr(&self) -> *const bindings::ndb_config { + &self.config + } +} diff --git a/rust/src/error.rs b/rust/src/error.rs @@ -0,0 +1,3 @@ +pub enum Error { + DbOpenFailed, +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs @@ -4,31 +4,7 @@ #[allow(unused)] mod bindings; -#[cfg(test)] -mod tests { - use super::*; - use bindings as ndb; - use std::ffi::CString; - - #[test] - fn ndb_init_works() { - unsafe { - // Initialize ndb - let mut ndb_ptr: *mut bindings::ndb = std::ptr::null_mut(); - let mut config = ndb::ndb_config { - filter_context: std::ptr::null_mut(), - ingest_filter: None, - flags: 0, - ingester_threads: 0, - mapsize: 0, - }; - - let path = CString::new(".").expect("Failed to create CString"); - ndb::ndb_default_config(&mut config); - ndb::ndb_init(&mut ndb_ptr, path.as_ptr(), &mut config); - - // Clean up - bindings::ndb_destroy(ndb_ptr); - } - } -} +mod config; +mod error; +mod ndb; +mod result; diff --git a/rust/src/ndb.rs b/rust/src/ndb.rs @@ -0,0 +1,61 @@ +use std::ffi::CString; +use std::ptr; + +use crate::bindings; +use crate::config::NdbConfig; +use crate::error::Error; +use crate::result::Result; + +pub struct Ndb { + ndb: *mut bindings::ndb, +} + +impl Ndb { + // Constructor + pub fn new(db_dir: &str, config: &NdbConfig) -> Result<Self> { + let db_dir_cstr = match CString::new(db_dir) { + Ok(cstr) => cstr, + Err(_) => return Err(Error::DbOpenFailed), + }; + let mut ndb: *mut bindings::ndb = ptr::null_mut(); + let result = unsafe { bindings::ndb_init(&mut ndb, db_dir_cstr.as_ptr(), config.as_ptr()) }; + + if result != 0 { + return Err(Error::DbOpenFailed); + } + + Ok(Ndb { ndb }) + } + + // Add other methods to interact with the library here +} + +impl Drop for Ndb { + fn drop(&mut self) { + unsafe { + bindings::ndb_destroy(self.ndb); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + fn cleanup() { + let _ = fs::remove_file("data.mdb"); + let _ = fs::remove_file("lock.mdb"); + } + + #[test] + fn ndb_init_works() { + // Initialize ndb + { + let cfg = NdbConfig::new(); + let _ = Ndb::new(".", &cfg); + } + + cleanup(); + } +} diff --git a/rust/src/result.rs b/rust/src/result.rs @@ -0,0 +1,3 @@ +use crate::error::Error; + +pub type Result<T> = std::result::Result<T, Error>;