aboutsummaryrefslogtreecommitdiff
path: root/backend/storage/db.go
blob: 7a7c6e046784eb320264f364e7afbf2a6a6631b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package storage

import (
	"context"
	"database/sql"
	"embed"
	"fmt"
	"log/slog"
	"regexp"
	"slices"
	"strconv"

	_ "github.com/mattn/go-sqlite3"
)

//go:embed migrations
var migrations embed.FS

var nameReg = regexp.MustCompile(`(\d{3})_[a-zA-Z_-]+.sql`)

func ConnectDatabase(file string) *sql.DB {
	db, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?cache=shared", file))
	if err != nil {
		panic(err)
	}
	return db
}

func RunMigration(ctx context.Context, db *sql.DB) error {
	entries, err := migrations.ReadDir("migrations")
	if err != nil {
		return err
	}
	type runMig struct {
		val string
		n   int
	}
	var toRun []runMig
	for _, e := range entries {
		rawId := nameReg.FindStringSubmatch(e.Name())
		id, err := strconv.Atoi(rawId[1])
		if err != nil {
			return err
		}
		b, err := migrations.ReadFile("migrations/" + e.Name())
		if err != nil {
			return err
		}
		slog.Debug("loading migration", "n", id, "file", e.Name(), "content", string(b))
		toRun = append(toRun, runMig{
			val: string(b), n: id,
		})
	}
	if len(toRun) == 0 {
		return nil
	}
	slices.SortFunc(toRun, func(a, b runMig) int {
		return a.n - b.n
	})
	for _, m := range toRun {
		slog.Info("migrating", "n", m.n)
		_, err := db.ExecContext(ctx, m.val)
		if err != nil {
			return err
		}
	}
	return nil
}