Files
speiseplan/db.go
clawd fc7fad9713
Some checks failed
Build & Release / 🏗️ Windows Build (push) Has been cancelled
v0.4.3 — DB in AppData/Local/Speiseplan statt User-Home
- speiseplan.db jetzt in %LOCALAPPDATA%/Speiseplan/
- Uninstaller räumt AppData-Ordner auf
2026-02-20 11:02:07 +00:00

136 lines
3.2 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"github.com/jmoiron/sqlx"
_ "modernc.org/sqlite"
)
var db *sqlx.DB
// InitDatabase initialisiert die SQLite-Datenbank
func InitDatabase() error {
// DB-Datei in AppData/Local/Speiseplan
configDir, err := os.UserConfigDir()
if err != nil {
return fmt.Errorf("failed to get config directory: %w", err)
}
appDir := filepath.Join(configDir, "Speiseplan")
if err := os.MkdirAll(appDir, 0755); err != nil {
return fmt.Errorf("failed to create app directory: %w", err)
}
dbPath := filepath.Join(appDir, "speiseplan.db")
// Verbindung zur Datenbank herstellen
database, err := sqlx.Open("sqlite", dbPath)
if err != nil {
return fmt.Errorf("failed to open database: %w", err)
}
db = database
// SQLite Pragmas setzen
db.MustExec("PRAGMA journal_mode=WAL")
db.MustExec("PRAGMA foreign_keys=ON")
// Schema erstellen
if err := createSchema(); err != nil {
return fmt.Errorf("failed to create schema: %w", err)
}
// Seed-Daten einfügen
if err := SeedDatabase(); err != nil {
return fmt.Errorf("failed to seed database: %w", err)
}
return nil
}
// createSchema erstellt das Datenbankschema
func createSchema() error {
schema := `
-- 14 EU-Allergene (gesetzlich vorgeschrieben, LMIV Verordnung)
CREATE TABLE IF NOT EXISTS allergens (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
category TEXT NOT NULL DEFAULT 'allergen'
);
-- Zusatzstoffe (deutsche Lebensmittelkennzeichnung)
CREATE TABLE IF NOT EXISTS additives (
id TEXT PRIMARY KEY,
name TEXT NOT NULL
);
-- Produkte
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
multiline BOOLEAN DEFAULT FALSE
);
-- Produkt-Allergen-Zuordnung (n:m)
CREATE TABLE IF NOT EXISTS product_allergens (
product_id INTEGER REFERENCES products(id) ON DELETE CASCADE,
allergen_id TEXT REFERENCES allergens(id),
PRIMARY KEY (product_id, allergen_id)
);
-- Produkt-Zusatzstoff-Zuordnung (n:m)
CREATE TABLE IF NOT EXISTS product_additives (
product_id INTEGER REFERENCES products(id) ON DELETE CASCADE,
additive_id TEXT REFERENCES additives(id),
PRIMARY KEY (product_id, additive_id)
);
-- Wochenpläne
CREATE TABLE IF NOT EXISTS week_plans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
year INTEGER NOT NULL,
week INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(year, week)
);
-- Einträge im Wochenplan
CREATE TABLE IF NOT EXISTS plan_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
week_plan_id INTEGER REFERENCES week_plans(id) ON DELETE CASCADE,
day INTEGER NOT NULL,
meal TEXT NOT NULL,
slot INTEGER NOT NULL DEFAULT 0,
product_id INTEGER REFERENCES products(id),
custom_text TEXT,
group_label TEXT
);
-- Sondertage
CREATE TABLE IF NOT EXISTS special_days (
id INTEGER PRIMARY KEY AUTOINCREMENT,
week_plan_id INTEGER REFERENCES week_plans(id) ON DELETE CASCADE,
day INTEGER NOT NULL,
type TEXT NOT NULL,
label TEXT
);`
_, err := db.Exec(schema)
return err
}
// GetDB gibt die Datenbankverbindung zurück
func GetDB() *sqlx.DB {
return db
}
// CloseDatabase schließt die Datenbankverbindung
func CloseDatabase() error {
if db != nil {
return db.Close()
}
return nil
}