@@ -3,6 +3,7 @@ package cmdopts
33import (
44 "context"
55 "errors"
6+ "fmt"
67
78 "github.com/cybertec-postgresql/pgwatch/v5/internal/db"
89 "github.com/cybertec-postgresql/pgwatch/v5/internal/metrics"
@@ -87,46 +88,62 @@ type ConfigUpgradeCommand struct {
8788// Execute upgrades the configuration schema.
8889func (cmd * ConfigUpgradeCommand ) Execute ([]string ) (err error ) {
8990 opts := cmd .owner
90- if err = opts .ValidateConfig (); err != nil {
91- return
91+ // For upgrade command, validate that at least one component is specified
92+ if len (opts .Sources .Sources )+ len (opts .Metrics .Metrics )+ len (opts .Sinks .Sinks ) == 0 {
93+ opts .CompleteCommand (ExitCodeConfigError )
94+ return errors .New ("at least one of --sources, --metrics, or --sink must be specified" )
9295 }
96+
9397 ctx := context .Background ()
94- // Upgrade metrics/sources configuration if it's postgres
95- if opts .IsPgConnStr (opts .Metrics .Metrics ) && opts .IsPgConnStr (opts .Sources .Sources ) {
96- err = opts .InitMetricReader (ctx )
97- if err != nil {
98- opts .CompleteCommand (ExitCodeConfigError )
99- return
98+
99+ f := func (uri string , newMigratorFunc func () (any , error )) error {
100+ if uri == "" {
101+ return nil
100102 }
101- if m , ok := opts .MetricsReaderWriter .(db.Migrator ); ok {
102- err = m .Migrate ()
103- if err != nil {
104- opts .CompleteCommand (ExitCodeConfigError )
105- return
106- }
103+ if ! opts .IsPgConnStr (uri ) {
104+ return fmt .Errorf ("cannot upgrade storage %s: %w" , uri , errors .ErrUnsupported )
107105 }
108- } else {
109- opts .CompleteCommand (ExitCodeConfigError )
110- return errors .New ("configuration storage does not support upgrade" )
111- }
112- // Upgrade sinks configuration if it's postgres
113- if len (opts .Sinks .Sinks ) > 0 {
114- opts .SinksWriter , err = sinks .NewSinkWriter (ctx , & opts .Sinks )
115- if err != nil {
116- opts .CompleteCommand (ExitCodeConfigError )
117- return
106+ m , initErr := newMigratorFunc ()
107+ if initErr != nil {
108+ return initErr
118109 }
119- if m , ok := opts .SinksWriter .(db.Migrator ); ok {
120- err = m .Migrate ()
121- if err != nil {
122- opts .CompleteCommand (ExitCodeConfigError )
123- return
124- }
125- } else {
126- opts .CompleteCommand (ExitCodeConfigError )
127- return errors .New ("sink storage does not support upgrade" )
110+ return m .(db.Migrator ).Migrate ()
111+
112+ }
113+
114+ err = f (opts .Sources .Sources , func () (any , error ) {
115+ return sources .NewPostgresSourcesReaderWriter (ctx , opts .Sources .Sources )
116+ })
117+
118+ err = errors .Join (err , f (opts .Metrics .Metrics , func () (any , error ) {
119+ return metrics .NewPostgresMetricReaderWriter (ctx , opts .Metrics .Metrics )
120+ }))
121+
122+ for _ , uri := range opts .Sinks .Sinks {
123+ err = errors .Join (err , f (uri , func () (any , error ) {
124+ return sinks .NewPostgresSinkMigrator (ctx , uri )
125+ }))
126+ }
127+
128+ if err == nil {
129+ opts .CompleteCommand (ExitCodeOK )
130+ return nil
131+ }
132+
133+ // Check if all errors are ErrUnsupported
134+ allUnsupported := true
135+ for _ , e := range err .(interface { Unwrap () []error }).Unwrap () {
136+ if ! errors .Is (e , errors .ErrUnsupported ) {
137+ allUnsupported = false
138+ break
128139 }
140+ fmt .Fprintln (opts .OutputWriter , e )
129141 }
130- opts .CompleteCommand (ExitCodeOK )
131- return
142+
143+ if allUnsupported {
144+ opts .CompleteCommand (ExitCodeOK )
145+ return nil
146+ }
147+ opts .CompleteCommand (ExitCodeConfigError )
148+ return err
132149}
0 commit comments