288 lines
8.5 KiB
Go
288 lines
8.5 KiB
Go
package pgsql
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
|
)
|
|
|
|
func TestWriteMigration_NewTable(t *testing.T) {
|
|
// Current database (empty)
|
|
current := models.InitDatabase("testdb")
|
|
currentSchema := models.InitSchema("public")
|
|
current.Schemas = append(current.Schemas, currentSchema)
|
|
|
|
// Model database (with new table)
|
|
model := models.InitDatabase("testdb")
|
|
modelSchema := models.InitSchema("public")
|
|
|
|
table := models.InitTable("users", "public")
|
|
idCol := models.InitColumn("id", "users", "public")
|
|
idCol.Type = "integer"
|
|
idCol.NotNull = true
|
|
table.Columns["id"] = idCol
|
|
|
|
nameCol := models.InitColumn("name", "users", "public")
|
|
nameCol.Type = "text"
|
|
table.Columns["name"] = nameCol
|
|
|
|
modelSchema.Tables = append(modelSchema.Tables, table)
|
|
model.Schemas = append(model.Schemas, modelSchema)
|
|
|
|
// Generate migration
|
|
var buf bytes.Buffer
|
|
writer := NewMigrationWriter(&writers.WriterOptions{})
|
|
writer.writer = &buf
|
|
|
|
err := writer.WriteMigration(model, current)
|
|
if err != nil {
|
|
t.Fatalf("WriteMigration failed: %v", err)
|
|
}
|
|
|
|
output := buf.String()
|
|
t.Logf("Generated migration:\n%s", output)
|
|
|
|
// Verify CREATE TABLE is present
|
|
if !strings.Contains(output, "CREATE TABLE") {
|
|
t.Error("Migration missing CREATE TABLE statement")
|
|
}
|
|
if !strings.Contains(output, "users") {
|
|
t.Error("Migration missing table name 'users'")
|
|
}
|
|
}
|
|
|
|
func TestWriteMigration_AddColumn(t *testing.T) {
|
|
// Current database (with table but missing column)
|
|
current := models.InitDatabase("testdb")
|
|
currentSchema := models.InitSchema("public")
|
|
currentTable := models.InitTable("users", "public")
|
|
|
|
idCol := models.InitColumn("id", "users", "public")
|
|
idCol.Type = "integer"
|
|
currentTable.Columns["id"] = idCol
|
|
|
|
currentSchema.Tables = append(currentSchema.Tables, currentTable)
|
|
current.Schemas = append(current.Schemas, currentSchema)
|
|
|
|
// Model database (with additional column)
|
|
model := models.InitDatabase("testdb")
|
|
modelSchema := models.InitSchema("public")
|
|
modelTable := models.InitTable("users", "public")
|
|
|
|
idCol2 := models.InitColumn("id", "users", "public")
|
|
idCol2.Type = "integer"
|
|
modelTable.Columns["id"] = idCol2
|
|
|
|
emailCol := models.InitColumn("email", "users", "public")
|
|
emailCol.Type = "text"
|
|
modelTable.Columns["email"] = emailCol
|
|
|
|
modelSchema.Tables = append(modelSchema.Tables, modelTable)
|
|
model.Schemas = append(model.Schemas, modelSchema)
|
|
|
|
// Generate migration
|
|
var buf bytes.Buffer
|
|
writer := NewMigrationWriter(&writers.WriterOptions{})
|
|
writer.writer = &buf
|
|
|
|
err := writer.WriteMigration(model, current)
|
|
if err != nil {
|
|
t.Fatalf("WriteMigration failed: %v", err)
|
|
}
|
|
|
|
output := buf.String()
|
|
t.Logf("Generated migration:\n%s", output)
|
|
|
|
// Verify ADD COLUMN is present
|
|
if !strings.Contains(output, "ADD COLUMN") {
|
|
t.Error("Migration missing ADD COLUMN statement")
|
|
}
|
|
if !strings.Contains(output, "email") {
|
|
t.Error("Migration missing column name 'email'")
|
|
}
|
|
}
|
|
|
|
func TestWriteMigration_ChangeColumnType(t *testing.T) {
|
|
// Current database (with integer column)
|
|
current := models.InitDatabase("testdb")
|
|
currentSchema := models.InitSchema("public")
|
|
currentTable := models.InitTable("users", "public")
|
|
|
|
idCol := models.InitColumn("id", "users", "public")
|
|
idCol.Type = "integer"
|
|
currentTable.Columns["id"] = idCol
|
|
|
|
currentSchema.Tables = append(currentSchema.Tables, currentTable)
|
|
current.Schemas = append(current.Schemas, currentSchema)
|
|
|
|
// Model database (changed to bigint)
|
|
model := models.InitDatabase("testdb")
|
|
modelSchema := models.InitSchema("public")
|
|
modelTable := models.InitTable("users", "public")
|
|
|
|
idCol2 := models.InitColumn("id", "users", "public")
|
|
idCol2.Type = "bigint"
|
|
modelTable.Columns["id"] = idCol2
|
|
|
|
modelSchema.Tables = append(modelSchema.Tables, modelTable)
|
|
model.Schemas = append(model.Schemas, modelSchema)
|
|
|
|
// Generate migration
|
|
var buf bytes.Buffer
|
|
writer := NewMigrationWriter(&writers.WriterOptions{})
|
|
writer.writer = &buf
|
|
|
|
err := writer.WriteMigration(model, current)
|
|
if err != nil {
|
|
t.Fatalf("WriteMigration failed: %v", err)
|
|
}
|
|
|
|
output := buf.String()
|
|
t.Logf("Generated migration:\n%s", output)
|
|
|
|
// Verify ALTER COLUMN TYPE is present
|
|
if !strings.Contains(output, "ALTER COLUMN") {
|
|
t.Error("Migration missing ALTER COLUMN statement")
|
|
}
|
|
if !strings.Contains(output, "TYPE bigint") {
|
|
t.Error("Migration missing TYPE bigint")
|
|
}
|
|
}
|
|
|
|
func TestWriteMigration_AddForeignKey(t *testing.T) {
|
|
// Current database (two tables, no relationship)
|
|
current := models.InitDatabase("testdb")
|
|
currentSchema := models.InitSchema("public")
|
|
|
|
usersTable := models.InitTable("users", "public")
|
|
idCol := models.InitColumn("id", "users", "public")
|
|
idCol.Type = "integer"
|
|
usersTable.Columns["id"] = idCol
|
|
|
|
postsTable := models.InitTable("posts", "public")
|
|
postIdCol := models.InitColumn("id", "posts", "public")
|
|
postIdCol.Type = "integer"
|
|
postsTable.Columns["id"] = postIdCol
|
|
|
|
userIdCol := models.InitColumn("user_id", "posts", "public")
|
|
userIdCol.Type = "integer"
|
|
postsTable.Columns["user_id"] = userIdCol
|
|
|
|
currentSchema.Tables = append(currentSchema.Tables, usersTable, postsTable)
|
|
current.Schemas = append(current.Schemas, currentSchema)
|
|
|
|
// Model database (with foreign key)
|
|
model := models.InitDatabase("testdb")
|
|
modelSchema := models.InitSchema("public")
|
|
|
|
modelUsersTable := models.InitTable("users", "public")
|
|
modelIdCol := models.InitColumn("id", "users", "public")
|
|
modelIdCol.Type = "integer"
|
|
modelUsersTable.Columns["id"] = modelIdCol
|
|
|
|
modelPostsTable := models.InitTable("posts", "public")
|
|
modelPostIdCol := models.InitColumn("id", "posts", "public")
|
|
modelPostIdCol.Type = "integer"
|
|
modelPostsTable.Columns["id"] = modelPostIdCol
|
|
|
|
modelUserIdCol := models.InitColumn("user_id", "posts", "public")
|
|
modelUserIdCol.Type = "integer"
|
|
modelPostsTable.Columns["user_id"] = modelUserIdCol
|
|
|
|
// Add foreign key constraint
|
|
fkConstraint := &models.Constraint{
|
|
Name: "fk_posts_users",
|
|
Type: models.ForeignKeyConstraint,
|
|
Columns: []string{"user_id"},
|
|
ReferencedTable: "users",
|
|
ReferencedSchema: "public",
|
|
ReferencedColumns: []string{"id"},
|
|
OnDelete: "CASCADE",
|
|
OnUpdate: "CASCADE",
|
|
}
|
|
modelPostsTable.Constraints["fk_posts_users"] = fkConstraint
|
|
|
|
modelSchema.Tables = append(modelSchema.Tables, modelUsersTable, modelPostsTable)
|
|
model.Schemas = append(model.Schemas, modelSchema)
|
|
|
|
// Generate migration
|
|
var buf bytes.Buffer
|
|
writer := NewMigrationWriter(&writers.WriterOptions{})
|
|
writer.writer = &buf
|
|
|
|
err := writer.WriteMigration(model, current)
|
|
if err != nil {
|
|
t.Fatalf("WriteMigration failed: %v", err)
|
|
}
|
|
|
|
output := buf.String()
|
|
t.Logf("Generated migration:\n%s", output)
|
|
|
|
// Verify FOREIGN KEY is present
|
|
if !strings.Contains(output, "FOREIGN KEY") {
|
|
t.Error("Migration missing FOREIGN KEY statement")
|
|
}
|
|
if !strings.Contains(output, "ON DELETE CASCADE") {
|
|
t.Error("Migration missing ON DELETE CASCADE")
|
|
}
|
|
}
|
|
|
|
func TestWriteMigration_AddIndex(t *testing.T) {
|
|
// Current database (table without index)
|
|
current := models.InitDatabase("testdb")
|
|
currentSchema := models.InitSchema("public")
|
|
currentTable := models.InitTable("users", "public")
|
|
|
|
emailCol := models.InitColumn("email", "users", "public")
|
|
emailCol.Type = "text"
|
|
currentTable.Columns["email"] = emailCol
|
|
|
|
currentSchema.Tables = append(currentSchema.Tables, currentTable)
|
|
current.Schemas = append(current.Schemas, currentSchema)
|
|
|
|
// Model database (with unique index)
|
|
model := models.InitDatabase("testdb")
|
|
modelSchema := models.InitSchema("public")
|
|
modelTable := models.InitTable("users", "public")
|
|
|
|
modelEmailCol := models.InitColumn("email", "users", "public")
|
|
modelEmailCol.Type = "text"
|
|
modelTable.Columns["email"] = modelEmailCol
|
|
|
|
// Add unique index
|
|
index := &models.Index{
|
|
Name: "uk_users_email",
|
|
Unique: true,
|
|
Columns: []string{"email"},
|
|
Type: "btree",
|
|
}
|
|
modelTable.Indexes["uk_users_email"] = index
|
|
|
|
modelSchema.Tables = append(modelSchema.Tables, modelTable)
|
|
model.Schemas = append(model.Schemas, modelSchema)
|
|
|
|
// Generate migration
|
|
var buf bytes.Buffer
|
|
writer := NewMigrationWriter(&writers.WriterOptions{})
|
|
writer.writer = &buf
|
|
|
|
err := writer.WriteMigration(model, current)
|
|
if err != nil {
|
|
t.Fatalf("WriteMigration failed: %v", err)
|
|
}
|
|
|
|
output := buf.String()
|
|
t.Logf("Generated migration:\n%s", output)
|
|
|
|
// Verify CREATE UNIQUE INDEX is present
|
|
if !strings.Contains(output, "CREATE UNIQUE INDEX") {
|
|
t.Error("Migration missing CREATE UNIQUE INDEX statement")
|
|
}
|
|
if !strings.Contains(output, "uk_users_email") {
|
|
t.Error("Migration missing index name")
|
|
}
|
|
}
|