//! `SQLite` schema definition for the message log database. use rusqlite::Connection; use anyhow::Result; /// Create the message log's tables and indexes if they don't already /// exist (`messages`, `archives`, `blobs`). /// /// Why: idempotent via `CREATE TABLE/INDEX IF NOT EXISTS`, so it's safe /// to call on every `open_or_create`. /// /// Return: `Ok(())` on success, or the underlying `SQLite` error. pub fn init_schema(conn: &Connection) -> Result<()> { conn.execute_batch("PRAGMA foreign_keys = ON;")?; conn.execute_batch( " CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, role TEXT NOT NULL, content TEXT, tool_call_id TEXT, tool_name TEXT, tool_arguments TEXT, created_at INTEGER NOT NULL, FOREIGN KEY (session_id) REFERENCES archives(session_id) ); CREATE TABLE IF NOT EXISTS archives ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL UNIQUE, title TEXT, model TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, message_count INTEGER DEFAULT 0, token_count INTEGER DEFAULT 0, summary TEXT ); CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id); CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at); CREATE INDEX IF NOT EXISTS idx_archives_created_at ON archives(created_at); CREATE TABLE IF NOT EXISTS blobs ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, blob_key TEXT NOT NULL, data BLOB NOT NULL, mime_type TEXT, created_at INTEGER NOT NULL, UNIQUE(session_id, blob_key) ); " )?; Ok(()) }