support different text type with JSON type
This commit is contained in:
parent
774f83c1bc
commit
18362d2340
|
@ -243,7 +243,7 @@ func (db *mssql) SqlType(c *core.Column) string {
|
||||||
c.Length = 7
|
c.Length = 7
|
||||||
case core.MediumInt:
|
case core.MediumInt:
|
||||||
res = core.Int
|
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)"
|
res = core.Varchar + "(MAX)"
|
||||||
case core.Double:
|
case core.Double:
|
||||||
res = core.Real
|
res = core.Real
|
||||||
|
|
|
@ -222,8 +222,6 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||||
case core.Uuid:
|
case core.Uuid:
|
||||||
res = core.Varchar
|
res = core.Varchar
|
||||||
c.Length = 40
|
c.Length = 40
|
||||||
case core.Json:
|
|
||||||
res = core.Text
|
|
||||||
default:
|
default:
|
||||||
res = t
|
res = t
|
||||||
}
|
}
|
||||||
|
|
|
@ -519,7 +519,7 @@ func (db *oracle) SqlType(c *core.Column) string {
|
||||||
res = "TIMESTAMP WITH TIME ZONE"
|
res = "TIMESTAMP WITH TIME ZONE"
|
||||||
case core.Float, core.Double, core.Numeric, core.Decimal:
|
case core.Float, core.Double, core.Numeric, core.Decimal:
|
||||||
res = "NUMBER"
|
res = "NUMBER"
|
||||||
case core.Text, core.MediumText, core.LongText, core.Json:
|
case core.Text, core.MediumText, core.LongText:
|
||||||
res = "CLOB"
|
res = "CLOB"
|
||||||
case core.Char, core.Varchar, core.TinyText:
|
case core.Char, core.Varchar, core.TinyText:
|
||||||
res = "VARCHAR2"
|
res = "VARCHAR2"
|
||||||
|
|
|
@ -165,7 +165,7 @@ func (db *sqlite3) SqlType(c *core.Column) string {
|
||||||
case core.TimeStampz:
|
case core.TimeStampz:
|
||||||
return core.Text
|
return core.Text
|
||||||
case core.Char, core.Varchar, core.NVarchar, core.TinyText,
|
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
|
return core.Text
|
||||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt:
|
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt:
|
||||||
return core.Integer
|
return core.Integer
|
||||||
|
|
|
@ -1023,7 +1023,6 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
table.AddColumn(col)
|
table.AddColumn(col)
|
||||||
|
|
||||||
} // end for
|
} // end for
|
||||||
|
|
||||||
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
|
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
|
||||||
|
|
|
@ -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) {
|
if engine.dialect.DBType() == core.MSSQL && (col.SQLType.Name == core.Text || col.SQLType.IsBlob() || col.SQLType.Name == core.TimeStampz) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if col.SQLType.IsJson() {
|
if col.IsJSON || col.SQLType.IsJson() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if col.SQLType.IsJson() {
|
if col.IsJSON || col.SQLType.IsJson() {
|
||||||
if col.SQLType.IsText() {
|
if col.SQLType.IsText() {
|
||||||
bytes, err := json.Marshal(fieldValue.Interface())
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -408,7 +408,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, f
|
||||||
fieldType := fieldValue.Type()
|
fieldType := fieldValue.Type()
|
||||||
hasAssigned := false
|
hasAssigned := false
|
||||||
|
|
||||||
if col.SQLType.IsJson() {
|
if col.IsJSON || col.SQLType.IsJson() {
|
||||||
var bs []byte
|
var bs []byte
|
||||||
if rawValueType.Kind() == reflect.String {
|
if rawValueType.Kind() == reflect.String {
|
||||||
bs = []byte(vv.String())
|
bs = []byte(vv.String())
|
||||||
|
@ -584,7 +584,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, f
|
||||||
session.Engine.logger.Error("sql.Sanner error:", err.Error())
|
session.Engine.logger.Error("sql.Sanner error:", err.Error())
|
||||||
hasAssigned = false
|
hasAssigned = false
|
||||||
}
|
}
|
||||||
} else if col.SQLType.IsJson() {
|
} else if col.IsJSON || col.SQLType.IsJson() {
|
||||||
if rawValueType.Kind() == reflect.String {
|
if rawValueType.Kind() == reflect.String {
|
||||||
hasAssigned = true
|
hasAssigned = true
|
||||||
x := reflect.New(fieldType)
|
x := reflect.New(fieldType)
|
||||||
|
|
|
@ -591,7 +591,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
return tf, nil
|
return tf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !col.SQLType.IsJson() {
|
if !(col.IsJSON || col.SQLType.IsJson()) {
|
||||||
// !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
|
// !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
|
||||||
if v, ok := fieldValue.Interface().(driver.Valuer); ok {
|
if v, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||||
return v.Value()
|
return v.Value()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +22,12 @@ func TestDelete(t *testing.T) {
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(UserinfoDelete)))
|
assert.NoError(t, testEngine.Sync2(new(UserinfoDelete)))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if testEngine.dialect.DBType() == core.MSSQL {
|
||||||
|
_, err = testEngine.Exec("SET IDENTITY_INSERT " + testEngine.TableMapper.Obj2Table("UserinfoDelete") + " ON")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
user := UserinfoDelete{Uid: 1}
|
user := UserinfoDelete{Uid: 1}
|
||||||
cnt, err := testEngine.Insert(&user)
|
cnt, err := testEngine.Insert(&user)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -37,10 +37,18 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if session.Engine.dialect.DBType() == core.MSSQL {
|
||||||
|
sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s WHERE %s", tableName, condSQL)
|
||||||
|
} else {
|
||||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
||||||
|
}
|
||||||
args = condArgs
|
args = condArgs
|
||||||
|
} else {
|
||||||
|
if session.Engine.dialect.DBType() == core.MSSQL {
|
||||||
|
sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s", tableName)
|
||||||
} else {
|
} else {
|
||||||
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
||||||
|
}
|
||||||
args = []interface{}{}
|
args = []interface{}{}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -380,7 +380,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
|
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||||
val, _ = nulType.Value()
|
val, _ = nulType.Value()
|
||||||
} else {
|
} else {
|
||||||
if !col.SQLType.IsJson() {
|
if !(col.IsJSON || col.SQLType.IsJson()) {
|
||||||
engine.autoMapType(fieldValue)
|
engine.autoMapType(fieldValue)
|
||||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||||
if len(table.PrimaryKeys) == 1 {
|
if len(table.PrimaryKeys) == 1 {
|
||||||
|
|
15
tag.go
15
tag.go
|
@ -55,13 +55,17 @@ var (
|
||||||
"CACHE": CacheTagHandler,
|
"CACHE": CacheTagHandler,
|
||||||
"NOCACHE": NoCacheTagHandler,
|
"NOCACHE": NoCacheTagHandler,
|
||||||
"COMMENT": CommentTagHandler,
|
"COMMENT": CommentTagHandler,
|
||||||
|
"JSON": JSONTagHandler,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
for k := range core.SqlTypes {
|
for k := range core.SqlTypes {
|
||||||
|
// don't overwrite
|
||||||
|
if _, ok := defaultTagHandlers[k]; !ok {
|
||||||
defaultTagHandlers[k] = SQLTypeTagHandler
|
defaultTagHandlers[k] = SQLTypeTagHandler
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IgnoreTagHandler describes ignored tag handler
|
// IgnoreTagHandler describes ignored tag handler
|
||||||
|
@ -241,8 +245,19 @@ func SQLTypeTagHandler(ctx *tagContext) error {
|
||||||
return nil
|
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
|
// ExtendsTagHandler describes extends tag handler
|
||||||
func ExtendsTagHandler(ctx *tagContext) error {
|
func ExtendsTagHandler(ctx *tagContext) error {
|
||||||
|
ctx.ignoreNext = true
|
||||||
var fieldValue = ctx.fieldValue
|
var fieldValue = ctx.fieldValue
|
||||||
switch fieldValue.Kind() {
|
switch fieldValue.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
|
45
tag_test.go
45
tag_test.go
|
@ -270,3 +270,48 @@ func TestTagComment(t *testing.T) {
|
||||||
assert.EqualValues(t, 1, len(tables[0].Columns()))
|
assert.EqualValues(t, 1, len(tables[0].Columns()))
|
||||||
assert.EqualValues(t, "主键", tables[0].Columns()[0].Comment)
|
assert.EqualValues(t, "主键", tables[0].Columns()[0].Comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test"
|
go test -db=mssql -conn_str="server=192.168.1.158;user id=sa;password=123456;database=xorm_test"
|
Loading…
Reference in New Issue