From beac298c02bfe40f54e7b82bbfdf2b090fb4f06a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 3 Nov 2020 17:10:35 +0800 Subject: [PATCH] Fix json tag with other type (#1822) Fix json tag with other type Reviewed-on: https://gitea.com/xorm/xorm/pulls/1822 Co-Authored-By: Lunny Xiao Co-Committed-By: Lunny Xiao --- integrations/session_get_test.go | 54 ++++++++++++++++++++++++++++++++ internal/statements/statement.go | 4 +-- internal/statements/update.go | 2 +- internal/statements/values.go | 2 +- schemas/column.go | 1 + session.go | 4 +-- tags/tag.go | 3 ++ 7 files changed, 64 insertions(+), 6 deletions(-) diff --git a/integrations/session_get_test.go b/integrations/session_get_test.go index 4e50f9ab..e4d9f82e 100644 --- a/integrations/session_get_test.go +++ b/integrations/session_get_test.go @@ -394,6 +394,60 @@ func TestJSONString(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, 1, len(jss)) assert.True(t, `["1","2"]` == jss[0].Content || `["1", "2"]` == jss[0].Content) + + type JsonAnonymousStruct struct { + Id int64 + JsonString `xorm:"'json_string' JSON LONGTEXT"` + } + + assertSync(t, new(JsonAnonymousStruct)) + + _, err = testEngine.Insert(&JsonAnonymousStruct{ + JsonString: JsonString{ + Content: "1", + }, + }) + assert.NoError(t, err) + + var jas JsonAnonymousStruct + has, err = testEngine.Get(&jas) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, jas.Id) + assert.EqualValues(t, "1", jas.Content) + + var jass []JsonAnonymousStruct + err = testEngine.Find(&jass) + assert.NoError(t, err) + assert.EqualValues(t, 1, len(jass)) + assert.EqualValues(t, "1", jass[0].Content) + + type JsonStruct struct { + Id int64 + JSON JsonString `xorm:"'json_string' JSON LONGTEXT"` + } + + assertSync(t, new(JsonStruct)) + + _, err = testEngine.Insert(&JsonStruct{ + JSON: JsonString{ + Content: "2", + }, + }) + assert.NoError(t, err) + + var jst JsonStruct + has, err = testEngine.Get(&jst) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, jst.Id) + assert.EqualValues(t, "2", jst.JSON.Content) + + var jsts []JsonStruct + err = testEngine.Find(&jsts) + assert.NoError(t, err) + assert.EqualValues(t, 1, len(jsts)) + assert.EqualValues(t, "2", jsts[0].JSON.Content) } func TestGetActionMapping(t *testing.T) { diff --git a/internal/statements/statement.go b/internal/statements/statement.go index ed7bdaeb..a4294bec 100644 --- a/internal/statements/statement.go +++ b/internal/statements/statement.go @@ -704,7 +704,7 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{}, col.SQLType.IsBlob() || col.SQLType.Name == schemas.TimeStampz) { continue } - if col.SQLType.IsJson() { + if col.IsJSON { continue } @@ -813,7 +813,7 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{}, continue } } else { - if col.SQLType.IsJson() { + if col.IsJSON { if col.SQLType.IsText() { bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface()) if err != nil { diff --git a/internal/statements/update.go b/internal/statements/update.go index ff5f82b7..251880b2 100644 --- a/internal/statements/update.go +++ b/internal/statements/update.go @@ -204,7 +204,7 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value, continue } } else { - if !col.SQLType.IsJson() { + if !col.IsJSON { table, err := statement.tagParser.ParseWithCache(fieldValue) if err != nil { val = fieldValue.Interface() diff --git a/internal/statements/values.go b/internal/statements/values.go index 99eaa766..71327c55 100644 --- a/internal/statements/values.go +++ b/internal/statements/values.go @@ -86,7 +86,7 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl return t.Float64, nil } - if !col.SQLType.IsJson() { + if !col.IsJSON { // !! 增加支持driver.Valuer接口的结构,如sql.NullString if v, ok := fieldValue.Interface().(driver.Valuer); ok { return v.Value() diff --git a/schemas/column.go b/schemas/column.go index db66a3a6..4f32afab 100644 --- a/schemas/column.go +++ b/schemas/column.go @@ -51,6 +51,7 @@ type Column struct { func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column { return &Column{ Name: name, + IsJSON: sqlType.IsJson(), TableName: "", FieldName: fieldName, SQLType: sqlType, diff --git a/session.go b/session.go index b6ab3eb5..17abd453 100644 --- a/session.go +++ b/session.go @@ -503,7 +503,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b fieldType := fieldValue.Type() hasAssigned := false - if col.SQLType.IsJson() { + if col.IsJSON { var bs []byte if rawValueType.Kind() == reflect.String { bs = []byte(vv.String()) @@ -683,7 +683,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b session.engine.logger.Errorf("sql.Sanner error: %v", err) hasAssigned = false } - } else if col.SQLType.IsJson() { + } else if col.IsJSON { if rawValueType.Kind() == reflect.String { hasAssigned = true x := reflect.New(fieldType) diff --git a/tags/tag.go b/tags/tag.go index ee3f1e82..bb5b5838 100644 --- a/tags/tag.go +++ b/tags/tag.go @@ -226,6 +226,9 @@ func CommentTagHandler(ctx *Context) error { // SQLTypeTagHandler describes SQL Type tag handler func SQLTypeTagHandler(ctx *Context) error { ctx.col.SQLType = schemas.SQLType{Name: ctx.tagName} + if strings.EqualFold(ctx.tagName, "JSON") { + ctx.col.IsJSON = true + } if len(ctx.params) > 0 { if ctx.tagName == schemas.Enum { ctx.col.EnumOptions = make(map[string]int)