OpenSQLiteEventLog opens (or creates) a SQLite database at path and initializes the event log schema.
(path string)
| 36 | |
| 37 | // OpenSQLiteEventLog opens (or creates) a SQLite database at path and initializes the event log schema. |
| 38 | func OpenSQLiteEventLog(path string) (*SQLiteEventLog, error) { |
| 39 | dir := filepath.Dir(path) |
| 40 | if err := os.MkdirAll(dir, 0755); err != nil { |
| 41 | return nil, fmt.Errorf("sqlite_eventlog: mkdir %s: %w", dir, err) |
| 42 | } |
| 43 | |
| 44 | dsn := fmt.Sprintf("%s?_pragma=busy_timeout(%d)", path, sqliteBusyTimeout.Milliseconds()) |
| 45 | db, err := sql.Open("sqlite", dsn) |
| 46 | if err != nil { |
| 47 | return nil, fmt.Errorf("sqlite_eventlog: open %s: %w", dsn, err) |
| 48 | } |
| 49 | |
| 50 | // Create tables if they don't exist |
| 51 | if _, err := db.Exec(` |
| 52 | CREATE TABLE IF NOT EXISTS conversation_log ( |
| 53 | conversation_id TEXT NOT NULL, |
| 54 | seq INTEGER NOT NULL, |
| 55 | payload TEXT NOT NULL, |
| 56 | PRIMARY KEY (conversation_id, seq) |
| 57 | )`); err != nil { |
| 58 | db.Close() |
| 59 | return nil, fmt.Errorf("sqlite_eventlog: create conversation_log table: %w", err) |
| 60 | } |
| 61 | |
| 62 | if _, err := db.Exec(` |
| 63 | CREATE TABLE IF NOT EXISTS execution_log ( |
| 64 | exec_id TEXT NOT NULL, |
| 65 | payload TEXT NOT NULL, |
| 66 | timestamp DATETIME NOT NULL |
| 67 | )`); err != nil { |
| 68 | db.Close() |
| 69 | return nil, fmt.Errorf("sqlite_eventlog: create execution_log table: %w", err) |
| 70 | } |
| 71 | |
| 72 | // Create indexes if they don't exist |
| 73 | if _, err := db.Exec(`CREATE INDEX IF NOT EXISTS idx_execution_log_exec_id ON execution_log(exec_id)`); err != nil { |
| 74 | db.Close() |
| 75 | return nil, fmt.Errorf("sqlite_eventlog: create index exec_id: %w", err) |
| 76 | } |
| 77 | |
| 78 | return &SQLiteEventLog{db: db}, nil |
| 79 | } |
| 80 | |
| 81 | // Append serializes the event to JSON and inserts it into the database. |
| 82 | func (l *SQLiteEventLog) Append(ctx context.Context, event *proto.ConversationEvent) (int32, error) { |