/* * Copyright (C) 2024 Jonni Liljamo * * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for * more information. */ package db import ( "fmt" "log/slog" "os" ) var migrationsTable = "schema_migrations" func runMigrations() { slog.Info("Running migrations") var schemaVersion int schemaVersionQuery := fmt.Sprintf( `SELECT schema_version FROM %s ORDER BY schema_version DESC LIMIT 1`, migrationsTable) err := DBConn.QueryRow(schemaVersionQuery).Scan(&schemaVersion) if err != nil { slog.Info("No schema version found, running all migrations") } else { slog.Info("Current schema", slog.Int("version", schemaVersion)) } migrations := migrations() if schemaVersion != len(migrations) { for i := 0; i < len(migrations); i++ { if i >= schemaVersion { slog.Info("Running migration", slog.Int("version", i+1)) // + 1 is just a visual thing _, err := DBConn.Exec(migrations[i]) if err != nil { slog.Error("Migration failed to run!", slog.Int("version", i), slog.String("error", err.Error())) os.Exit(1) } } } // We are now up to date schemaVersion = len(migrations) // Create a new entry in the migrations table schemaMigrationInsertQuery := fmt.Sprintf( `INSERT INTO %s(schema_version) VALUES(%d)`, migrationsTable, schemaVersion) _, err = DBConn.Exec(schemaMigrationInsertQuery) if err != nil { slog.Error("Migrations ran, but was not able to create migration entry") os.Exit(1) } slog.Info("Migrations ran successfully") } else { slog.Info("No migrations to run") } } func migrations() []string { return []string{ fmt.Sprintf(`CREATE TABLE %s ( schema_version INTEGER )`, migrationsTable), fmt.Sprintf(`CREATE TABLE users ( id TEXT NOT NULL PRIMARY KEY UNIQUE, email TEXT NOT NULL UNIQUE, pwd TEXT NOT NULL, is_admin INTEGER DEFAULT FALSE NOT NULL )`), fmt.Sprintf(`CREATE TABLE domains ( id TEXT NOT NULL PRIMARY KEY UNIQUE, apikey TEXT NOT NULL, owner TEXT NOT NULL, ddns_domain TEXT NOT NULL UNIQUE, a_record TEXT, FOREIGN KEY(owner) REFERENCES users(id) )`), fmt.Sprintf(`ALTER TABLE domains ADD acme_challenge TEXT DEFAULT ''`), fmt.Sprintf(`ALTER TABLE domains ADD tsigkey TEXT DEFAULT ''`), } }