276 lines
9.3 KiB
C
276 lines
9.3 KiB
C
/*
|
|
* 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 <glib.h>
|
|
|
|
/* 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 */
|