/* * db.h — SQLite storage for sovereign_browser * * Provides persistent local storage for Nostr events and misc data. * The database lives at ~/.sovereign_browser/browser.db. * * Tables: * events — Nostr events (id, pubkey, kind, created_at, content, sig, raw_json) * event_tags — Tag rows for querying by tag name/value * key_value — Simple key-value store for misc settings/cache * * Thread safety: the database is opened with SQLITE_OPEN_FULLMUTEX, so * calls from multiple threads are safe (serialized by SQLite's mutex). */ #ifndef DB_H #define DB_H #include /* cJSON is in the vendored nostr_core_lib */ #include "../nostr_core_lib/cjson/cJSON.h" #ifdef __cplusplus extern "C" { #endif /* * Initialize the database at ~/.sovereign_browser/browser.db. * Creates tables and indexes if they don't exist. * Kept for compatibility; prefer db_init_with_path() for per-user dbs. * * Returns 0 on success, -1 on error. */ int db_init(void); /* * Initialize the global database at ~/.sovereign_browser/global.db. * Used at startup for global settings + shortcuts, before login. * Creates tables and indexes if they don't exist. * * Returns 0 on success, -1 on error. */ int db_init_global(void); /* * Open a SQLite database at the given path with the standard schema. * Closes any currently-open database first (so you can switch from * global.db to a per-user browser.db after login). * * Returns 0 on success, -1 on error. */ int db_init_with_path(const char *path); /* * Close the database. Call at shutdown, or before switching to a * different database via db_init_with_path(). */ void db_close(void); /* ── Events ────────────────────────────────────────────────────────── */ /* * Store a Nostr event (upsert — replaces if same event_id exists). * Parses the cJSON event and stores it in the events + event_tags tables. * * event — a cJSON object representing a Nostr event with at least: * id, pubkey, kind, created_at, content, sig, tags * * Returns 0 on success, -1 on error. */ int db_store_event(const cJSON *event); /* * Fetch the most recent event of a given kind for a pubkey. * * Returns a newly allocated cJSON event (parsed from raw_json), or NULL * if not found. Caller must cJSON_Delete() the result. */ cJSON *db_get_latest_event(const char *pubkey_hex, int kind); /* * Fetch all events of a given kind for a pubkey, newest first. * * limit — max number of events (0 = no limit) * * Returns a cJSON array of event objects. Caller must cJSON_Delete(). * Returns NULL on error. */ cJSON *db_get_events(const char *pubkey_hex, int kind, int limit); /* * Count events of a given kind for a pubkey. * Returns the count, or -1 on error. */ int db_count_events(const char *pubkey_hex, int kind); /* * Fetch all events of a given kind from ALL authors (no pubkey filter), * newest first. Used for public events like kind 31123 skills that are * authored by anyone. * * limit — max number of events (0 = no limit) * * Returns a cJSON array of event objects. Caller must cJSON_Delete(). * Returns NULL on error. */ cJSON *db_get_events_by_kind(int kind, int limit); /* * Delete a single event by its event id (and its tags, via cascade). * Returns 0 on success, -1 on error. */ int db_delete_event(const char *event_id); /* ── Key-Value store ───────────────────────────────────────────────── */ /* * Set a key-value pair (upsert) in the currently-open database. * Returns 0 on success, -1 on error. */ int db_kv_set(const char *key, const char *value); /* * Set a key-value pair in a specific database file, opening a separate * short-lived connection. Used to save global settings to global.db * while the per-user browser.db is the main open database. Creates the * key_value table if it doesn't exist. * Returns 0 on success, -1 on error. */ int db_kv_set_to_file(const char *path, const char *key, const char *value); /* * Get a value by key. * Returns a pointer to the value string, or NULL if not found. * The pointer is valid until the next db_kv_get() call (uses a static * buffer). Call db_kv_get_copy() if you need a persistent copy. */ const char *db_kv_get(const char *key); /* * Get a value by key, returning a newly allocated copy. * Caller must g_free() the result. Returns NULL if not found. */ char *db_kv_get_copy(const char *key); /* ── History ───────────────────────────────────────────────────────── */ /* * Add a URL to the history (UPSERT — increments visit_count and updates * visited_at if the URL already exists). * url — the URL to record * title — optional page title (NULL or "" for none) * Returns 0 on success, -1 on error. */ int db_history_add(const char *url, const char *title); /* * Get recent history entries (most-recent-first). * limit — max number of entries (0 = default 50) * * Fills urls_out and titles_out with parallel arrays of newly allocated * strings. Caller must free each string and the arrays themselves. * Returns the number of entries, or -1 on error. */ int db_history_get(char ***urls_out, char ***titles_out, int *count_out, int limit); /* * Clear all history entries. * Returns 0 on success, -1 on error. */ int db_history_clear(void); /* * Search history entries by URL or title substring. * query — substring to search for (case-insensitive) * limit — max number of entries (0 = default 10) * * Results are ranked by visit_count DESC, then visited_at DESC — so * frequently-visited and recently-visited sites appear first. * * Fills urls_out and titles_out with parallel arrays of newly allocated * strings. Caller must free each string and the arrays themselves. * Returns the number of entries, or -1 on error. */ int db_history_search(const char *query, char ***urls_out, char ***titles_out, int *count_out, int limit); /* ── Session ───────────────────────────────────────────────────────── */ /* * Save the current session (open tab URLs) to the database. * Clears the session table first, then inserts the given URLs in order. * urls — array of URL strings * titles — array of title strings (can be NULL for no titles) * count — number of tabs * Returns 0 on success, -1 on error. */ int db_session_save(const char **urls, const char **titles, int count); /* * Load the saved session from the database. * Fills urls_out and titles_out with parallel arrays (tab_index order). * Caller must free each string and the arrays. * Returns the number of tabs, or -1 on error / no session. */ int db_session_load(char ***urls_out, char ***titles_out, int *count_out); /* * Clear the saved session. * Returns 0 on success, -1 on error. */ int db_session_clear(void); /* ── Agent chat sessions ───────────────────────────────────────────── */ /* * Create a new chat session. Returns the session ID (newly allocated string, * caller must g_free). Returns NULL on error. */ char *db_agent_session_create(const char *title); /* * Get the most recent chat session ID. Returns a newly allocated string, * or NULL if no sessions exist. Caller must g_free. */ char *db_agent_session_get_latest(void); /* * Update a session's title and updated_at timestamp. * Returns 0 on success, -1 on error. */ int db_agent_session_update(const char *session_id, const char *title); /* * List all chat sessions, newest first. Fills arrays with session IDs and * titles. Caller must free each string and the arrays. * Returns the number of sessions, or -1 on error. */ int db_agent_session_list(char ***ids_out, char ***titles_out, int *count_out); /* * Add a message to a chat session. * role — "user", "assistant", "tool", or "system" * content — message text (may be NULL for assistant msgs with only tool_calls) * tool_calls — JSON string of tool calls array (may be NULL) * tool_call_id — for role="tool", the ID of the tool call this responds to (may be NULL) * Returns the message row ID (>0) on success, -1 on error. */ int db_agent_message_add(const char *session_id, const char *role, const char *content, const char *tool_calls, const char *tool_call_id); /* * Load all messages for a session, ordered by created_at (oldest first). * Returns a cJSON array of message objects, each with: * {"id":N, "role":"...", "content":"...", "tool_calls":"...", "tool_call_id":"..."} * Returns NULL on error. Caller must cJSON_Delete(). */ cJSON *db_agent_message_list(const char *session_id); /* * Delete a chat session and all its messages. * Returns 0 on success, -1 on error. */ int db_agent_session_delete(const char *session_id); #ifdef __cplusplus } #endif #endif /* DB_H */