sdaduanbilei 8cb4e041c8 fix
2026-03-09 17:38:43 +08:00

127 lines
3.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package store
import (
"database/sql"
"sync"
_ "modernc.org/sqlite"
)
type Store struct {
db *sql.DB
mu sync.Mutex
}
func New(dbPath string) (*Store, error) {
db, err := sql.Open("sqlite", dbPath+"?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)")
if err != nil {
return nil, err
}
s := &Store{db: db}
if err := s.migrate(); err != nil {
db.Close()
return nil, err
}
return s, nil
}
func (s *Store) Close() error {
return s.db.Close()
}
func (s *Store) migrate() error {
_, err := s.db.Exec(`
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
agent TEXT NOT NULL,
role TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
filename TEXT,
title TEXT,
group_id INTEGER,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_msg_room ON messages(room_id, created_at);
CREATE INDEX IF NOT EXISTS idx_msg_group ON messages(group_id);
CREATE TABLE IF NOT EXISTS token_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
agent TEXT NOT NULL,
prompt_tokens INTEGER NOT NULL DEFAULT 0,
completion_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_tu_room ON token_usage(room_id);
CREATE TABLE IF NOT EXISTS schedules (
id TEXT PRIMARY KEY,
room_id TEXT NOT NULL,
cron TEXT NOT NULL,
message TEXT NOT NULL,
user_name TEXT NOT NULL DEFAULT 'scheduler',
enabled INTEGER NOT NULL DEFAULT 1,
once INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
last_run_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_sch_room ON schedules(room_id);
CREATE TABLE IF NOT EXISTS file_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
filename TEXT NOT NULL,
content TEXT NOT NULL,
agent TEXT NOT NULL DEFAULT '',
version INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_fv_room_file ON file_versions(room_id, filename);
CREATE TABLE IF NOT EXISTS agent_configs (
room_id TEXT NOT NULL,
agent_name TEXT NOT NULL,
file_type TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
PRIMARY KEY (room_id, agent_name, file_type)
);
CREATE INDEX IF NOT EXISTS idx_ac_room ON agent_configs(room_id);
`)
if err != nil {
return err
}
// 安全添加 part_type 列SQLite 不支持 ALTER TABLE ... IF NOT EXISTS
var hasPartType bool
rows, err := s.db.Query(`PRAGMA table_info(messages)`)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var cid int
var name, typ string
var notnull int
var dfltValue *string
var pk int
if err := rows.Scan(&cid, &name, &typ, &notnull, &dfltValue, &pk); err != nil {
return err
}
if name == "part_type" {
hasPartType = true
break
}
}
if !hasPartType {
_, err = s.db.Exec(`ALTER TABLE messages ADD COLUMN part_type TEXT NOT NULL DEFAULT 'text'`)
if err != nil {
return err
}
}
return nil
}