refactor(memory): migration files + embed.FS

- shell/memory/migrations/001_init.sql extraido del schema inline
- sqlite.go: applyMigrations() con embed.FS aplicado al abrir
- aplica regla db_migrations.md (fn_registry/.claude/rules/)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 00:45:00 +02:00
parent 2317ba0599
commit 199dc18eb5
2 changed files with 49 additions and 22 deletions
+27 -22
View File
@@ -4,38 +4,43 @@ package shellmem
import (
"context"
"database/sql"
"embed"
"fmt"
"io/fs"
"log/slog"
"os"
"path/filepath"
"sort"
"strings"
"time"
"github.com/enmanuel/agents/pkg/llm"
"github.com/enmanuel/agents/pkg/memory"
)
const schema = `
CREATE TABLE IF NOT EXISTS facts (
agent_id TEXT NOT NULL,
subject TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (agent_id, subject, key)
);
//go:embed migrations/*.sql
var migrationsFS embed.FS
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id TEXT NOT NULL,
room_id TEXT NOT NULL,
role TEXT NOT NULL,
content TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_messages_room ON messages(agent_id, room_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_facts_subject ON facts(agent_id, subject);
`
func applyMigrations(db *sql.DB) error {
files, err := fs.Glob(migrationsFS, "migrations/*.sql")
if err != nil {
return err
}
sort.Strings(files)
for _, f := range files {
b, err := migrationsFS.ReadFile(f)
if err != nil {
return err
}
if _, err := db.Exec(string(b)); err != nil {
if strings.Contains(err.Error(), "duplicate column") || strings.Contains(err.Error(), "already exists") {
continue
}
return fmt.Errorf("migrate %s: %w", f, err)
}
}
return nil
}
// SQLiteStore implements memory.Store using SQLite.
type SQLiteStore struct {
@@ -54,7 +59,7 @@ func New(dbPath string, logger *slog.Logger) (*SQLiteStore, error) {
if err != nil {
return nil, fmt.Errorf("open memory db: %w", err)
}
if _, err := db.Exec(schema); err != nil {
if err := applyMigrations(db); err != nil {
db.Close()
return nil, fmt.Errorf("migrate memory db: %w", err)
}