db: make migrations a struct instead of a plain string
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
|||||||
var sql_schema string
|
var sql_schema string
|
||||||
|
|
||||||
// Database starts at version 0. First migration brings us to version 1
|
// Database starts at version 0. First migration brings us to version 1
|
||||||
var MIGRATIONS = []string{}
|
var MIGRATIONS = []db.Migration{}
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ type DBConfig struct {
|
|||||||
sql_schema *string
|
sql_schema *string
|
||||||
|
|
||||||
// Database starts at version 0. First migration brings us to version 1
|
// Database starts at version 0. First migration brings us to version 1
|
||||||
migrations *[]string
|
migrations *[]Migration
|
||||||
version_number uint
|
version_number uint
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init(schema *string, migrationsList *[]string) DBConfig {
|
func Init(schema *string, migrationsList *[]Migration) DBConfig {
|
||||||
return DBConfig{
|
return DBConfig{
|
||||||
sql_schema: schema,
|
sql_schema: schema,
|
||||||
migrations: migrationsList,
|
migrations: migrationsList,
|
||||||
@@ -99,7 +99,7 @@ func (c DBConfig) CheckAndUpdateVersion(db *sqlx.DB) error {
|
|||||||
func (c DBConfig) UpgradeFromXToY(db *sqlx.DB, x uint, y uint) {
|
func (c DBConfig) UpgradeFromXToY(db *sqlx.DB, x uint, y uint) {
|
||||||
for i := x; i < y; i++ {
|
for i := x; i < y; i++ {
|
||||||
fmt.Print(textutils.ColorCyan)
|
fmt.Print(textutils.ColorCyan)
|
||||||
fmt.Println((*c.migrations)[i])
|
fmt.Println((*c.migrations)[i].SQL)
|
||||||
fmt.Print(textutils.ColorReset)
|
fmt.Print(textutils.ColorReset)
|
||||||
|
|
||||||
// Execute the migration in a transaction
|
// Execute the migration in a transaction
|
||||||
@@ -107,7 +107,7 @@ func (c DBConfig) UpgradeFromXToY(db *sqlx.DB, x uint, y uint) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tx.MustExec((*c.migrations)[i])
|
tx.MustExec((*c.migrations)[i].SQL)
|
||||||
tx.MustExec("update db_version set version = ?", i+1)
|
tx.MustExec("update db_version set version = ?", i+1)
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func TestCreateAndConnectToDB(t *testing.T) {
|
|||||||
_schema_sql, err := os.ReadFile("../../sample_data/test_schemas/food.sql")
|
_schema_sql, err := os.ReadFile("../../sample_data/test_schemas/food.sql")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
schema_sql := string(_schema_sql)
|
schema_sql := string(_schema_sql)
|
||||||
migrations := []string{}
|
migrations := []db.Migration{}
|
||||||
|
|
||||||
config := db.Init(&schema_sql, &migrations)
|
config := db.Init(&schema_sql, &migrations)
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ func TestVersionUpgrade(t *testing.T) {
|
|||||||
create table db_version (version integer primary key) strict, without rowid;
|
create table db_version (version integer primary key) strict, without rowid;
|
||||||
insert into db_version values(0);
|
insert into db_version values(0);
|
||||||
`
|
`
|
||||||
migrations := []string{}
|
migrations := []db.Migration{}
|
||||||
config := db.Init(&initial_schema, &migrations)
|
config := db.Init(&initial_schema, &migrations)
|
||||||
|
|
||||||
connection, err := config.Create(":memory:")
|
connection, err := config.Create(":memory:")
|
||||||
@@ -61,7 +61,7 @@ func TestVersionUpgrade(t *testing.T) {
|
|||||||
require.Equal(0, get_version(connection))
|
require.Equal(0, get_version(connection))
|
||||||
|
|
||||||
// Create a migration to add a new Item
|
// Create a migration to add a new Item
|
||||||
migrations = append(migrations, "insert into items (rowid) values (1)")
|
migrations = append(migrations, db.Migration{ID: 1, SQL: "insert into items (rowid) values (1)"})
|
||||||
db.Init(&initial_schema, &migrations) // Reinitialize with the new migration
|
db.Init(&initial_schema, &migrations) // Reinitialize with the new migration
|
||||||
config.UpgradeFromXToY(connection, uint(len(migrations)-1), uint(len(migrations)))
|
config.UpgradeFromXToY(connection, uint(len(migrations)-1), uint(len(migrations)))
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ func TestVersionUpgrade(t *testing.T) {
|
|||||||
require.Equal(1, get_version(connection))
|
require.Equal(1, get_version(connection))
|
||||||
|
|
||||||
// Create a migration to add a new Item
|
// Create a migration to add a new Item
|
||||||
migrations = append(migrations, `alter table items add column name string default 'asdf'`)
|
migrations = append(migrations, db.Migration{ID: 2, SQL: `alter table items add column name string default 'asdf'`})
|
||||||
config = db.Init(&initial_schema, &migrations) // Reinitialize with the new migration
|
config = db.Init(&initial_schema, &migrations) // Reinitialize with the new migration
|
||||||
config.UpgradeFromXToY(connection, uint(len(migrations)-1), uint(len(migrations)))
|
config.UpgradeFromXToY(connection, uint(len(migrations)-1), uint(len(migrations)))
|
||||||
|
|
||||||
|
|||||||
12
pkg/db/migration.go
Normal file
12
pkg/db/migration.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
type Migration struct {
|
||||||
|
// ID is the version number that the schema will be at, after applying the migration.
|
||||||
|
ID int
|
||||||
|
|
||||||
|
// Title is an optional name for the migration.
|
||||||
|
Title string
|
||||||
|
|
||||||
|
// SQL is the body of the migration that will be executed.
|
||||||
|
SQL string
|
||||||
|
}
|
||||||
@@ -50,13 +50,13 @@ func TestVerifyCorrectMigration(t *testing.T) {
|
|||||||
db1Schema := schema.SchemaFromDB(db1)
|
db1Schema := schema.SchemaFromDB(db1)
|
||||||
|
|
||||||
t.Run("migrate in 1 step", func(t *testing.T) {
|
t.Run("migrate in 1 step", func(t *testing.T) {
|
||||||
migration := `
|
migration := db.Migration{ID: 1, SQL: `
|
||||||
create table t2 (
|
create table t2 (
|
||||||
rowid integer primary key
|
rowid integer primary key
|
||||||
);
|
);
|
||||||
alter table t1 add column data3 integer;
|
alter table t1 add column data3 integer;
|
||||||
`
|
`}
|
||||||
db2Config := db.Init(&baseSchema, &[]string{migration})
|
db2Config := db.Init(&baseSchema, &[]db.Migration{migration})
|
||||||
db2 := must.Get(db2Config.Create(":memory:"))
|
db2 := must.Get(db2Config.Create(":memory:"))
|
||||||
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
||||||
db2Schema := schema.SchemaFromDB(db2)
|
db2Schema := schema.SchemaFromDB(db2)
|
||||||
@@ -67,16 +67,16 @@ func TestVerifyCorrectMigration(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("migrate in 2 steps", func(t *testing.T) {
|
t.Run("migrate in 2 steps", func(t *testing.T) {
|
||||||
migration1 := `
|
migration1 := db.Migration{ID: 1, SQL: `
|
||||||
create table t2 (
|
create table t2 (
|
||||||
rowid integer primary key
|
rowid integer primary key
|
||||||
);
|
);
|
||||||
`
|
`}
|
||||||
migration2 := `
|
migration2 := db.Migration{ID: 2, SQL: `
|
||||||
alter table t1 add column data3 integer;
|
alter table t1 add column data3 integer;
|
||||||
`
|
`}
|
||||||
|
|
||||||
db2Config := db.Init(&baseSchema, &[]string{migration1, migration2})
|
db2Config := db.Init(&baseSchema, &[]db.Migration{migration1, migration2})
|
||||||
db2 := must.Get(db2Config.Create(":memory:"))
|
db2 := must.Get(db2Config.Create(":memory:"))
|
||||||
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
||||||
db2Schema := schema.SchemaFromDB(db2)
|
db2Schema := schema.SchemaFromDB(db2)
|
||||||
@@ -92,7 +92,7 @@ func TestIncorrectMigrations(t *testing.T) {
|
|||||||
db1Schema := schema.SchemaFromDB(db1)
|
db1Schema := schema.SchemaFromDB(db1)
|
||||||
|
|
||||||
t.Run("missing migration", func(t *testing.T) {
|
t.Run("missing migration", func(t *testing.T) {
|
||||||
db2Config := db.Init(&baseSchema, &[]string{})
|
db2Config := db.Init(&baseSchema, &[]db.Migration{})
|
||||||
db2 := must.Get(db2Config.Create(":memory:"))
|
db2 := must.Get(db2Config.Create(":memory:"))
|
||||||
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
||||||
db2Schema := schema.SchemaFromDB(db2)
|
db2Schema := schema.SchemaFromDB(db2)
|
||||||
@@ -109,11 +109,13 @@ func TestIncorrectMigrations(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("incomplete migration", func(t *testing.T) {
|
t.Run("incomplete migration", func(t *testing.T) {
|
||||||
db2Config := db.Init(&baseSchema, &[]string{`
|
db2Config := db.Init(&baseSchema, &[]db.Migration{
|
||||||
|
{ID: 1, SQL: `
|
||||||
create table t2 (
|
create table t2 (
|
||||||
rowid integer primary key
|
rowid integer primary key
|
||||||
);
|
);
|
||||||
`})
|
`},
|
||||||
|
})
|
||||||
db2 := must.Get(db2Config.Create(":memory:"))
|
db2 := must.Get(db2Config.Create(":memory:"))
|
||||||
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
||||||
db2Schema := schema.SchemaFromDB(db2)
|
db2Schema := schema.SchemaFromDB(db2)
|
||||||
@@ -130,12 +132,14 @@ func TestIncorrectMigrations(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("incorrect migration (wrong data type)", func(t *testing.T) {
|
t.Run("incorrect migration (wrong data type)", func(t *testing.T) {
|
||||||
db2Config := db.Init(&baseSchema, &[]string{`
|
db2Config := db.Init(&baseSchema, &[]db.Migration{
|
||||||
|
{ID: 1, SQL: `
|
||||||
create table t2 (
|
create table t2 (
|
||||||
rowid integer primary key
|
rowid integer primary key
|
||||||
);
|
);
|
||||||
alter table t1 add column data3 text;
|
alter table t1 add column data3 text;
|
||||||
`})
|
`},
|
||||||
|
})
|
||||||
db2 := must.Get(db2Config.Create(":memory:"))
|
db2 := must.Get(db2Config.Create(":memory:"))
|
||||||
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
require.NoError(t, db2Config.CheckAndUpdateVersion(db2))
|
||||||
db2Schema := schema.SchemaFromDB(db2)
|
db2Schema := schema.SchemaFromDB(db2)
|
||||||
|
|||||||
Reference in New Issue
Block a user