package plugins
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("migrateDB", func() {
var db *sql.DB
BeforeEach(func() {
var err error
db, err = sql.Open("sqlite3", ":memory:")
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
if db != nil {
db.Close()
}
})
getUserVersion := func() int {
var version int
Expect(db.QueryRow(`PRAGMA user_version`).Scan(&version)).To(Succeed())
return version
}
It("applies all migrations on a fresh database", func() {
migrations := []string{
`CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)`,
`ALTER TABLE test ADD COLUMN email TEXT`,
}
Expect(migrateDB(db, migrations)).To(Succeed())
Expect(getUserVersion()).To(Equal(2))
_, err := db.Exec(`INSERT INTO test (id, name, email) VALUES (1, 'Alice', 'alice@test.com')`)
Expect(err).ToNot(HaveOccurred())
})
It("skips already applied migrations", func() {
migrations1 := []string{
`CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)`,
}
Expect(migrateDB(db, migrations1)).To(Succeed())
Expect(getUserVersion()).To(Equal(1))
migrations2 := []string{
`CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)`,
`ALTER TABLE test ADD COLUMN email TEXT`,
}
Expect(migrateDB(db, migrations2)).To(Succeed())
Expect(getUserVersion()).To(Equal(2))
_, err := db.Exec(`INSERT INTO test (id, name, email) VALUES (1, 'Alice', 'alice@test.com')`)
Expect(err).ToNot(HaveOccurred())
})
It("is a no-op when all migrations are applied", func() {
migrations := []string{
`CREATE TABLE test (id INTEGER PRIMARY KEY)`,
}
Expect(migrateDB(db, migrations)).To(Succeed())
Expect(migrateDB(db, migrations)).To(Succeed())
Expect(getUserVersion()).To(Equal(1))
})
It("is a no-op with empty migrations slice", func() {
Expect(migrateDB(db, nil)).To(Succeed())
Expect(getUserVersion()).To(Equal(0))
})
It("rolls back on failure", func() {
migrations := []string{
`CREATE TABLE test (id INTEGER PRIMARY KEY)`,
`INVALID SQL STATEMENT`,
}
err := migrateDB(db, migrations)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("migration 2 failed"))
Expect(getUserVersion()).To(Equal(0))
_, err = db.Exec(`INSERT INTO test (id) VALUES (1)`)
Expect(err).To(HaveOccurred())
})
})