This repository has been archived on 2026-05-07. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
ccrm/server/internal/db/db.go

65 lines
1.5 KiB
Go

package db
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
// DB wraps the SQL database connection.
type DB struct {
*sql.DB
}
// Open opens a SQLite database and runs migrations.
func Open(path string) (*DB, error) {
sqlDB, err := sql.Open("sqlite3", path+"?_journal_mode=WAL&_foreign_keys=on")
if err != nil {
return nil, fmt.Errorf("opening database: %w", err)
}
if err := sqlDB.Ping(); err != nil {
return nil, fmt.Errorf("pinging database: %w", err)
}
db := &DB{sqlDB}
if err := db.migrate(); err != nil {
return nil, fmt.Errorf("running migrations: %w", err)
}
return db, nil
}
func (db *DB) migrate() error {
// Ensure schema_migrations table exists
_, err := db.Exec(`CREATE TABLE IF NOT EXISTS schema_migrations (
version INTEGER PRIMARY KEY,
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`)
if err != nil {
return err
}
// Get current version
var currentVersion int
row := db.QueryRow("SELECT COALESCE(MAX(version), 0) FROM schema_migrations")
if err := row.Scan(&currentVersion); err != nil {
return err
}
// Apply new migrations
for i := currentVersion; i < len(migrations); i++ {
log.Printf("Applying migration %d...", i+1)
if _, err := db.Exec(migrations[i]); err != nil {
return fmt.Errorf("migration %d: %w", i+1, err)
}
if _, err := db.Exec("INSERT INTO schema_migrations (version) VALUES (?)", i+1); err != nil {
return fmt.Errorf("recording migration %d: %w", i+1, err)
}
}
return nil
}