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