Create a simple migrations subcommand.

This commit is contained in:
Victor Vrantchan
2021-02-20 21:26:27 -05:00
parent 7d18671835
commit 5202ca027d
2 changed files with 70 additions and 27 deletions

View File

@@ -84,25 +84,6 @@ func sqliteInit(conn *sqlite.Conn) error {
return err
}
var (
migrations []byte
script = "internal/data/migrations/sqlite/initial_tables.sql"
)
// only load and run migrations script if the path exists.
// temporary workaround for tests which will have to be
// replaced once the schema needs to exist for the tests.
if _, err := os.Stat(script); err == nil {
migrations, err = ioutil.ReadFile(script)
if err != nil {
return err
}
}
if err := sqlitex.ExecScript(conn, string(migrations)); err != nil {
return err
}
return nil
}
@@ -117,13 +98,6 @@ func setupPostgres(ctx context.Context, f *cliFlags, logger log.Logger) (*postgr
return nil, err
}
// temporary until migrations are set up
migrations, err := ioutil.ReadFile("internal/data/migrations/postgres/initial_tables.sql")
if _, err := dbpool.Exec(ctx, string(migrations)); err != nil {
dbpool.Close()
return nil, err
}
db := &postgresdb{
userdb: user.NewPostgres(dbpool),
sessiondb: session.NewPostgres(dbpool),
@@ -133,3 +107,52 @@ func setupPostgres(ctx context.Context, f *cliFlags, logger log.Logger) (*postgr
return db, nil
}
func migrate(ctx context.Context, f *cliFlags, logger log.Logger) error {
var err error
switch driver := dbDriver(f.databaseURL); driver {
case "postgres":
dbpool, err := pgxpool.Connect(ctx, f.databaseURL)
if err != nil {
return err
}
log.Info(logger).Log("msg", "connected to db", "backend", driver)
migrations, err := ioutil.ReadFile("internal/data/migrations/postgres/initial_tables.sql")
if _, err := dbpool.Exec(ctx, string(migrations)); err != nil {
dbpool.Close()
return err
}
return nil
case "sqlite":
conn, err := sqlite.OpenConn(f.databaseURL, 0)
if err != nil {
return fmt.Errorf("open sqlite dbfile: %s", err)
}
log.Info(logger).Log("msg", "connected to db", "backend", driver)
var (
migrations []byte
script = "internal/data/migrations/sqlite/initial_tables.sql"
)
// only load and run migrations script if the path exists.
// temporary workaround for tests which will have to be
// replaced once the schema needs to exist for the tests.
if _, err := os.Stat(script); err == nil {
migrations, err = ioutil.ReadFile(script)
if err != nil {
return err
}
}
if err := sqlitex.ExecScript(conn, string(migrations)); err != nil {
return err
}
default:
err = fmt.Errorf("unsupported database_url value or restricted path %q", f.databaseURL)
}
return err
}

View File

@@ -78,6 +78,26 @@ func micromdm(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
},
}
migrate := &ffcli.Command{
Name: "migrate",
ShortUsage: "migrate [<arg> ...]",
ShortHelp: "Run database migrations.",
Exec: func(_ context.Context, args []string) error {
logOpts := []log.Option{log.Output(stderr)}
if cli.debug {
logOpts = append(logOpts, log.StartDebug())
}
logger = log.New(logOpts...)
err := migrate(ctx, cli, logger)
if err != nil {
return err
}
return nil
},
}
// add a help subcommand to make usage more discoverable.
helpCmd := &ffcli.Command{
Name: "help",
@@ -93,7 +113,7 @@ func micromdm(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
ShortUsage: "micromdm [flags] <subcommand>",
FlagSet: rootfs,
Options: []ff.Option{ff.WithEnvVarPrefix("MICROMDM"), ff.WithConfigFileParser(ff.PlainParser), ff.WithConfigFileFlag("config")},
Subcommands: []*ffcli.Command{helpCmd, version},
Subcommands: []*ffcli.Command{helpCmd, version, migrate},
Exec: func(context.Context, []string) error {
logOpts := []log.Option{log.Output(stderr)}