#pragma once /** ** \defgroup ssb_db SSB Database ** This is the main interface to SSB persistence. Everything about getting and ** storing messages and blobs goes through here. ** @{ */ #include "ssb.h" #include "quickjs.h" #include /** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; /** ** Initialize the database writer for an SSB instance. ** @param ssb The SSB instance. */ void tf_ssb_db_init(tf_ssb_t* ssb); /** ** Configure an opened SQLite database for reading. */ void tf_ssb_db_init_reader(sqlite3* db); /** ** Get message content by ID. ** @param ssb The SSB instance. ** @param id The message identifier. ** @param[out] out_blob Populated with the message content. ** @param[out] out_size POpulated with the size of the message content. ** @return true If the message content was found and retrieved. */ bool tf_ssb_db_message_content_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size); /** ** Determine whether a blob is in the database by ID. ** @param ssb The SSB instasnce. ** @param id The blob identifier. ** @return true If the blob is in the database. */ bool tf_ssb_db_blob_has(tf_ssb_t* ssb, const char* id); /** ** Retrieve a blob from the database. ** @param ssb The SSB instance. ** @param id The blob identifier. ** @param[out] out_blob Populated with the blob data. ** @param[out] out_size The size of the blob data. ** @return true If the blob was found and retrieved. */ bool tf_ssb_db_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size); /** ** A function called when a message is stored in the database. ** @param id The message identifier. ** @param stored True if the message wasn't already in the database. ** @param user_data The user data. */ typedef void(tf_ssb_db_store_message_callback_t)(const char* id, bool stored, void* user_data); /** ** Store a message in the database. ** @param ssb The SSB instance. ** @param context The JS context. ** @param id The message identifier. ** @param val The message object. ** @param signature The signature of the message. ** @param sequence_before_author The order of the message fields. ** @param callback A callback to call upon completion. ** @param user_data User data for the callback. */ void tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, JSValue val, const char* signature, bool sequence_before_author, tf_ssb_db_store_message_callback_t* callback, void* user_data); /** ** A function called when a block is stored in the database. ** @param id The blob identifier. ** @param is_new True if the blob wasn't already in the database. ** @param user_data The user data. */ typedef void(tf_ssb_db_blob_store_callback_t)(const char* id, bool is_new, void* user_data); /** ** Store a blob in the database asynchronously. ** @param ssb The SSB instance. ** @param blob The blob data. ** @param size The size of the blob data. ** @param callback A callback to call upon completion. ** @param user_data User data for the callback. */ void tf_ssb_db_blob_store_async(tf_ssb_t* ssb, const uint8_t* blob, size_t size, tf_ssb_db_blob_store_callback_t* callback, void* user_data); /** ** Store a blob in the database and wait for the operation to complete. ** @param ssb The SSB instance. ** @param blob The blob data. ** @param size The size of the blob. ** @param[out] out_id Populated with the blob identifier. ** @param out_id_size The size of the out_id buffer. ** @param[out] out_new True if the blob wasn't already in the datbase. */ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* out_id, size_t out_id_size, bool* out_new); /** ** Get a message by its identifier. ** @param ssb The SSB instance. ** @param id The message identifier. ** @param is_keys Whether to produce {"key": id, "value": message, "timestamp": ts} or just the message. ** @return The message. */ JSValue tf_ssb_db_get_message_by_id(tf_ssb_t* ssb, const char* id, bool is_keys); bool tf_ssb_db_get_message_by_author_and_sequence( tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content); bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, int64_t* out_sequence, char* out_message_id, size_t out_message_id_size); JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data); bool tf_ssb_db_check(sqlite3* db, const char* author); int tf_ssb_db_identity_get_count_for_user(tf_ssb_t* ssb, const char* user); bool tf_ssb_db_identity_create(tf_ssb_t* ssb, const char* user, uint8_t* out_public_key, uint8_t* out_private_key); bool tf_ssb_db_identity_delete(tf_ssb_t* ssb, const char* user, const char* public_key); bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_key, const char* private_key); void tf_ssb_db_identity_visit(tf_ssb_t* ssb, const char* user, void (*callback)(const char* identity, void* user_data), void* user_data); void tf_ssb_db_identity_visit_all(tf_ssb_t* ssb, void (*callback)(const char* identity, void* user_data), void* user_data); bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const char* public_key, uint8_t* out_private_key, size_t private_key_size); JSValue tf_ssb_format_message(JSContext* context, const char* previous, const char* author, int64_t sequence, double timestamp, const char* hash, const char* content, const char* signature, bool sequence_before_author); typedef struct _tf_ssb_following_t { int following_count; int blocking_count; int followed_by_count; int blocked_by_count; char id[k_id_base64_len]; } tf_ssb_following_t; const char** tf_ssb_db_following_deep_ids(tf_ssb_t* ssb, const char** ids, int count, int depth); tf_ssb_following_t* tf_ssb_db_following_deep(tf_ssb_t* ssb, const char** ids, int count, int depth); const char** tf_ssb_db_get_all_visible_identities(tf_ssb_t* ssb, int depth); typedef struct _tf_ssb_db_stored_connection_t { char address[256]; int port; char pubkey[k_id_base64_len]; } tf_ssb_db_stored_connection_t; tf_ssb_db_stored_connection_t* tf_ssb_db_get_stored_connections(tf_ssb_t* ssb, int* out_count); void tf_ssb_db_forget_stored_connection(tf_ssb_t* ssb, const char* address, int port, const char* pubkey); int tf_ssb_sqlite_authorizer(void* user_data, int action_code, const char* arg0, const char* arg1, const char* arg2, const char* arg3); /** @} */