From 9964381208bb09a8eb3d844f8bc0f0fa01167564 Mon Sep 17 00:00:00 2001 From: vinit717 Date: Wed, 8 May 2024 09:42:40 +0530 Subject: [PATCH 1/3] add auto migration --- main.go | 7 ++++ migrations/20230912194711_init.down.sql | 8 ++++ utils/migration.go | 52 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 utils/migration.go diff --git a/main.go b/main.go index bf38aa0..8acb1d7 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,13 @@ func main() { os.Exit(1) } + migrationsDir := "./migrations" + if err := utils.ApplyMigrations(db, migrationsDir); err != nil { + log.Fatalf("failed to apply migrations: %v", err) + os.Exit(1) + } + + port := flag.String("port", os.Getenv("PORT"), "server address to listen on") flag.Parse() diff --git a/migrations/20230912194711_init.down.sql b/migrations/20230912194711_init.down.sql index c99ddcd..cc684e6 100644 --- a/migrations/20230912194711_init.down.sql +++ b/migrations/20230912194711_init.down.sql @@ -1 +1,9 @@ +BEGIN; + +-- Check and drop the tiny_url table first if it exists. +DROP TABLE IF EXISTS tiny_url; + +-- Now it is safe to drop the users table. DROP TABLE IF EXISTS users; + +COMMIT; diff --git a/utils/migration.go b/utils/migration.go new file mode 100644 index 0000000..deee895 --- /dev/null +++ b/utils/migration.go @@ -0,0 +1,52 @@ +package utils + +import ( + "log" + "os" + "path/filepath" + "strings" + + "github.com/uptrace/bun" +) + +func ApplyMigrations(db *bun.DB, migrationsDir string) error { + log.Println("Starting migration process...") + files, err := os.ReadDir(migrationsDir) + if err != nil { + log.Printf("Error reading migration directory: %v", err) + return err + } + + for _, file := range files { + if !file.IsDir() && strings.HasSuffix(file.Name(), ".sql") { + log.Printf("Applying migration from file: %s", file.Name()) + content, err := os.ReadFile(filepath.Join(migrationsDir, file.Name())) + if err != nil { + log.Printf("Error reading file %s: %v", file.Name(), err) + return err + } + + tx, err := db.Begin() + if err != nil { + log.Printf("Error starting transaction: %v", err) + return err + } + + _, err = tx.Exec(string(content)) + if err != nil { + tx.Rollback() + log.Printf("Error executing migration %s: %v", file.Name(), err) + return err + } + + err = tx.Commit() + if err != nil { + log.Printf("Error committing transaction for %s: %v", file.Name(), err) + return err + } + log.Printf("Successfully applied migration: %s", file.Name()) + } + } + log.Println("Migration process completed successfully.") + return nil +} From 3712611e96ad5e3ad78d35ae3e35232f950fad19 Mon Sep 17 00:00:00 2001 From: vinit717 Date: Tue, 14 May 2024 10:46:26 +0530 Subject: [PATCH 2/3] fix auto migration by bun --- cmd/bun/main.go | 4 +- main.go | 28 ++++++------- migrations/20230912194711_init.down.sql | 8 ---- utils/migration.go | 52 ------------------------- 4 files changed, 14 insertions(+), 78 deletions(-) delete mode 100644 utils/migration.go diff --git a/cmd/bun/main.go b/cmd/bun/main.go index a9f2836..0a8d977 100644 --- a/cmd/bun/main.go +++ b/cmd/bun/main.go @@ -1,4 +1,4 @@ -package main +package migration import ( "fmt" @@ -13,7 +13,7 @@ import ( "github.com/urfave/cli/v2" ) -func main() { +func RunMigrations() { currentDir, err := os.Getwd() if err != nil { diff --git a/main.go b/main.go index 8acb1d7..b7727d5 100644 --- a/main.go +++ b/main.go @@ -5,28 +5,24 @@ import ( "log" "os" + migration "github.com/Real-Dev-Squad/tiny-site-backend/cmd/bun" "github.com/Real-Dev-Squad/tiny-site-backend/routes" "github.com/Real-Dev-Squad/tiny-site-backend/utils" ) func main() { - utils.LoadEnv(".env") - dsn := os.Getenv("DB_URL") - db, err := utils.SetupDBConnection(dsn) - if err != nil { - log.Fatalf("failed to connect to the database: %v", err) - os.Exit(1) - } + utils.LoadEnv(".env") + dsn := os.Getenv("DB_URL") + db, err := utils.SetupDBConnection(dsn) + if err != nil { + log.Fatalf("failed to connect to the database: %v", err) + os.Exit(1) + } - migrationsDir := "./migrations" - if err := utils.ApplyMigrations(db, migrationsDir); err != nil { - log.Fatalf("failed to apply migrations: %v", err) - os.Exit(1) - } + migration.RunMigrations() + port := flag.String("port", os.Getenv("PORT"), "server address to listen on") + flag.Parse() - port := flag.String("port", os.Getenv("PORT"), "server address to listen on") - flag.Parse() - - routes.Listen("0.0.0.0:"+*port, db) + routes.Listen("0.0.0.0:"+*port, db) } diff --git a/migrations/20230912194711_init.down.sql b/migrations/20230912194711_init.down.sql index cc684e6..c99ddcd 100644 --- a/migrations/20230912194711_init.down.sql +++ b/migrations/20230912194711_init.down.sql @@ -1,9 +1 @@ -BEGIN; - --- Check and drop the tiny_url table first if it exists. -DROP TABLE IF EXISTS tiny_url; - --- Now it is safe to drop the users table. DROP TABLE IF EXISTS users; - -COMMIT; diff --git a/utils/migration.go b/utils/migration.go deleted file mode 100644 index deee895..0000000 --- a/utils/migration.go +++ /dev/null @@ -1,52 +0,0 @@ -package utils - -import ( - "log" - "os" - "path/filepath" - "strings" - - "github.com/uptrace/bun" -) - -func ApplyMigrations(db *bun.DB, migrationsDir string) error { - log.Println("Starting migration process...") - files, err := os.ReadDir(migrationsDir) - if err != nil { - log.Printf("Error reading migration directory: %v", err) - return err - } - - for _, file := range files { - if !file.IsDir() && strings.HasSuffix(file.Name(), ".sql") { - log.Printf("Applying migration from file: %s", file.Name()) - content, err := os.ReadFile(filepath.Join(migrationsDir, file.Name())) - if err != nil { - log.Printf("Error reading file %s: %v", file.Name(), err) - return err - } - - tx, err := db.Begin() - if err != nil { - log.Printf("Error starting transaction: %v", err) - return err - } - - _, err = tx.Exec(string(content)) - if err != nil { - tx.Rollback() - log.Printf("Error executing migration %s: %v", file.Name(), err) - return err - } - - err = tx.Commit() - if err != nil { - log.Printf("Error committing transaction for %s: %v", file.Name(), err) - return err - } - log.Printf("Successfully applied migration: %s", file.Name()) - } - } - log.Println("Migration process completed successfully.") - return nil -} From 255b5f7ba386716e65ae084f29fe9ac231e572aa Mon Sep 17 00:00:00 2001 From: vinit717 Date: Wed, 22 May 2024 22:50:25 +0530 Subject: [PATCH 3/3] refactor automigration file --- cmd/bun/main.go | 89 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/cmd/bun/main.go b/cmd/bun/main.go index 0a8d977..d941aed 100644 --- a/cmd/bun/main.go +++ b/cmd/bun/main.go @@ -1,6 +1,7 @@ package migration import ( + "context" "fmt" "log" "os" @@ -14,36 +15,72 @@ import ( ) func RunMigrations() { + currentDir, err := os.Getwd() + if err != nil { + panic(err) + } + + envFilePath := filepath.Join(currentDir, ".env") + utils.LoadEnv(envFilePath) + dsn := os.Getenv("DB_URL") + + db, err := utils.SetupDBConnection(dsn) + if err != nil { + log.Fatalf("failed to connect to the database: %v", err) + os.Exit(1) + } + defer db.Close() + + migrator := migrate.NewMigrator(db, migrations.Migrations) + + err = migrator.Init(context.Background()) + if err != nil { + log.Fatalf("failed to initialize migration tables: %v", err) + } + + err = runMigrate(migrator) + if err != nil { + log.Fatalf("failed to run migrations: %v", err) + } +} - currentDir, err := os.Getwd() - if err != nil { - panic(err) - } - - envFilePath := filepath.Join(currentDir, ".env") - - utils.LoadEnv(envFilePath) +func runMigrate(migrator *migrate.Migrator) error { + ctx := context.Background() + if err := migrator.Lock(ctx); err != nil { + return err + } + defer migrator.Unlock(ctx) // nolint: errcheck + + group, err := migrator.Migrate(ctx) + if err != nil { + return err + } + if group.IsZero() { + fmt.Println("there are no new migrations to run (database is up to date)") + return nil + } + fmt.Printf("migrated to %s\n", group) + return nil +} - dsn := os.Getenv("DB_URL") +func RegisterCLICommands() *cli.App { + dsn := os.Getenv("DB_URL") + db, err := utils.SetupDBConnection(dsn) + if err != nil { + log.Fatalf("failed to connect to the database: %v", err) + } + defer db.Close() - db, err := utils.SetupDBConnection(dsn) - if err != nil { - log.Fatalf("failed to connect to the database: %v", err) - os.Exit(1) - } + migrator := migrate.NewMigrator(db, migrations.Migrations) - app := &cli.App{ - Name: "bun", + app := &cli.App{ + Name: "bun", + Commands: []*cli.Command{ + newDBCommand(migrator), + }, + } - Commands: []*cli.Command{ - newDBCommand(migrate.NewMigrator(db, migrations.Migrations)), - }, - } - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - } - - defer db.Close() + return app } func newDBCommand(migrator *migrate.Migrator) *cli.Command { @@ -193,4 +230,4 @@ func newDBCommand(migrator *migrate.Migrator) *cli.Command { }, }, } -} +} \ No newline at end of file