dex/vendor/github.com/rubenv/sql-migrate/migrate_test.go
2016-04-08 11:56:29 -07:00

357 lines
9.5 KiB
Go

package migrate
import (
"database/sql"
"os"
_ "github.com/mattn/go-sqlite3"
. "gopkg.in/check.v1"
"gopkg.in/gorp.v1"
)
var filename = "/tmp/sql-migrate-sqlite.db"
var sqliteMigrations = []*Migration{
&Migration{
Id: "123",
Up: []string{"CREATE TABLE people (id int)"},
Down: []string{"DROP TABLE people"},
},
&Migration{
Id: "124",
Up: []string{"ALTER TABLE people ADD COLUMN first_name text"},
Down: []string{"SELECT 0"}, // Not really supported
},
}
type SqliteMigrateSuite struct {
Db *sql.DB
DbMap *gorp.DbMap
}
var _ = Suite(&SqliteMigrateSuite{})
func (s *SqliteMigrateSuite) SetUpTest(c *C) {
db, err := sql.Open("sqlite3", filename)
c.Assert(err, IsNil)
s.Db = db
s.DbMap = &gorp.DbMap{Db: db, Dialect: &gorp.SqliteDialect{}}
}
func (s *SqliteMigrateSuite) TearDownTest(c *C) {
err := os.Remove(filename)
c.Assert(err, IsNil)
}
func (s *SqliteMigrateSuite) TestRunMigration(c *C) {
migrations := &MemoryMigrationSource{
Migrations: sqliteMigrations[:1],
}
// Executes one migration
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
// Can use table now
_, err = s.DbMap.Exec("SELECT * FROM people")
c.Assert(err, IsNil)
// Shouldn't apply migration again
n, err = Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 0)
}
func (s *SqliteMigrateSuite) TestMigrateMultiple(c *C) {
migrations := &MemoryMigrationSource{
Migrations: sqliteMigrations[:2],
}
// Executes two migrations
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Can use column now
_, err = s.DbMap.Exec("SELECT first_name FROM people")
c.Assert(err, IsNil)
}
func (s *SqliteMigrateSuite) TestMigrateIncremental(c *C) {
migrations := &MemoryMigrationSource{
Migrations: sqliteMigrations[:1],
}
// Executes one migration
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
// Execute a new migration
migrations = &MemoryMigrationSource{
Migrations: sqliteMigrations[:2],
}
n, err = Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
// Can use column now
_, err = s.DbMap.Exec("SELECT first_name FROM people")
c.Assert(err, IsNil)
}
func (s *SqliteMigrateSuite) TestFileMigrate(c *C) {
migrations := &FileMigrationSource{
Dir: "test-migrations",
}
// Executes two migrations
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Has data
id, err := s.DbMap.SelectInt("SELECT id FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(1))
}
func (s *SqliteMigrateSuite) TestAssetMigrate(c *C) {
migrations := &AssetMigrationSource{
Asset: Asset,
AssetDir: AssetDir,
Dir: "test-migrations",
}
// Executes two migrations
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Has data
id, err := s.DbMap.SelectInt("SELECT id FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(1))
}
func (s *SqliteMigrateSuite) TestMigrateMax(c *C) {
migrations := &FileMigrationSource{
Dir: "test-migrations",
}
// Executes one migration
n, err := ExecMax(s.Db, "sqlite3", migrations, Up, 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
id, err := s.DbMap.SelectInt("SELECT COUNT(*) FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(0))
}
func (s *SqliteMigrateSuite) TestMigrateDown(c *C) {
migrations := &FileMigrationSource{
Dir: "test-migrations",
}
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Has data
id, err := s.DbMap.SelectInt("SELECT id FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(1))
// Undo the last one
n, err = ExecMax(s.Db, "sqlite3", migrations, Down, 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
// No more data
id, err = s.DbMap.SelectInt("SELECT COUNT(*) FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(0))
// Remove the table.
n, err = ExecMax(s.Db, "sqlite3", migrations, Down, 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, 1)
// Cannot query it anymore
_, err = s.DbMap.SelectInt("SELECT COUNT(*) FROM people")
c.Assert(err, Not(IsNil))
// Nothing left to do.
n, err = ExecMax(s.Db, "sqlite3", migrations, Down, 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, 0)
}
func (s *SqliteMigrateSuite) TestMigrateDownFull(c *C) {
migrations := &FileMigrationSource{
Dir: "test-migrations",
}
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Has data
id, err := s.DbMap.SelectInt("SELECT id FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(1))
// Undo the last one
n, err = Exec(s.Db, "sqlite3", migrations, Down)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
// Cannot query it anymore
_, err = s.DbMap.SelectInt("SELECT COUNT(*) FROM people")
c.Assert(err, Not(IsNil))
// Nothing left to do.
n, err = Exec(s.Db, "sqlite3", migrations, Down)
c.Assert(err, IsNil)
c.Assert(n, Equals, 0)
}
func (s *SqliteMigrateSuite) TestMigrateTransaction(c *C) {
migrations := &MemoryMigrationSource{
Migrations: []*Migration{
sqliteMigrations[0],
sqliteMigrations[1],
&Migration{
Id: "125",
Up: []string{"INSERT INTO people (id, first_name) VALUES (1, 'Test')", "SELECT fail"},
Down: []string{}, // Not important here
},
},
}
// Should fail, transaction should roll back the INSERT.
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, Not(IsNil))
c.Assert(n, Equals, 2)
// INSERT should be rolled back
count, err := s.DbMap.SelectInt("SELECT COUNT(*) FROM people")
c.Assert(err, IsNil)
c.Assert(count, Equals, int64(0))
}
func (s *SqliteMigrateSuite) TestPlanMigration(c *C) {
migrations := &MemoryMigrationSource{
Migrations: []*Migration{
&Migration{
Id: "1_create_table.sql",
Up: []string{"CREATE TABLE people (id int)"},
Down: []string{"DROP TABLE people"},
},
&Migration{
Id: "2_alter_table.sql",
Up: []string{"ALTER TABLE people ADD COLUMN first_name text"},
Down: []string{"SELECT 0"}, // Not really supported
},
&Migration{
Id: "10_add_last_name.sql",
Up: []string{"ALTER TABLE people ADD COLUMN last_name text"},
Down: []string{"ALTER TABLE people DROP COLUMN last_name"},
},
},
}
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 3)
migrations.Migrations = append(migrations.Migrations, &Migration{
Id: "11_add_middle_name.sql",
Up: []string{"ALTER TABLE people ADD COLUMN middle_name text"},
Down: []string{"ALTER TABLE people DROP COLUMN middle_name"},
})
plannedMigrations, _, err := PlanMigration(s.Db, "sqlite3", migrations, Up, 0)
c.Assert(err, IsNil)
c.Assert(plannedMigrations, HasLen, 1)
c.Assert(plannedMigrations[0].Migration, Equals, migrations.Migrations[3])
plannedMigrations, _, err = PlanMigration(s.Db, "sqlite3", migrations, Down, 0)
c.Assert(err, IsNil)
c.Assert(plannedMigrations, HasLen, 3)
c.Assert(plannedMigrations[0].Migration, Equals, migrations.Migrations[2])
c.Assert(plannedMigrations[1].Migration, Equals, migrations.Migrations[1])
c.Assert(plannedMigrations[2].Migration, Equals, migrations.Migrations[0])
}
func (s *SqliteMigrateSuite) TestPlanMigrationWithHoles(c *C) {
up := "SELECT 0"
down := "SELECT 1"
migrations := &MemoryMigrationSource{
Migrations: []*Migration{
&Migration{
Id: "1",
Up: []string{up},
Down: []string{down},
},
&Migration{
Id: "3",
Up: []string{up},
Down: []string{down},
},
},
}
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)
migrations.Migrations = append(migrations.Migrations, &Migration{
Id: "2",
Up: []string{up},
Down: []string{down},
})
migrations.Migrations = append(migrations.Migrations, &Migration{
Id: "4",
Up: []string{up},
Down: []string{down},
})
migrations.Migrations = append(migrations.Migrations, &Migration{
Id: "5",
Up: []string{up},
Down: []string{down},
})
// apply all the missing migrations
plannedMigrations, _, err := PlanMigration(s.Db, "sqlite3", migrations, Up, 0)
c.Assert(err, IsNil)
c.Assert(plannedMigrations, HasLen, 3)
c.Assert(plannedMigrations[0].Migration.Id, Equals, "2")
c.Assert(plannedMigrations[0].Queries[0], Equals, up)
c.Assert(plannedMigrations[1].Migration.Id, Equals, "4")
c.Assert(plannedMigrations[1].Queries[0], Equals, up)
c.Assert(plannedMigrations[2].Migration.Id, Equals, "5")
c.Assert(plannedMigrations[2].Queries[0], Equals, up)
// first catch up to current target state 123, then migrate down 1 step to 12
plannedMigrations, _, err = PlanMigration(s.Db, "sqlite3", migrations, Down, 1)
c.Assert(err, IsNil)
c.Assert(plannedMigrations, HasLen, 2)
c.Assert(plannedMigrations[0].Migration.Id, Equals, "2")
c.Assert(plannedMigrations[0].Queries[0], Equals, up)
c.Assert(plannedMigrations[1].Migration.Id, Equals, "3")
c.Assert(plannedMigrations[1].Queries[0], Equals, down)
// first catch up to current target state 123, then migrate down 2 steps to 1
plannedMigrations, _, err = PlanMigration(s.Db, "sqlite3", migrations, Down, 2)
c.Assert(err, IsNil)
c.Assert(plannedMigrations, HasLen, 3)
c.Assert(plannedMigrations[0].Migration.Id, Equals, "2")
c.Assert(plannedMigrations[0].Queries[0], Equals, up)
c.Assert(plannedMigrations[1].Migration.Id, Equals, "3")
c.Assert(plannedMigrations[1].Queries[0], Equals, down)
c.Assert(plannedMigrations[2].Migration.Id, Equals, "2")
c.Assert(plannedMigrations[2].Queries[0], Equals, down)
}