add more tests #595

Merged
lunny merged 2 commits from lunny/add_tests into master 2017-05-30 12:33:30 +00:00
10 changed files with 1309 additions and 2 deletions

View File

@ -143,7 +143,6 @@ func (engine *Engine) Quote(value string) string {
// QuoteTo quotes string and writes into the buffer
func (engine *Engine) QuoteTo(buf *bytes.Buffer, value string) {
if buf == nil {
return
}
@ -781,6 +780,12 @@ func (engine *Engine) Having(conditions string) *Session {
return session.Having(conditions)
}
func (engine *Engine) unMapType(t reflect.Type) {
engine.mutex.Lock()
defer engine.mutex.Unlock()
delete(engine.Tables, t)
}
func (engine *Engine) autoMapType(v reflect.Value) (*core.Table, error) {
t := v.Type()
engine.mutex.Lock()

View File

@ -5,8 +5,11 @@
package xorm
import (
"errors"
"fmt"
"testing"
"github.com/go-xorm/core"
"github.com/stretchr/testify/assert"
)
@ -57,3 +60,407 @@ func TestJoinLimit(t *testing.T) {
Find(&salaries)
assert.NoError(t, err)
}
func assertSync(t *testing.T, beans ...interface{}) {
for _, bean := range beans {
assert.NoError(t, testEngine.DropTables(bean))
assert.NoError(t, testEngine.Sync(bean))
}
}
func TestWhere(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.Where("(id) > ?", 2).Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)
err = testEngine.Where("(id) > ?", 2).And("(id) < ?", 10).Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)
}
func TestFind(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
for _, user := range users {
fmt.Println(user)
}
users2 := make([]Userinfo, 0)
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
err = testEngine.Sql("select * from " + testEngine.Quote(userinfo)).Find(&users2)
if err != nil {
t.Error(err)
panic(err)
}
}
func TestFind2(t *testing.T) {
assert.NoError(t, prepareEngine())
users := make([]*Userinfo, 0)
assertSync(t, new(Userinfo))
err := testEngine.Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
for _, user := range users {
fmt.Println(user)
}
}
type Team struct {
Id int64
}
type TeamUser struct {
OrgId int64
Uid int64
TeamId int64
}
func TestFind3(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.Sync2(new(Team), new(TeamUser))
if err != nil {
t.Error(err)
panic(err.Error())
}
var teams []Team
err = testEngine.Cols("`team`.id").
Where("`team_user`.org_id=?", 1).
And("`team_user`.uid=?", 2).
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
Find(&teams)
if err != nil {
t.Error(err)
panic(err.Error())
}
}
func TestFindMap(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make(map[int64]Userinfo)
err := testEngine.Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
for _, user := range users {
fmt.Println(user)
}
}
func TestFindMap2(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make(map[int64]*Userinfo)
err := testEngine.Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
for id, user := range users {
fmt.Println(id, user)
}
}
func TestDistinct(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
_, err := testEngine.Insert(&Userinfo{
Username: "lunny",
})
assert.NoError(t, err)
users := make([]Userinfo, 0)
departname := testEngine.TableMapper.Obj2Table("Departname")
err = testEngine.Distinct(departname).Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
if len(users) != 1 {
t.Error(err)
panic(errors.New("should be one record"))
}
fmt.Println(users)
type Depart struct {
Departname string
}
users2 := make([]Depart, 0)
err = testEngine.Distinct(departname).Table(new(Userinfo)).Find(&users2)
if err != nil {
t.Error(err)
panic(err)
}
if len(users2) != 1 {
t.Error(err)
panic(errors.New("should be one record"))
}
fmt.Println(users2)
}
func TestOrder(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.OrderBy("id desc").Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)
users2 := make([]Userinfo, 0)
err = testEngine.Asc("id", "username").Desc("height").Find(&users2)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users2)
}
func TestHaving(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.GroupBy("username").Having("username='xlw'").Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)
/*users = make([]Userinfo, 0)
err = testEngine.Cols("id, username").GroupBy("username").Having("username='xlw'").Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)*/
}
func TestOrderSameMapper(t *testing.T) {
assert.NoError(t, prepareEngine())
testEngine.unMapType(rValue(new(Userinfo)).Type())
mapper := testEngine.TableMapper
testEngine.SetMapper(core.SameMapper{})
defer func() {
testEngine.unMapType(rValue(new(Userinfo)).Type())
testEngine.SetMapper(mapper)
}()
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.OrderBy("(id) desc").Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users)
users2 := make([]Userinfo, 0)
err = testEngine.Asc("(id)", "Username").Desc("Height").Find(&users2)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(users2)
}
func TestHavingSameMapper(t *testing.T) {
assert.NoError(t, prepareEngine())
testEngine.unMapType(rValue(new(Userinfo)).Type())
mapper := testEngine.TableMapper
testEngine.SetMapper(core.SameMapper{})
defer func() {
testEngine.unMapType(rValue(new(Userinfo)).Type())
testEngine.SetMapper(mapper)
}()
assertSync(t, new(Userinfo))
users := make([]Userinfo, 0)
err := testEngine.GroupBy("`Username`").Having("`Username`='xlw'").Find(&users)
if err != nil {
t.Fatal(err)
}
fmt.Println(users)
}
func TestFindInts(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
var idsInt64 []int64
err := testEngine.Table(userinfo).Cols("id").Desc("id").Find(&idsInt64)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsInt64)
var idsInt32 []int32
err = testEngine.Table(userinfo).Cols("id").Desc("id").Find(&idsInt32)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsInt32)
var idsInt []int
err = testEngine.Table(userinfo).Cols("id").Desc("id").Find(&idsInt)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsInt)
var idsUint []uint
err = testEngine.Table(userinfo).Cols("id").Desc("id").Find(&idsUint)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsUint)
type MyInt int
var idsMyInt []MyInt
err = testEngine.Table(userinfo).Cols("id").Desc("id").Find(&idsMyInt)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsMyInt)
}
func TestFindStrings(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
username := testEngine.ColumnMapper.Obj2Table("Username")
var idsString []string
err := testEngine.Table(userinfo).Cols(username).Desc("id").Find(&idsString)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsString)
}
func TestFindMyString(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
username := testEngine.ColumnMapper.Obj2Table("Username")
var idsMyString []MyString
err := testEngine.Table(userinfo).Cols(username).Desc("id").Find(&idsMyString)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsMyString)
}
func TestFindInterface(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
username := testEngine.ColumnMapper.Obj2Table("Username")
var idsInterface []interface{}
err := testEngine.Table(userinfo).Cols(username).Desc("id").Find(&idsInterface)
if err != nil {
t.Fatal(err)
}
fmt.Println(idsInterface)
}
func TestFindSliceBytes(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
var ids [][][]byte
err := testEngine.Table(userinfo).Desc("id").Find(&ids)
if err != nil {
t.Fatal(err)
}
for _, record := range ids {
fmt.Println(record)
}
}
func TestFindSlicePtrString(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
var ids [][]*string
err := testEngine.Table(userinfo).Desc("id").Find(&ids)
if err != nil {
t.Fatal(err)
}
for _, record := range ids {
fmt.Println(record)
}
}
func TestFindMapBytes(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
var ids []map[string][]byte
err := testEngine.Table(userinfo).Desc("id").Find(&ids)
if err != nil {
t.Fatal(err)
}
for _, record := range ids {
fmt.Println(record)
}
}
func TestFindMapPtrString(t *testing.T) {
assert.NoError(t, prepareEngine())
assertSync(t, new(Userinfo))
userinfo := testEngine.TableMapper.Obj2Table("Userinfo")
var ids []map[string]*string
err := testEngine.Table(userinfo).Desc("id").Find(&ids)
if err != nil {
t.Fatal(err)
}
for _, record := range ids {
fmt.Println(record)
}
}

View File

@ -5,7 +5,9 @@
package xorm
import (
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
@ -72,3 +74,131 @@ func TestUpdateLimit(t *testing.T) {
assert.EqualValues(t, 35, uts[0].Age)
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 := engine.DropTables(v)
if err != nil {
return err
}
err = engine.CreateTables(v)
if err != nil {
return err
}
list := []ForUpdate{
{1, "data1"},
{2, "data2"},
{3, "data3"},
}
for _, f := range list {
_, err = engine.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()
}

524
tag_extends_test.go Normal file
View File

@ -0,0 +1,524 @@
// 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 (
"errors"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type tempUser struct {
Id int64
Username string
}
type tempUser2 struct {
TempUser tempUser `xorm:"extends"`
Departname string
}
type tempUser3 struct {
Temp *tempUser `xorm:"extends"`
Departname string
}
type tempUser4 struct {
TempUser2 tempUser2 `xorm:"extends"`
}
type Userinfo struct {
Uid int64 `xorm:"id pk not null autoincr"`
Username string `xorm:"unique"`
Departname string
Alias string `xorm:"-"`
Created time.Time
Detail Userdetail `xorm:"detail_id int(11)"`
Height float64
Avatar []byte
IsMan bool
}
type Userdetail struct {
Id int64
Intro string `xorm:"text"`
Profile string `xorm:"varchar(2000)"`
}
type UserAndDetail struct {
Userinfo `xorm:"extends"`
Userdetail `xorm:"extends"`
}
func TestExtends(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.DropTables(&tempUser2{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&tempUser2{})
if err != nil {
t.Error(err)
panic(err)
}
tu := &tempUser2{tempUser{0, "extends"}, "dev depart"}
_, err = testEngine.Insert(tu)
if err != nil {
t.Error(err)
panic(err)
}
tu2 := &tempUser2{}
_, err = testEngine.Get(tu2)
if err != nil {
t.Error(err)
panic(err)
}
tu3 := &tempUser2{tempUser{0, "extends update"}, ""}
_, err = testEngine.Id(tu2.TempUser.Id).Update(tu3)
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.DropTables(&tempUser4{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&tempUser4{})
if err != nil {
t.Error(err)
panic(err)
}
tu8 := &tempUser4{tempUser2{tempUser{0, "extends"}, "dev depart"}}
_, err = testEngine.Insert(tu8)
if err != nil {
t.Error(err)
panic(err)
}
tu9 := &tempUser4{}
_, err = testEngine.Get(tu9)
if err != nil {
t.Error(err)
panic(err)
}
if tu9.TempUser2.TempUser.Username != tu8.TempUser2.TempUser.Username || tu9.TempUser2.Departname != tu8.TempUser2.Departname {
err = errors.New(fmt.Sprintln("not equal for", tu8, tu9))
t.Error(err)
panic(err)
}
tu10 := &tempUser4{tempUser2{tempUser{0, "extends update"}, ""}}
_, err = testEngine.Id(tu9.TempUser2.TempUser.Id).Update(tu10)
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.DropTables(&tempUser3{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&tempUser3{})
if err != nil {
t.Error(err)
panic(err)
}
tu4 := &tempUser3{&tempUser{0, "extends"}, "dev depart"}
_, err = testEngine.Insert(tu4)
if err != nil {
t.Error(err)
panic(err)
}
tu5 := &tempUser3{}
_, err = testEngine.Get(tu5)
if err != nil {
t.Error(err)
panic(err)
}
if tu5.Temp == nil {
err = errors.New("error get data extends")
t.Error(err)
panic(err)
}
if tu5.Temp.Id != 1 || tu5.Temp.Username != "extends" ||
tu5.Departname != "dev depart" {
err = errors.New("error get data extends")
t.Error(err)
panic(err)
}
tu6 := &tempUser3{&tempUser{0, "extends update"}, ""}
_, err = testEngine.Id(tu5.Temp.Id).Update(tu6)
if err != nil {
t.Error(err)
panic(err)
}
users := make([]tempUser3, 0)
err = testEngine.Find(&users)
if err != nil {
t.Error(err)
panic(err)
}
if len(users) != 1 {
err = errors.New("error get data not 1")
t.Error(err)
panic(err)
}
assertSync(t, new(Userinfo), new(Userdetail))
detail := Userdetail{
Intro: "I'm in China",
}
_, err = testEngine.Insert(&detail)
assert.NoError(t, err)
_, err = testEngine.Insert(&Userinfo{
Username: "lunny",
Detail: detail,
})
assert.NoError(t, err)
var info UserAndDetail
qt := testEngine.Quote
ui := testEngine.TableMapper.Obj2Table("Userinfo")
ud := testEngine.TableMapper.Obj2Table("Userdetail")
uiid := testEngine.TableMapper.Obj2Table("Id")
udid := "detail_id"
sql := fmt.Sprintf("select * from %s, %s where %s.%s = %s.%s",
qt(ui), qt(ud), qt(ui), qt(udid), qt(ud), qt(uiid))
b, err := testEngine.Sql(sql).NoCascade().Get(&info)
if err != nil {
t.Error(err)
panic(err)
}
if !b {
err = errors.New("should has lest one record")
t.Error(err)
panic(err)
}
fmt.Println(info)
if info.Userinfo.Uid == 0 || info.Userdetail.Id == 0 {
err = errors.New("all of the id should has value")
t.Error(err)
panic(err)
}
fmt.Println("----join--info2")
var info2 UserAndDetail
b, err = testEngine.Table(&Userinfo{}).
Join("LEFT", qt(ud), qt(ui)+"."+qt("detail_id")+" = "+qt(ud)+"."+qt(uiid)).
NoCascade().Get(&info2)
if err != nil {
t.Error(err)
panic(err)
}
if !b {
err = errors.New("should has lest one record")
t.Error(err)
panic(err)
}
if info2.Userinfo.Uid == 0 || info2.Userdetail.Id == 0 {
err = errors.New("all of the id should has value")
t.Error(err)
panic(err)
}
fmt.Println(info2)
fmt.Println("----join--infos2")
var infos2 = make([]UserAndDetail, 0)
err = testEngine.Table(&Userinfo{}).
Join("LEFT", qt(ud), qt(ui)+"."+qt("detail_id")+" = "+qt(ud)+"."+qt(uiid)).
NoCascade().
Find(&infos2)
if err != nil {
t.Error(err)
panic(err)
}
fmt.Println(infos2)
}
type MessageBase struct {
Id int64 `xorm:"int(11) pk autoincr"`
TypeId int64 `xorm:"int(11) notnull"`
}
type Message struct {
MessageBase `xorm:"extends"`
Title string `xorm:"varchar(100) notnull"`
Content string `xorm:"text notnull"`
Uid int64 `xorm:"int(11) notnull"`
ToUid int64 `xorm:"int(11) notnull"`
CreateTime time.Time `xorm:"datetime notnull created"`
}
type MessageUser struct {
Id int64
Name string
}
type MessageType struct {
Id int64
Name string
}
type MessageExtend3 struct {
Message `xorm:"extends"`
Sender MessageUser `xorm:"extends"`
Receiver MessageUser `xorm:"extends"`
Type MessageType `xorm:"extends"`
}
type MessageExtend4 struct {
Message `xorm:"extends"`
MessageUser `xorm:"extends"`
MessageType `xorm:"extends"`
}
func TestExtends2(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.DropTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
var sender = MessageUser{Name: "sender"}
var receiver = MessageUser{Name: "receiver"}
var msgtype = MessageType{Name: "type"}
_, err = testEngine.Insert(&sender, &receiver, &msgtype)
if err != nil {
t.Error(err)
panic(err)
}
msg := Message{
MessageBase: MessageBase{
Id: msgtype.Id,
},
Title: "test",
Content: "test",
Uid: sender.Id,
ToUid: receiver.Id,
}
_, err = testEngine.Insert(&msg)
if err != nil {
t.Error(err)
panic(err)
}
var mapper = testEngine.TableMapper.Obj2Table
userTableName := mapper("MessageUser")
typeTableName := mapper("MessageType")
msgTableName := mapper("Message")
list := make([]Message, 0)
err = testEngine.Table(msgTableName).Join("LEFT", []string{userTableName, "sender"}, "`sender`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Uid")+"`").
Join("LEFT", []string{userTableName, "receiver"}, "`receiver`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("ToUid")+"`").
Join("LEFT", []string{typeTableName, "type"}, "`type`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Id")+"`").
Find(&list)
if err != nil {
t.Error(err)
panic(err)
}
if len(list) != 1 {
err = errors.New(fmt.Sprintln("should have 1 message, got", len(list)))
t.Error(err)
panic(err)
}
if list[0].Id != msg.Id {
err = errors.New(fmt.Sprintln("should message equal", list[0], msg))
t.Error(err)
panic(err)
}
}
func TestExtends3(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.DropTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
var sender = MessageUser{Name: "sender"}
var receiver = MessageUser{Name: "receiver"}
var msgtype = MessageType{Name: "type"}
_, err = testEngine.Insert(&sender, &receiver, &msgtype)
if err != nil {
t.Error(err)
panic(err)
}
msg := Message{
MessageBase: MessageBase{
Id: msgtype.Id,
},
Title: "test",
Content: "test",
Uid: sender.Id,
ToUid: receiver.Id,
}
_, err = testEngine.Insert(&msg)
if err != nil {
t.Error(err)
panic(err)
}
var mapper = testEngine.TableMapper.Obj2Table
userTableName := mapper("MessageUser")
typeTableName := mapper("MessageType")
msgTableName := mapper("Message")
list := make([]MessageExtend3, 0)
err = testEngine.Table(msgTableName).Join("LEFT", []string{userTableName, "sender"}, "`sender`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Uid")+"`").
Join("LEFT", []string{userTableName, "receiver"}, "`receiver`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("ToUid")+"`").
Join("LEFT", []string{typeTableName, "type"}, "`type`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Id")+"`").
Find(&list)
if err != nil {
t.Error(err)
panic(err)
}
if len(list) != 1 {
err = errors.New(fmt.Sprintln("should have 1 message, got", len(list)))
t.Error(err)
panic(err)
}
if list[0].Message.Id != msg.Id {
err = errors.New(fmt.Sprintln("should message equal", list[0].Message, msg))
t.Error(err)
panic(err)
}
if list[0].Sender.Id != sender.Id || list[0].Sender.Name != sender.Name {
err = errors.New(fmt.Sprintln("should sender equal", list[0].Sender, sender))
t.Error(err)
panic(err)
}
if list[0].Receiver.Id != receiver.Id || list[0].Receiver.Name != receiver.Name {
err = errors.New(fmt.Sprintln("should receiver equal", list[0].Receiver, receiver))
t.Error(err)
panic(err)
}
if list[0].Type.Id != msgtype.Id || list[0].Type.Name != msgtype.Name {
err = errors.New(fmt.Sprintln("should msgtype equal", list[0].Type, msgtype))
t.Error(err)
panic(err)
}
}
func TestExtends4(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.DropTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
err = testEngine.CreateTables(&Message{}, &MessageUser{}, &MessageType{})
if err != nil {
t.Error(err)
panic(err)
}
var sender = MessageUser{Name: "sender"}
var msgtype = MessageType{Name: "type"}
_, err = testEngine.Insert(&sender, &msgtype)
if err != nil {
t.Error(err)
panic(err)
}
msg := Message{
MessageBase: MessageBase{
Id: msgtype.Id,
},
Title: "test",
Content: "test",
Uid: sender.Id,
}
_, err = testEngine.Insert(&msg)
if err != nil {
t.Error(err)
panic(err)
}
var mapper = testEngine.TableMapper.Obj2Table
userTableName := mapper("MessageUser")
typeTableName := mapper("MessageType")
msgTableName := mapper("Message")
list := make([]MessageExtend4, 0)
err = testEngine.Table(msgTableName).Join("LEFT", userTableName, "`"+userTableName+"`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Uid")+"`").
Join("LEFT", typeTableName, "`"+typeTableName+"`.`"+mapper("Id")+"`=`"+msgTableName+"`.`"+mapper("Id")+"`").
Find(&list)
if err != nil {
t.Error(err)
panic(err)
}
if len(list) != 1 {
err = errors.New(fmt.Sprintln("should have 1 message, got", len(list)))
t.Error(err)
panic(err)
}
if list[0].Message.Id != msg.Id {
err = errors.New(fmt.Sprintln("should message equal", list[0].Message, msg))
t.Error(err)
panic(err)
}
if list[0].MessageUser.Id != sender.Id || list[0].MessageUser.Name != sender.Name {
err = errors.New(fmt.Sprintln("should sender equal", list[0].MessageUser, sender))
t.Error(err)
panic(err)
}
if list[0].MessageType.Id != msgtype.Id || list[0].MessageType.Name != msgtype.Name {
err = errors.New(fmt.Sprintln("should msgtype equal", list[0].MessageType, msgtype))
t.Error(err)
panic(err)
}
}

1
test_mysql.sh Executable file
View File

@ -0,0 +1 @@
go test -db=mysql -conn_str="root:@/xorm_test"

1
test_postgres.sh Executable file
View File

@ -0,0 +1 @@
go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable"

1
test_sqlite.sh Executable file
View File

@ -0,0 +1 @@
go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc"

View File

@ -5,8 +5,12 @@
package xorm
import (
"encoding/json"
"errors"
"fmt"
"testing"
"github.com/go-xorm/core"
"github.com/stretchr/testify/assert"
)
@ -95,3 +99,237 @@ func TestGetBytes(t *testing.T) {
assert.Equal(t, true, has)
assert.Equal(t, "test", string(b.Data))
}
type ConvString string
func (s *ConvString) FromDB(data []byte) error {
*s = ConvString("prefix---" + string(data))
return nil
}
func (s *ConvString) ToDB() ([]byte, error) {
return []byte(string(*s)), nil
}
type ConvConfig struct {
Name string
Id int64
}
func (s *ConvConfig) FromDB(data []byte) error {
return json.Unmarshal(data, s)
}
func (s *ConvConfig) ToDB() ([]byte, error) {
return json.Marshal(s)
}
type SliceType []*ConvConfig
func (s *SliceType) FromDB(data []byte) error {
return json.Unmarshal(data, s)
}
func (s *SliceType) ToDB() ([]byte, error) {
return json.Marshal(s)
}
type ConvStruct struct {
Conv ConvString
Conv2 *ConvString
Cfg1 ConvConfig
Cfg2 *ConvConfig `xorm:"TEXT"`
Cfg3 core.Conversion `xorm:"BLOB"`
Slice SliceType
}
func (c *ConvStruct) BeforeSet(name string, cell Cell) {
if name == "cfg3" || name == "Cfg3" {
c.Cfg3 = new(ConvConfig)
}
}
func TestConversion(t *testing.T) {
assert.NoError(t, prepareEngine())
c := new(ConvStruct)
assert.NoError(t, testEngine.DropTables(c))
assert.NoError(t, testEngine.Sync(c))
var s ConvString = "sssss"
c.Conv = "tttt"
c.Conv2 = &s
c.Cfg1 = ConvConfig{"mm", 1}
c.Cfg2 = &ConvConfig{"xx", 2}
c.Cfg3 = &ConvConfig{"zz", 3}
c.Slice = []*ConvConfig{{"yy", 4}, {"ff", 5}}
_, err := testEngine.Insert(c)
assert.NoError(t, err)
c1 := new(ConvStruct)
has, err := testEngine.Get(c1)
assert.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, "prefix---tttt", string(c1.Conv))
assert.NotNil(t, c1.Conv2)
assert.EqualValues(t, "prefix---"+s, *c1.Conv2)
assert.EqualValues(t, c.Cfg1, c1.Cfg1)
assert.NotNil(t, c1.Cfg2)
assert.EqualValues(t, *c.Cfg2, *c1.Cfg2)
assert.NotNil(t, c1.Cfg3)
assert.EqualValues(t, *c.Cfg3.(*ConvConfig), *c1.Cfg3.(*ConvConfig))
assert.EqualValues(t, 2, len(c1.Slice))
assert.EqualValues(t, *c.Slice[0], *c1.Slice[0])
assert.EqualValues(t, *c.Slice[1], *c1.Slice[1])
}
type MyInt int
type MyUInt uint
type MyFloat float64
type MyStruct struct {
Type MyInt
U MyUInt
F MyFloat
S MyString
IA []MyInt
UA []MyUInt
FA []MyFloat
SA []MyString
NameArray []string
Name string
UIA []uint
UIA8 []uint8
UIA16 []uint16
UIA32 []uint32
UIA64 []uint64
UI uint
//C64 complex64
MSS map[string]string
}
func TestCustomType1(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.DropTables(&MyStruct{})
assert.NoError(t, err)
err = testEngine.CreateTables(&MyStruct{})
assert.NoError(t, err)
i := MyStruct{Name: "Test", Type: MyInt(1)}
i.U = 23
i.F = 1.34
i.S = "fafdsafdsaf"
i.UI = 2
i.IA = []MyInt{1, 3, 5}
i.UIA = []uint{1, 3}
i.UIA16 = []uint16{2}
i.UIA32 = []uint32{4, 5}
i.UIA64 = []uint64{6, 7, 9}
i.UIA8 = []uint8{1, 2, 3, 4}
i.NameArray = []string{"ssss", "fsdf", "lllll, ss"}
i.MSS = map[string]string{"s": "sfds,ss", "x": "lfjljsl"}
cnt, err := testEngine.Insert(&i)
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
fmt.Println(i)
i.NameArray = []string{}
i.MSS = map[string]string{}
i.F = 0
has, err := testEngine.Get(&i)
assert.NoError(t, err)
assert.True(t, has)
ss := []MyStruct{}
err = testEngine.Find(&ss)
assert.NoError(t, err)
assert.EqualValues(t, 1, len(ss))
assert.EqualValues(t, i, ss[0])
sss := MyStruct{}
has, err = testEngine.Get(&sss)
assert.NoError(t, err)
assert.True(t, has)
sss.NameArray = []string{}
sss.MSS = map[string]string{}
cnt, err = testEngine.Delete(&sss)
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
}
type Status struct {
Name string
Color string
}
var (
_ core.Conversion = &Status{}
Registed Status = Status{"Registed", "white"}
Approved Status = Status{"Approved", "green"}
Removed Status = Status{"Removed", "red"}
Statuses map[string]Status = map[string]Status{
Registed.Name: Registed,
Approved.Name: Approved,
Removed.Name: Removed,
}
)
func (s *Status) FromDB(bytes []byte) error {
if r, ok := Statuses[string(bytes)]; ok {
*s = r
return nil
} else {
return errors.New("no this data")
}
}
func (s *Status) ToDB() ([]byte, error) {
return []byte(s.Name), nil
}
type UserCus struct {
Id int64
Name string
Status Status `xorm:"varchar(40)"`
}
func TestCustomType2(t *testing.T) {
assert.NoError(t, prepareEngine())
err := testEngine.CreateTables(&UserCus{})
assert.NoError(t, err)
tableName := testEngine.TableMapper.Obj2Table("UserCus")
_, err = testEngine.Exec("delete from " + testEngine.Quote(tableName))
assert.NoError(t, err)
if testEngine.Dialect().DBType() == core.MSSQL {
return
/*_, err = engine.Exec("set IDENTITY_INSERT " + tableName + " on")
if err != nil {
t.Fatal(err)
}*/
}
_, err = testEngine.Insert(&UserCus{1, "xlw", Registed})
assert.NoError(t, err)
user := UserCus{}
exist, err := testEngine.Id(1).Get(&user)
assert.NoError(t, err)
assert.True(t, exist)
fmt.Println(user)
users := make([]UserCus, 0)
err = testEngine.Where("`"+testEngine.ColumnMapper.Obj2Table("Status")+"` = ?", "Registed").Find(&users)
assert.NoError(t, err)
assert.EqualValues(t, 1, len(users))
fmt.Println(users)
}

View File

@ -58,7 +58,7 @@ func TestMain(m *testing.M) {
dbType = *db
if *db == "sqlite3" {
if ptrConnStr == nil {
connString = "./test.db"
connString = "./test.db?cache=shared&mode=rwc"
} else {
connString = *ptrConnStr
}