/*
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
* more information.
*/
package db
import (
"fmt"
"log"
)
var migrationsTable string = "schema_migrations"
func runMigrations() {
log.Print("[felu/db] Running migrations")
var schemaVersion int = 0
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 {
log.Print("[felu/db] No schema version found, running all migrations")
} else {
log.Printf("[felu/db] Currently on schema version %d", schemaVersion)
}
migrations := migrations()
if schemaVersion != len(migrations) {
for i := 0; i < len(migrations); i++ {
if i >= schemaVersion {
log.Printf("[felu/db] Running migration %d", i + 1) // + 1 is just a visual thing
_, err := DBConn.Exec(migrations[i])
if err != nil {
log.Fatalf("[felu/db] Migration %d failed to run!", i)
}
}
}
// 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 {
log.Fatal("[felu/db] Migrations ran, but was not able to create migration entry")
} else {
log.Print("[felu/db] Migrations ran successfully")
}
} else {
log.Printf("[felu/db] Already on schema version %d, no migrations to run", schemaVersion)
}
}
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,
email TEXT NOT NULL,
pwd TEXT NOT NULL,
is_admin INTEGER DEFAULT FALSE NOT NULL,
UNIQUE(id, email)
)`),
fmt.Sprintf(`CREATE TABLE domains (
id TEXT NOT NULL PRIMARY KEY,
apikey TEXT NOT NULL,
owner TEXT NOT NULL,
ddns_domain TEXT NOT NULL,
a_record TEXT,
UNIQUE(id, ddns_domain),
FOREIGN KEY(owner) REFERENCES users(id)
)`),
}
}