From 68577b4a2b81c9ace69d5306cf5227cbd6e46097 Mon Sep 17 00:00:00 2001 From: sunary Date: Mon, 7 Oct 2024 14:12:34 +0700 Subject: [PATCH] ignore field order --- element/migration.go | 7 +++-- element/table.go | 12 ++++----- options.go | 18 +++++++++---- sql-builder/builder.go | 61 +++++++++++++++++++++++++++++------------- sql-parser/mysql.go | 1 - sql-parser/parser.go | 9 ++++--- sqlize.go | 13 ++++----- sqlize_test.go | 1 + 8 files changed, 80 insertions(+), 42 deletions(-) diff --git a/element/migration.go b/element/migration.go index a9f06d9..3e330e5 100644 --- a/element/migration.go +++ b/element/migration.go @@ -11,7 +11,8 @@ import ( ) var ( - sql *sql_templates.Sql + sql *sql_templates.Sql + ignoreFieldOrder bool ) // Migration ... @@ -22,8 +23,10 @@ type Migration struct { } // NewMigration ... -func NewMigration(dialect sql_templates.SqlDialect, lowercase bool) Migration { +func NewMigration(dialect sql_templates.SqlDialect, lowercase, ignoreOrder bool) Migration { sql = sql_templates.NewSql(dialect, lowercase) + ignoreFieldOrder = ignoreOrder + return Migration{ Tables: []Table{}, tableIndexes: map[string]int{}, diff --git a/element/table.go b/element/table.go index 0bae6aa..c606f59 100644 --- a/element/table.go +++ b/element/table.go @@ -383,10 +383,10 @@ func (t Table) MigrationColumnUp() ([]string, map[string]struct{}) { dropCols[t.Columns[i].Name] = struct{}{} } - if after != "" { - strSqls = append(strSqls, t.Columns[i].migrationUp(t.Name, after, -1)...) - } else { + if ignoreFieldOrder || after == "" { strSqls = append(strSqls, t.Columns[i].migrationUp(t.Name, "", -1)...) + } else { + strSqls = append(strSqls, t.Columns[i].migrationUp(t.Name, after, -1)...) } } } @@ -516,10 +516,10 @@ func (t Table) MigrationColumnDown() ([]string, map[string]struct{}) { dropCols[t.Columns[i].Name] = struct{}{} } - if after != "" { - strSqls = append(strSqls, t.Columns[i].migrationDown(t.Name, after)...) - } else { + if ignoreFieldOrder || after == "" { strSqls = append(strSqls, t.Columns[i].migrationDown(t.Name, "")...) + } else { + strSqls = append(strSqls, t.Columns[i].migrationDown(t.Name, after)...) } } } diff --git a/options.go b/options.go index 5d8ceab..5394d42 100644 --- a/options.go +++ b/options.go @@ -10,11 +10,12 @@ type sqlizeOptions struct { migrationDownSuffix string migrationTable string - sqlTag string - dialect sql_templates.SqlDialect - lowercase bool - pluralTableName bool - generateComment bool + sqlTag string + dialect sql_templates.SqlDialect + lowercase bool + pluralTableName bool + generateComment bool + ignoreFieldOrder bool } type funcSqlizeOption struct { @@ -120,3 +121,10 @@ func WithCommentGenerate() SqlizeOption { o.generateComment = true }) } + +// WithIgnoreFieldOrder ... +func WithIgnoreFieldOrder() SqlizeOption { + return newFuncSqlizeOption(func(o *sqlizeOptions) { + o.ignoreFieldOrder = true + }) +} diff --git a/sql-builder/builder.go b/sql-builder/builder.go index 39491b0..b616f91 100644 --- a/sql-builder/builder.go +++ b/sql-builder/builder.go @@ -12,35 +12,51 @@ import ( "github.com/sunary/sqlize/utils" ) +// Tag prefixes const ( - // SqlTagDefault ... SqlTagDefault = "sql" - tagIsSquash = "squash" - tagIsEmbedded = "embedded" prefixColumn = "column:" // set column name, eg: 'column:column_name' prefixEmbedded = "embedded_prefix:" // set embed prefix for flatten struct, eg: 'embedded_prefix:base_' prefixPreviousName = ",previous:" // mark previous name-field, eg: 'column:column_name,previous:old_name' prefixType = "type:" // set field type, eg: 'type:VARCHAR(64)' prefixDefault = "default:" // set default value, eg: 'default:0' - tagEnum = "enum" // type:ENUM('open','close') prefixComment = "comment:" // comment field, eg: 'comment:sth you want to comment' +) + +// Special tags +const ( + tagIsSquash = "squash" + tagIsEmbedded = "embedded" + tagEnum = "enum" // type:ENUM('open','close') +) +// Null and key constraints +const ( tagIsNull = "null" tagIsNotNull = "not_null" tagIsAutoIncrement = "auto_increment" tagIsPrimaryKey = "primary_key" // this field is primary key, eg: 'primary_key' - tagIsIndex = "index" // indexing this field, eg: 'index' (=> idx_column_name) - tagIsUniqueIndex = "unique" // unique indexing this field, eg: 'unique' (=> idx_column_name) +) +// Index related +const ( + tagIsIndex = "index" // indexing this field, eg: 'index' (=> idx_column_name) + tagIsUniqueIndex = "unique" // unique indexing this field, eg: 'unique' (=> idx_column_name) prefixIndex = "index:" // indexing with name, eg: 'index:idx_name' prefixUniqueIndex = "unique:" // unique indexing with name, eg: 'unique:idx_name' prefixIndexColumns = "index_columns:" // indexing these fields, eg: 'index_columns:col1,col2' (=> idx_col1_col2) prefixIndexType = "index_type:" // indexing with type, eg: 'index_type:btree' (default) or 'index_type:hash' +) +// Foreign key related +const ( prefixForeignKey = "foreign_key:" // 'foreign_key:' prefixFkReferences = "references:" // 'references:' prefixFkConstraint = "constraint:" // 'constraint:' +) +// Function names +const ( funcTableName = "TableName" ) @@ -140,21 +156,30 @@ func (s SqlBuilder) AddTable(obj interface{}) string { } type attrs struct { - Name string - Prefix string - Type string - Value string - IsPk bool - ForeignKey *fkAttrs - IsUnique bool + // Basic attributes + Name string + Prefix string + Type string + Value string + Comment string + + // Key and constraint attributes + IsPk bool + IsUnique bool + IsNull bool + IsNotNull bool + IsAutoIncr bool + + // Foreign key + ForeignKey *fkAttrs + + // Index attributes Index string IndexType string IndexColumns string - IsNull bool - IsNotNull bool - IsAutoIncr bool - Comment string - IsEmbedded bool + + // Special attribute + IsEmbedded bool } type fkAttrs struct { diff --git a/sql-parser/mysql.go b/sql-parser/mysql.go index 2838a29..cf440e1 100644 --- a/sql-parser/mysql.go +++ b/sql-parser/mysql.go @@ -19,7 +19,6 @@ func (p *Parser) ParserMysql(sql string) error { switch n.(type) { case ast.DDLNode: n.Accept(p) - break } } diff --git a/sql-parser/parser.go b/sql-parser/parser.go index ec410d8..6d4120a 100644 --- a/sql-parser/parser.go +++ b/sql-parser/parser.go @@ -7,15 +7,16 @@ import ( // Parser ... type Parser struct { - dialect sql_templates.SqlDialect - Migration element.Migration + dialect sql_templates.SqlDialect + Migration element.Migration + ignoreOrder bool } // NewParser ... -func NewParser(dialect sql_templates.SqlDialect, lowercase bool) *Parser { +func NewParser(dialect sql_templates.SqlDialect, lowercase, ignoreOrder bool) *Parser { return &Parser{ dialect: dialect, - Migration: element.NewMigration(dialect, lowercase), + Migration: element.NewMigration(dialect, lowercase, ignoreOrder), } } diff --git a/sqlize.go b/sqlize.go index 8282d67..5ea56f4 100644 --- a/sqlize.go +++ b/sqlize.go @@ -40,11 +40,12 @@ func NewSqlize(opts ...SqlizeOption) *Sqlize { migrationDownSuffix: utils.DefaultMigrationDownSuffix, migrationTable: utils.DefaultMigrationTable, - dialect: sql_templates.MysqlDialect, - lowercase: false, - sqlTag: sql_builder.SqlTagDefault, - pluralTableName: false, - generateComment: false, + dialect: sql_templates.MysqlDialect, + lowercase: false, + sqlTag: sql_builder.SqlTagDefault, + pluralTableName: false, + generateComment: false, + ignoreFieldOrder: false, } for i := range opts { opts[i].apply(&o) @@ -75,7 +76,7 @@ func NewSqlize(opts ...SqlizeOption) *Sqlize { lowercase: o.lowercase, pluralTableName: o.pluralTableName, sqlBuilder: sb, - parser: sql_parser.NewParser(o.dialect, o.lowercase), + parser: sql_parser.NewParser(o.dialect, o.lowercase, o.ignoreFieldOrder), } } diff --git a/sqlize_test.go b/sqlize_test.go index b0c6759..adf4d5a 100644 --- a/sqlize_test.go +++ b/sqlize_test.go @@ -736,6 +736,7 @@ func TestSqlize_MigrationVersion(t *testing.T) { WithMigrationFolder(""), WithMigrationTable(utils.DefaultMigrationTable), WithPostgresql(), + WithIgnoreFieldOrder(), } s := NewSqlize(opts...)