commit 36c3b8a3df7df8ff9c6fdcd341c6a6221bc00241
parent df37b006bfbcc9bfa10fda81bdae25a3a8a9c344
Author: William Casarin <jb55@jb55.com>
Date: Sun, 17 Dec 2023 14:20:04 -0800
ndb: add get_profile_by_pubkey
This allows us to fetch flatbuffer profile records from the database
Diffstat:
M | src/lib.rs | | | 16 | ++++++++-------- |
M | src/ndb.rs | | | 37 | ++++++++++++++++++++++++++++++++----- |
A | src/profile.rs | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 107 insertions(+), 13 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
@@ -8,19 +8,19 @@ mod bindings;
#[allow(non_snake_case)]
mod ndb_profile;
-pub type Profile<'a> = ndb_profile::NdbProfile<'a>;
-
-pub mod config;
-pub mod error;
-pub mod ndb;
-pub mod note;
-pub mod result;
-pub mod transaction;
+mod config;
+mod error;
+mod ndb;
+mod note;
+mod profile;
+mod result;
+mod transaction;
pub use config::Config;
pub use error::Error;
pub use ndb::Ndb;
pub use note::Note;
+pub use profile::ProfileRecord;
pub use result::Result;
pub use transaction::Transaction;
diff --git a/src/ndb.rs b/src/ndb.rs
@@ -3,11 +3,7 @@ use std::ffi::CString;
use std::ptr;
use crate::bindings;
-use crate::config::Config;
-use crate::error::Error;
-use crate::note::Note;
-use crate::result::Result;
-use crate::transaction::Transaction;
+use crate::{Config, Error, Note, ProfileRecord, Result, Transaction};
use std::fs;
use std::path::Path;
use std::sync::Arc;
@@ -82,6 +78,37 @@ impl Ndb {
Ok(())
}
+ pub fn get_profile_by_pubkey<'a>(
+ &self,
+ transaction: &'a mut Transaction,
+ id: &[u8; 32],
+ ) -> Result<ProfileRecord<'a>> {
+ let mut len: usize = 0;
+ let mut primkey: u64 = 0;
+
+ let profile_record_ptr = unsafe {
+ bindings::ndb_get_profile_by_pubkey(
+ transaction.as_mut_ptr(),
+ id.as_ptr(),
+ &mut len,
+ &mut primkey,
+ )
+ };
+
+ if profile_record_ptr.is_null() {
+ // Handle null pointer (e.g., note not found or error occurred)
+ return Err(Error::NotFound);
+ }
+
+ // Convert the raw pointer to a Note instance
+ Ok(ProfileRecord::new(
+ profile_record_ptr,
+ len,
+ primkey,
+ transaction,
+ ))
+ }
+
/// Get a note from the database. Takes a [Transaction] and a 32-byte [Note] Id
pub fn get_note_by_id<'a>(
&self,
diff --git a/src/profile.rs b/src/profile.rs
@@ -0,0 +1,67 @@
+use crate::ndb_profile::{root_as_ndb_profile_record_unchecked, NdbProfileRecord};
+use crate::Transaction;
+
+pub struct ProfileRecord<'a> {
+ record: NdbProfileRecord<'a>,
+ primary_key: u64,
+ transaction: &'a Transaction,
+}
+
+impl<'a> ProfileRecord<'a> {
+ pub(crate) fn new(
+ ptr: *mut ::std::os::raw::c_void,
+ len: usize,
+ primary_key: u64,
+ transaction: &'a Transaction,
+ ) -> ProfileRecord<'a> {
+ let record = unsafe {
+ let bytes = std::slice::from_raw_parts(ptr as *const u8, len);
+ root_as_ndb_profile_record_unchecked(bytes)
+ };
+ ProfileRecord {
+ record,
+ transaction,
+ primary_key,
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn profile_record_words() {
+ use crate::config::Config;
+ use crate::error::Error;
+ use crate::ndb::Ndb;
+ use crate::test_util;
+
+ let db = "target/testdbs/profile_record_works";
+
+ {
+ let cfg = Config::new();
+ let ndb = Ndb::new(&db, &cfg).unwrap();
+ let _ = ndb.process_event(r#"["EVENT","nostril-query",{"content":"{\"nip05\":\"_@jb55.com\",\"website\":\"https://damus.io\",\"name\":\"jb55\",\"about\":\"I made damus, npubs and zaps. banned by apple & the ccp. my notes are not for sale.\",\"lud16\":\"jb55@sendsats.lol\",\"banner\":\"https://nostr.build/i/3d6f22d45d95ecc2c19b1acdec57aa15f2dba9c423b536e26fc62707c125f557.jpg\",\"display_name\":\"Will\",\"picture\":\"https://cdn.jb55.com/img/red-me.jpg\"}","created_at":1700855305,"id":"cad04d11f7fa9c36d57400baca198582dfeb94fa138366c4469e58da9ed60051","kind":0,"pubkey":"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245","sig":"7a15e379ff27318460172b4a1d55a13e064c5007d05d5a188e7f60e244a9ed08996cb7676058b88c7a91ae9488f8edc719bc966cb5bf1eb99be44cdb745f915f","tags":[]}]"#);
+ }
+
+ // Initialize ndb
+ {
+ let cfg = Config::new();
+ let ndb = Ndb::new(&db, &cfg).expect("db open");
+ let mut txn = Transaction::new(&ndb).expect("new txn");
+
+ let pk =
+ hex::decode("32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")
+ .expect("hex decode");
+ let pr = ndb
+ .get_profile_by_pubkey(&mut txn, &pk.try_into().expect("bytes"))
+ .expect("profile record");
+
+ let profile = pr.record.profile().unwrap();
+ assert_eq!(Some("jb55"), profile.name());
+ }
+
+ test_util::cleanup_db(db);
+ }
+}