forked from ebabani/pgtestdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dbmate.go
134 lines (121 loc) · 3.3 KB
/
dbmate.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
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
128
129
130
131
132
133
134
package dbmatemigrator
import (
"context"
"database/sql"
"io/fs"
"net/url"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/postgres" // driver
"github.com/Bikappa/pgtestdb"
"github.com/Bikappa/pgtestdb/migrators/common"
)
// Option provides a way to configure the DbmateMigrator struct and its behavior.
//
// dbmate documentation: https://github.com/amacneil/dbmate#command-line-options
//
// See:
// - [WithDir]
// - [WithTableName]
// - [WithFS]
type Option func(*DbmateMigrator)
// WithDir specifies the location(s) of the migration files. If you have migrations
// in multiple directories, you should pass each path here instead of passing
// WithDir multiple times.
//
// Default: `"./db/migrations"`
//
// Equivalent to `--migrations-dir`
// https://github.com/amacneil/dbmate#command-line-options
func WithDir(dir ...string) Option {
return func(m *DbmateMigrator) {
m.MigrationsDir = dir
}
}
// WithTableName specifies the name of the table in which dbmate will store its
// migration records.
//
// Default: `"schema_migrations"`
//
// Equivalent to `--migrations-table`
// https://github.com/amacneil/dbmate#command-line-options
func WithTableName(name string) Option {
return func(m *DbmateMigrator) {
m.MigrationsTableName = name
}
}
// WithFS specifies a `fs.FS` from which to read the migration files.
//
// Default: `<nil>` (reads from the real filesystem)
func WithFS(x fs.FS) Option {
return func(m *DbmateMigrator) {
m.FS = x
}
}
// New returns a [DbmateMigrator], which is a pgtestdb.Migrator that
// uses dbmate to perform migrations.
//
// You can configure the behavior of dbmate by passing Options:
// - [WithDir] is the same as --migrations-dir
// - [WithTableName] is the same as --migrations-table
// - [WithFS] allows you to use an embedded filesystem.
func New(opts ...Option) *DbmateMigrator {
defaults := dbmate.New(nil)
m := &DbmateMigrator{
MigrationsDir: defaults.MigrationsDir,
MigrationsTableName: defaults.MigrationsTableName,
FS: defaults.FS,
}
for _, opt := range opts {
opt(m)
}
return m
}
// DbmateMigrator is a pgtestdb.Migrator that uses dbmate to perform migrations.
//
// DbmateMigrator does not perform any Verify() or Prepare() logic.
type DbmateMigrator struct {
MigrationsDir []string
MigrationsTableName string
FS fs.FS
}
func (m *DbmateMigrator) Hash() (string, error) {
hash := common.NewRecursiveHash(
common.Field("MigrationsTableName", m.MigrationsTableName),
)
if err := hash.AddDirs(m.FS, "*.sql", m.MigrationsDir...); err != nil {
return "", err
}
return hash.String(), nil
}
// Migrate runs dbmate.CreateAndMigrate() to migrate the template database.
func (m *DbmateMigrator) Migrate(
_ context.Context,
_ *sql.DB,
templateConfig pgtestdb.Config,
) error {
u, err := url.Parse(templateConfig.URL())
if err != nil {
return err
}
dbm := dbmate.New(u)
dbm.MigrationsDir = m.MigrationsDir
dbm.MigrationsTableName = m.MigrationsTableName
dbm.FS = m.FS
return dbm.CreateAndMigrate()
}
// Prepare is a no-op method.
func (*DbmateMigrator) Prepare(
_ context.Context,
_ *sql.DB,
_ pgtestdb.Config,
) error {
return nil
}
// Verify is a no-op method.
func (*DbmateMigrator) Verify(
_ context.Context,
_ *sql.DB,
_ pgtestdb.Config,
) error {
return nil
}