diff --git a/engine.go b/engine.go index 17d16063..4539f7aa 100644 --- a/engine.go +++ b/engine.go @@ -1545,7 +1545,17 @@ func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{} case core.Date: v = t.Format("2006-01-02") case core.DateTime, core.TimeStamp: +<<<<<<< HEAD v = t.Format("2006-01-02 15:04:05") +======= + if engine.dialect.DBType() == "ql" { + v = t + } else if engine.dialect.DBType() == "sqlite3" { + v = t.UTC().Format("2006-01-02 15:04:05") + } else { + v = t.Format("2006-01-02 15:04:05.999") + } +>>>>>>> 8c9ffa956bec4149aa6f6961ab1afe93ff93b2eb case core.TimeStampz: if engine.dialect.DBType() == core.MSSQL { v = t.Format("2006-01-02T15:04:05.9999999Z07:00") diff --git a/session_insert_test.go b/session_insert_test.go index d4878af6..b421e1b3 100644 --- a/session_insert_test.go +++ b/session_insert_test.go @@ -5,9 +5,6 @@ package xorm import ( - "errors" - "fmt" - "reflect" "testing" "time" @@ -30,635 +27,18 @@ 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) { +func TestInsertOne2(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"` + type Test2 struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + Created time.Time `xorm:"datetime created"` } - assert.NoError(t, testEngine.Sync2(new(TestPoint))) - msg := "hi" - data := TestPoint{Msg: &msg} - _, err := testEngine.InsertOne(&data) + assert.NoError(t, testEngine.Sync2(new(Test2))) + + data := Test2{Msg: "hi"} + _, err := testEngine.InsertOne(data) assert.NoError(t, err) } - -func TestInsertOneIfPkIsPointRename(t *testing.T) { - assert.NoError(t, prepareEngine()) - type ID *int64 - type TestPoint2 struct { - Id ID `xorm:"autoincr pk notnull 'id'"` - Msg *string `xorm:"varchar(255)"` - Created *time.Time `xorm:"created"` - } - - assert.NoError(t, testEngine.Sync2(new(TestPoint2))) - msg := "hi" - data := TestPoint2{Msg: &msg} - _, err := testEngine.InsertOne(&data) - assert.NoError(t, err) -} - -func TestInsert(t *testing.T) { - assert.NoError(t, prepareEngine()) - assertSync(t, new(Userinfo)) - - user := Userinfo{0, "xiaolunwen", "dev", "lunny", time.Now(), - Userdetail{Id: 1}, 1.78, []byte{1, 2, 3}, true} - cnt, err := testEngine.Insert(&user) - fmt.Println(user.Uid) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - } - - if user.Uid <= 0 { - err = errors.New("not return id error") - t.Error(err) - panic(err) - } - - user.Uid = 0 - cnt, err = testEngine.Insert(&user) - if err == nil { - err = errors.New("insert failed but no return error") - t.Error(err) - panic(err) - } - if cnt != 0 { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - return - } -} - -func TestInsertAutoIncr(t *testing.T) { - assert.NoError(t, prepareEngine()) - - assertSync(t, new(Userinfo)) - - // auto increment insert - user := Userinfo{Username: "xiaolunwen2", Departname: "dev", Alias: "lunny", Created: time.Now(), - Detail: Userdetail{Id: 1}, Height: 1.78, Avatar: []byte{1, 2, 3}, IsMan: true} - cnt, err := testEngine.Insert(&user) - fmt.Println(user.Uid) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - } - if user.Uid <= 0 { - t.Error(errors.New("not return id error")) - } -} - -type DefaultInsert struct { - Id int64 - Status int `xorm:"default -1"` - Name string - Created time.Time `xorm:"created"` - Updated time.Time `xorm:"updated"` -} - -func TestInsertDefault(t *testing.T) { - assert.NoError(t, prepareEngine()) - - di := new(DefaultInsert) - err := testEngine.Sync2(di) - if err != nil { - t.Error(err) - } - - var di2 = DefaultInsert{Name: "test"} - _, err = testEngine.Omit(testEngine.ColumnMapper.Obj2Table("Status")).Insert(&di2) - if err != nil { - t.Error(err) - } - - has, err := testEngine.Desc("(id)").Get(di) - if err != nil { - t.Error(err) - } - if !has { - err = errors.New("error with no data") - t.Error(err) - panic(err) - } - if di.Status != -1 { - err = errors.New("inserted error data") - t.Error(err) - panic(err) - } - if di2.Updated.Unix() != di.Updated.Unix() { - err = errors.New("updated should equal") - t.Error(err, di.Updated, di2.Updated) - panic(err) - } - if di2.Created.Unix() != di.Created.Unix() { - err = errors.New("created should equal") - t.Error(err, di.Created, di2.Created) - panic(err) - } -} - -type DefaultInsert2 struct { - Id int64 - Name string - Url string `xorm:"text"` - CheckTime time.Time `xorm:"not null default '2000-01-01 00:00:00' TIMESTAMP"` -} - -func TestInsertDefault2(t *testing.T) { - assert.NoError(t, prepareEngine()) - - di := new(DefaultInsert2) - err := testEngine.Sync2(di) - if err != nil { - t.Error(err) - } - - var di2 = DefaultInsert2{Name: "test"} - _, err = testEngine.Omit(testEngine.ColumnMapper.Obj2Table("CheckTime")).Insert(&di2) - if err != nil { - t.Error(err) - } - - has, err := testEngine.Desc("(id)").Get(di) - if err != nil { - t.Error(err) - } - if !has { - err = errors.New("error with no data") - t.Error(err) - panic(err) - } - - has, err = testEngine.NoAutoCondition().Desc("(id)").Get(&di2) - if err != nil { - t.Error(err) - } - - if !has { - err = errors.New("error with no data") - t.Error(err) - panic(err) - } - - if *di != di2 { - err = fmt.Errorf("%v is not equal to %v", di, di2) - t.Error(err) - panic(err) - } - - /*if di2.Updated.Unix() != di.Updated.Unix() { - err = errors.New("updated should equal") - t.Error(err, di.Updated, di2.Updated) - panic(err) - } - if di2.Created.Unix() != di.Created.Unix() { - err = errors.New("created should equal") - t.Error(err, di.Created, di2.Created) - panic(err) - }*/ -} - -type CreatedInsert struct { - Id int64 - Created time.Time `xorm:"created"` -} - -type CreatedInsert2 struct { - Id int64 - Created int64 `xorm:"created"` -} - -type CreatedInsert3 struct { - Id int64 - Created int `xorm:"created bigint"` -} - -type CreatedInsert4 struct { - Id int64 - Created int `xorm:"created"` -} - -type CreatedInsert5 struct { - Id int64 - Created time.Time `xorm:"created bigint"` -} - -type CreatedInsert6 struct { - Id int64 - Created time.Time `xorm:"created bigint"` -} - -func TestInsertCreated(t *testing.T) { - assert.NoError(t, prepareEngine()) - - di := new(CreatedInsert) - err := testEngine.Sync2(di) - if err != nil { - t.Fatal(err) - } - ci := &CreatedInsert{} - _, err = testEngine.Insert(ci) - if err != nil { - t.Fatal(err) - } - - has, err := testEngine.Desc("(id)").Get(di) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci.Created.Unix() != di.Created.Unix() { - t.Fatal("should equal:", ci, di) - } - fmt.Println("ci:", ci, "di:", di) - - di2 := new(CreatedInsert2) - err = testEngine.Sync2(di2) - if err != nil { - t.Fatal(err) - } - ci2 := &CreatedInsert2{} - _, err = testEngine.Insert(ci2) - if err != nil { - t.Fatal(err) - } - has, err = testEngine.Desc("(id)").Get(di2) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci2.Created != di2.Created { - t.Fatal("should equal:", ci2, di2) - } - fmt.Println("ci2:", ci2, "di2:", di2) - - di3 := new(CreatedInsert3) - err = testEngine.Sync2(di3) - if err != nil { - t.Fatal(err) - } - ci3 := &CreatedInsert3{} - _, err = testEngine.Insert(ci3) - if err != nil { - t.Fatal(err) - } - has, err = testEngine.Desc("(id)").Get(di3) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci3.Created != di3.Created { - t.Fatal("should equal:", ci3, di3) - } - fmt.Println("ci3:", ci3, "di3:", di3) - - di4 := new(CreatedInsert4) - err = testEngine.Sync2(di4) - if err != nil { - t.Fatal(err) - } - ci4 := &CreatedInsert4{} - _, err = testEngine.Insert(ci4) - if err != nil { - t.Fatal(err) - } - has, err = testEngine.Desc("(id)").Get(di4) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci4.Created != di4.Created { - t.Fatal("should equal:", ci4, di4) - } - fmt.Println("ci4:", ci4, "di4:", di4) - - di5 := new(CreatedInsert5) - err = testEngine.Sync2(di5) - if err != nil { - t.Fatal(err) - } - ci5 := &CreatedInsert5{} - _, err = testEngine.Insert(ci5) - if err != nil { - t.Fatal(err) - } - has, err = testEngine.Desc("(id)").Get(di5) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci5.Created.Unix() != di5.Created.Unix() { - t.Fatal("should equal:", ci5, di5) - } - fmt.Println("ci5:", ci5, "di5:", di5) - - di6 := new(CreatedInsert6) - err = testEngine.Sync2(di6) - if err != nil { - t.Fatal(err) - } - oldTime := time.Now().Add(-time.Hour) - ci6 := &CreatedInsert6{Created: oldTime} - _, err = testEngine.Insert(ci6) - if err != nil { - t.Fatal(err) - } - - has, err = testEngine.Desc("(id)").Get(di6) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci6.Created.Unix() != di6.Created.Unix() { - t.Fatal("should equal:", ci6, di6) - } - fmt.Println("ci6:", ci6, "di6:", di6) -} - -type JsonTime time.Time - -func (j JsonTime) format() string { - t := time.Time(j) - if t.IsZero() { - return "" - } - - return t.Format("2006-01-02") -} - -func (j JsonTime) MarshalText() ([]byte, error) { - return []byte(j.format()), nil -} - -func (j JsonTime) MarshalJSON() ([]byte, error) { - return []byte(`"` + j.format() + `"`), nil -} - -func TestDefaultTime3(t *testing.T) { - type PrepareTask struct { - Id int `xorm:"not null pk autoincr INT(11)" json:"id"` - // ... - StartTime JsonTime `xorm:"not null default '2006-01-02 15:04:05' TIMESTAMP index" json:"start_time"` - EndTime JsonTime `xorm:"not null default '2006-01-02 15:04:05' TIMESTAMP" json:"end_time"` - Cuser string `xorm:"not null default '' VARCHAR(64) index" json:"cuser"` - Muser string `xorm:"not null default '' VARCHAR(64)" json:"muser"` - Ctime JsonTime `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP created" json:"ctime"` - Mtime JsonTime `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP updated" json:"mtime"` - } - - assert.NoError(t, prepareEngine()) - assertSync(t, new(PrepareTask)) - - prepareTask := &PrepareTask{ - StartTime: JsonTime(time.Now()), - Cuser: "userId", - Muser: "userId", - } - cnt, err := testEngine.Omit("end_time").InsertOne(prepareTask) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) -} - -type MyJsonTime struct { - Id int64 `json:"id"` - Created JsonTime `xorm:"created" json:"created_at"` -} - -func TestCreatedJsonTime(t *testing.T) { - assert.NoError(t, prepareEngine()) - - di5 := new(MyJsonTime) - err := testEngine.Sync2(di5) - if err != nil { - t.Fatal(err) - } - ci5 := &MyJsonTime{} - _, err = testEngine.Insert(ci5) - if err != nil { - t.Fatal(err) - } - has, err := testEngine.Desc("(id)").Get(di5) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if time.Time(ci5.Created).Unix() != time.Time(di5.Created).Unix() { - t.Fatal("should equal:", time.Time(ci5.Created).Unix(), time.Time(di5.Created).Unix()) - } - fmt.Println("ci5:", ci5, "di5:", di5) - - var dis = make([]MyJsonTime, 0) - err = testEngine.Find(&dis) - if err != nil { - t.Fatal(err) - } -} - -func TestInsertMulti2(t *testing.T) { - assert.NoError(t, prepareEngine()) - - assertSync(t, new(Userinfo)) - - users := []Userinfo{ - {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()}, - {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()}, - {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()}, - {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()}, - } - cnt, err := testEngine.Insert(&users) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != int64(len(users)) { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - return - } - - users2 := []*Userinfo{ - &Userinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()}, - &Userinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()}, - &Userinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()}, - &Userinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()}, - } - - cnt, err = testEngine.Insert(&users2) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != int64(len(users2)) { - err = errors.New(fmt.Sprintf("insert not returned %v", len(users2))) - t.Error(err) - panic(err) - } -} - -func TestInsertTwoTable(t *testing.T) { - assert.NoError(t, prepareEngine()) - - assertSync(t, new(Userinfo), new(Userdetail)) - - userdetail := Userdetail{ /*Id: 1, */ Intro: "I'm a very beautiful women.", Profile: "sfsaf"} - userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now(), Detail: userdetail} - - cnt, err := testEngine.Insert(&userinfo, &userdetail) - if err != nil { - t.Error(err) - panic(err) - } - - if userinfo.Uid <= 0 { - err = errors.New("not return id error") - t.Error(err) - panic(err) - } - - if userdetail.Id <= 0 { - err = errors.New("not return id error") - t.Error(err) - panic(err) - } - - if cnt != 2 { - err = errors.New("insert not returned 2") - t.Error(err) - panic(err) - } -} - -func TestInsertCreatedInt64(t *testing.T) { - assert.NoError(t, prepareEngine()) - - type TestCreatedInt64 struct { - Id int64 `xorm:"autoincr pk"` - Msg string `xorm:"varchar(255)"` - Created int64 `xorm:"created"` - } - - assert.NoError(t, testEngine.Sync2(new(TestCreatedInt64))) - - data := TestCreatedInt64{Msg: "hi"} - now := time.Now() - cnt, err := testEngine.Insert(&data) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) - assert.True(t, now.Unix() <= data.Created) - - var data2 TestCreatedInt64 - has, err := testEngine.Get(&data2) - assert.NoError(t, err) - assert.True(t, has) - - assert.EqualValues(t, data.Created, data2.Created) -} diff --git a/session_update_test.go b/session_update_test.go index 690bd106..a6aa805c 100644 --- a/session_update_test.go +++ b/session_update_test.go @@ -5,13 +5,9 @@ package xorm import ( - "errors" - "fmt" - "sync" "testing" "time" - "github.com/go-xorm/core" "github.com/stretchr/testify/assert" ) @@ -43,14 +39,14 @@ func TestUpdateMap(t *testing.T) { func TestUpdateLimit(t *testing.T) { assert.NoError(t, prepareEngine()) - type UpdateTable2 struct { + type UpdateTable struct { Id int64 Name string Age int } - assert.NoError(t, testEngine.Sync2(new(UpdateTable2))) - var tb = UpdateTable2{ + assert.NoError(t, testEngine.Sync2(new(UpdateTable))) + var tb = UpdateTable{ Name: "test1", Age: 35, } @@ -64,13 +60,13 @@ func TestUpdateLimit(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - cnt, err = testEngine.OrderBy("name desc").Limit(1).Update(&UpdateTable2{ + cnt, err = testEngine.OrderBy("name desc").Limit(1).Update(&UpdateTable{ Age: 30, }) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - var uts []UpdateTable2 + var uts []UpdateTable err = testEngine.Find(&uts) assert.NoError(t, err) assert.EqualValues(t, 2, len(uts)) @@ -78,1140 +74,27 @@ func TestUpdateLimit(t *testing.T) { assert.EqualValues(t, 30, uts[1].Age) } -type ForUpdate struct { - Id int64 `xorm:"pk"` - Name string -} - -func setupForUpdate(engine *Engine) error { - v := new(ForUpdate) - err := testEngine.DropTables(v) - if err != nil { - return err - } - err = testEngine.CreateTables(v) - if err != nil { - return err - } - - list := []ForUpdate{ - {1, "data1"}, - {2, "data2"}, - {3, "data3"}, - } - - for _, f := range list { - _, err = testEngine.Insert(f) - if err != nil { - return err - } - } - return nil -} - -func TestForUpdate(t *testing.T) { - if testEngine.DriverName() != "mysql" && testEngine.DriverName() != "mymysql" { - return - } - - err := setupForUpdate(testEngine) - if err != nil { - t.Error(err) - return - } - - session1 := testEngine.NewSession() - session2 := testEngine.NewSession() - session3 := testEngine.NewSession() - defer session1.Close() - defer session2.Close() - defer session3.Close() - - // start transaction - err = session1.Begin() - if err != nil { - t.Error(err) - return - } - - // use lock - fList := make([]ForUpdate, 0) - session1.ForUpdate() - session1.Where("(id) = ?", 1) - err = session1.Find(&fList) - switch { - case err != nil: - t.Error(err) - return - case len(fList) != 1: - t.Errorf("find not returned single row") - return - case fList[0].Name != "data1": - t.Errorf("for_update.name must be `data1`") - return - } - - // wait for lock - wg := &sync.WaitGroup{} - - // lock is used - wg.Add(1) - go func() { - f2 := new(ForUpdate) - session2.Where("(id) = ?", 1).ForUpdate() - has, err := session2.Get(f2) // wait release lock - switch { - case err != nil: - t.Error(err) - case !has: - t.Errorf("cannot find target row. for_update.id = 1") - case f2.Name != "updated by session1": - t.Errorf("read lock failed") - } - wg.Done() - }() - - // lock is NOT used - wg.Add(1) - go func() { - f3 := new(ForUpdate) - session3.Where("(id) = ?", 1) - has, err := session3.Get(f3) // wait release lock - switch { - case err != nil: - t.Error(err) - case !has: - t.Errorf("cannot find target row. for_update.id = 1") - case f3.Name != "data1": - t.Errorf("read lock failed") - } - wg.Done() - }() - - // wait for go rountines - time.Sleep(50 * time.Millisecond) - - f := new(ForUpdate) - f.Name = "updated by session1" - session1.Where("(id) = ?", 1) - session1.Update(f) - - // release lock - err = session1.Commit() - if err != nil { - t.Error(err) - return - } - - wg.Wait() -} - -func TestWithIn(t *testing.T) { - type temp3 struct { - Id int64 `xorm:"Id pk autoincr"` - Name string `xorm:"Name"` - Test bool `xorm:"Test"` - } - - assert.NoError(t, prepareEngine()) - assert.NoError(t, testEngine.Sync(new(temp3))) - - testEngine.Insert(&[]temp3{ - { - Name: "user1", - }, - { - Name: "user1", - }, - { - Name: "user1", - }, - }) - - cnt, err := testEngine.In("Id", 1, 2, 3, 4).Update(&temp3{Name: "aa"}, &temp3{Name: "user1"}) - assert.NoError(t, err) - assert.EqualValues(t, 3, cnt) -} - -type Condi map[string]interface{} - -type UpdateAllCols struct { - Id int64 - Bool bool - String string - Ptr *string -} - -type UpdateMustCols struct { - Id int64 - Bool bool - String string -} - -type UpdateIncr struct { - Id int64 - Cnt int - Name string -} - -type Article struct { - Id int32 `xorm:"pk INT autoincr"` - Name string `xorm:"VARCHAR(45)"` - Img string `xorm:"VARCHAR(100)"` - Aside string `xorm:"VARCHAR(200)"` - Desc string `xorm:"VARCHAR(200)"` - Content string `xorm:"TEXT"` - Status int8 `xorm:"TINYINT(4)"` -} - -func TestUpdateMap2(t *testing.T) { - assert.NoError(t, prepareEngine()) - assertSync(t, new(UpdateMustCols)) - - _, err := testEngine.Table("update_must_cols").Where("id =?", 1).Update(map[string]interface{}{ - "bool": true, - }) - if err != nil { - t.Error(err) - panic(err) - } -} - -func TestUpdate1(t *testing.T) { - assert.NoError(t, prepareEngine()) - assertSync(t, new(Userinfo)) - - _, err := testEngine.Insert(&Userinfo{ - Username: "user1", - }) - - var ori Userinfo - has, err := testEngine.Get(&ori) - if err != nil { - t.Error(err) - panic(err) - } - if !has { - t.Error(errors.New("not exist")) - panic(errors.New("not exist")) - } - - // update by id - user := Userinfo{Username: "xxx", Height: 1.2} - cnt, err := testEngine.ID(ori.Uid).Update(&user) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("update not returned 1") - t.Error(err) - panic(err) - return - } - - condi := Condi{"username": "zzz", "departname": ""} - cnt, err = testEngine.Table(&user).ID(ori.Uid).Update(&condi) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("update not returned 1") - t.Error(err) - panic(err) - return - } - - cnt, err = testEngine.Update(&Userinfo{Username: "yyy"}, &user) - if err != nil { - t.Error(err) - panic(err) - } - total, err := testEngine.Count(&user) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != total { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - return - } - - // nullable update - { - user := &Userinfo{Username: "not null data", Height: 180.5} - _, err := testEngine.Insert(user) - if err != nil { - t.Error(err) - panic(err) - } - userID := user.Uid - - has, err := testEngine.ID(userID). - And("username = ?", user.Username). - And("height = ?", user.Height). - And("departname = ?", ""). - And("detail_id = ?", 0). - And("is_man = ?", 0). - Get(&Userinfo{}) - if err != nil { - t.Error(err) - panic(err) - } - if !has { - err = errors.New("cannot insert properly") - t.Error(err) - panic(err) - } - - updatedUser := &Userinfo{Username: "null data"} - cnt, err = testEngine.ID(userID). - Nullable("height", "departname", "is_man", "created"). - Update(updatedUser) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("update not returned 1") - t.Error(err) - panic(err) - } - - has, err = testEngine.ID(userID). - And("username = ?", updatedUser.Username). - And("height IS NULL"). - And("departname IS NULL"). - And("is_man IS NULL"). - And("created IS NULL"). - And("detail_id = ?", 0). - Get(&Userinfo{}) - if err != nil { - t.Error(err) - panic(err) - } - if !has { - err = errors.New("cannot update with null properly") - t.Error(err) - panic(err) - } - - cnt, err = testEngine.ID(userID).Delete(&Userinfo{}) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("delete not returned 1") - t.Error(err) - panic(err) - } - } - - err = testEngine.StoreEngine("Innodb").Sync2(&Article{}) - if err != nil { - t.Error(err) - panic(err) - } - - defer func() { - err = testEngine.DropTables(&Article{}) - if err != nil { - t.Error(err) - panic(err) - } - }() - - a := &Article{0, "1", "2", "3", "4", "5", 2} - cnt, err = testEngine.Insert(a) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != 1 { - err = errors.New(fmt.Sprintf("insert not returned 1 but %d", cnt)) - t.Error(err) - panic(err) - } - - if a.Id == 0 { - err = errors.New("insert returned id is 0") - t.Error(err) - panic(err) - } - - cnt, err = testEngine.ID(a.Id).Update(&Article{Name: "6"}) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != 1 { - err = errors.New(fmt.Sprintf("insert not returned 1 but %d", cnt)) - t.Error(err) - panic(err) - return - } - - var s = "test" - - col1 := &UpdateAllCols{Ptr: &s} - err = testEngine.Sync(col1) - if err != nil { - t.Error(err) - panic(err) - } - - _, err = testEngine.Insert(col1) - if err != nil { - t.Error(err) - panic(err) - } - - col2 := &UpdateAllCols{col1.Id, true, "", nil} - _, err = testEngine.ID(col2.Id).AllCols().Update(col2) - if err != nil { - t.Error(err) - panic(err) - } - - col3 := &UpdateAllCols{} - has, err = testEngine.ID(col2.Id).Get(col3) - if err != nil { - t.Error(err) - panic(err) - } - - if !has { - err = errors.New(fmt.Sprintf("cannot get id %d", col2.Id)) - t.Error(err) - panic(err) - return - } - - if *col2 != *col3 { - err = errors.New(fmt.Sprintf("col2 should eq col3")) - t.Error(err) - panic(err) - return - } - - { - - col1 := &UpdateMustCols{} - err = testEngine.Sync(col1) - if err != nil { - t.Error(err) - panic(err) - } - - _, err = testEngine.Insert(col1) - if err != nil { - t.Error(err) - panic(err) - } - - col2 := &UpdateMustCols{col1.Id, true, ""} - boolStr := testEngine.ColumnMapper.Obj2Table("Bool") - stringStr := testEngine.ColumnMapper.Obj2Table("String") - _, err = testEngine.ID(col2.Id).MustCols(boolStr, stringStr).Update(col2) - if err != nil { - t.Error(err) - panic(err) - } - - col3 := &UpdateMustCols{} - has, err := testEngine.ID(col2.Id).Get(col3) - if err != nil { - t.Error(err) - panic(err) - } - - if !has { - err = errors.New(fmt.Sprintf("cannot get id %d", col2.Id)) - t.Error(err) - panic(err) - return - } - - if *col2 != *col3 { - err = errors.New(fmt.Sprintf("col2 should eq col3")) - t.Error(err) - panic(err) - return - } - } -} - -func TestUpdateIncrDecr(t *testing.T) { +func TestUpdate(t *testing.T) { assert.NoError(t, prepareEngine()) - col1 := &UpdateIncr{ - Name: "test", + type UpdateTable2 struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + Created time.Time `xorm:"datetime updated"` } - assert.NoError(t, testEngine.Sync(col1)) - _, err := testEngine.Insert(col1) - assert.NoError(t, err) + assert.NoError(t, testEngine.Sync2(new(UpdateTable2))) - colName := testEngine.ColumnMapper.Obj2Table("Cnt") + data := UpdateTable2{Msg: "test1"} - cnt, err := testEngine.ID(col1.Id).Incr(colName).Update(col1) + cnt, err := testEngine.Insert(&data) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - newCol := new(UpdateIncr) - has, err := testEngine.ID(col1.Id).Get(newCol) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 1, newCol.Cnt) - - cnt, err = testEngine.ID(col1.Id).Decr(colName).Update(col1) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) - - newCol = new(UpdateIncr) - has, err = testEngine.ID(col1.Id).Get(newCol) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 0, newCol.Cnt) - - cnt, err = testEngine.ID(col1.Id).Cols(colName).Incr(colName).Update(col1) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) -} - -type UpdatedUpdate struct { - Id int64 - Updated time.Time `xorm:"updated"` -} - -type UpdatedUpdate2 struct { - Id int64 - Updated int64 `xorm:"updated"` -} - -type UpdatedUpdate3 struct { - Id int64 - Updated int `xorm:"updated bigint"` -} - -type UpdatedUpdate4 struct { - Id int64 - Updated int `xorm:"updated"` -} - -type UpdatedUpdate5 struct { - Id int64 - Updated time.Time `xorm:"updated bigint"` -} - -func TestUpdateUpdated(t *testing.T) { - assert.NoError(t, prepareEngine()) - - di := new(UpdatedUpdate) - err := testEngine.Sync2(di) - if err != nil { - t.Fatal(err) - } - - _, err = testEngine.Insert(&UpdatedUpdate{}) - if err != nil { - t.Fatal(err) - } - - ci := &UpdatedUpdate{} - _, err = testEngine.ID(1).Update(ci) - if err != nil { - t.Fatal(err) - } - - has, err := testEngine.ID(1).Get(di) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci.Updated.Unix() != di.Updated.Unix() { - t.Fatal("should equal:", ci, di) - } - fmt.Println("ci:", ci, "di:", di) - - di2 := new(UpdatedUpdate2) - err = testEngine.Sync2(di2) - assert.NoError(t, err) - - now := time.Now() - var di20 UpdatedUpdate2 - cnt, err := testEngine.Insert(&di20) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) - assert.True(t, now.Unix() <= di20.Updated) - - var di21 UpdatedUpdate2 - has, err = testEngine.ID(di20.Id).Get(&di21) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, di20.Updated, di21.Updated) - - ci2 := &UpdatedUpdate2{} - _, err = testEngine.ID(1).Update(ci2) - assert.NoError(t, err) - - has, err = testEngine.ID(1).Get(di2) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, ci2.Updated, di2.Updated) - assert.True(t, ci2.Updated >= di21.Updated) - - di3 := new(UpdatedUpdate3) - err = testEngine.Sync2(di3) - if err != nil { - t.Fatal(err) - } - - _, err = testEngine.Insert(&UpdatedUpdate3{}) - if err != nil { - t.Fatal(err) - } - ci3 := &UpdatedUpdate3{} - _, err = testEngine.ID(1).Update(ci3) - if err != nil { - t.Fatal(err) - } - - has, err = testEngine.ID(1).Get(di3) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci3.Updated != di3.Updated { - t.Fatal("should equal:", ci3, di3) - } - fmt.Println("ci3:", ci3, "di3:", di3) - - di4 := new(UpdatedUpdate4) - err = testEngine.Sync2(di4) - if err != nil { - t.Fatal(err) - } - - _, err = testEngine.Insert(&UpdatedUpdate4{}) - if err != nil { - t.Fatal(err) - } - - ci4 := &UpdatedUpdate4{} - _, err = testEngine.ID(1).Update(ci4) - if err != nil { - t.Fatal(err) - } - - has, err = testEngine.ID(1).Get(di4) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci4.Updated != di4.Updated { - t.Fatal("should equal:", ci4, di4) - } - fmt.Println("ci4:", ci4, "di4:", di4) - - di5 := new(UpdatedUpdate5) - err = testEngine.Sync2(di5) - if err != nil { - t.Fatal(err) - } - - _, err = testEngine.Insert(&UpdatedUpdate5{}) - if err != nil { - t.Fatal(err) - } - ci5 := &UpdatedUpdate5{} - _, err = testEngine.ID(1).Update(ci5) - if err != nil { - t.Fatal(err) - } - - has, err = testEngine.ID(1).Get(di5) - if err != nil { - t.Fatal(err) - } - if !has { - t.Fatal(ErrNotExist) - } - if ci5.Updated.Unix() != di5.Updated.Unix() { - t.Fatal("should equal:", ci5, di5) - } - fmt.Println("ci5:", ci5, "di5:", di5) -} - -func TestUpdateSameMapper(t *testing.T) { - assert.NoError(t, prepareEngine()) - - oldMapper := testEngine.ColumnMapper - testEngine.unMapType(rValue(new(Userinfo)).Type()) - testEngine.unMapType(rValue(new(Condi)).Type()) - testEngine.unMapType(rValue(new(Article)).Type()) - testEngine.unMapType(rValue(new(UpdateAllCols)).Type()) - testEngine.unMapType(rValue(new(UpdateMustCols)).Type()) - testEngine.unMapType(rValue(new(UpdateIncr)).Type()) - testEngine.SetMapper(core.SameMapper{}) - defer func() { - testEngine.unMapType(rValue(new(Userinfo)).Type()) - testEngine.unMapType(rValue(new(Condi)).Type()) - testEngine.unMapType(rValue(new(Article)).Type()) - testEngine.unMapType(rValue(new(UpdateAllCols)).Type()) - testEngine.unMapType(rValue(new(UpdateMustCols)).Type()) - testEngine.unMapType(rValue(new(UpdateIncr)).Type()) - testEngine.SetMapper(oldMapper) - }() - - assertSync(t, new(Userinfo)) - - _, err := testEngine.Insert(&Userinfo{ - Username: "user1", - }) - assert.NoError(t, err) - - var ori Userinfo - has, err := testEngine.Get(&ori) - if err != nil { - t.Error(err) - panic(err) - } - if !has { - t.Error(errors.New("not exist")) - panic(errors.New("not exist")) - } - // update by id - user := Userinfo{Username: "xxx", Height: 1.2} - cnt, err := testEngine.ID(ori.Uid).Update(&user) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("update not returned 1") - t.Error(err) - panic(err) - return - } - - condi := Condi{"Username": "zzz", "Departname": ""} - cnt, err = testEngine.Table(&user).ID(ori.Uid).Update(&condi) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != 1 { - err = errors.New("update not returned 1") - t.Error(err) - panic(err) - return - } - - cnt, err = testEngine.Update(&Userinfo{Username: "yyy"}, &user) - if err != nil { - t.Error(err) - panic(err) - } - - total, err := testEngine.Count(&user) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != total { - err = errors.New("insert not returned 1") - t.Error(err) - panic(err) - return - } - - err = testEngine.Sync(&Article{}) - if err != nil { - t.Error(err) - panic(err) - } - - defer func() { - err = testEngine.DropTables(&Article{}) - if err != nil { - t.Error(err) - panic(err) - } - }() - - a := &Article{0, "1", "2", "3", "4", "5", 2} - cnt, err = testEngine.Insert(a) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != 1 { - err = errors.New(fmt.Sprintf("insert not returned 1 but %d", cnt)) - t.Error(err) - panic(err) - } - - if a.Id == 0 { - err = errors.New("insert returned id is 0") - t.Error(err) - panic(err) - } - - cnt, err = testEngine.ID(a.Id).Update(&Article{Name: "6"}) - if err != nil { - t.Error(err) - panic(err) - } - - if cnt != 1 { - err = errors.New(fmt.Sprintf("insert not returned 1 but %d", cnt)) - t.Error(err) - panic(err) - return - } - - col1 := &UpdateAllCols{} - err = testEngine.Sync(col1) - if err != nil { - t.Error(err) - panic(err) - } - - _, err = testEngine.Insert(col1) - if err != nil { - t.Error(err) - panic(err) - } - - col2 := &UpdateAllCols{col1.Id, true, "", nil} - _, err = testEngine.ID(col2.Id).AllCols().Update(col2) - if err != nil { - t.Error(err) - panic(err) - } - - col3 := &UpdateAllCols{} - has, err = testEngine.ID(col2.Id).Get(col3) - if err != nil { - t.Error(err) - panic(err) - } - - if !has { - err = errors.New(fmt.Sprintf("cannot get id %d", col2.Id)) - t.Error(err) - panic(err) - return - } - - if *col2 != *col3 { - err = errors.New(fmt.Sprintf("col2 should eq col3")) - t.Error(err) - panic(err) - return - } - - { - col1 := &UpdateMustCols{} - err = testEngine.Sync(col1) - if err != nil { - t.Error(err) - panic(err) - } - - _, err = testEngine.Insert(col1) - if err != nil { - t.Error(err) - panic(err) - } - - col2 := &UpdateMustCols{col1.Id, true, ""} - boolStr := testEngine.ColumnMapper.Obj2Table("Bool") - stringStr := testEngine.ColumnMapper.Obj2Table("String") - _, err = testEngine.ID(col2.Id).MustCols(boolStr, stringStr).Update(col2) - if err != nil { - t.Error(err) - panic(err) - } - - col3 := &UpdateMustCols{} - has, err := testEngine.ID(col2.Id).Get(col3) - if err != nil { - t.Error(err) - panic(err) - } - - if !has { - err = errors.New(fmt.Sprintf("cannot get id %d", col2.Id)) - t.Error(err) - panic(err) - return - } - - if *col2 != *col3 { - err = errors.New(fmt.Sprintf("col2 should eq col3")) - t.Error(err) - panic(err) - return - } - } - - { - - col1 := &UpdateIncr{} - err = testEngine.Sync(col1) - if err != nil { - t.Error(err) - panic(err) - } - - _, err = testEngine.Insert(col1) - if err != nil { - t.Error(err) - panic(err) - } - - cnt, err := testEngine.ID(col1.Id).Incr("`Cnt`").Update(col1) - if err != nil { - t.Error(err) - panic(err) - } - if cnt != 1 { - err = errors.New("update incr failed") - t.Error(err) - panic(err) - } - - newCol := new(UpdateIncr) - has, err := testEngine.ID(col1.Id).Get(newCol) - if err != nil { - t.Error(err) - panic(err) - } - if !has { - err = errors.New("has incr failed") - t.Error(err) - panic(err) - } - if 1 != newCol.Cnt { - err = errors.New("incr failed") - t.Error(err) - panic(err) - } - } -} - -func TestUseBool(t *testing.T) { - assert.NoError(t, prepareEngine()) - assertSync(t, new(Userinfo)) - - cnt1, err := testEngine.Count(&Userinfo{}) - if err != nil { - t.Error(err) - panic(err) - } - - users := make([]Userinfo, 0) - err = testEngine.Find(&users) - if err != nil { - t.Error(err) - panic(err) - } - var fNumber int64 - for _, u := range users { - if u.IsMan == false { - fNumber += 1 - } - } - - cnt2, err := testEngine.UseBool().Update(&Userinfo{IsMan: true}) - if err != nil { - t.Error(err) - panic(err) - } - if fNumber != cnt2 { - fmt.Println("cnt1", cnt1, "fNumber", fNumber, "cnt2", cnt2) - /*err = errors.New("Updated number is not corrected.") - t.Error(err) - panic(err)*/ - } - - _, err = testEngine.Update(&Userinfo{IsMan: true}) - if err == nil { - err = errors.New("error condition") - t.Error(err) - panic(err) - } -} - -func TestBool(t *testing.T) { - assert.NoError(t, prepareEngine()) - assertSync(t, new(Userinfo)) - - _, err := testEngine.UseBool().Update(&Userinfo{IsMan: true}) - if err != nil { - t.Error(err) - panic(err) - } - users := make([]Userinfo, 0) - err = testEngine.Find(&users) - if err != nil { - t.Error(err) - panic(err) - } - for _, user := range users { - if !user.IsMan { - err = errors.New("update bool or find bool error") - t.Error(err) - panic(err) - } - } - - _, err = testEngine.UseBool().Update(&Userinfo{IsMan: false}) - if err != nil { - t.Error(err) - panic(err) - } - users = make([]Userinfo, 0) - err = testEngine.Find(&users) - if err != nil { - t.Error(err) - panic(err) - } - for _, user := range users { - if user.IsMan { - err = errors.New("update bool or find bool error") - t.Error(err) - panic(err) - } - } -} - -func TestNoUpdate(t *testing.T) { - assert.NoError(t, prepareEngine()) - - type NoUpdate struct { - Id int64 - Content string - } - - assertSync(t, new(NoUpdate)) - - cnt, err := testEngine.Insert(&NoUpdate{ - Content: "test", + cnt, err = testEngine.Update(&UpdateTable2{ + Id: data.Id, + Msg: "test2", }) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - - _, err = testEngine.ID(1).Update(&NoUpdate{}) - assert.Error(t, err) - assert.EqualValues(t, "No content found to be updated", err.Error()) -} - -func TestNewUpdate(t *testing.T) { - assert.NoError(t, prepareEngine()) - - type TbUserInfo struct { - Id int64 `xorm:"pk autoincr unique BIGINT" json:"id"` - Phone string `xorm:"not null unique VARCHAR(20)" json:"phone"` - UserName string `xorm:"VARCHAR(20)" json:"user_name"` - Gender int `xorm:"default 0 INTEGER" json:"gender"` - Pw string `xorm:"VARCHAR(100)" json:"pw"` - Token string `xorm:"TEXT" json:"token"` - Avatar string `xorm:"TEXT" json:"avatar"` - Extras interface{} `xorm:"JSON" json:"extras"` - Created time.Time `xorm:"DATETIME created"` - Updated time.Time `xorm:"DATETIME updated"` - Deleted time.Time `xorm:"DATETIME deleted"` - } - - assertSync(t, new(TbUserInfo)) - - targetUsr := TbUserInfo{Phone: "13126564922"} - changeUsr := TbUserInfo{Token: "ABCDEFG"} - af, err := testEngine.Update(&changeUsr, &targetUsr) - assert.NoError(t, err) - assert.EqualValues(t, 0, af) - - af, err = testEngine.Table(new(TbUserInfo)).Where("phone=?", 13126564922).Update(&changeUsr) - assert.NoError(t, err) - assert.EqualValues(t, 0, af) -} - -func TestUpdateUpdate(t *testing.T) { - assert.NoError(t, prepareEngine()) - - type PublicKeyUpdate struct { - Id int64 - UpdatedUnix int64 `xorm:"updated"` - } - - assertSync(t, new(PublicKeyUpdate)) - - cnt, err := testEngine.ID(1).Cols("updated_unix").Update(&PublicKeyUpdate{ - UpdatedUnix: time.Now().Unix(), - }) - assert.NoError(t, err) - assert.EqualValues(t, 0, cnt) -} - -func TestCreatedUpdated2(t *testing.T) { - assert.NoError(t, prepareEngine()) - - type CreatedUpdatedStruct struct { - Id int64 - Name string - CreateAt time.Time `xorm:"created" json:"create_at"` - UpdateAt time.Time `xorm:"updated" json:"update_at"` - } - - assertSync(t, new(CreatedUpdatedStruct)) - - var s = CreatedUpdatedStruct{ - Name: "test", - } - cnt, err := testEngine.Insert(&s) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) - assert.EqualValues(t, s.UpdateAt.Unix(), s.CreateAt.Unix()) - - time.Sleep(time.Second) - - var s1 = CreatedUpdatedStruct{ - Name: "test1", - CreateAt: s.CreateAt, - UpdateAt: s.UpdateAt, - } - - cnt, err = testEngine.ID(1).Update(&s1) - assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) - assert.EqualValues(t, s.CreateAt.Unix(), s1.CreateAt.Unix()) - assert.True(t, s1.UpdateAt.Unix() > s.UpdateAt.Unix()) - - var s2 CreatedUpdatedStruct - has, err := testEngine.ID(1).Get(&s2) - assert.NoError(t, err) - assert.True(t, has) - - assert.EqualValues(t, s.CreateAt.Unix(), s2.CreateAt.Unix()) - assert.True(t, s2.UpdateAt.Unix() > s.UpdateAt.Unix()) - assert.True(t, s2.UpdateAt.Unix() > s2.CreateAt.Unix()) }