Merge branch 'v1' into feature/gbase-nullable

This commit is contained in:
Lunny Xiao 2025-07-21 18:21:54 +00:00
commit dd22d92ff1
5 changed files with 116 additions and 16 deletions

View File

@ -26,6 +26,7 @@ type Column struct {
FieldIndex []int // Available only when parsed from a struct FieldIndex []int // Available only when parsed from a struct
SQLType SQLType SQLType SQLType
IsJSON bool IsJSON bool
IsJSONB bool
Length int64 Length int64
Length2 int64 Length2 int64
Nullable bool Nullable bool

View File

@ -250,12 +250,18 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f
} }
if col.SQLType.Name == "" { if col.SQLType.Name == "" {
if col.IsJSONB { // check is jsonb first because it is also json
col.SQLType = schemas.SQLType{Name: schemas.Jsonb}
} else if col.IsJSON {
col.SQLType = schemas.SQLType{Name: schemas.Json}
} else {
var err error var err error
col.SQLType, err = parser.getSQLTypeByType(field.Type) col.SQLType, err = parser.getSQLTypeByType(field.Type)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
}
if ctx.isUnsigned && col.SQLType.IsNumeric() && !strings.HasPrefix(col.SQLType.Name, "UNSIGNED") { if ctx.isUnsigned && col.SQLType.IsNumeric() && !strings.HasPrefix(col.SQLType.Name, "UNSIGNED") {
col.SQLType.Name = "UNSIGNED " + col.SQLType.Name col.SQLType.Name = "UNSIGNED " + col.SQLType.Name
} }

View File

@ -577,7 +577,7 @@ func TestParseWithJSONB(t *testing.T) {
assert.EqualValues(t, "struct_with_jsonb", table.Name) assert.EqualValues(t, "struct_with_jsonb", table.Name)
assert.EqualValues(t, 1, len(table.Columns())) assert.EqualValues(t, 1, len(table.Columns()))
assert.EqualValues(t, "default1", table.Columns()[0].Name) assert.EqualValues(t, "default1", table.Columns()[0].Name)
assert.True(t, table.Columns()[0].IsJSON) assert.True(t, table.Columns()[0].IsJSONB)
} }
func TestParseWithSQLType(t *testing.T) { func TestParseWithSQLType(t *testing.T) {
@ -617,3 +617,53 @@ func TestParseWithSQLType(t *testing.T) {
assert.EqualValues(t, "DATETIME", table.Columns()[3].SQLType.Name) assert.EqualValues(t, "DATETIME", table.Columns()[3].SQLType.Name)
assert.EqualValues(t, "UUID", table.Columns()[4].SQLType.Name) assert.EqualValues(t, "UUID", table.Columns()[4].SQLType.Name)
} }
func TestParseWithJSONLongText(t *testing.T) {
parser := NewParser(
"db",
dialects.QueryDialect("mysql"),
names.GonicMapper{
"JSON": true,
},
names.GonicMapper{
"JSON": true,
},
caches.NewManager(),
)
type StructWithJSONLongText struct {
Col1 string `db:"LongText json"`
}
table, err := parser.Parse(reflect.ValueOf(new(StructWithJSONLongText)))
assert.NoError(t, err)
assert.EqualValues(t, "struct_with_json_long_text", table.Name)
assert.EqualValues(t, 1, len(table.Columns()))
assert.EqualValues(t, "col1", table.Columns()[0].Name)
assert.EqualValues(t, "LONGTEXT", table.Columns()[0].SQLType.Name)
assert.EqualValues(t, true, table.Columns()[0].IsJSON)
type StructWithJSONLongText2 struct {
Col1 string `db:"json"`
}
table, err = parser.Parse(reflect.ValueOf(new(StructWithJSONLongText2)))
assert.NoError(t, err)
assert.EqualValues(t, "struct_with_json_long_text2", table.Name)
assert.EqualValues(t, 1, len(table.Columns()))
assert.EqualValues(t, "col1", table.Columns()[0].Name)
assert.EqualValues(t, "JSON", table.Columns()[0].SQLType.Name)
assert.EqualValues(t, true, table.Columns()[0].IsJSON)
type StructWithJSONLongText3 struct {
Col1 string `db:"jsonb"`
}
table, err = parser.Parse(reflect.ValueOf(new(StructWithJSONLongText3)))
assert.NoError(t, err)
assert.EqualValues(t, "struct_with_json_long_text3", table.Name)
assert.EqualValues(t, 1, len(table.Columns()))
assert.EqualValues(t, "col1", table.Columns()[0].Name)
assert.EqualValues(t, "JSONB", table.Columns()[0].SQLType.Name)
assert.EqualValues(t, true, table.Columns()[0].IsJSONB)
}

View File

@ -124,10 +124,16 @@ var defaultTagHandlers = map[string]Handler{
"EXTENDS": ExtendsTagHandler, "EXTENDS": ExtendsTagHandler,
"UNSIGNED": UnsignedTagHandler, "UNSIGNED": UnsignedTagHandler,
"COLLATE": CollateTagHandler, "COLLATE": CollateTagHandler,
"JSON": JSONTagHandler,
"JSONB": JSONBTagHandler,
} }
func init() { func init() {
for k := range schemas.SqlTypes { for k := range schemas.SqlTypes {
// don't override default tag handlers
if _, ok := defaultTagHandlers[k]; ok {
continue
}
defaultTagHandlers[k] = SQLTypeTagHandler defaultTagHandlers[k] = SQLTypeTagHandler
} }
} }
@ -293,12 +299,20 @@ func CollateTagHandler(ctx *Context) error {
return nil return nil
} }
func JSONTagHandler(ctx *Context) error {
ctx.col.IsJSON = true
return nil
}
func JSONBTagHandler(ctx *Context) error {
ctx.col.IsJSONB = true
ctx.col.IsJSON = true // jsonb is also json
return nil
}
// SQLTypeTagHandler describes SQL Type tag handler // SQLTypeTagHandler describes SQL Type tag handler
func SQLTypeTagHandler(ctx *Context) error { func SQLTypeTagHandler(ctx *Context) error {
ctx.col.SQLType = schemas.SQLType{Name: ctx.tagUname} ctx.col.SQLType = schemas.SQLType{Name: ctx.tagUname}
if ctx.tagUname == "JSON" || ctx.tagUname == "JSONB" {
ctx.col.IsJSON = true
}
if len(ctx.params) == 0 { if len(ctx.params) == 0 {
return nil return nil
} }

View File

@ -752,7 +752,6 @@ func getKeysFromMap(m map[string]*schemas.Index) []string {
return ss return ss
} }
type SyncTestUser struct { type SyncTestUser struct {
Id int64 `xorm:"pk autoincr 'id' comment('primary key 1')"` Id int64 `xorm:"pk autoincr 'id' comment('primary key 1')"`
Name string `xorm:"'name' notnull comment('nickname')" json:"name"` Name string `xorm:"'name' notnull comment('nickname')" json:"name"`
@ -762,7 +761,6 @@ func (m *SyncTestUser) TableName() string {
return "sync_test_user" return "sync_test_user"
} }
type SyncTestUser2 struct { type SyncTestUser2 struct {
Id int64 `xorm:"pk autoincr 'id' comment('primary key 2')"` Id int64 `xorm:"pk autoincr 'id' comment('primary key 2')"`
Name string `xorm:"'name' notnull comment('nickname')" json:"name"` Name string `xorm:"'name' notnull comment('nickname')" json:"name"`
@ -789,5 +787,36 @@ func TestSync2_3(t *testing.T) {
assert.EqualValues(t, tables[0].GetColumn("id").Comment, tableInfo.GetColumn("id").Comment) assert.EqualValues(t, tables[0].GetColumn("id").Comment, tableInfo.GetColumn("id").Comment)
} }
}
func TestSyncJSON(t *testing.T) {
type SyncTestJSON struct {
Id int64
Value string `xorm:"LONGTEXT JSON 'value' comment('json value')"`
}
assert.NoError(t, PrepareEngine())
assertSync(t, new(SyncTestJSON))
assert.NoError(t, testEngine.Sync(new(SyncTestJSON)))
tables, err := testEngine.DBMetas()
assert.NoError(t, err)
tableInfo, err := testEngine.TableInfo(new(SyncTestJSON))
assert.NoError(t, err)
assert.EqualValues(t, tables[0].GetColumn("id").IsAutoIncrement, tableInfo.GetColumn("id").IsAutoIncrement)
assert.EqualValues(t, tables[0].GetColumn("id").Name, tableInfo.GetColumn("id").Name)
if testEngine.Dialect().URI().DBType == schemas.MYSQL {
assert.EqualValues(t, tables[0].GetColumn("id").SQLType.Name, tableInfo.GetColumn("id").SQLType.Name)
}
assert.EqualValues(t, tables[0].GetColumn("id").Nullable, tableInfo.GetColumn("id").Nullable)
assert.EqualValues(t, tables[0].GetColumn("value").IsAutoIncrement, tableInfo.GetColumn("value").IsAutoIncrement)
assert.EqualValues(t, tables[0].GetColumn("value").Name, tableInfo.GetColumn("value").Name)
assert.EqualValues(t, tables[0].GetColumn("value").Nullable, tableInfo.GetColumn("value").Nullable)
if testEngine.Dialect().URI().DBType == schemas.MYSQL {
assert.EqualValues(t, tables[0].GetColumn("value").SQLType.Name, tableInfo.GetColumn("value").SQLType.Name)
}
} }