feat(storage): add SQLite wrapper and full schema migrations (15 tables)
This commit is contained in:
113
internal/storage/migrations.go
Normal file
113
internal/storage/migrations.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package storage
|
||||
|
||||
var migrations = []string{
|
||||
divacodeSchema,
|
||||
companionSchema,
|
||||
}
|
||||
|
||||
const divacodeSchema = `
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id TEXT PRIMARY KEY,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id TEXT PRIMARY KEY,
|
||||
conversation_id TEXT NOT NULL REFERENCES conversations(id),
|
||||
role TEXT NOT NULL CHECK(role IN ('user','assistant','system','tool')),
|
||||
content TEXT NOT NULL,
|
||||
tool_call TEXT,
|
||||
token_count INTEGER,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS context_state (
|
||||
conversation_id TEXT PRIMARY KEY REFERENCES conversations(id),
|
||||
token_count INTEGER NOT NULL DEFAULT 0,
|
||||
summary TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS memories (
|
||||
id TEXT PRIMARY KEY,
|
||||
content TEXT NOT NULL,
|
||||
embedding BLOB,
|
||||
source TEXT,
|
||||
importance REAL DEFAULT 0.5,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
last_accessed TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance);
|
||||
CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
|
||||
`
|
||||
|
||||
const companionSchema = `
|
||||
CREATE TABLE IF NOT EXISTS personality_traits (
|
||||
id TEXT PRIMARY KEY,
|
||||
trait TEXT NOT NULL UNIQUE,
|
||||
value REAL NOT NULL DEFAULT 0.5,
|
||||
min_value REAL NOT NULL DEFAULT 0.0,
|
||||
max_value REAL NOT NULL DEFAULT 1.0,
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS relationship_metrics (
|
||||
id TEXT PRIMARY KEY,
|
||||
metric TEXT NOT NULL UNIQUE,
|
||||
value REAL NOT NULL DEFAULT 0.0,
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS shared_topics (
|
||||
id TEXT PRIMARY KEY,
|
||||
topic TEXT NOT NULL UNIQUE,
|
||||
count INTEGER NOT NULL DEFAULT 1,
|
||||
last_discussed TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS inside_jokes (
|
||||
id TEXT PRIMARY KEY,
|
||||
joke TEXT NOT NULL,
|
||||
context TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS diary_entries (
|
||||
id TEXT PRIMARY KEY,
|
||||
date TEXT NOT NULL,
|
||||
summary TEXT NOT NULL,
|
||||
mood TEXT,
|
||||
topics TEXT,
|
||||
observations TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS observations (
|
||||
id TEXT PRIMARY KEY,
|
||||
content TEXT NOT NULL,
|
||||
confidence REAL DEFAULT 0.5,
|
||||
category TEXT,
|
||||
applied INTEGER DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_promises (
|
||||
id TEXT PRIMARY KEY,
|
||||
promise TEXT NOT NULL,
|
||||
context TEXT,
|
||||
fulfilled INTEGER DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
deadline TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_strategies (
|
||||
id TEXT PRIMARY KEY,
|
||||
situation TEXT NOT NULL,
|
||||
strategy TEXT NOT NULL,
|
||||
outcome TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
`
|
||||
48
internal/storage/sqlite.go
Normal file
48
internal/storage/sqlite.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func Open(path string) (*DB, error) {
|
||||
db, err := sql.Open("sqlite", path+"?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)&_pragma=foreign_keys(1)")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Ping(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DB{db}, nil
|
||||
}
|
||||
|
||||
func (db *DB) Migrate() error {
|
||||
for _, m := range migrations {
|
||||
if err := db.Exec(m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DB) Exec(query string, args ...interface{}) error {
|
||||
_, err := db.DB.Exec(query, args...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
|
||||
return db.DB.Query(query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row {
|
||||
return db.DB.QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) Close() error {
|
||||
return db.DB.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user