Skip to content

Commit

Permalink
Enable override of migrations folder (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
efixler authored Aug 9, 2024
1 parent 3f53d16 commit aab739c
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 26 deletions.
8 changes: 5 additions & 3 deletions database/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
)

const (
MigrationDir = "migrations" // Default directory for migration files (in the embed.FS)
// TODO: This should be configurable or removeable
MigrationDir = "migrations" // Default directory for migration files (in the passed FS)
)

var (
ErrNoMigrationFS = fmt.Errorf("migration filesystem is not set")
ErrNoMigrationFS = fmt.Errorf("migration filesystem is not set")
ErrNoMigrationsFound = fmt.Errorf("could not find any migrations")
)

// Execute an up migration using goose.
Expand Down Expand Up @@ -137,5 +139,5 @@ func findMigrationsDir(fsys fs.FS, currentPath string) (fs.FS, string, error) {
}
}

return nil, "", ErrNoMigrationFS
return nil, "", ErrNoMigrationsFound
}
11 changes: 7 additions & 4 deletions database/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (

const MySQLDriver = "mysql"

//go:embed migrations/*.sql
var migrationFS embed.FS

type MySQL struct {
config Config
}
Expand All @@ -21,6 +24,9 @@ func New(options ...Option) (*MySQL, error) {
return nil, err
}
}
if config.migrationFS == nil {
config.migrationFS = migrationFS
}
s := &MySQL{
config: config,
}
Expand All @@ -43,11 +49,8 @@ func (s MySQL) DSNSource() database.DataSource {
return s.config
}

//go:embed migrations/*.sql
var migrationFS embed.FS

func (s MySQL) MigrationFS() fs.FS {
return migrationFS
return s.config.migrationFS
}

func (s MySQL) MigrationEnv() []string {
Expand Down
9 changes: 9 additions & 0 deletions database/mysql/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mysql
import (
"errors"
"fmt"
"io/fs"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -106,12 +107,20 @@ func WithQueryTimeout(timeout time.Duration) Option {
}
}

func WithMigrationFS(fs fs.FS) Option {
return func(c *Config) error {
c.migrationFS = fs
return nil
}
}

type Config struct {
mysql.Config
TargetSchema string // here for schema-less conns, e.g. for create
queryTimeout time.Duration
maxConns int
connMaxLifetime time.Duration
migrationFS fs.FS
}

func defaultConfig() Config {
Expand Down
31 changes: 20 additions & 11 deletions database/sqlite/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sqlite
import (
"errors"
"fmt"
"io/fs"
"time"

"github.com/efixler/scrape/database"
Expand All @@ -27,6 +28,20 @@ const (
AccessModeMemory AccessMode = "memory"
)

type config struct {
filename string
busyTimeout time.Duration // SQLite's busy timeout specifies the time to wait if a table is locked
queryTimeout time.Duration
journalMode JournalMode
cacheSize int
synchronous SyncMode
accessMode AccessMode
maxConnections int // 0 = use driver defaults
connMaxLifetime time.Duration // 0 = use driver defaults
noAutoCreate bool
migrationFS fs.FS
}

func InMemoryDB() Option {
return func(c *config) error {
c.filename = InMemoryDBName
Expand Down Expand Up @@ -90,17 +105,11 @@ func WithoutAutoCreate() Option {
}
}

type config struct {
filename string
busyTimeout time.Duration // SQLite's busy timeout specifies the time to wait if a table is locked
queryTimeout time.Duration
journalMode JournalMode
cacheSize int
synchronous SyncMode
accessMode AccessMode
maxConnections int // 0 = use driver defaults
connMaxLifetime time.Duration // 0 = use driver defaults
noAutoCreate bool
func WithMigrationFS(fs fs.FS) Option {
return func(c *config) error {
c.migrationFS = fs
return nil
}
}

func (o config) DSN() string {
Expand Down
19 changes: 14 additions & 5 deletions database/sqlite/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (

const SQLiteDriver = "sqlite3"

//go:embed migrations/*.sql
var migrationFS embed.FS

type SQLite struct {
config config
stats *Stats
Expand All @@ -33,6 +36,15 @@ func New(options ...Option) (*SQLite, error) {
return nil, err
}
}
// If the migrationFS is not set, use the embedded migrations
// This would make the embedded migrations in this package redundant --
// it would be good to remove these to keep the engine implementation (reusable)
// totally separate from migrations (not reusable().
// However, that requires too many changes in too many places
// (particularly in the tests) to be worth it right now, so leaving it hardwired/as-is.
if c.migrationFS == nil {
c.migrationFS = migrationFS
}
s := &SQLite{
config: *c,
}
Expand All @@ -47,11 +59,8 @@ func (s SQLite) DSNSource() database.DataSource {
return s.config
}

//go:embed migrations/*.sql
var migrationFS embed.FS

func (s SQLite) MigrationFS() fs.FS {
return migrationFS
func (s *SQLite) MigrationFS() fs.FS {
return s.config.migrationFS
}

func (s *SQLite) AfterOpen(dbh *database.DBHandle) error {
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ func database(spec DatabaseSpec, username string, password string, migration Mig
mysql.Username(username),
mysql.Password(password),
}
// For MySQL we need special handling only when it's possible that the db doesn't
// exist yet.
if migration == Up {
// For MySQL we need special handling only when it's possible
// that the db doesn't exist yet.
options = append(options, mysql.ForMigration())
}
engine, err := mysql.New(options...)
Expand Down
2 changes: 1 addition & 1 deletion internal/server/version/version.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package version

const (
Commit = "87b5e32"
Commit = "81bd03a"
Tag = "v0.8.6"
RepoURL = "https://github.com/efixler/scrape"
)

0 comments on commit aab739c

Please sign in to comment.