diff --git a/dialect_mssql.go b/dialect_mssql.go index 29070da2..5ef870d3 100644 --- a/dialect_mssql.go +++ b/dialect_mssql.go @@ -244,7 +244,7 @@ func (db *mssql) SqlType(c *core.Column) string { c.Length = 7 case core.MediumInt: res = core.Int - case core.Text, core.MediumText, core.TinyText, core.LongText, core.Json: + case core.Text, core.MediumText, core.TinyText, core.LongText: res = core.Varchar + "(MAX)" case core.Double: res = core.Real diff --git a/dialect_mysql.go b/dialect_mysql.go index cf1dbb6f..7e28625c 100644 --- a/dialect_mysql.go +++ b/dialect_mysql.go @@ -243,8 +243,6 @@ func (db *mysql) SqlType(c *core.Column) string { case core.Uuid: res = core.Varchar c.Length = 40 - case core.Json: - res = core.Text default: res = t } diff --git a/dialect_oracle.go b/dialect_oracle.go index 15010ca5..d4a6b0f4 100644 --- a/dialect_oracle.go +++ b/dialect_oracle.go @@ -519,7 +519,7 @@ func (db *oracle) SqlType(c *core.Column) string { res = "TIMESTAMP WITH TIME ZONE" case core.Float, core.Double, core.Numeric, core.Decimal: res = "NUMBER" - case core.Text, core.MediumText, core.LongText, core.Json: + case core.Text, core.MediumText, core.LongText: res = "CLOB" case core.Char, core.Varchar, core.TinyText: res = "VARCHAR2" diff --git a/dialect_sqlite3.go b/dialect_sqlite3.go index 0a290f3c..1b08b974 100644 --- a/dialect_sqlite3.go +++ b/dialect_sqlite3.go @@ -165,7 +165,7 @@ func (db *sqlite3) SqlType(c *core.Column) string { case core.TimeStampz: return core.Text case core.Char, core.Varchar, core.NVarchar, core.TinyText, - core.Text, core.MediumText, core.LongText, core.Json: + core.Text, core.MediumText, core.LongText: return core.Text case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt: return core.Integer diff --git a/engine.go b/engine.go index a7e52ea4..41c00605 100644 --- a/engine.go +++ b/engine.go @@ -1076,7 +1076,6 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) { } table.AddColumn(col) - } // end for if idFieldColName != "" && len(table.PrimaryKeys) == 0 { diff --git a/engine_cond.go b/engine_cond.go index 702ac804..5db03d46 100644 --- a/engine_cond.go +++ b/engine_cond.go @@ -34,7 +34,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{}, if engine.dialect.DBType() == core.MSSQL && (col.SQLType.Name == core.Text || col.SQLType.IsBlob() || col.SQLType.Name == core.TimeStampz) { continue } - if col.SQLType.IsJson() { + if col.IsJSON || col.SQLType.IsJson() { continue } @@ -144,7 +144,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{}, continue } } else { - if col.SQLType.IsJson() { + if col.IsJSON || col.SQLType.IsJson() { if col.SQLType.IsText() { bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) if err != nil { diff --git a/session.go b/session.go index 83071935..6a5c40fb 100644 --- a/session.go +++ b/session.go @@ -484,7 +484,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b fieldType := fieldValue.Type() hasAssigned := false - if col.SQLType.IsJson() { + if col.IsJSON || col.SQLType.IsJson() { var bs []byte if rawValueType.Kind() == reflect.String { bs = []byte(vv.String()) @@ -664,7 +664,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b session.engine.logger.Error("sql.Sanner error:", err.Error()) hasAssigned = false } - } else if col.SQLType.IsJson() { + } else if col.IsJSON || col.SQLType.IsJson() { if rawValueType.Kind() == reflect.String { hasAssigned = true x := reflect.New(fieldType) diff --git a/session_convert.go b/session_convert.go index 7f11354d..fdd5900a 100644 --- a/session_convert.go +++ b/session_convert.go @@ -595,7 +595,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val return t.Float64, nil } - if !col.SQLType.IsJson() { + if !(col.IsJSON || col.SQLType.IsJson()) { // !! 增加支持driver.Valuer接口的结构,如sql.NullString if v, ok := fieldValue.Interface().(driver.Valuer); ok { return v.Value() diff --git a/session_delete_test.go b/session_delete_test.go index 5edb0718..4c02d770 100644 --- a/session_delete_test.go +++ b/session_delete_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "xorm.io/core" "github.com/stretchr/testify/assert" + "xorm.io/core" ) func TestDelete(t *testing.T) { @@ -29,7 +29,7 @@ func TestDelete(t *testing.T) { if testEngine.Dialect().DBType() == core.MSSQL { err = session.Begin() assert.NoError(t, err) - _, err = session.Exec("SET IDENTITY_INSERT userinfo_delete ON") + _, err = session.Exec("SET IDENTITY_INSERT " + testEngine.TableMapper.Obj2Table("UserinfoDelete") + " ON") assert.NoError(t, err) } diff --git a/statement.go b/statement.go index 67e35213..98d942e5 100644 --- a/statement.go +++ b/statement.go @@ -397,7 +397,7 @@ func (statement *Statement) buildUpdates(bean interface{}, } else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok { val, _ = nulType.Value() } else { - if !col.SQLType.IsJson() { + if !(col.IsJSON || col.SQLType.IsJson()) { engine.autoMapType(fieldValue) if table, ok := engine.Tables[fieldValue.Type()]; ok { if len(table.PrimaryKeys) == 1 { diff --git a/tag.go b/tag.go index ec8d5cf0..1cae62f0 100644 --- a/tag.go +++ b/tag.go @@ -55,12 +55,16 @@ var ( "CACHE": CacheTagHandler, "NOCACHE": NoCacheTagHandler, "COMMENT": CommentTagHandler, + "JSON": JSONTagHandler, } ) func init() { for k := range core.SqlTypes { - defaultTagHandlers[k] = SQLTypeTagHandler + // don't overwrite + if _, ok := defaultTagHandlers[k]; !ok { + defaultTagHandlers[k] = SQLTypeTagHandler + } } } @@ -242,8 +246,19 @@ func SQLTypeTagHandler(ctx *tagContext) error { return nil } +// JSONTagHandler handle json tag +func JSONTagHandler(ctx *tagContext) error { + fmt.Println("fdsfafadfs") + ctx.col.IsJSON = true + if len(ctx.params) == 0 { + ctx.col.SQLType = core.SQLType{Name: core.Text} + } + return nil +} + // ExtendsTagHandler describes extends tag handler func ExtendsTagHandler(ctx *tagContext) error { + ctx.ignoreNext = true var fieldValue = ctx.fieldValue var isPtr = false switch fieldValue.Kind() { diff --git a/tag_test.go b/tag_test.go index 979ba929..64ad7b3e 100644 --- a/tag_test.go +++ b/tag_test.go @@ -598,3 +598,48 @@ func TestTagPrimarykey(t *testing.T) { assert.True(t, col2.IsPrimaryKey) assert.False(t, col2.IsAutoIncrement) } + +func TestTagJSON(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type TestTagJSON1 struct { + Stings []string `xorm:"json"` + } + + assert.NoError(t, testEngine.Sync2(new(TestTagJSON1))) + + table := testEngine.TableInfo(new(TestTagJSON1)) + assert.NotNil(t, table) + assert.EqualValues(t, 1, len(table.Columns())) + assert.True(t, table.Columns()[0].IsJSON) + assert.EqualValues(t, "TEXT", table.Columns()[0].SQLType.Name) + + tables, err := testEngine.DBMetas() + assert.NoError(t, err) + assert.EqualValues(t, 1, len(tables)) + assert.EqualValues(t, 1, len(tables[0].Columns())) + if testEngine.dialect.DBType() != core.MSSQL { + assert.EqualValues(t, "TEXT", tables[0].Columns()[0].SQLType.Name) + } + assert.NoError(t, testEngine.DropTables(new(TestTagJSON1))) + + type TestTagJSON2 struct { + Stings []string `xorm:"json MediumText"` + } + + assert.NoError(t, testEngine.Sync2(new(TestTagJSON2))) + + table = testEngine.TableInfo(new(TestTagJSON2)) + assert.NotNil(t, table) + assert.EqualValues(t, 1, len(table.Columns())) + assert.True(t, table.Columns()[0].IsJSON) + assert.EqualValues(t, "MEDIUMTEXT", table.Columns()[0].SQLType.Name) + + tables, err = testEngine.DBMetas() + assert.NoError(t, err) + assert.EqualValues(t, 1, len(tables)) + assert.EqualValues(t, 1, len(tables[0].Columns())) + if testEngine.dialect.DBType() == core.MYSQL { + assert.EqualValues(t, "MEDIUMTEXT", tables[0].Columns()[0].SQLType.Name) + } +} diff --git a/test_mssql.sh b/test_mssql.sh index 7f060cff..a378089d 100755 --- a/test_mssql.sh +++ b/test_mssql.sh @@ -1 +1 @@ -go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test" \ No newline at end of file +go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test"