/* * Copyright (C) 2023 Jonni Liljamo * * 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 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) )`), } }