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