Skip to content

Commit

Permalink
feat: add schema sql generated optionally
Browse files Browse the repository at this point in the history
- better logging support
- possibility to migrate using schema.sql (for fresh installs)
- dump the schema via amigo schema
- dump the schema via migrate/rollback cmd (-d flag)
- update documentation
  • Loading branch information
alexisvisco committed Nov 8, 2024
1 parent 631d00b commit 037e60e
Show file tree
Hide file tree
Showing 30 changed files with 880 additions and 580 deletions.
9 changes: 4 additions & 5 deletions cmd/create.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"bytes"
"fmt"
"path"
"path/filepath"
Expand Down Expand Up @@ -35,12 +36,13 @@ var createCmd = &cobra.Command{
inUp := ""

if cmdCtx.Create.Dump {
dump, err := am.DumpSchema()
buffer := &bytes.Buffer{}
err := am.DumpSchema(buffer, true)
if err != nil {
return err
}

inUp += fmt.Sprintf("s.Exec(`%s`)\n", dump)
inUp += fmt.Sprintf("s.Exec(`%s`)\n", buffer.String())

cmdCtx.Create.Type = "classic"
}
Expand Down Expand Up @@ -107,9 +109,6 @@ func init() {
createCmd.Flags().BoolVarP(&cmdCtx.Create.Dump, "dump", "d", false,
"dump with pg_dump the current schema and add it to the current migration")

createCmd.Flags().StringVarP(&cmdCtx.Create.DumpSchema, "dump-schema", "s", "public",
"the schema to dump if --dump is set")

createCmd.Flags().StringVar(&cmdCtx.Create.SQLSeparator, "sql-separator", "-- migrate:down",
"the separator to split the up and down part of the migration")

Expand Down
11 changes: 10 additions & 1 deletion cmd/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ var migrateCmd = &cobra.Command{
return err
}

return am.ExecuteMain(amigo.MainArgMigrate)
if err := am.ExecuteMain(amigo.MainArgMigrate); err != nil {
return err
}

return nil
}),
}

Expand Down Expand Up @@ -43,10 +47,15 @@ func init() {
cmd.Flags().BoolVar(&m.ContinueOnError, "continue-on-error", false,
"Will not rollback the migration if an error occurs")
cmd.Flags().DurationVar(&m.Timeout, "timeout", amigoctx.DefaultTimeout, "The timeout for the migration")
cmd.Flags().BoolVarP(&m.DumpSchemaAfter, "dump-schema-after", "d", false,
"Dump schema after migrate/rollback (not compatible with --use-schema-dump)")
}

registerBase(migrateCmd, cmdCtx.Migration)
migrateCmd.Flags().BoolVar(&cmdCtx.Migration.UseSchemaDump, "use-schema-dump", false,
"Use the schema file to apply the migration (for fresh install without any migration)")

registerBase(rollbackCmd, cmdCtx.Migration)
rollbackCmd.Flags().IntVar(&cmdCtx.Migration.Steps, "steps", 1, "The number of steps to rollback")

}
23 changes: 19 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var rootCmd = &cobra.Command{
Long: `Basic usage:
First you need to create a main folder with amigo init:
will create a folder in migrations/db with a context file inside to not have to pass the dsn every time.
will create a folder in db with a context file inside to not have to pass the dsn every time.
Postgres:
$ amigo context --dsn "postgres://user:password@host:port/dbname?sslmode=disable"
Expand Down Expand Up @@ -92,9 +92,15 @@ func init() {
rootCmd.PersistentFlags().BoolVar(&cmdCtx.ShowSQLSyntaxHighlighting, "sql-syntax-highlighting", true,
"Print SQL queries with syntax highlighting")

rootCmd.Flags().StringVar(&cmdCtx.PGDumpPath, "pg-dump-path", amigoctx.DefaultPGDumpPath,
rootCmd.PersistentFlags().StringVar(&cmdCtx.SchemaOutPath, "schema-out-path", amigoctx.DefaultSchemaOutPath,
"File path of the schema dump if any")

rootCmd.PersistentFlags().StringVar(&cmdCtx.PGDumpPath, "pg-dump-path", amigoctx.DefaultPGDumpPath,
"Path to the pg_dump command if --dump is set")

rootCmd.PersistentFlags().StringVar(&cmdCtx.SchemaDBDumpSchema, "schema-db-dump-schema",
amigoctx.DefaultDBDumpSchema, "Schema to use when dumping schema")

rootCmd.PersistentFlags().BoolVar(&cmdCtx.Debug, "debug", false, "Print debug information")
initConfig()
}
Expand Down Expand Up @@ -122,7 +128,8 @@ func initConfig() {
_ = viper.BindPFlag("pg-dump-path", createCmd.Flags().Lookup("pg-dump-path"))
_ = viper.BindPFlag("sql", rootCmd.PersistentFlags().Lookup("sql"))
_ = viper.BindPFlag("sql-syntax-highlighting", rootCmd.PersistentFlags().Lookup("sql-syntax-highlighting"))

_ = viper.BindPFlag("schema-out-path", rootCmd.Flags().Lookup("schema-out-path"))
_ = viper.BindPFlag("schema-db-dump-schema", rootCmd.Flags().Lookup("schema-db-dump-schema"))
_ = viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug"))

viper.SetConfigFile(filepath.Join(cmdCtx.AmigoFolderPath, contextFileName))
Expand Down Expand Up @@ -171,12 +178,20 @@ func initConfig() {
if viper.IsSet("debug") {
cmdCtx.Debug = viper.GetBool("debug")
}

if viper.IsSet("schema-out-path") {
cmdCtx.SchemaOutPath = viper.GetString("schema-out-path")
}

if viper.IsSet("schema-db-dump-schema") {
cmdCtx.SchemaDBDumpSchema = viper.GetString("schema-db-dump-schema")
}
}

func wrapCobraFunc(f func(cmd *cobra.Command, am amigo.Amigo, args []string) error) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
am := amigo.NewAmigo(cmdCtx)
am.SetupSlog(os.Stdout)
am.SetupSlog(os.Stdout, nil)

if err := f(cmd, am, args); err != nil {
logger.Error(events.MessageEvent{Message: err.Error()})
Expand Down
48 changes: 48 additions & 0 deletions cmd/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cmd

import (
"fmt"
"path"

"github.com/alexisvisco/amigo/pkg/amigo"
"github.com/alexisvisco/amigo/pkg/utils"
"github.com/alexisvisco/amigo/pkg/utils/events"
"github.com/alexisvisco/amigo/pkg/utils/logger"
"github.com/spf13/cobra"
)

var schemaCmd = &cobra.Command{
Use: "schema",
Short: "Dump the schema of the database using appropriate tool",
Long: `Dump the schema of the database using appropriate tool.
Supported databases:
- postgres with pg_dump`,
Run: wrapCobraFunc(func(cmd *cobra.Command, am amigo.Amigo, args []string) error {
if err := cmdCtx.ValidateDSN(); err != nil {
return err
}

return dumpSchema(am)
}),
}

func dumpSchema(am amigo.Amigo) error {
file, err := utils.CreateOrOpenFile(cmdCtx.SchemaOutPath)
if err != nil {
return fmt.Errorf("unable to open/create file: %w", err)
}

defer file.Close()

err = am.DumpSchema(file, false)
if err != nil {
return fmt.Errorf("unable to dump schema: %w", err)
}

logger.Info(events.FileModifiedEvent{FileName: path.Join(cmdCtx.SchemaOutPath)})
return nil
}

func init() {
rootCmd.AddCommand(schemaCmd)
}
2 changes: 1 addition & 1 deletion docs/docs/02-quick-start/02-initialize.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

To start using mig, you need to initialize it. This process creates few things:
- A `migrations` folder where you will write your migrations.
- A `migrations/db` folder where mig stores its configuration and the main file to run migrations.
- A `db/migrations` folder where mig stores its configuration and the main file to run migrations.
- A migration file to setup the table that will store the migration versions.

To initialize mig, run the following command:
Expand Down
Loading

0 comments on commit 037e60e

Please sign in to comment.