summaryrefslogtreecommitdiff
path: root/db.go
blob: b2b43affad518e5f3982155da7631e014c74e511 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package libmkwebpage

import (
	"database/sql"
	"embed"
	"errors"
	"fmt"
	"io"
	"io/fs"
	"os"
	"path"
	"slices"
	"strconv"
	"strings"

	_ "github.com/glebarez/go-sqlite"
)

type migrations struct {
	staticRoot  embed.FS
	dynamicRoot fs.FS
}

func (w *Webpage) NewMigrations(static embed.FS, dynamic fs.FS) *Webpage {
	w.migrations = migrations{staticRoot: static, dynamicRoot: dynamic}
	return w
}
func (w *Webpage) getMigrationRoot() fs.FS {
	if w.IsDynamic() {
		return w.migrations.dynamicRoot
	}
	return w.migrations.staticRoot
}

func (w *Webpage) ConnectDb() (*sql.DB, error) {
	db, err := sql.Open("sqlite", "./test.db")
	if err != nil {
		return nil, err
	}

	var dir fs.ReadDirFile
	potenriallyDir, err := w.getMigrationRoot().Open("db")
	if err != nil {
		return nil, err
	}
	if foo, ok := potenriallyDir.(fs.ReadDirFile); !ok {
		dir = foo
	} else {
		return nil, errors.New("db directory is not a directory")
	}
	files, err := dir.ReadDir(0)
	if err != nil {
		return nil, err
	}

	err = db.Ping()
	if err != nil {
		return nil, err
	}

	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	var migration_level int
	rows := tx.QueryRow("SELECT level FROM __MIGRATIONLEVEL")
	fmt.Fprintln(os.Stderr, *rows)
	if rows.Scan(&migration_level) != nil {
		fmt.Fprintln(os.Stderr, "Creating Migration-Metadata")
		_, err := tx.Exec("CREATE TABLE __MIGRATIONLEVEL (level INTEGER PRIMARY KEY)")
		if err != nil {
			return nil, err
		}
		_, err = tx.Exec("INSERT INTO __MIGRATIONLEVEL(level) VALUES (0)")
		if err != nil {
			return nil, err
		}
		migration_level = 0
	}
	slices.SortFunc(files, func(a, b fs.DirEntry) int {
		if a.Name() < b.Name() {
			return -1
		}
		if a.Name() > b.Name() {
			return 1
		}
		return 0
	})
	for _, file := range files {
		if !file.Type().IsRegular() {
			continue
		}
		id, err := strconv.Atoi(strings.Split(file.Name(), "-")[0])
		if err != nil {
			return nil, err
		}
		if migration_level < id {
			fmt.Fprintln(os.Stderr, "Running Migration nr", id)
			migration, err := w.getMigrationRoot().Open(path.Join("db", file.Name()))
			if err != nil {
				return nil, err
			}
			migrationContent, err := io.ReadAll(migration)
			if err != nil {
				return nil, err
			}

			_, err = tx.Exec(string(migrationContent))
			if err != nil {
				return nil, err
			}
			_, err = tx.Exec("UPDATE __MIGRATIONLEVEL SET level = ?", id)
			if err != nil {
				return nil, err
			}
		}

	}
	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	return db, nil
}