feat(migration): enhance primary key handling and add GIN index support in migration writer
This commit is contained in:
@@ -31,6 +31,10 @@ type MigrationWriter struct {
|
||||
|
||||
// NewMigrationWriter creates a new templated migration writer
|
||||
func NewMigrationWriter(options *writers.WriterOptions) (*MigrationWriter, error) {
|
||||
if options == nil {
|
||||
options = &writers.WriterOptions{}
|
||||
}
|
||||
|
||||
executor, err := NewTemplateExecutor(options.FlattenSchema)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create template executor: %w", err)
|
||||
@@ -44,6 +48,16 @@ func NewMigrationWriter(options *writers.WriterOptions) (*MigrationWriter, error
|
||||
|
||||
// WriteMigration generates migration scripts using templates
|
||||
func (w *MigrationWriter) WriteMigration(model *models.Database, current *models.Database) error {
|
||||
if model == nil {
|
||||
return fmt.Errorf("model database is required")
|
||||
}
|
||||
if w.options == nil {
|
||||
w.options = &writers.WriterOptions{}
|
||||
}
|
||||
if current == nil {
|
||||
current = models.InitDatabase(model.Name)
|
||||
}
|
||||
|
||||
var writer io.Writer
|
||||
var file *os.File
|
||||
var err error
|
||||
@@ -86,9 +100,16 @@ func (w *MigrationWriter) WriteMigration(model *models.Database, current *models
|
||||
|
||||
// Process each schema in the model
|
||||
for _, modelSchema := range model.Schemas {
|
||||
if modelSchema == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Find corresponding schema in current database
|
||||
var currentSchema *models.Schema
|
||||
for _, cs := range current.Schemas {
|
||||
if cs == nil {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(cs.Name, modelSchema.Name) {
|
||||
currentSchema = cs
|
||||
break
|
||||
@@ -545,12 +566,17 @@ func (w *MigrationWriter) generateIndexScripts(model *models.Schema, current *mo
|
||||
indexType = modelIndex.Type
|
||||
}
|
||||
|
||||
columnExprs := buildIndexColumnExpressions(modelTable, modelIndex, indexType)
|
||||
if len(columnExprs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
sql, err := w.executor.ExecuteCreateIndex(CreateIndexData{
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
IndexName: indexName,
|
||||
IndexType: indexType,
|
||||
Columns: strings.Join(modelIndex.Columns, ", "),
|
||||
Columns: strings.Join(columnExprs, ", "),
|
||||
Unique: modelIndex.Unique,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -573,6 +599,27 @@ func (w *MigrationWriter) generateIndexScripts(model *models.Schema, current *mo
|
||||
return scripts, nil
|
||||
}
|
||||
|
||||
func buildIndexColumnExpressions(table *models.Table, index *models.Index, indexType string) []string {
|
||||
columnExprs := make([]string, 0, len(index.Columns))
|
||||
for _, colName := range index.Columns {
|
||||
colExpr := colName
|
||||
if table != nil {
|
||||
if col, ok := table.Columns[colName]; ok && col != nil {
|
||||
colExpr = col.SQLName()
|
||||
if strings.EqualFold(indexType, "gin") && isTextType(col.Type) {
|
||||
opClass := extractOperatorClass(index.Comment)
|
||||
if opClass == "" {
|
||||
opClass = "gin_trgm_ops"
|
||||
}
|
||||
colExpr = fmt.Sprintf("%s %s", col.SQLName(), opClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
columnExprs = append(columnExprs, colExpr)
|
||||
}
|
||||
return columnExprs
|
||||
}
|
||||
|
||||
// generateForeignKeyScripts generates ADD CONSTRAINT FOREIGN KEY scripts using templates
|
||||
func (w *MigrationWriter) generateForeignKeyScripts(model *models.Schema, current *models.Schema) ([]MigrationScript, error) {
|
||||
scripts := make([]MigrationScript, 0)
|
||||
|
||||
Reference in New Issue
Block a user