Files
bot_ticket_r6_elite/internal/db/db.go
T
2026-05-02 03:23:51 +02:00

82 lines
2.2 KiB
Go

package db
import (
"context"
"database/sql"
"fmt"
_ "modernc.org/sqlite"
)
func Open(path string) (*sql.DB, error) {
db, err := sql.Open("sqlite", path+"?_journal=WAL&_timeout=5000&_fk=true")
if err != nil {
return nil, err
}
db.SetMaxOpenConns(1) // SQLite is single-writer
if err := migrate(db); err != nil {
db.Close()
return nil, fmt.Errorf("migrate: %w", err)
}
return db, nil
}
func migrate(db *sql.DB) error {
ctx := context.Background()
if _, err := db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS schema_version (version INTEGER NOT NULL)`); err != nil {
return err
}
var version int
db.QueryRowContext(ctx, `SELECT COALESCE(MAX(version),0) FROM schema_version`).Scan(&version) //nolint
migrations := []string{
// v1: core schema
`CREATE TABLE IF NOT EXISTS tickets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ticket_number INTEGER NOT NULL,
user_id TEXT NOT NULL,
panel TEXT NOT NULL,
type TEXT NOT NULL,
channel_id TEXT NOT NULL UNIQUE,
opened_at DATETIME NOT NULL,
claimed_by TEXT,
claimed_at DATETIME,
closed_at DATETIME,
closed_by TEXT,
reason TEXT,
transcript_path TEXT,
status TEXT NOT NULL DEFAULT 'open'
);
CREATE INDEX IF NOT EXISTS idx_tickets_user ON tickets(user_id);
CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
CREATE INDEX IF NOT EXISTS idx_tickets_type ON tickets(type);
CREATE TABLE IF NOT EXISTS claim_messages (
ticket_id INTEGER PRIMARY KEY,
message_id TEXT NOT NULL,
last_reup_at DATETIME NOT NULL
);
CREATE TABLE IF NOT EXISTS convocation_counter (
id INTEGER PRIMARY KEY CHECK(id=1),
count INTEGER NOT NULL DEFAULT 0
);
INSERT OR IGNORE INTO convocation_counter(id,count) VALUES(1,0);`,
// v2: user-supplied ticket title and description (from modal)
`ALTER TABLE tickets ADD COLUMN ticket_title TEXT;
ALTER TABLE tickets ADD COLUMN ticket_description TEXT;`,
}
for i, m := range migrations {
v := i + 1
if v <= version {
continue
}
if _, err := db.ExecContext(ctx, m); err != nil {
return fmt.Errorf("migration v%d: %w", v, err)
}
if _, err := db.ExecContext(ctx, `INSERT INTO schema_version(version) VALUES(?)`, v); err != nil {
return fmt.Errorf("record migration v%d: %w", v, err)
}
}
return nil
}