Skip to content

Commit

Permalink
chore: synchronize workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Nov 26, 2024
1 parent 8e892d0 commit 85539a4
Showing 1 changed file with 5 additions and 183 deletions.
188 changes: 5 additions & 183 deletions cmd/cli/handler_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,19 @@ package cli
import (
"bytes"
"fmt"
"github.com/ory/x/popx"
"github.com/ory/x/servicelocatorx"
"io"
"io/fs"
"os"
"path/filepath"
"regexp"
"strings"
"time"

"github.com/ory/x/popx"
"github.com/ory/x/servicelocatorx"

"github.com/pkg/errors"

"github.com/ory/x/configx"

"github.com/ory/x/errorsx"

"github.com/ory/x/cmdx"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -321,195 +317,21 @@ func (h *MigrateHandler) MigrateSQLUp(cmd *cobra.Command, args []string) (err er
if err != nil {
return err
}
conn := p.Connection(cmd.Context())
if conn == nil {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Migrations can only be executed against a SQL-compatible driver but DSN is not a SQL source.")
return cmdx.FailSilently(cmd)
}

if err := conn.Open(); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not open the database connection:\n%+v\n", err)
return cmdx.FailSilently(cmd)
}

// convert migration tables
if err := p.PrepareMigration(cmd.Context()); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not convert the migration table:\n%+v\n", err)
return cmdx.FailSilently(cmd)
}

// print migration status
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "The following migration is planned:")

// print migration status
status, err := p.MigrationStatus(cmd.Context())
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get the migration status:\n%+v\n", errorsx.WithStack(err))
return cmdx.FailSilently(cmd)
}
_ = status.Write(os.Stdout)

if !flagx.MustGetBool(cmd, "yes") {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "To skip the next question use flag --yes (at your own risk).")
if !cmdx.AskForConfirmation("Do you wish to execute this migration plan?", nil, nil) {
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Migration aborted.")
return nil
}
}

// apply migrations
if err := p.MigrateUp(cmd.Context()); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not apply migrations:\n%+v\n", errorsx.WithStack(err))
return cmdx.FailSilently(cmd)
}

_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Successfully applied migrations!")
return nil
return popx.MigrateSQLUp(cmd, p)
}

func (h *MigrateHandler) MigrateSQLDown(cmd *cobra.Command, args []string) (err error) {
p, err := h.makePersister(cmd, args)
if err != nil {
return err
}

steps := flagx.MustGetInt(cmd, "steps")
if steps < 0 {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Flag --steps must be a positive integer.")
return cmdx.FailSilently(cmd)
}

versions := flagx.MustGetStringSlice(cmd, "version")
if len(versions) > 0 && steps > 0 {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Flags --steps and --version are mutually exclusive.")
return cmdx.FailSilently(cmd)
}

conn := p.Connection(cmd.Context())
if conn == nil {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Migrations can only be executed against a SQL-compatible driver but DSN is not a SQL source.")
return cmdx.FailSilently(cmd)
}

if err := conn.Open(); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not open the database connection:\n%+v\n", err)
return cmdx.FailSilently(cmd)
}

// convert migration tables
if err := p.PrepareMigration(cmd.Context()); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not convert the migration table:\n%+v\n", err)
return cmdx.FailSilently(cmd)
}

status, err := p.MigrationStatus(cmd.Context())
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get the migration status:\n%+v\n", errorsx.WithStack(err))
return cmdx.FailSilently(cmd)
}

// Now we need to rollback the last `steps` migrations that have a status of "Applied":
var count int
var rollingBack int
var contents []string
for i := len(status) - 1; i >= 0; i-- {
if status[i].State == popx.Applied {
count++
if steps > 0 && count <= steps {
status[i].State = "Rollback"
rollingBack++
contents = append(contents, status[i].Content)
}
if len(versions) > 0 {
for _, v := range versions {
if status[i].Version == v {
status[i].State = "Rollback"
rollingBack++
contents = append(contents, status[i].Content)
}
}
}
}
}

// print migration status
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "The migration plan is as follows:")
_ = status.Write(os.Stdout)

if rollingBack < 1 {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "")
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "There are apparently no migrations to roll back.")
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Please provide the --steps argument with a value larger than 0.")
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "")
return cmdx.FailSilently(cmd)
}

_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe SQL statements to be executed from top to bottom are:\n\n")

for i := len(status) - 1; i >= 0; i-- {
if status[i].State == "Rollback" {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "------------ %s - %s ------------\n", status[i].Version, status[i].Name)
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n", status[i].Content)
}
}

if !flagx.MustGetBool(cmd, "yes") {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "To skip the next question use flag --yes (at your own risk).")
if !cmdx.AskForConfirmation("Do you wish to execute this migration plan?", nil, nil) {
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Migration aborted.")
return nil
}
}

// apply migrations
if err := p.MigrateDown(cmd.Context(), steps); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not apply migrations:\n%+v\n", errorsx.WithStack(err))
return cmdx.FailSilently(cmd)
}

_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Successfully applied migrations!")
return nil
return popx.MigrateSQLDown(cmd, p)
}

func (h *MigrateHandler) MigrateStatus(cmd *cobra.Command, args []string) error {
p, err := h.makePersister(cmd, args)
if err != nil {
return err
}
conn := p.Connection(cmd.Context())
if conn == nil {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "Migrations can only be checked against a SQL-compatible driver but DSN is not a SQL source.")
return cmdx.FailSilently(cmd)
}

if err := conn.Open(); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not open the database connection:\n%+v\n", err)
return cmdx.FailSilently(cmd)
}

block := flagx.MustGetBool(cmd, "block")
ctx := cmd.Context()
s, err := p.MigrationStatus(ctx)
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get migration status: %+v\n", err)
return cmdx.FailSilently(cmd)
}

for block && s.HasPending() {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Waiting for migrations to finish...\n")
for _, m := range s {
if m.State == popx.Pending {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), " - %s\n", m.Name)
}
}
time.Sleep(time.Second)
s, err = p.MigrationStatus(ctx)
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get migration status: %+v\n", err)
return cmdx.FailSilently(cmd)
}
}

cmdx.PrintTable(cmd, s)
return nil
return popx.MigrateStatus(cmd, p)
}

0 comments on commit 85539a4

Please sign in to comment.