diff --git a/session_cond_test.go b/session_cond_test.go index d5a93924..d90fbc2f 100644 --- a/session_cond_test.go +++ b/session_cond_test.go @@ -5,6 +5,8 @@ package xorm import ( + "errors" + "fmt" "testing" "github.com/go-xorm/builder" @@ -93,3 +95,168 @@ func TestBuilder(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, 1, len(conds), "records should exist") } + +func TestIn(t *testing.T) { + assert.NoError(t, prepareEngine()) + assert.NoError(t, testEngine.Sync2(new(Userinfo))) + + cnt, err := testEngine.Insert([]Userinfo{ + { + Username: "user1", + Departname: "dev", + }, + { + Username: "user2", + Departname: "dev", + }, + { + Username: "user3", + Departname: "dev", + }, + }) + assert.NoError(t, err) + assert.EqualValues(t, 3, cnt) + + var usrs []Userinfo + err = testEngine.Limit(3).Find(&usrs) + if err != nil { + t.Error(err) + panic(err) + } + + if len(usrs) != 3 { + err = errors.New("there are not 3 records") + t.Error(err) + panic(err) + } + + var ids []int64 + var idsStr string + for _, u := range usrs { + ids = append(ids, u.Uid) + idsStr = fmt.Sprintf("%d,", u.Uid) + } + idsStr = idsStr[:len(idsStr)-1] + + users := make([]Userinfo, 0) + err = testEngine.In("(id)", ids[0], ids[1], ids[2]).Find(&users) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(users) + if len(users) != 3 { + err = errors.New("in uses should be " + idsStr + " total 3") + t.Error(err) + panic(err) + } + + users = make([]Userinfo, 0) + err = testEngine.In("(id)", ids).Find(&users) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(users) + if len(users) != 3 { + err = errors.New("in uses should be " + idsStr + " total 3") + t.Error(err) + panic(err) + } + + for _, user := range users { + if user.Uid != ids[0] && user.Uid != ids[1] && user.Uid != ids[2] { + err = errors.New("in uses should be " + idsStr + " total 3") + t.Error(err) + panic(err) + } + } + + users = make([]Userinfo, 0) + var idsInterface []interface{} + for _, id := range ids { + idsInterface = append(idsInterface, id) + } + + department := "`" + testEngine.ColumnMapper.Obj2Table("Departname") + "`" + err = testEngine.Where(department+" = ?", "dev").In("(id)", idsInterface...).Find(&users) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(users) + + if len(users) != 3 { + err = errors.New("in uses should be " + idsStr + " total 3") + t.Error(err) + panic(err) + } + + for _, user := range users { + if user.Uid != ids[0] && user.Uid != ids[1] && user.Uid != ids[2] { + err = errors.New("in uses should be " + idsStr + " total 3") + t.Error(err) + panic(err) + } + } + + dev := testEngine.ColumnMapper.Obj2Table("Dev") + + err = testEngine.In("(id)", 1).In("(id)", 2).In(department, dev).Find(&users) + + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(users) + + cnt, err = testEngine.In("(id)", ids[0]).Update(&Userinfo{Departname: "dev-"}) + if err != nil { + t.Error(err) + panic(err) + } + if cnt != 1 { + err = errors.New("update records not 1") + t.Error(err) + panic(err) + } + + user := new(Userinfo) + has, err := testEngine.Id(ids[0]).Get(user) + if err != nil { + t.Error(err) + panic(err) + } + if !has { + err = errors.New("get record not 1") + t.Error(err) + panic(err) + } + if user.Departname != "dev-" { + err = errors.New("update not success") + t.Error(err) + panic(err) + } + + cnt, err = testEngine.In("(id)", ids[0]).Update(&Userinfo{Departname: "dev"}) + if err != nil { + t.Error(err) + panic(err) + } + if cnt != 1 { + err = errors.New("update records not 1") + t.Error(err) + panic(err) + } + + cnt, err = testEngine.In("(id)", ids[1]).Delete(&Userinfo{}) + if err != nil { + t.Error(err) + panic(err) + } + if cnt != 1 { + err = errors.New("deleted records not 1") + t.Error(err) + panic(err) + } +} diff --git a/session_insert_test.go b/session_insert_test.go index f0d26007..6c63ebf3 100644 --- a/session_insert_test.go +++ b/session_insert_test.go @@ -5,6 +5,7 @@ package xorm import ( + "errors" "fmt" "reflect" "testing" @@ -136,3 +137,477 @@ func TestInsertOneIfPkIsPointRename(t *testing.T) { _, 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 +} + +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) + } +} diff --git a/tag_id_test.go b/tag_id_test.go new file mode 100644 index 00000000..7a6d2c8a --- /dev/null +++ b/tag_id_test.go @@ -0,0 +1,85 @@ +// 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/go-xorm/core" + "github.com/stretchr/testify/assert" +) + +type IDGonicMapper struct { + ID int64 +} + +func TestGonicMapperID(t *testing.T) { + assert.NoError(t, prepareEngine()) + + oldMapper := testEngine.ColumnMapper + testEngine.unMapType(rValue(new(IDGonicMapper)).Type()) + testEngine.SetMapper(core.LintGonicMapper) + defer func() { + testEngine.unMapType(rValue(new(IDGonicMapper)).Type()) + testEngine.SetMapper(oldMapper) + }() + + err := testEngine.CreateTables(new(IDGonicMapper)) + if err != nil { + t.Fatal(err) + } + + tables, err := testEngine.DBMetas() + if err != nil { + t.Fatal(err) + } + + for _, tb := range tables { + if tb.Name == "id_gonic_mapper" { + if len(tb.PKColumns()) != 1 && !tb.PKColumns()[0].IsPrimaryKey && !tb.PKColumns()[0].IsPrimaryKey { + t.Fatal(tb) + } + return + } + } + + t.Fatal("not table id_gonic_mapper") +} + +type IDSameMapper struct { + ID int64 +} + +func TestSameMapperID(t *testing.T) { + assert.NoError(t, prepareEngine()) + + oldMapper := testEngine.ColumnMapper + testEngine.unMapType(rValue(new(IDSameMapper)).Type()) + testEngine.SetMapper(core.SameMapper{}) + defer func() { + testEngine.unMapType(rValue(new(IDSameMapper)).Type()) + testEngine.SetMapper(oldMapper) + }() + + err := testEngine.CreateTables(new(IDSameMapper)) + if err != nil { + t.Fatal(err) + } + + tables, err := testEngine.DBMetas() + if err != nil { + t.Fatal(err) + } + + for _, tb := range tables { + if tb.Name == "IDSameMapper" { + if len(tb.PKColumns()) != 1 && !tb.PKColumns()[0].IsPrimaryKey && !tb.PKColumns()[0].IsPrimaryKey { + t.Fatal(tb) + } + return + } + } + t.Fatal("not table IDSameMapper") +}