-
Notifications
You must be signed in to change notification settings - Fork 0
/
loader.go
80 lines (69 loc) · 1.97 KB
/
loader.go
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
package migrator
import (
"errors"
"fmt"
"io/fs"
"os"
"regexp"
"sort"
"strconv"
)
const MigrationSQLFilePattern = `^(\d{14})_([\-_a-z0-9]+)?\.(up|down)\.(sql)$`
var mrx = regexp.MustCompile(MigrationSQLFilePattern)
func LoadMigrations(folder string) ([]SQLMigration, []SQLMigration, error) {
migrationDir := os.DirFS(folder)
dirEntries, err := fs.ReadDir(migrationDir, ".")
if err != nil {
return nil, nil, err
}
upMigrations := make([]SQLMigration, 0, 10)
downMigrations := make([]SQLMigration, 0, 10)
for _, d := range dirEntries {
if d.IsDir() {
continue
}
fileName := d.Name()
matches := mrx.FindAllStringSubmatch(fileName, -1)
if len(matches) == 0 {
return nil, nil, fmt.Errorf(`%q is not a valid migration SQL file name`, fileName)
}
if len(matches[0]) != 5 {
return nil, nil, fmt.Errorf(`%q is not a valid migration SQL file name`, fileName)
}
version, err := strconv.ParseInt(matches[0][1], 10, 64)
if err != nil {
return nil, nil, err
}
description := matches[0][2]
op := matches[0][3]
rawQuery, err := fs.ReadFile(migrationDir, fileName)
if err != nil {
return nil, nil, err
}
m, err := NewSQLMigration(version, description, string(rawQuery), fileName)
if err != nil {
return nil, nil, err
}
if op == "up" {
upMigrations = append(upMigrations, m)
} else {
downMigrations = append(downMigrations, m)
}
}
sort.SliceStable(upMigrations, func(i, j int) bool {
return upMigrations[i].Less(upMigrations[j])
})
sort.SliceStable(downMigrations, func(i, j int) bool {
return downMigrations[i].Less(downMigrations[j])
})
// Check if migration SQL files are well paired
if len(upMigrations) != len(downMigrations) {
return nil, nil, errors.New("migration UPs and Downs are not well paired")
}
for i := range upMigrations {
if upMigrations[i].version != downMigrations[i].version {
return nil, nil, errors.New("migration UPs and Downs are not well paired")
}
}
return upMigrations, downMigrations, nil
}