feat(models): add support for generated and identity columns
* extend Column struct with Generated, GenerationExpression, Identity, and IdentityGeneration fields * update queryColumns to handle new column properties * modify migration writer to avoid altering generated and identity columns * add tests to ensure correct handling of generated and identity columns
This commit is contained in:
@@ -219,6 +219,91 @@ func TestWriteMigration_AltersColumnNullabilityWhenNotNullDiffers(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteMigration_DoesNotDropDefaultOnGeneratedColumn(t *testing.T) {
|
||||
current := models.InitDatabase("testdb")
|
||||
currentSchema := models.InitSchema("public")
|
||||
currentTable := models.InitTable("info_city", "public")
|
||||
currentGeom := models.InitColumn("geom", "info_city", "public")
|
||||
currentGeom.Type = "text"
|
||||
currentGeom.Generated = true
|
||||
currentGeom.GenerationExpression = "st_makepoint(lon, lat)"
|
||||
currentTable.Columns["geom"] = currentGeom
|
||||
currentSchema.Tables = append(currentSchema.Tables, currentTable)
|
||||
current.Schemas = append(current.Schemas, currentSchema)
|
||||
|
||||
model := models.InitDatabase("testdb")
|
||||
modelSchema := models.InitSchema("public")
|
||||
modelTable := models.InitTable("info_city", "public")
|
||||
modelGeom := models.InitColumn("geom", "info_city", "public")
|
||||
modelGeom.Type = "text"
|
||||
// DBML cannot express GENERATED ALWAYS columns, so the model declares
|
||||
// this as a plain column with no default — it must not be treated as a
|
||||
// default-value drift against the DB-side generated column.
|
||||
modelTable.Columns["geom"] = modelGeom
|
||||
modelSchema.Tables = append(modelSchema.Tables, modelTable)
|
||||
model.Schemas = append(model.Schemas, modelSchema)
|
||||
|
||||
var buf bytes.Buffer
|
||||
writer, err := NewMigrationWriter(&writers.WriterOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create writer: %v", err)
|
||||
}
|
||||
writer.writer = &buf
|
||||
|
||||
if err := writer.WriteMigration(model, current); err != nil {
|
||||
t.Fatalf("WriteMigration failed: %v", err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if strings.Contains(output, "DROP DEFAULT") {
|
||||
t.Fatalf("did not expect DROP DEFAULT against a generated column, got:\n%s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteMigration_DoesNotAlterIdentityColumn(t *testing.T) {
|
||||
current := models.InitDatabase("testdb")
|
||||
currentSchema := models.InitSchema("public")
|
||||
currentTable := models.InitTable("users", "public")
|
||||
currentID := models.InitColumn("id", "users", "public")
|
||||
currentID.Type = "bigint"
|
||||
currentID.NotNull = true
|
||||
currentID.Identity = true
|
||||
currentID.IdentityGeneration = "ALWAYS"
|
||||
currentTable.Columns["id"] = currentID
|
||||
currentSchema.Tables = append(currentSchema.Tables, currentTable)
|
||||
current.Schemas = append(current.Schemas, currentSchema)
|
||||
|
||||
model := models.InitDatabase("testdb")
|
||||
modelSchema := models.InitSchema("public")
|
||||
modelTable := models.InitTable("users", "public")
|
||||
modelID := models.InitColumn("id", "users", "public")
|
||||
modelID.Type = "bigint"
|
||||
// DBML cannot express GENERATED ... AS IDENTITY, so the model declares this
|
||||
// as a plain nullable column — it must not be diffed as NOT NULL drift
|
||||
// against the DB-side identity column (Postgres rejects DROP NOT NULL on
|
||||
// an identity column).
|
||||
modelID.NotNull = false
|
||||
modelTable.Columns["id"] = modelID
|
||||
modelSchema.Tables = append(modelSchema.Tables, modelTable)
|
||||
model.Schemas = append(model.Schemas, modelSchema)
|
||||
|
||||
var buf bytes.Buffer
|
||||
writer, err := NewMigrationWriter(&writers.WriterOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create writer: %v", err)
|
||||
}
|
||||
writer.writer = &buf
|
||||
|
||||
if err := writer.WriteMigration(model, current); err != nil {
|
||||
t.Fatalf("WriteMigration failed: %v", err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if strings.Contains(output, "DROP NOT NULL") {
|
||||
t.Fatalf("did not expect DROP NOT NULL against an identity column, got:\n%s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteMigration_UsesStorageTypeForSerialAlterStatements(t *testing.T) {
|
||||
current := models.InitDatabase("testdb")
|
||||
currentSchema := models.InitSchema("public")
|
||||
|
||||
Reference in New Issue
Block a user