From a012756d38e973f6f2d7bad78a99520d943c6dd5 Mon Sep 17 00:00:00 2001 From: biless Date: Thu, 18 May 2017 10:37:20 +0800 Subject: [PATCH 1/2] fix pk can't set value when pk is point value or rename (#588) * fix pk can't set value when pk is point value * Revert "fix pk can't set value when pk is point value" This reverts commit e78c076e5768549b0b034b6820a7ba8f4e6bacba. * fix pk can't set value when pk is point value or rename * remove trace * fix insert nil pk in pg --- helpers.go | 59 ++++++++++++++++++++++++++++-------------- session_insert_test.go | 33 +++++++++++++++++++++++ 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/helpers.go b/helpers.go index 324c5bea..bac1fd9c 100644 --- a/helpers.go +++ b/helpers.go @@ -12,7 +12,6 @@ import ( "strconv" "strings" "time" - "github.com/go-xorm/core" ) @@ -196,25 +195,43 @@ func isArrayValueZero(v reflect.Value) bool { func int64ToIntValue(id int64, tp reflect.Type) reflect.Value { var v interface{} - switch tp.Kind() { - case reflect.Int16: - v = int16(id) - case reflect.Int32: - v = int32(id) - case reflect.Int: - v = int(id) - case reflect.Int64: - v = id - case reflect.Uint16: - v = uint16(id) - case reflect.Uint32: - v = uint32(id) - case reflect.Uint64: - v = uint64(id) - case reflect.Uint: - v = uint(id) + kind := tp.Kind() + + if kind == reflect.Ptr { + kind = tp.Elem().Kind() } - return reflect.ValueOf(v).Convert(tp) + + switch kind { + case reflect.Int16: + temp := int16(id) + v = &temp + case reflect.Int32: + temp := int32(id) + v = &temp + case reflect.Int: + temp := int(id) + v = &temp + case reflect.Int64: + temp := id + v = &temp + case reflect.Uint16: + temp := uint16(id) + v = &temp + case reflect.Uint32: + temp := uint32(id) + v = &temp + case reflect.Uint64: + temp := uint64(id) + v = &temp + case reflect.Uint: + temp := uint(id) + v = &temp + } + + if tp.Kind() == reflect.Ptr { + return reflect.ValueOf(v).Convert(tp) + } + return reflect.ValueOf(v).Elem().Convert(tp) } func int64ToInt(id int64, tp reflect.Type) interface{} { @@ -537,6 +554,10 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, if len(fieldValue.String()) == 0 { continue } + case reflect.Ptr: + if fieldValue.Pointer() == 0 { + continue + } } } diff --git a/session_insert_test.go b/session_insert_test.go index b232d3f7..32925b6a 100644 --- a/session_insert_test.go +++ b/session_insert_test.go @@ -26,3 +26,36 @@ func TestInsertOne(t *testing.T) { _, err := testEngine.InsertOne(data) assert.NoError(t, err) } + + +func TestInsertOneIfPkIsPoint(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type TestPoint struct { + Id *int64 `xorm:"autoincr pk notnull 'id'"` + Msg *string `xorm:"varchar(255)"` + Created *time.Time `xorm:"created"` + } + + assert.NoError(t, testEngine.Sync2(new(TestPoint))) + msg := "hi" + data := TestPoint{Msg: &msg} + _, err := testEngine.InsertOne(&data) + assert.NoError(t, err) +} + +func TestInsertOneIfPkIsPointRename (t *testing.T) { + assert.NoError(t, prepareEngine()) + type ID *int64 + type TestPoint struct { + Id ID `xorm:"autoincr pk notnull 'id'"` + Msg *string `xorm:"varchar(255)"` + Created *time.Time `xorm:"created"` + } + + assert.NoError(t, testEngine.Sync2(new(TestPoint))) + msg := "hi" + data := TestPoint{Msg: &msg} + _, err := testEngine.InsertOne(&data) + assert.NoError(t, err) +} \ No newline at end of file From 9d7e85c39db42f7c0f1f0c9c58a073e9fd6a069b Mon Sep 17 00:00:00 2001 From: Henry Huang Date: Mon, 22 May 2017 23:03:57 +0800 Subject: [PATCH 2/2] update for valueof interface (#578) --- session_insert.go | 2 +- session_insert_test.go | 93 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/session_insert.go b/session_insert.go index 2c8ad782..1b3f7fb9 100644 --- a/session_insert.go +++ b/session_insert.go @@ -67,7 +67,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error return 0, errors.New("could not insert a empty slice") } - if err := session.Statement.setRefValue(sliceValue.Index(0)); err != nil { + if err := session.Statement.setRefValue(reflect.ValueOf(sliceValue.Index(0).Interface())); err != nil { return 0, err } diff --git a/session_insert_test.go b/session_insert_test.go index 32925b6a..f0d26007 100644 --- a/session_insert_test.go +++ b/session_insert_test.go @@ -5,6 +5,8 @@ package xorm import ( + "fmt" + "reflect" "testing" "time" @@ -27,14 +29,89 @@ func TestInsertOne(t *testing.T) { assert.NoError(t, err) } +func TestInsertMulti(t *testing.T) { + + assert.NoError(t, prepareEngine()) + type TestMulti struct { + Id int64 `xorm:"int(11) pk"` + Name string `xorm:"varchar(255)"` + } + + assert.NoError(t, testEngine.Sync2(new(TestMulti))) + + num, err := insertMultiDatas(1, + append([]TestMulti{}, TestMulti{1, "test1"}, TestMulti{2, "test2"}, TestMulti{3, "test3"})) + assert.NoError(t, err) + assert.EqualValues(t, 3, num) +} + +func insertMultiDatas(step int, datas interface{}) (num int64, err error) { + sliceValue := reflect.Indirect(reflect.ValueOf(datas)) + var iLen int64 + if sliceValue.Kind() != reflect.Slice { + return 0, fmt.Errorf("not silce") + } + iLen = int64(sliceValue.Len()) + if iLen == 0 { + return + } + + session := testEngine.NewSession() + defer session.Close() + + if err = callbackLooper(datas, step, + func(innerDatas interface{}) error { + n, e := session.InsertMulti(innerDatas) + if e != nil { + return e + } + num += n + return nil + }); err != nil { + return 0, err + } else if num != iLen { + return 0, fmt.Errorf("num error: %d - %d", num, iLen) + } + return +} + +func callbackLooper(datas interface{}, step int, actionFunc func(interface{}) error) (err error) { + + sliceValue := reflect.Indirect(reflect.ValueOf(datas)) + if sliceValue.Kind() != reflect.Slice { + return fmt.Errorf("not slice") + } + if sliceValue.Len() <= 0 { + return + } + + tempLen := 0 + processedLen := sliceValue.Len() + for i := 0; i < sliceValue.Len(); i += step { + if processedLen > step { + tempLen = i + step + } else { + tempLen = sliceValue.Len() + } + var tempInterface []interface{} + for j := i; j < tempLen; j++ { + tempInterface = append(tempInterface, sliceValue.Index(j).Interface()) + } + if err = actionFunc(tempInterface); err != nil { + return + } + processedLen = processedLen - step + } + return +} func TestInsertOneIfPkIsPoint(t *testing.T) { assert.NoError(t, prepareEngine()) type TestPoint struct { - Id *int64 `xorm:"autoincr pk notnull 'id'"` - Msg *string `xorm:"varchar(255)"` - Created *time.Time `xorm:"created"` + Id *int64 `xorm:"autoincr pk notnull 'id'"` + Msg *string `xorm:"varchar(255)"` + Created *time.Time `xorm:"created"` } assert.NoError(t, testEngine.Sync2(new(TestPoint))) @@ -44,13 +121,13 @@ func TestInsertOneIfPkIsPoint(t *testing.T) { assert.NoError(t, err) } -func TestInsertOneIfPkIsPointRename (t *testing.T) { +func TestInsertOneIfPkIsPointRename(t *testing.T) { assert.NoError(t, prepareEngine()) type ID *int64 type TestPoint struct { - Id ID `xorm:"autoincr pk notnull 'id'"` - Msg *string `xorm:"varchar(255)"` - Created *time.Time `xorm:"created"` + Id ID `xorm:"autoincr pk notnull 'id'"` + Msg *string `xorm:"varchar(255)"` + Created *time.Time `xorm:"created"` } assert.NoError(t, testEngine.Sync2(new(TestPoint))) @@ -58,4 +135,4 @@ func TestInsertOneIfPkIsPointRename (t *testing.T) { data := TestPoint{Msg: &msg} _, err := testEngine.InsertOne(&data) assert.NoError(t, err) -} \ No newline at end of file +}