Files
2026-05-11 11:38:31 +03:00

58 lines
1.3 KiB
Go

package db
import (
"database/sql"
_ "embed"
"fmt"
_ "modernc.org/sqlite"
"golang.org/x/crypto/bcrypt"
"qbank/internal/config"
)
//go:embed schema.sql
var schema string
func Open(path string) (*sql.DB, error) {
db, err := sql.Open("sqlite", path)
if err != nil {
return nil, fmt.Errorf("open sqlite: %w", err)
}
db.SetMaxOpenConns(1)
for _, stmt := range []string{
"PRAGMA journal_mode=WAL",
"PRAGMA foreign_keys=ON",
} {
if _, err := db.Exec(stmt); err != nil {
db.Close()
return nil, fmt.Errorf("pragma %q: %w", stmt, err)
}
}
if _, err := db.Exec(schema); err != nil {
db.Close()
return nil, fmt.Errorf("apply schema: %w", err)
}
return db, nil
}
func Seed(db *sql.DB, users []config.AdminUser) error {
var count int
if err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count); err != nil {
return fmt.Errorf("count users: %w", err)
}
if count > 0 {
return nil
}
for _, u := range users {
hash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
if err != nil {
return fmt.Errorf("hash password for %q: %w", u.Name, err)
}
if _, err := db.Exec("INSERT INTO users (name, password_hash) VALUES (?, ?)", u.Name, string(hash)); err != nil {
return fmt.Errorf("insert user %q: %w", u.Name, err)
}
}
return nil
}