Files
feedmee/backend/db.go

146 lines
3.7 KiB
Go

package main
import (
"database/sql"
"embed"
"fmt"
"log/slog"
"os"
"path/filepath"
"github.com/pressly/goose/v3"
_ "modernc.org/sqlite"
)
//go:embed migrations/*.sql
var embedMigrations embed.FS
// Create new sqlite database
// If filepath parameter is empty
func NewDatabaseConnection(dataDir string, dbName string) (*sql.DB, error) {
var dbFilePath string
if dbName == "" {
dbFilePath = filepath.Join(dataDir, "app.db")
} else {
dbFilePath = filepath.Join(dataDir, filepath.Base(dbName))
}
db, err := sql.Open("sqlite", dbFilePath)
if err != nil {
return nil, fmt.Errorf("database open error: %w", err)
}
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("database connection error: %w", err)
}
return db, nil
}
func MigrateDatabase(db *sql.DB) {
dialect := "sqlite3"
goose.SetBaseFS(embedMigrations)
if err := goose.SetDialect(dialect); err != nil {
slog.Error("Database dialect error", "dialect", dialect, "error", err)
os.Exit(1)
}
if err := goose.Up(db, "migrations"); err != nil {
slog.Error("Database migration error", "error", err)
os.Exit(1)
}
migratedVersion, err := goose.GetDBVersion(db)
if err != nil {
slog.Error("Datatabase migration version check error", "error", err)
os.Exit(1)
}
slog.Info("Database up to date", "version", migratedVersion)
}
func SeedDatabase(db *sql.DB, superadminPassword string) error {
seededValue := "false"
row := db.QueryRow("SELECT value FROM settings WHERE key='seeded';")
_ = row.Scan(&seededValue)
if seededValue == "true" {
slog.Info("Database already seeded with default data, skipping")
return nil
}
slog.Info("Database empty, seeding with default values")
row = db.QueryRow("SELECT COUNT(*) FROM menu_items")
var count int
_ = row.Scan(&count)
if count == 0 {
slog.Info("Seeding default menu_items")
defaults := []struct {
category string
name string
}{
{"soup", "Erőleves"},
{"soup", "Dörgicsei Csibeleves"},
{"soup", "Újházi Tyúkhúsleves"},
{"soup", "Jókai Bableves"},
{"soup", "Tárkonyos Raguleves"},
{"soup", "Frankfurti Leves"},
{"soup", "Tavaszi Zöldségleves"},
{"soup", "Fokhagyma Krémleves"},
{"main", "Babragus Csülök"},
{"main", "Rántott Csirkemell"},
{"main", "Rántott Gomba és Rántott Camembert"},
{"main", "Cordon Bleu"},
{"main", "Cigánypecsenye Kakastaréjjal"},
{"main", "Mozzarellás-Paradicsomos Csirkemell Roston"},
{"main", "Kemencés Fokhagymás Csülökszeletek"},
{"main", "Holstein Szelet"},
{"main", "Jalapeños Sajtgolyók"},
{"main", "Cornflakes Bundában Sült Csirkemell"},
{"main", "Baconköntösben Pirított Csirkemáj"},
{"side", "Friss Saláta Kapros Joghurtos Öntettel"},
{"side", "Párolt Rizs"},
{"side", "Fűszeres Steakburgonya"},
{"side", "Grill Zöldség"},
{"side", "Lilahagymás Kukoricasaláta"},
}
for _, d := range defaults {
_, err := db.Exec("INSERT INTO menu_items (category, name) VALUES (?, ?)", d.category, d.name)
if err != nil {
return fmt.Errorf("Error seeding menu_items table: %w", err)
}
}
} else {
slog.Info("Table menu_items already seeded, skipping")
}
_, err := db.Exec(`INSERT OR REPLACE INTO settings (key, value) VALUES ('seeded', 'true')`)
if err != nil {
return fmt.Errorf("Error saving setting table: %w", err)
}
updateSuperadminPassword(db, superadminPassword)
return nil
}
func updateSuperadminPassword(db *sql.DB, superadminPassword string) {
_, err := db.Exec(`INSERT OR REPLACE INTO users (id, username, password, role)
VALUES (
1,
'superadmin',
?,
COALESCE((SELECT role FROM users WHERE id = 1), '0')
)`, superadminPassword)
if err != nil {
slog.Error("Error setting superadmin password", "error", err)
}
}