diff --git a/helpers.go b/helpers.go index 4e26e841..398ec679 100644 --- a/helpers.go +++ b/helpers.go @@ -180,6 +180,20 @@ func isStructZero(v reflect.Value) bool { return true } +func isArrayValueZero(v reflect.Value) bool { + if !v.IsValid() || v.Len() == 0 { + return true + } + + for i := 0; i < v.Len(); i++ { + if !isZero(v.Index(i).Interface()) { + return false + } + } + + return true +} + func int64ToIntValue(id int64, tp reflect.Type) reflect.Value { var v interface{} switch tp.Kind() { diff --git a/session.go b/session.go index 4e7c3a6c..0e4cfcf1 100644 --- a/session.go +++ b/session.go @@ -458,7 +458,21 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i case reflect.Uint8: if fieldType.Elem().Kind() == reflect.Uint8 { hasAssigned = true - fieldValue.Set(vv) + if col.SQLType.IsText() { + x := reflect.New(fieldType) + err := json.Unmarshal(vv.Bytes(), x.Interface()) + if err != nil { + session.Engine.logger.Error(err) + return nil, err + } + fieldValue.Set(x.Elem()) + } else { + for i := 0; i < fieldValue.Len(); i++ { + if i < vv.Len() { + fieldValue.Index(i).Set(vv.Index(i)) + } + } + } } } } diff --git a/statement.go b/statement.go index 78c83661..82101ff2 100644 --- a/statement.go +++ b/statement.go @@ -410,7 +410,11 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, if fieldValue == reflect.Zero(fieldType) { continue } - if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { + if fieldType.Kind() == reflect.Array { + if isArrayValueZero(fieldValue) { + continue + } + } else if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { continue } } @@ -425,13 +429,16 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, } else if col.SQLType.IsBlob() { var bytes []byte var err error - if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) && + if fieldType.Kind() == reflect.Slice && fieldType.Elem().Kind() == reflect.Uint8 { if fieldValue.Len() > 0 { val = fieldValue.Bytes() } else { continue } + } else if fieldType.Kind() == reflect.Array && + fieldType.Elem().Kind() == reflect.Uint8 { + val = fieldValue.Slice(0, 0).Interface() } else { bytes, err = json.Marshal(fieldValue.Interface()) if err != nil { @@ -643,7 +650,9 @@ func buildConds(engine *Engine, table *core.Table, bean interface{}, } } } - case reflect.Array, reflect.Slice, reflect.Map: + case reflect.Array: + continue + case reflect.Slice, reflect.Map: if fieldValue == reflect.Zero(fieldType) { continue } diff --git a/statement_test.go b/statement_test.go index 8fc092d2..eba4f698 100644 --- a/statement_test.go +++ b/statement_test.go @@ -1,3 +1,7 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package xorm import ( diff --git a/types_test.go b/types_test.go new file mode 100644 index 00000000..47c59de7 --- /dev/null +++ b/types_test.go @@ -0,0 +1,74 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestArrayField(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type ArrayStruct struct { + Id int64 + Name [20]byte `xorm:"char(20)"` + } + + assert.NoError(t, testEngine.Sync2(new(ArrayStruct))) + + var as = ArrayStruct{ + Name: [20]byte{ + 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + }, + } + cnt, err := testEngine.Insert(&as) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var arr ArrayStruct + has, err := testEngine.Id(1).Get(&arr) + assert.NoError(t, err) + assert.Equal(t, true, has) + assert.Equal(t, as.Name, arr.Name) + + var arrs []ArrayStruct + err = testEngine.Find(&arrs) + assert.NoError(t, err) + assert.EqualValues(t, 1, len(arrs)) + assert.Equal(t, as.Name, arrs[0].Name) + + var newName = [20]byte{ + 90, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, + } + + cnt, err = testEngine.ID(1).Update(&ArrayStruct{ + Name: newName, + }) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var newArr ArrayStruct + has, err = testEngine.ID(1).Get(&newArr) + assert.NoError(t, err) + assert.Equal(t, true, has) + assert.Equal(t, newName, newArr.Name) + + cnt, err = testEngine.ID(1).Delete(new(ArrayStruct)) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var cfgArr ArrayStruct + has, err = testEngine.ID(1).Get(&cfgArr) + assert.NoError(t, err) + assert.Equal(t, false, has) +} diff --git a/xorm_test.go b/xorm_test.go index b9adaee4..df77f281 100644 --- a/xorm_test.go +++ b/xorm_test.go @@ -12,6 +12,7 @@ import ( var ( testEngine *Engine dbType string + connStr string ) func prepareSqlite3Engine() error { @@ -27,9 +28,27 @@ func prepareSqlite3Engine() error { return nil } +func prepareMysqlEngine() error { + if testEngine == nil { + var err error + testEngine, err = NewEngine("mysql", connStr) + if err != nil { + return err + } + testEngine.ShowSQL(*showSQL) + _, err = testEngine.Exec("DROP DATABASE") + if err != nil { + return err + } + } + return nil +} + func prepareEngine() error { if dbType == "sqlite" { return prepareSqlite3Engine() + } else if dbType == "mysql" { + return prepareMysqlEngine() } return errors.New("Unknown test database driver") }