cli: add All option for migrate sub-commands (apply, delete and status) and seed apply command

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2509
Co-authored-by: Aravind K P <8335904+scriptonist@users.noreply.github.com>
GitOrigin-RevId: 03ee878072b58c6dc7f43af9d26d30a5594d9a50
This commit is contained in:
Kali Vara Purushotham Santhati 2021-12-23 21:28:53 +05:30 committed by hasura-bot
parent 5ad04cc58d
commit f0bef2b482
17 changed files with 276 additions and 135 deletions

View File

@ -9,6 +9,7 @@
(Add entries below in the order of server, console, cli, docs, others)
- server: extend support for insert mutations to tables without primary key constraint in a MSSQL backend
- cli: migrate and seed subcommands has an option in prompt to choose and apply operation on all available databases
## v2.1.1

View File

@ -451,6 +451,9 @@ type ExecutionContext struct {
Source Source
HasMetadataV3 bool
// AllDatabases should be taken only incase if database isn't mentioned
AllDatabases bool
// after a `scripts update-config-v3` all migrate commands will try to automatically
// move cli state from hdb_catalog.* tables to catalog state if that hasn't happened
// already this configuration option will disable this step

View File

@ -93,8 +93,9 @@ func (opts *DeployOptions) Run() error {
if configV2FSM.Current == failedOperation {
return fmt.Errorf("operation failed: %w", context.err)
}
return nil
}
configV3FSM := newConfigV3DeployFSM()
if err := configV3FSM.SendEvent(applyInitialMetadata, context); err != nil {
return err
@ -177,8 +178,8 @@ func (a *applyingMigrationsAction) Execute(ctx fsm.EventContext) eventType {
context.ec.Config.DisableInteractive = true
opts := MigrateApplyOptions{
EC: context.ec,
AllDatabases: true,
}
opts.EC.AllDatabases = true
if err := opts.Run(); err != nil {
context.err = err
return applyMigrationsFailed

View File

@ -118,6 +118,60 @@ func executeStatus(t *migrate.Migrate) (*migrate.Status, error) {
}
func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
return err
}
if ec.Config.Version < cli.V3 {
return nil
}
if err := databaseChooser(ec); err != nil {
return err
}
if err := validateSourceInfo(ec); err != nil {
return err
}
// check if migration ops are supported for the database
if !migrate.IsMigrationsSupported(ec.Source.Kind) {
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
}
return nil
}
func validateConfigV3FlagsWithAll(cmd *cobra.Command, ec *cli.ExecutionContext) error {
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
return err
}
if ec.Config.Version < cli.V3 {
return nil
}
// if --all-databases flag is present, ignore --database-name and showing UI prompt for choosing a single database
if cmd.Flags().Changed("all-databases") {
return nil
}
if err := databaseChooserWithAllOption(ec); err != nil {
return err
}
if ec.AllDatabases {
return nil
}
if err := validateSourceInfo(ec); err != nil {
return err
}
// check if migration ops are supported for the database
if !migrate.IsMigrationsSupported(ec.Source.Kind) {
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
}
return nil
}
func validateConfigV3Prechecks(cmd *cobra.Command, ec *cli.ExecutionContext) error {
// for project using config older than v3, use PG source kind
if ec.Config.Version < cli.V3 {
ec.Source.Kind = hasura.SourceKindPG
@ -127,34 +181,16 @@ func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
return nil
}
// if --all-databases flag is present, ignore --database-name and showing UI prompt for choosing a single database
if cmd.Flags().Changed("all-databases") {
return nil
}
// In case of single database, just choose the source automatically
sources, err := metadatautil.GetSources(ec.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return fmt.Errorf("unable to get available databases: %w", err)
}
if !cmd.Flags().Changed("database-name") && len(sources) == 1 {
ec.Source.Name = sources[0]
}
// for project using config equal to or greater than v3
// database-name flag is required when running in non-terminal mode
if (!ec.IsTerminal || ec.Config.DisableInteractive) && ec.Source.Name == "" {
if (!ec.IsTerminal || ec.Config.DisableInteractive) && !cmd.Flags().Changed("all-databases") && !cmd.Flags().Changed("database-name") {
return errDatabaseNameNotSet
}
// prompt UI for choosing database if source name is not set
if ec.Source.Name == "" {
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return err
}
ec.Source.Name = databaseName
}
return nil
}
func validateSourceInfo(ec *cli.ExecutionContext) error {
// find out the database kind by making a API call to server
// and update ec to include the database name and kind
sourceKind, err := metadatautil.GetSourceKind(ec.APIClient.V1Metadata.ExportMetadata, ec.Source.Name)
@ -165,10 +201,33 @@ func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
return fmt.Errorf("%w: error determining database kind for %s, check if database exists on hasura", errDatabaseNotFound, ec.Source.Name)
}
ec.Source.Kind = *sourceKind
return nil
}
// check if migration ops are supported for the database
if !migrate.IsMigrationsSupported(*sourceKind) {
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, *sourceKind)
func databaseChooser(ec *cli.ExecutionContext) error {
// prompt UI for choosing database if source name is not set
if ec.Source.Name == "" {
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return err
}
ec.Source.Name = databaseName
}
return nil
}
func databaseChooserWithAllOption(ec *cli.ExecutionContext) error {
// prompt UI for choosing database if source name is not set
if ec.Source.Name == "" {
databaseName, err := metadatautil.DatabaseChooserUIWithAll(ec.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return err
}
if databaseName == metadatautil.ChooseAllDatabases {
ec.AllDatabases = true
return nil
}
ec.Source.Name = databaseName
}
return nil
}

View File

@ -67,7 +67,7 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
hasura migrate apply --down all`,
SilenceUsage: true,
PreRunE: func(cmd *cobra.Command, args []string) error {
return validateConfigV3Flags(cmd, ec)
return validateConfigV3FlagsWithAll(cmd, ec)
},
RunE: func(cmd *cobra.Command, args []string) error {
return opts.Run()
@ -85,7 +85,7 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
f.StringVar(&opts.MigrationType, "type", "up", "type of migration (up, down) to be used with version flag")
f.BoolVar(&opts.DryRun, "dry-run", false, "print the names of migrations which are going to be applied")
f.BoolVar(&opts.AllDatabases, "all-databases", false, "set this flag to attempt to apply migrations on all databases present on server")
f.BoolVar(&opts.EC.AllDatabases, "all-databases", false, "set this flag to attempt to apply migrations on all databases present on server")
f.BoolVar(&opts.ProgressBarLogs, "progressbar-logs", false, "print the logs of progressbar")
if err := f.MarkHidden("progressbar-logs"); err != nil {
ec.Logger.WithError(err).Errorf("error while using a dependency library")
@ -105,7 +105,6 @@ type MigrateApplyOptions struct {
SkipExecution bool
DryRun bool
Source cli.Source
AllDatabases bool
ProgressBarLogs bool
}
@ -118,15 +117,15 @@ func (o *MigrateApplyOptions) Validate() error {
if o.DryRun && o.SkipExecution {
return errors.New("both --skip-execution and --dry-run flags cannot be used together")
}
if o.DryRun && o.AllDatabases {
if o.DryRun && o.EC.AllDatabases {
return errors.New("both --all-databases and --dry-run flags cannot be used together")
}
if o.EC.Config.Version >= cli.V3 {
if !o.AllDatabases && len(o.Source.Name) == 0 {
if !o.EC.AllDatabases && len(o.Source.Name) == 0 {
return fmt.Errorf("unable to determine database on which migration should be applied")
}
if !o.AllDatabases {
if !o.EC.AllDatabases {
if len(o.Source.Name) == 0 {
return fmt.Errorf("empty database name")
}
@ -203,13 +202,13 @@ func (o *MigrateApplyOptions) Apply() (chan MigrateApplyResult, error) {
return "", nil
}
if len(o.Source.Name) == 0 {
if len(o.Source.Name) == 0 && !o.EC.AllDatabases {
o.Source = o.EC.Source
}
if err := o.Validate(); err != nil {
return nil, err
}
if o.AllDatabases && o.EC.Config.Version >= cli.V3 {
if o.EC.AllDatabases && o.EC.Config.Version >= cli.V3 {
o.EC.Spin("getting lists of databases from server ")
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
o.EC.Spinner.Stop()
@ -264,7 +263,7 @@ func (o *MigrateApplyOptions) Exec() error {
return &errDatabaseMigrationDirectoryNotFound{fmt.Sprintf("expected to find a migrations directory for database %s in %s, but encountered error: %s", o.Source.Name, o.EC.MigrationDir, err.Error())}
}
}
if o.AllDatabases && (len(o.GotoVersion) > 0 || len(o.VersionMigration) > 0) {
if o.EC.AllDatabases && (len(o.GotoVersion) > 0 || len(o.VersionMigration) > 0) {
return fmt.Errorf("cannot use --goto or --version in conjunction with --all-databases")
}
migrationType, step, err := getMigrationTypeAndStep(o.UpMigration, o.DownMigration, o.VersionMigration, o.MigrationType, o.GotoVersion, o.SkipExecution)

View File

@ -7,7 +7,6 @@ import (
"strings"
"github.com/Pallinder/go-randomdata"
"golang.org/x/term"
"github.com/hasura/graphql-engine/cli/v2/internal/testutil"
. "github.com/onsi/ginkgo"
@ -218,11 +217,7 @@ var testProgressBar = func(projectDirectory string) {
WorkingDirectory: projectDirectory,
})
if !term.IsTerminal(int(os.Stdout.Fd())) {
Eventually(session.Err, 60*40).ShouldNot(Say(progressBar))
} else {
Eventually(session.Err, 60*40).Should(Say(progressBar))
}
Eventually(session, 60*40).Should(Exit(0))
})
}

View File

@ -6,6 +6,7 @@ import (
"strconv"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/migrate"
mig "github.com/hasura/graphql-engine/cli/v2/migrate/cmd"
"github.com/hasura/graphql-engine/cli/v2/util"
@ -28,7 +29,7 @@ func newMigrateDeleteCmd(ec *cli.ExecutionContext) *cobra.Command {
SilenceUsage: true,
PreRunE: func(cmd *cobra.Command, args []string) error {
ec.Logger.Warn("[PREVIEW] this command is in preview. usage may change in future\n")
if err := validateConfigV3Flags(cmd, ec); err != nil {
if err := validateConfigV3FlagsWithAll(cmd, ec); err != nil {
return err
}
if !cmd.Flags().Changed("all") && !cmd.Flags().Changed("version") {
@ -52,21 +53,17 @@ func newMigrateDeleteCmd(ec *cli.ExecutionContext) *cobra.Command {
}
}
opts.Source = ec.Source
if ec.Config.Version >= cli.V3 {
var err error
opts.EC.Spin("Removing migrations")
err = opts.Run()
opts.EC.Spinner.Stop()
if ec.AllDatabases && !opts.force {
confirmation, err := util.GetYesNoPrompt("clear all mentioned migrations of all databases and it's history on the server?")
if err != nil {
return fmt.Errorf("operation failed: %w", err)
return fmt.Errorf("error getting user input: %w", err)
}
return err
if !confirmation {
return nil
}
opts.EC.Spin("Removing migrations")
err := opts.Run()
opts.EC.Spinner.Stop()
if err != nil {
}
if err := opts.Run(); err != nil {
return fmt.Errorf("operation failed: %w", err)
}
return nil
@ -93,6 +90,27 @@ type MigrateDeleteOptions struct {
}
func (o *MigrateDeleteOptions) Run() error {
o.EC.Spin("Removing migrations")
defer o.EC.Spinner.Stop()
if ec.AllDatabases {
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return fmt.Errorf("got error while getting the sources list : %v", err)
}
for _, source := range sourcesAndKind {
o.Source = cli.Source(source)
err := o.RunOnSource()
if err != nil {
return fmt.Errorf("error while deleting status for database %s: %v", o.Source.Name, err)
}
}
return nil
}
o.Source = ec.Source
return o.RunOnSource()
}
func (o *MigrateDeleteOptions) RunOnSource() error {
o.EC.Spin("Deleting migration...")
migrateDrv, err := migrate.NewMigrate(o.EC, true, o.Source.Name, o.Source.Kind)

View File

@ -6,6 +6,7 @@ import (
"text/tabwriter"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/util"
@ -18,6 +19,7 @@ import (
func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
opts := &MigrateStatusOptions{
EC: ec,
StatusOpts: make(StatusOptions),
}
migrateStatusCmd := &cobra.Command{
Use: "status",
@ -29,17 +31,13 @@ func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
hasura migrate status --endpoint "<endpoint>"`,
SilenceUsage: true,
PreRunE: func(cmd *cobra.Command, args []string) error {
return validateConfigV3Flags(cmd, ec)
return validateConfigV3FlagsWithAll(cmd, ec)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.EC.Spin("Fetching migration status...")
opts.Source = ec.Source
status, err := opts.Run()
opts.EC.Spinner.Stop()
if err != nil {
if err := opts.Run(); err != nil {
return err
}
buf := printStatus(status)
buf := printStatus(opts.StatusOpts)
fmt.Fprintf(ec.Stdout, "%s", buf)
return nil
},
@ -47,12 +45,41 @@ func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
return migrateStatusCmd
}
func (o *MigrateStatusOptions) Run() error {
o.EC.Spin("Fetching migration status...")
defer o.EC.Spinner.Stop()
if ec.AllDatabases {
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return fmt.Errorf("got error while getting the sources list : %v", err)
}
for _, source := range sourcesAndKind {
o.Source = cli.Source(source)
status, err := o.RunOnSource()
if err != nil {
return fmt.Errorf("error getting status for database %s: %v", o.Source.Name, err)
}
o.StatusOpts[o.Source] = status
}
return err
}
o.Source = ec.Source
status, err := o.RunOnSource()
if err != nil {
return fmt.Errorf("error getting status for database %s: %v", o.Source.Name, err)
}
o.StatusOpts[o.Source] = status
return err
}
type StatusOptions map[cli.Source]*migrate.Status
type MigrateStatusOptions struct {
EC *cli.ExecutionContext
Source cli.Source
StatusOpts StatusOptions
}
func (o *MigrateStatusOptions) Run() (*migrate.Status, error) {
func (o *MigrateStatusOptions) RunOnSource() (*migrate.Status, error) {
if o.EC.Config.Version <= cli.V2 {
o.Source.Name = ""
o.Source.Kind = hasura.SourceKindPG
@ -68,11 +95,15 @@ func (o *MigrateStatusOptions) Run() (*migrate.Status, error) {
return status, nil
}
func printStatus(status *migrate.Status) *bytes.Buffer {
func printStatus(statusOpts StatusOptions) *bytes.Buffer {
out := new(tabwriter.Writer)
buf := &bytes.Buffer{}
out.Init(buf, 0, 8, 2, ' ', 0)
w := util.NewPrefixWriter(out)
for source, status := range statusOpts {
if source.Name != "" {
w.Write(util.LEVEL_0, fmt.Sprintf("\nDatabase: %s\n", source.Name))
}
w.Write(util.LEVEL_0, "VERSION\tNAME\tSOURCE STATUS\tDATABASE STATUS\n")
for _, version := range status.Index {
w.Write(util.LEVEL_0, "%d\t%s\t%s\t%s\n",
@ -82,6 +113,7 @@ func printStatus(status *migrate.Status) *bytes.Buffer {
convertBool(status.Migrations[version].IsApplied),
)
}
}
out.Flush()
return buf
}

View File

@ -1,16 +1,10 @@
package commands
import (
"fmt"
"github.com/hasura/graphql-engine/cli/v2/seed"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/internal/scripts"
"github.com/hasura/graphql-engine/cli/v2/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
@ -32,44 +26,6 @@ func NewSeedCmd(ec *cli.ExecutionContext) *cobra.Command {
if err := ec.Validate(); err != nil {
return err
}
// for project using config older than v3, use PG source kind
if ec.Config.Version < cli.V3 {
ec.Source.Kind = hasura.SourceKindPG
if err := scripts.CheckIfUpdateToConfigV3IsRequired(ec); err != nil {
return err
}
return nil
}
// for project using config equal to or greater than v3
// database-name flag is required when running in non-terminal mode
if (!ec.IsTerminal || ec.Config.DisableInteractive) && !cmd.Flags().Changed("database-name") {
return errors.New("--database-name flag is required")
}
// prompt UI for choosing database if source name is not set
if ec.Source.Name == "" {
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return err
}
ec.Source.Name = databaseName
}
sourceKind, err := metadatautil.GetSourceKind(ec.APIClient.V1Metadata.ExportMetadata, ec.Source.Name)
if err != nil {
return err
}
if sourceKind == nil {
return fmt.Errorf("cannot determine source kind for %v", ec.Source.Name)
}
ec.Source.Kind = *sourceKind
// check if seed ops are supported for the database
if !seed.IsSeedsSupported(*sourceKind) {
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, *sourceKind)
}
return nil
},
}

View File

@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/seed"
)
@ -33,15 +34,33 @@ func newSeedApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
hasura seed apply --file seeds/1234_add_some_seed_data.sql`,
SilenceUsage: false,
PreRunE: func(cmd *cobra.Command, args []string) error {
return ec.Validate()
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
return err
}
if ec.Config.Version < cli.V3 {
return nil
}
if err := databaseChooserWithAllOption(ec); err != nil {
return err
}
if ec.AllDatabases {
return nil
}
if err := validateSourceInfo(ec); err != nil {
return err
}
// check if seed ops are supported for the database
if !seed.IsSeedsSupported(ec.Source.Kind) {
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.Driver = getSeedDriver(ec.Config.Version)
opts.EC.Spin("Applying seeds...")
opts.Source = ec.Source
err := opts.Run()
opts.EC.Spinner.Stop()
if err != nil {
if err := opts.Run(); err != nil {
return fmt.Errorf("operation failed \n%w", err)
}
opts.EC.Logger.Info("Seeds planted")
@ -53,6 +72,27 @@ func newSeedApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
}
func (o *SeedApplyOptions) Run() error {
fs := afero.NewOsFs()
return o.Driver.ApplySeedsToDatabase(fs, o.EC.SeedsDirectory, o.FileNames, o.EC.Source)
o.EC.Spin("Applying seeds...")
defer o.EC.Spinner.Stop()
if o.EC.AllDatabases {
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return fmt.Errorf("got error while getting the sources list : %v", err)
}
for _, source := range sourcesAndKind {
o.Source = cli.Source(source)
err := o.ApplyOnSource()
if err != nil {
return fmt.Errorf("error while applying seeds for database %s: %v", o.Source.Name, err)
}
}
return nil
}
o.Source = o.EC.Source
return o.ApplyOnSource()
}
func (o *SeedApplyOptions) ApplyOnSource() error {
fs := afero.NewOsFs()
return o.Driver.ApplySeedsToDatabase(fs, o.EC.SeedsDirectory, o.FileNames, o.Source)
}

View File

@ -50,7 +50,25 @@ func newSeedCreateCmd(ec *cli.ExecutionContext) *cobra.Command {
Args: cobra.ExactArgs(1),
SilenceUsage: false,
PreRunE: func(cmd *cobra.Command, args []string) error {
return ec.Validate()
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
return err
}
if ec.Config.Version < cli.V3 {
return nil
}
if err := databaseChooser(ec); err != nil {
return err
}
if err := validateSourceInfo(ec); err != nil {
return err
}
// check if seed ops are supported for the database
if !seed.IsSeedsSupported(ec.Source.Kind) {
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.SeedName = args[0]

View File

@ -187,7 +187,7 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) {
EC: ec,
Source: cli.Source{Name: "", Kind: hasura.SourceKindPG},
}
actualStatus, err := statusOpts.Run()
actualStatus, err := statusOpts.RunOnSource()
if err != nil {
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
}

View File

@ -107,7 +107,7 @@ func TestDeployCmd(t *testing.T, ec *cli.ExecutionContext) {
EC: ec,
Source: cli.Source{Name: "default", Kind: hasura.SourceKindPG},
}
actualStatus, err := statusOpts.Run()
actualStatus, err := statusOpts.RunOnSource()
if err != nil {
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
}

View File

@ -188,7 +188,7 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) {
EC: ec,
Source: cli.Source{Name: "default", Kind: hasura.SourceKindPG},
}
actualStatus, err := statusOpts.Run()
actualStatus, err := statusOpts.RunOnSource()
if err != nil {
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
}

View File

@ -139,3 +139,22 @@ func DatabaseChooserUI(exportMetadata func() (io.Reader, error)) (string, error)
return databaseName, nil
}
const ChooseAllDatabases = "All (all available databases)"
func DatabaseChooserUIWithAll(exportMetadata func() (io.Reader, error)) (string, error) {
sources, err := GetSources(exportMetadata)
if err != nil {
return "", fmt.Errorf("unable to get available databases: %w", err)
}
if len(sources) == 0 {
return "", errors.New("no connected databases found in the server")
}
sources = append([]string{ChooseAllDatabases}, sources...)
databaseName, err := util.GetSelectPrompt("Select a database to use", sources)
if err != nil {
return "", fmt.Errorf("error in selecting a database to use: %w", err)
}
return databaseName, nil
}

View File

@ -19,7 +19,7 @@ type ProjectMigrationApplierOption func(applier *projectMigrationsApplier)
func ApplyOnAllDatabases() ProjectMigrationApplierOption {
return func(p *projectMigrationsApplier) {
p.opts.AllDatabases = true
p.opts.EC.AllDatabases = true
}
}

View File

@ -41,7 +41,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) (
Kind: source.Kind,
},
}
status, err := opts.Run()
status, err := opts.RunOnSource()
if err != nil {
return nil, err
}