diff --git a/migrate.go b/migrate.go index e24f80a..2e3d8b2 100644 --- a/migrate.go +++ b/migrate.go @@ -153,7 +153,7 @@ func migrate(goal, crupath, driver, connStr string) { os.Exit(2) } defer db.Close() - checkForSchemaUpdateTable(db) + checkForSchemaUpdateTable(db, driver) latestName, latestTime := getLatestMigration(db, goal) writeMigrationSourceFile(dir, source, driver, connStr, latestTime, latestName, goal) buildMigrationBinary(dir, binary) @@ -164,20 +164,24 @@ func migrate(goal, crupath, driver, connStr string) { // checkForSchemaUpdateTable checks the existence of migrations table. // It checks for the proper table structures and creates the table using MYSQL_MIGRATION_DDL if it does not exist. -func checkForSchemaUpdateTable(db *sql.DB) { - if rows, err := db.Query("SHOW TABLES LIKE 'migrations'"); err != nil { +func checkForSchemaUpdateTable(db *sql.DB, driver string) { + showTableSql := showMigrationsTableSql(driver) + if rows, err := db.Query(showTableSql); err != nil { ColorLog("[ERRO] Could not show migrations table: %s\n", err) os.Exit(2) } else if !rows.Next() { // no migrations table, create anew + createTableSql := createMigrationsTableSql(driver) ColorLog("[INFO] Creating 'migrations' table...\n") - if _, err := db.Query(MYSQL_MIGRATION_DDL); err != nil { + if _, err := db.Query(createTableSql); err != nil { ColorLog("[ERRO] Could not create migrations table: %s\n", err) os.Exit(2) } } + // checking that migrations table schema are expected - if rows, err := db.Query("DESC migrations"); err != nil { + selectTableSql := selectMigrationsTableSql(driver) + if rows, err := db.Query(selectTableSql); err != nil { ColorLog("[ERRO] Could not show columns of migrations table: %s\n", err) os.Exit(2) } else { @@ -213,6 +217,39 @@ func checkForSchemaUpdateTable(db *sql.DB) { } } +func showMigrationsTableSql(driver string) string { + switch driver { + case "mysql": + return "SHOW TABLES LIKE 'migrations'" + case "postgres": + return "SELECT * FROM pg_catalog.pg_tables WHERE tablename = 'migrations';" + default: + return "SHOW TABLES LIKE 'migrations'" + } +} + +func createMigrationsTableSql(driver string) string { + switch driver { + case "mysql": + return MYSQL_MIGRATION_DDL + case "postgres": + return POSTGRES_MIGRATION_DDL + default: + return MYSQL_MIGRATION_DDL + } +} + +func selectMigrationsTableSql(driver string) string { + switch driver { + case "mysql": + return "DESC migrations" + case "postgres": + return "SELECT * FROM migrations ORDER BY id_migration;" + default: + return "DESC migrations" + } +} + // getLatestMigration retrives latest migration with status 'update' func getLatestMigration(db *sql.DB, goal string) (file string, createdAt int64) { sql := "SELECT name FROM migrations where status = 'update' ORDER BY id_migration DESC LIMIT 1" @@ -339,6 +376,7 @@ import( "github.com/astaxie/beego/migration" _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" ) func init(){ @@ -379,4 +417,16 @@ CREATE TABLE migrations ( PRIMARY KEY (id_migration) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ` + + POSTGRES_MIGRATION_DDL = ` +CREATE TYPE migrations_status AS ENUM('update', 'rollback'); + +CREATE TABLE migrations ( + id_migration SERIAL PRIMARY KEY, + name varchar(255) DEFAULT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + statements text, + rollback_statements text, + status migrations_status +)` )