summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--database.go45
-rw-r--r--database_test.go44
-rw-r--r--meson.build1
-rw-r--r--sql/migrations/0001.sqlite31
4 files changed, 91 insertions, 0 deletions
diff --git a/database.go b/database.go
new file mode 100644
index 0000000..c2d69c1
--- /dev/null
+++ b/database.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+ "embed"
+ "fmt"
+ "io/fs"
+ "log"
+ "path/filepath"
+)
+
+const (
+ migrationDir = `sql/migrations`
+ migrationFilePattern = `%04d.sqlite3`
+)
+
+var migrations []string
+
+//go:embed sql/migrations/*.sqlite3
+var migrationsFS embed.FS
+
+func init() {
+ readMigrations()
+}
+
+func readMigrations() {
+ i := 1
+
+ _ = fs.WalkDir(migrationsFS, migrationDir, func(path string, d fs.DirEntry, err error) error {
+ if !d.IsDir() {
+ expected := fmt.Sprintf(migrationFilePattern, i)
+ if filepath.Base(path) == expected {
+ data, err := fs.ReadFile(migrationsFS, path)
+ if err != nil {
+ log.Fatalf("Could not read migration: %v", err)
+ }
+
+ migrations = append(migrations, string(data))
+
+ i += 1
+ }
+ }
+
+ return nil
+ })
+}
diff --git a/database_test.go b/database_test.go
new file mode 100644
index 0000000..fce0c02
--- /dev/null
+++ b/database_test.go
@@ -0,0 +1,44 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func TestMigrationNumber(t *testing.T) {
+ n := len(migrations)
+
+ entries, err := os.ReadDir(migrationDir)
+ if err != nil {
+ t.Fatalf("Failed to determine number of migration files: %v", err)
+ }
+ expectation := len(entries)
+
+ if n != expectation {
+ t.Fatalf("Expected %d migration files but got %d.", expectation, n)
+ }
+}
+
+func TestMigrationContent(t *testing.T) {
+ for i, migration := range migrations {
+ name := fmt.Sprintf(migrationFilePattern, i+1)
+ path := filepath.Join(migrationDir, name)
+
+ expectation := fmt.Sprintf("PRAGMA user_version = %d;", i+1)
+ if !strings.HasPrefix(migration, expectation) {
+ t.Fatalf("Expected '%s' at start of '%s'.", expectation, path)
+ }
+
+ n := strings.Count(migration, `user_version`)
+ if n != 1 {
+ t.Fatalf(
+ "'user_version' was mentioned more than once in %s. "+
+ "This is likely not intended.",
+ path,
+ )
+ }
+ }
+}
diff --git a/meson.build b/meson.build
index 0bd75d3..ba66106 100644
--- a/meson.build
+++ b/meson.build
@@ -11,6 +11,7 @@ finserv_linux_amd64 = custom_target(
input : [
meson.current_source_dir() / 'main.go',
meson.current_source_dir() / 'handlers.go',
+ meson.current_source_dir() / 'database.go',
],
output : 'finserv-linux-amd64',
env : {'GOOS': 'linux', 'GOARCH': 'amd64'},
diff --git a/sql/migrations/0001.sqlite3 b/sql/migrations/0001.sqlite3
new file mode 100644
index 0000000..d0c13fc
--- /dev/null
+++ b/sql/migrations/0001.sqlite3
@@ -0,0 +1 @@
+PRAGMA user_version = 1;