nostrdb.h (19799B)
1 #ifndef NOSTRDB_H 2 #define NOSTRDB_H 3 4 #include <inttypes.h> 5 #include "win.h" 6 #include "cursor.h" 7 8 // maximum number of filters allowed in a filter group 9 #define NDB_PACKED_STR 0x1 10 #define NDB_PACKED_ID 0x2 11 12 #define NDB_FLAG_NOMIGRATE (1 << 0) 13 #define NDB_FLAG_SKIP_NOTE_VERIFY (1 << 1) 14 #define NDB_FLAG_NO_FULLTEXT (1 << 2) 15 #define NDB_FLAG_NO_NOTE_BLOCKS (1 << 3) 16 #define NDB_FLAG_NO_STATS (1 << 4) 17 18 //#define DEBUG 1 19 20 #ifdef NDB_LOG 21 #define ndb_debug(...) printf(__VA_ARGS__) 22 #else 23 #define ndb_debug(...) (void)0 24 #endif 25 26 #include "str_block.h" 27 28 struct ndb_json_parser; 29 struct ndb; 30 struct ndb_blocks; 31 struct ndb_block; 32 struct ndb_note; 33 struct ndb_tag; 34 struct ndb_tags; 35 struct ndb_lmdb; 36 union ndb_packed_str; 37 struct bolt11; 38 39 // some bindings like swift needs help with forward declared pointers 40 struct ndb_tag_ptr { struct ndb_tag *ptr; }; 41 struct ndb_tags_ptr { struct ndb_tags *ptr; }; 42 struct ndb_block_ptr { struct ndb_block *ptr; }; 43 struct ndb_blocks_ptr { struct ndb_blocks *ptr; }; 44 struct ndb_note_ptr { struct ndb_note *ptr; }; 45 46 struct ndb_t { 47 struct ndb *ndb; 48 }; 49 50 struct ndb_str { 51 unsigned char flag; 52 union { 53 const char *str; 54 unsigned char *id; 55 }; 56 }; 57 58 struct ndb_ingest_meta { 59 unsigned client; 60 const char *relay; 61 }; 62 63 struct ndb_keypair { 64 unsigned char pubkey[32]; 65 unsigned char secret[32]; 66 67 // this corresponds to secp256k1's keypair type. it's guaranteed to 68 // be 96 bytes according to their docs. I don't want to depend on 69 // the secp256k1 header here so we just use raw bytes. 70 unsigned char pair[96]; 71 }; 72 73 // function pointer for controlling what to do after we parse an id 74 typedef enum ndb_idres (*ndb_id_fn)(void *, const char *); 75 76 // callback function for when we receive new subscription results 77 typedef void (*ndb_sub_fn)(void *, uint64_t subid); 78 79 // id callback + closure data 80 struct ndb_id_cb { 81 ndb_id_fn fn; 82 void *data; 83 }; 84 85 // required to keep a read 86 struct ndb_txn { 87 struct ndb_lmdb *lmdb; 88 void *mdb_txn; 89 }; 90 91 struct ndb_event { 92 struct ndb_note *note; 93 }; 94 95 struct ndb_command_result { 96 int ok; 97 const char *msg; 98 int msglen; 99 }; 100 101 // From-client event types 102 enum fce_type { 103 NDB_FCE_EVENT = 0x1 104 }; 105 106 // To-client event types 107 enum tce_type { 108 NDB_TCE_EVENT = 0x1, 109 NDB_TCE_OK = 0x2, 110 NDB_TCE_NOTICE = 0x3, 111 NDB_TCE_EOSE = 0x4, 112 NDB_TCE_AUTH = 0x5, 113 }; 114 115 enum ndb_ingest_filter_action { 116 NDB_INGEST_REJECT, 117 NDB_INGEST_ACCEPT, 118 NDB_INGEST_SKIP_VALIDATION 119 }; 120 121 struct ndb_search_key 122 { 123 char search[24]; 124 unsigned char id[32]; 125 uint64_t timestamp; 126 }; 127 128 struct ndb_search { 129 struct ndb_search_key *key; 130 uint64_t profile_key; 131 void *cursor; // MDB_cursor * 132 }; 133 134 // From-client event 135 struct ndb_fce { 136 enum fce_type evtype; 137 union { 138 struct ndb_event event; 139 }; 140 }; 141 142 // To-client event 143 struct ndb_tce { 144 enum tce_type evtype; 145 const char *subid; 146 int subid_len; 147 148 union { 149 struct ndb_event event; 150 struct ndb_command_result command_result; 151 }; 152 }; 153 154 typedef enum ndb_ingest_filter_action (*ndb_ingest_filter_fn)(void *, struct ndb_note *); 155 156 enum ndb_filter_fieldtype { 157 NDB_FILTER_IDS = 1, 158 NDB_FILTER_AUTHORS = 2, 159 NDB_FILTER_KINDS = 3, 160 NDB_FILTER_TAGS = 4, 161 NDB_FILTER_SINCE = 5, 162 NDB_FILTER_UNTIL = 6, 163 NDB_FILTER_LIMIT = 7, 164 NDB_FILTER_SEARCH = 8, 165 }; 166 #define NDB_NUM_FILTERS 7 167 168 // when matching generic tags, we need to know if we're dealing with 169 // a pointer to a 32-byte ID or a null terminated string 170 enum ndb_generic_element_type { 171 NDB_ELEMENT_UNKNOWN = 0, 172 NDB_ELEMENT_STRING = 1, 173 NDB_ELEMENT_ID = 2, 174 NDB_ELEMENT_INT = 3, 175 }; 176 177 enum ndb_search_order { 178 NDB_ORDER_DESCENDING, 179 NDB_ORDER_ASCENDING, 180 }; 181 182 enum ndb_dbs { 183 NDB_DB_NOTE, 184 NDB_DB_META, 185 NDB_DB_PROFILE, 186 NDB_DB_NOTE_ID, 187 NDB_DB_PROFILE_PK, // profile pk index 188 NDB_DB_NDB_META, 189 NDB_DB_PROFILE_SEARCH, 190 NDB_DB_PROFILE_LAST_FETCH, 191 NDB_DB_NOTE_KIND, // note kind index 192 NDB_DB_NOTE_TEXT, // note fulltext index 193 NDB_DB_NOTE_BLOCKS, // parsed note blocks for rendering 194 NDB_DB_NOTE_TAGS, // note tags index 195 NDB_DB_NOTE_PUBKEY, // note pubkey index 196 NDB_DB_NOTE_PUBKEY_KIND, // note pubkey kind index 197 NDB_DB_NOTE_RELAY_KIND, // relay+kind+created -> note_id 198 NDB_DB_NOTE_RELAYS, // note_id -> relays 199 NDB_DBS, 200 }; 201 202 // common kinds. we collect stats on these in ndb_stat. mainly because I don't 203 // want to deal with including a hashtable to the project. 204 enum ndb_common_kind { 205 NDB_CKIND_PROFILE, 206 NDB_CKIND_TEXT, 207 NDB_CKIND_CONTACTS, 208 NDB_CKIND_DM, 209 NDB_CKIND_DELETE, 210 NDB_CKIND_REPOST, 211 NDB_CKIND_REACTION, 212 NDB_CKIND_ZAP, 213 NDB_CKIND_ZAP_REQUEST, 214 NDB_CKIND_NWC_REQUEST, 215 NDB_CKIND_NWC_RESPONSE, 216 NDB_CKIND_HTTP_AUTH, 217 NDB_CKIND_LIST, 218 NDB_CKIND_LONGFORM, 219 NDB_CKIND_STATUS, 220 NDB_CKIND_COUNT, // should always be last 221 }; 222 223 struct ndb_builder { 224 struct cursor mem; 225 struct cursor note_cur; 226 struct cursor strings; 227 struct cursor str_indices; 228 struct ndb_note *note; 229 struct ndb_tag *current_tag; 230 }; 231 232 struct ndb_note_relay_iterator { 233 struct ndb_txn *txn; 234 uint64_t note_key; 235 int cursor_op; 236 void *mdb_cur; 237 }; 238 239 struct ndb_iterator { 240 struct ndb_note *note; 241 struct ndb_tag *tag; 242 243 // current outer index 244 int index; 245 }; 246 247 struct ndb_filter_string { 248 const char *string; 249 int len; 250 }; 251 252 union ndb_filter_element { 253 struct ndb_filter_string string; 254 const unsigned char *id; 255 uint64_t integer; 256 }; 257 258 struct ndb_filter_field { 259 enum ndb_filter_fieldtype type; 260 enum ndb_generic_element_type elem_type; 261 char tag; // for generic queries like #t 262 }; 263 264 struct ndb_filter_elements { 265 struct ndb_filter_field field; 266 int count; 267 268 // this needs to be pointer size for reasons 269 // FIXME: what about on 32bit systems?? 270 uint64_t elements[0]; 271 }; 272 273 struct ndb_filter { 274 struct cursor elem_buf; 275 struct cursor data_buf; 276 int num_elements; 277 int finalized; 278 int current; 279 280 // struct ndb_filter_elements offsets into elem_buf 281 // 282 // TODO(jb55): this should probably be called fields. elements are 283 // the things within fields 284 int elements[NDB_NUM_FILTERS]; 285 }; 286 287 struct ndb_config { 288 int flags; 289 int ingester_threads; 290 int writer_scratch_buffer_size; 291 size_t mapsize; 292 void *filter_context; 293 ndb_ingest_filter_fn ingest_filter; 294 void *sub_cb_ctx; 295 ndb_sub_fn sub_cb; 296 }; 297 298 struct ndb_text_search_config { 299 enum ndb_search_order order; 300 int limit; 301 }; 302 303 struct ndb_stat_counts { 304 size_t key_size; 305 size_t value_size; 306 size_t count; 307 }; 308 309 struct ndb_stat { 310 struct ndb_stat_counts dbs[NDB_DBS]; 311 struct ndb_stat_counts common_kinds[NDB_CKIND_COUNT]; 312 struct ndb_stat_counts other_kinds; 313 }; 314 315 #define MAX_TEXT_SEARCH_RESULTS 128 316 #define MAX_TEXT_SEARCH_WORDS 8 317 318 // unpacked form of the actual lmdb fulltext search key 319 // see `ndb_make_text_search_key` for how the packed version is constructed 320 struct ndb_text_search_key 321 { 322 int str_len; 323 const char *str; 324 uint64_t timestamp; 325 uint64_t note_id; 326 uint64_t word_index; 327 }; 328 329 struct ndb_text_search_result { 330 struct ndb_text_search_key key; 331 int prefix_chars; 332 333 // This is only set if we passed a filter for nip50 searches 334 struct ndb_note *note; 335 uint64_t note_size; 336 }; 337 338 struct ndb_text_search_results { 339 struct ndb_text_search_result results[MAX_TEXT_SEARCH_RESULTS]; 340 int num_results; 341 }; 342 343 enum ndb_block_type { 344 BLOCK_HASHTAG = 1, 345 BLOCK_TEXT = 2, 346 BLOCK_MENTION_INDEX = 3, 347 BLOCK_MENTION_BECH32 = 4, 348 BLOCK_URL = 5, 349 BLOCK_INVOICE = 6, 350 }; 351 #define NDB_NUM_BLOCK_TYPES 6 352 #define NDB_MAX_RELAYS 24 353 354 struct ndb_relays { 355 struct ndb_str_block relays[NDB_MAX_RELAYS]; 356 int num_relays; 357 }; 358 359 enum nostr_bech32_type { 360 NOSTR_BECH32_NOTE = 1, 361 NOSTR_BECH32_NPUB = 2, 362 NOSTR_BECH32_NPROFILE = 3, 363 NOSTR_BECH32_NEVENT = 4, 364 NOSTR_BECH32_NRELAY = 5, 365 NOSTR_BECH32_NADDR = 6, 366 NOSTR_BECH32_NSEC = 7, 367 }; 368 #define NOSTR_BECH32_KNOWN_TYPES 7 369 370 struct bech32_note { 371 const unsigned char *event_id; 372 }; 373 374 struct bech32_npub { 375 const unsigned char *pubkey; 376 }; 377 378 struct bech32_nsec { 379 const unsigned char *nsec; 380 }; 381 382 struct bech32_nevent { 383 struct ndb_relays relays; 384 const unsigned char *event_id; 385 const unsigned char *pubkey; // optional 386 }; 387 388 struct bech32_nprofile { 389 struct ndb_relays relays; 390 const unsigned char *pubkey; 391 }; 392 393 struct bech32_naddr { 394 struct ndb_relays relays; 395 struct ndb_str_block identifier; 396 const unsigned char *pubkey; 397 }; 398 399 struct bech32_nrelay { 400 struct ndb_str_block relay; 401 }; 402 403 struct nostr_bech32 { 404 enum nostr_bech32_type type; 405 406 union { 407 struct bech32_note note; 408 struct bech32_npub npub; 409 struct bech32_nsec nsec; 410 struct bech32_nevent nevent; 411 struct bech32_nprofile nprofile; 412 struct bech32_naddr naddr; 413 struct bech32_nrelay nrelay; 414 }; 415 }; 416 417 418 struct ndb_mention_bech32_block { 419 struct ndb_str_block str; 420 struct nostr_bech32 bech32; 421 }; 422 423 struct ndb_invoice { 424 unsigned char version; 425 uint64_t amount; 426 uint64_t timestamp; 427 uint64_t expiry; 428 char *description; 429 unsigned char *description_hash; 430 }; 431 432 struct ndb_invoice_block { 433 struct ndb_str_block invstr; 434 struct ndb_invoice invoice; 435 }; 436 437 struct ndb_block { 438 enum ndb_block_type type; 439 union { 440 struct ndb_str_block str; 441 struct ndb_invoice_block invoice; 442 struct ndb_mention_bech32_block mention_bech32; 443 uint32_t mention_index; 444 } block; 445 }; 446 447 struct ndb_block_iterator { 448 const char *content; 449 struct ndb_blocks *blocks; 450 struct ndb_block block; 451 unsigned char *p; 452 }; 453 454 struct ndb_query_result { 455 struct ndb_note *note; 456 uint64_t note_size; 457 uint64_t note_id; 458 }; 459 460 struct ndb_query_results { 461 struct cursor cur; 462 }; 463 464 // CONFIG 465 void ndb_default_config(struct ndb_config *); 466 void ndb_config_set_ingest_threads(struct ndb_config *config, int threads); 467 void ndb_config_set_flags(struct ndb_config *config, int flags); 468 void ndb_config_set_mapsize(struct ndb_config *config, size_t mapsize); 469 void ndb_config_set_ingest_filter(struct ndb_config *config, ndb_ingest_filter_fn fn, void *); 470 void ndb_config_set_subscription_callback(struct ndb_config *config, ndb_sub_fn fn, void *ctx); 471 472 /// Configurable scratch buffer size for the writer thread. Default is 2MB. If you have smaller notes 473 /// you can decrease this to reduce memory usage. If you have bigger notes you should increase this so 474 /// that the writer thread can properly parse larger notes. 475 void ndb_config_set_writer_scratch_buffer_size(struct ndb_config *config, int scratch_size); 476 477 // HELPERS 478 int ndb_calculate_id(struct ndb_note *note, unsigned char *buf, int buflen); 479 int ndb_sign_id(struct ndb_keypair *keypair, unsigned char id[32], unsigned char sig[64]); 480 int ndb_create_keypair(struct ndb_keypair *key); 481 int ndb_decode_key(const char *secstr, struct ndb_keypair *keypair); 482 int ndb_note_verify(void *secp_ctx, unsigned char pubkey[32], unsigned char id[32], unsigned char signature[64]); 483 484 // NDB 485 int ndb_init(struct ndb **ndb, const char *dbdir, const struct ndb_config *); 486 int ndb_db_version(struct ndb_txn *txn); 487 488 // NOTE PROCESSING 489 int ndb_process_event(struct ndb *, const char *json, int len); 490 void ndb_ingest_meta_init(struct ndb_ingest_meta *meta, unsigned client, const char *relay); 491 // Process an event, recording the relay where it came from. 492 int ndb_process_event_with(struct ndb *, const char *json, int len, struct ndb_ingest_meta *meta); 493 int ndb_process_events(struct ndb *, const char *ldjson, size_t len); 494 int ndb_process_events_with(struct ndb *ndb, const char *ldjson, size_t json_len, struct ndb_ingest_meta *meta); 495 #ifndef _WIN32 496 // TODO: fix on windows 497 int ndb_process_events_stream(struct ndb *, FILE* fp); 498 #endif 499 // deprecated: use ndb_ingest_event_with 500 int ndb_process_client_event(struct ndb *, const char *json, int len); 501 // deprecated: use ndb_ingest_events_with 502 int ndb_process_client_events(struct ndb *, const char *json, size_t len); 503 504 int ndb_begin_query(struct ndb *, struct ndb_txn *); 505 int ndb_search_profile(struct ndb_txn *txn, struct ndb_search *search, const char *query); 506 int ndb_search_profile_next(struct ndb_search *search); 507 void ndb_search_profile_end(struct ndb_search *search); 508 int ndb_end_query(struct ndb_txn *); 509 int ndb_write_last_profile_fetch(struct ndb *ndb, const unsigned char *pubkey, uint64_t fetched_at); 510 uint64_t ndb_read_last_profile_fetch(struct ndb_txn *txn, const unsigned char *pubkey); 511 void *ndb_get_profile_by_pubkey(struct ndb_txn *txn, const unsigned char *pubkey, size_t *len, uint64_t *primkey); 512 void *ndb_get_profile_by_key(struct ndb_txn *txn, uint64_t key, size_t *len); 513 uint64_t ndb_get_notekey_by_id(struct ndb_txn *txn, const unsigned char *id); 514 uint64_t ndb_get_profilekey_by_pubkey(struct ndb_txn *txn, const unsigned char *id); 515 struct ndb_note *ndb_get_note_by_id(struct ndb_txn *txn, const unsigned char *id, size_t *len, uint64_t *primkey); 516 struct ndb_note *ndb_get_note_by_key(struct ndb_txn *txn, uint64_t key, size_t *len); 517 void *ndb_get_note_meta(struct ndb_txn *txn, const unsigned char *id, size_t *len); 518 int ndb_note_seen_on_relay(struct ndb_txn *txn, uint64_t note_key, const char *relay); 519 void ndb_destroy(struct ndb *); 520 521 // BUILDER 522 int ndb_parse_json_note(struct ndb_json_parser *, struct ndb_note **); 523 int ndb_client_event_from_json(const char *json, int len, struct ndb_fce *fce, unsigned char *buf, int bufsize, struct ndb_id_cb *cb); 524 int ndb_ws_event_from_json(const char *json, int len, struct ndb_tce *tce, unsigned char *buf, int bufsize, struct ndb_id_cb *); 525 int ndb_note_from_json(const char *json, int len, struct ndb_note **, unsigned char *buf, int buflen); 526 int ndb_builder_init(struct ndb_builder *builder, unsigned char *buf, size_t bufsize); 527 int ndb_builder_finalize(struct ndb_builder *builder, struct ndb_note **note, struct ndb_keypair *privkey); 528 int ndb_builder_set_content(struct ndb_builder *builder, const char *content, int len); 529 void ndb_builder_set_created_at(struct ndb_builder *builder, uint64_t created_at); 530 void ndb_builder_set_sig(struct ndb_builder *builder, unsigned char *sig); 531 void ndb_builder_set_pubkey(struct ndb_builder *builder, unsigned char *pubkey); 532 void ndb_builder_set_id(struct ndb_builder *builder, unsigned char *id); 533 void ndb_builder_set_kind(struct ndb_builder *builder, uint32_t kind); 534 int ndb_builder_new_tag(struct ndb_builder *builder); 535 int ndb_builder_push_tag_str(struct ndb_builder *builder, const char *str, int len); 536 537 // FILTERS 538 int ndb_filter_init(struct ndb_filter *); 539 540 /// Allocate a filter with a fixed sized buffer (where pages is number of 4096-byte sized blocks) 541 /// You can set pages to 1 if you know you are constructing small filters 542 // TODO: replace this with passed-in buffers 543 int ndb_filter_init_with(struct ndb_filter *filter, int pages); 544 545 int ndb_filter_add_id_element(struct ndb_filter *, const unsigned char *id); 546 int ndb_filter_add_int_element(struct ndb_filter *, uint64_t integer); 547 int ndb_filter_add_str_element(struct ndb_filter *, const char *str); 548 int ndb_filter_eq(const struct ndb_filter *, const struct ndb_filter *); 549 550 /// is `a` a subset of `b` 551 int ndb_filter_is_subset_of(const struct ndb_filter *a, const struct ndb_filter *b); 552 553 // filters from json 554 int ndb_filter_from_json(const char *, int len, struct ndb_filter *filter, unsigned char *buf, int bufsize); 555 556 // getting field elements 557 unsigned char *ndb_filter_get_id_element(const struct ndb_filter *, const struct ndb_filter_elements *, int index); 558 const char *ndb_filter_get_string_element(const struct ndb_filter *, const struct ndb_filter_elements *, int index); 559 uint64_t ndb_filter_get_int_element(const struct ndb_filter_elements *, int index); 560 uint64_t *ndb_filter_get_int_element_ptr(struct ndb_filter_elements *, int index); 561 562 struct ndb_filter_elements *ndb_filter_current_element(const struct ndb_filter *); 563 struct ndb_filter_elements *ndb_filter_get_elements(const struct ndb_filter *, int); 564 int ndb_filter_start_field(struct ndb_filter *, enum ndb_filter_fieldtype); 565 int ndb_filter_start_tag_field(struct ndb_filter *, char tag); 566 int ndb_filter_matches(struct ndb_filter *, struct ndb_note *); 567 int ndb_filter_clone(struct ndb_filter *dst, struct ndb_filter *src); 568 int ndb_filter_end(struct ndb_filter *); 569 void ndb_filter_end_field(struct ndb_filter *); 570 void ndb_filter_destroy(struct ndb_filter *); 571 int ndb_filter_json(const struct ndb_filter *, char *buf, int buflen); 572 573 // SUBSCRIPTIONS 574 uint64_t ndb_subscribe(struct ndb *, struct ndb_filter *, int num_filters); 575 int ndb_wait_for_notes(struct ndb *, uint64_t subid, uint64_t *note_ids, int note_id_capacity); 576 int ndb_poll_for_notes(struct ndb *, uint64_t subid, uint64_t *note_ids, int note_id_capacity); 577 int ndb_unsubscribe(struct ndb *, uint64_t subid); 578 int ndb_num_subscriptions(struct ndb *); 579 580 // FULLTEXT SEARCH 581 int ndb_text_search(struct ndb_txn *txn, const char *query, struct ndb_text_search_results *, struct ndb_text_search_config *); 582 int ndb_text_search_with(struct ndb_txn *txn, const char *query, struct ndb_text_search_results *, struct ndb_text_search_config *, struct ndb_filter *filter); 583 void ndb_default_text_search_config(struct ndb_text_search_config *); 584 void ndb_text_search_config_set_order(struct ndb_text_search_config *, enum ndb_search_order); 585 void ndb_text_search_config_set_limit(struct ndb_text_search_config *, int limit); 586 587 // QUERY 588 int ndb_query(struct ndb_txn *txn, struct ndb_filter *filters, int num_filters, struct ndb_query_result *results, int result_capacity, int *count); 589 590 // STATS 591 int ndb_stat(struct ndb *ndb, struct ndb_stat *stat); 592 void ndb_stat_counts_init(struct ndb_stat_counts *counts); 593 594 // NOTE 595 const char *ndb_note_content(struct ndb_note *note); 596 struct ndb_str ndb_note_str(struct ndb_note *note, union ndb_packed_str *pstr); 597 uint32_t ndb_note_content_length(struct ndb_note *note); 598 uint32_t ndb_note_created_at(struct ndb_note *note); 599 uint32_t ndb_note_kind(struct ndb_note *note); 600 unsigned char *ndb_note_id(struct ndb_note *note); 601 unsigned char *ndb_note_pubkey(struct ndb_note *note); 602 unsigned char *ndb_note_sig(struct ndb_note *note); 603 void _ndb_note_set_kind(struct ndb_note *note, uint32_t kind); 604 struct ndb_tags *ndb_note_tags(struct ndb_note *note); 605 int ndb_str_len(struct ndb_str *str); 606 607 /// write the note as json to a buffer 608 int ndb_note_json(struct ndb_note *, char *buf, int buflen); 609 610 // TAGS 611 void ndb_tags_iterate_start(struct ndb_note *note, struct ndb_iterator *iter); 612 uint16_t ndb_tags_count(struct ndb_tags *); 613 uint16_t ndb_tag_count(struct ndb_tag *); 614 615 // ITER 616 int ndb_tags_iterate_next(struct ndb_iterator *iter); 617 struct ndb_str ndb_iter_tag_str(struct ndb_iterator *iter, int ind); 618 struct ndb_str ndb_tag_str(struct ndb_note *note, struct ndb_tag *tag, int ind); 619 620 // RELAY ITER 621 int ndb_note_relay_iterate_start(struct ndb_txn *txn, struct ndb_note_relay_iterator *iter, uint64_t note_key); 622 const char *ndb_note_relay_iterate_next(struct ndb_note_relay_iterator *iter); 623 void ndb_note_relay_iterate_close(struct ndb_note_relay_iterator *iter); 624 625 // NAMES 626 const char *ndb_db_name(enum ndb_dbs db); 627 const char *ndb_kind_name(enum ndb_common_kind ck); 628 enum ndb_common_kind ndb_kind_to_common_kind(int kind); 629 630 // CONTENT PARSER 631 int ndb_parse_content(unsigned char *buf, int buf_size, 632 const char *content, int content_len, 633 struct ndb_blocks **blocks_p); 634 635 // BLOCKS 636 enum ndb_block_type ndb_get_block_type(struct ndb_block *block); 637 int ndb_blocks_flags(struct ndb_blocks *block); 638 size_t ndb_blocks_total_size(struct ndb_blocks *blocks); 639 int ndb_blocks_word_count(struct ndb_blocks *blocks); 640 641 /// Free blocks if they are owned, safe to call on unowned blocks as well. 642 void ndb_blocks_free(struct ndb_blocks *blocks); 643 644 // BLOCK DB 645 struct ndb_blocks *ndb_get_blocks_by_key(struct ndb *ndb, struct ndb_txn *txn, uint64_t note_key); 646 647 // BLOCK ITERATORS 648 void ndb_blocks_iterate_start(const char *, struct ndb_blocks *, struct ndb_block_iterator *); 649 struct ndb_block *ndb_blocks_iterate_next(struct ndb_block_iterator *); 650 651 // STR BLOCKS 652 struct ndb_str_block *ndb_block_str(struct ndb_block *); 653 const char *ndb_str_block_ptr(struct ndb_str_block *); 654 uint32_t ndb_str_block_len(struct ndb_str_block *); 655 656 // BECH32 BLOCKS 657 struct nostr_bech32 *ndb_bech32_block(struct ndb_block *block); 658 659 #endif