commit 750346cce36d7e533ec6e88fbd3011d9a753b91d
parent 8636e48ffa2852a922609d070f2e2af347236a45
Author: William Casarin <jb55@jb55.com>
Date: Fri, 11 Aug 2023 20:27:21 -0700
ndb: add note querying by id, add tests
Diffstat:
M | nostrdb.c | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | nostrdb.h | | | 2 | ++ |
M | test.c | | | 13 | +++++++++++++ |
3 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/nostrdb.c b/nostrdb.c
@@ -238,35 +238,76 @@ static int ndb_writer_queue_note(struct ndb_writer *writer,
return prot_queue_push(&writer->inbox, &msg);
}
-static uint64_t ndb_get_note_by_id(MDB_txn *txn, struct ndb_lmdb *lmdb,
- unsigned char *id)
+// get some value based on a clustered id key
+int ndb_get_tsid(MDB_txn *txn, struct ndb_lmdb *lmdb, enum ndb_dbs db,
+ unsigned char *id, MDB_val *val)
{
- MDB_val key, data;
+ MDB_val k, v;
MDB_cursor *cur;
struct ndb_tsid tsid;
+ int success = 0;
ndb_tsid_high(&tsid, id);
- key.mv_data = &tsid;
- key.mv_size = sizeof(tsid);
+ k.mv_data = &tsid;
+ k.mv_size = sizeof(tsid);
- mdb_cursor_open(txn, lmdb->dbs[NDB_DB_NOTE_ID], &cur);
+ mdb_cursor_open(txn, lmdb->dbs[db], &cur);
// Position cursor at the next key greater than or equal to the specified key
- if (mdb_cursor_get(cur, &key, &data, MDB_SET_RANGE)) {
- mdb_cursor_close(cur);
- return 0;
+ if (mdb_cursor_get(cur, &k, &v, MDB_SET_RANGE)) {
+ // Failed :(. It could be the last element?
+ if (mdb_cursor_get(cur, &k, &v, MDB_LAST))
+ goto cleanup;
+ } else {
+ // if set range worked and our key exists, it should be
+ // the one right before this one
+ if (mdb_cursor_get(cur, &k, &v, MDB_PREV))
+ goto cleanup;
}
- if (mdb_cursor_get(cur, &key, &data, MDB_PREV)) {
- mdb_cursor_close(cur);
- return 0;
+ if (memcmp(k.mv_data, id, 32) == 0) {
+ *val = v;
+ success = 1;
}
+cleanup:
mdb_cursor_close(cur);
- if (memcmp(key.mv_data, id, 32) == 0)
- return *((uint64_t*)data.mv_data);
+ return success;
+}
- return 0;
+struct ndb_note *ndb_get_note_by_id(struct ndb *ndb, unsigned char *id)
+{
+ MDB_val k, v;
+ MDB_txn *txn;
+
+ if (mdb_txn_begin(ndb->lmdb.env, 0, 0, &txn)) {
+ ndb_debug("ndb_get_note_by_id: mdb_txn_begin failed\n");
+ return NULL;
+ }
+
+ if (!ndb_get_tsid(txn, &ndb->lmdb, NDB_DB_NOTE_ID, id, &k)) {
+ ndb_debug("ndb_get_note_by_id: ndb_get_tsid failed\n");
+ return NULL;
+ }
+
+ if (mdb_get(txn, ndb->lmdb.dbs[NDB_DB_NOTE], &k, &v)) {
+ ndb_debug("ndb_get_note_by_id: mdb_get note failed\n");
+ return NULL;
+ }
+
+ mdb_txn_abort(txn);
+
+ return (struct ndb_note *)v.mv_data;
+}
+
+static int ndb_has_note(MDB_txn *txn, struct ndb_lmdb *lmdb, unsigned char *id)
+{
+ MDB_val val;
+
+ if (!ndb_get_tsid(txn, lmdb, NDB_DB_NOTE_ID, id, &val))
+ return 0;
+
+ return 1;
}
static enum ndb_idres ndb_ingester_json_controller(void *data, const char *hexid)
@@ -282,7 +323,7 @@ static enum ndb_idres ndb_ingester_json_controller(void *data, const char *hexid
key.mv_size = 32;
key.mv_data = id;
- if (!ndb_get_note_by_id(c->read_txn, c->lmdb, id))
+ if (!ndb_has_note(c->read_txn, c->lmdb, id))
return NDB_IDRES_CONT;
return NDB_IDRES_STOP;
@@ -315,6 +356,7 @@ static int ndb_process_profile_note(struct ndb_note *note, void **profile,
return 1;
}
+
static int ndb_ingester_process_event(secp256k1_context *ctx,
struct ndb_ingester *ingester,
struct ndb_ingester_event *ev,
diff --git a/nostrdb.h b/nostrdb.h
@@ -151,6 +151,8 @@ int ndb_note_verify(void *secp_ctx, unsigned char pubkey[32], unsigned char id[3
int ndb_init(struct ndb **ndb, size_t mapsize, int ingester_threads);
int ndb_process_event(struct ndb *, const char *json, int len);
int ndb_process_events(struct ndb *, const char *ldjson, int len);
+int ndb_get_profile(struct ndb *, unsigned char pubkey[32], void **out);
+struct ndb_note *ndb_get_note_by_id(struct ndb *, unsigned char *id);
void ndb_destroy(struct ndb *);
// BUILDER
diff --git a/test.c b/test.c
@@ -30,6 +30,19 @@ static void test_load_profiles()
ndb_destroy(ndb);
+ assert(ndb_init(&ndb, mapsize, ingester_threads));
+ unsigned char id[32] = {
+ 0x22, 0x05, 0x0b, 0x6d, 0x97, 0xbb, 0x9d, 0xa0, 0x9e, 0x90, 0xed, 0x0c,
+ 0x6d, 0xd9, 0x5e, 0xed, 0x1d, 0x42, 0x3e, 0x27, 0xd5, 0xcb, 0xa5, 0x94,
+ 0xd2, 0xb4, 0xd1, 0x3a, 0x55, 0x43, 0x09, 0x07 };
+ const char *expected_content = "{\"website\":\"selenejin.com\",\"lud06\":\"\",\"nip05\":\"selenejin@BitcoinNostr.com\",\"picture\":\"https://nostr.build/i/3549697beda0fe1f4ae621f359c639373d92b7c8d5c62582b656c5843138c9ed.jpg\",\"display_name\":\"Selene Jin\",\"about\":\"INTJ | Founding Designer @Blockstream\",\"name\":\"SeleneJin\"}";
+
+ struct ndb_note *note = ndb_get_note_by_id(ndb, id);
+ assert(note != NULL);
+ assert(!strcmp(ndb_note_content(note), expected_content));
+
+ ndb_destroy(ndb);
+
free(json);
free(buf);
}