890 lines
18 KiB
Go
890 lines
18 KiB
Go
|
package testsuite
|
||
|
|
||
|
import (
|
||
|
"database/sql/driver"
|
||
|
"time"
|
||
|
|
||
|
"git.hexq.cn/tiglog/mydb"
|
||
|
"github.com/stretchr/testify/suite"
|
||
|
"gopkg.in/mgo.v2/bson"
|
||
|
)
|
||
|
|
||
|
type birthday struct {
|
||
|
Name string `db:"name"`
|
||
|
Born time.Time `db:"born"`
|
||
|
BornUT *unixTimestamp `db:"born_ut,omitempty"`
|
||
|
OmitMe bool `json:"omit_me" db:"-" bson:"-"`
|
||
|
}
|
||
|
|
||
|
type fibonacci struct {
|
||
|
Input uint64 `db:"input"`
|
||
|
Output uint64 `db:"output"`
|
||
|
// Test for BSON option.
|
||
|
OmitMe bool `json:"omit_me" db:"omit_me,bson,omitempty" bson:"omit_me,omitempty"`
|
||
|
}
|
||
|
|
||
|
type oddEven struct {
|
||
|
// Test for JSON option.
|
||
|
Input int `json:"input" db:"input"`
|
||
|
// Test for JSON option.
|
||
|
// The "bson" tag is required by mgo.
|
||
|
IsEven bool `json:"is_even" db:"is_even,json" bson:"is_even"`
|
||
|
OmitMe bool `json:"omit_me" db:"-" bson:"-"`
|
||
|
}
|
||
|
|
||
|
// Struct that relies on explicit mapping.
|
||
|
type mapE struct {
|
||
|
ID uint `db:"id,omitempty" bson:"-"`
|
||
|
MongoID bson.ObjectId `db:"-" bson:"_id,omitempty"`
|
||
|
CaseTest string `db:"case_test" bson:"case_test"`
|
||
|
}
|
||
|
|
||
|
// Struct that will fallback to default mapping.
|
||
|
type mapN struct {
|
||
|
ID uint `db:"id,omitempty"`
|
||
|
MongoID bson.ObjectId `db:"-" bson:"_id,omitempty"`
|
||
|
Case_TEST string `db:"case_test"`
|
||
|
}
|
||
|
|
||
|
// Struct for testing marshalling.
|
||
|
type unixTimestamp struct {
|
||
|
// Time is handled internally as time.Time but saved as an (integer) unix
|
||
|
// timestamp.
|
||
|
value time.Time
|
||
|
}
|
||
|
|
||
|
func (u unixTimestamp) Value() (driver.Value, error) {
|
||
|
return u.value.UTC().Unix(), nil
|
||
|
}
|
||
|
|
||
|
func (u *unixTimestamp) Scan(v interface{}) error {
|
||
|
var unixTime int64
|
||
|
|
||
|
switch t := v.(type) {
|
||
|
case int64:
|
||
|
unixTime = t
|
||
|
case nil:
|
||
|
return nil
|
||
|
default:
|
||
|
return mydb.ErrUnsupportedValue
|
||
|
}
|
||
|
|
||
|
t := time.Unix(unixTime, 0).In(time.UTC)
|
||
|
*u = unixTimestamp{t}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func newUnixTimestamp(t time.Time) *unixTimestamp {
|
||
|
return &unixTimestamp{t.UTC()}
|
||
|
}
|
||
|
|
||
|
func even(i int) bool {
|
||
|
return i%2 == 0
|
||
|
}
|
||
|
|
||
|
func fib(i uint64) uint64 {
|
||
|
if i == 0 {
|
||
|
return 0
|
||
|
} else if i == 1 {
|
||
|
return 1
|
||
|
}
|
||
|
return fib(i-1) + fib(i-2)
|
||
|
}
|
||
|
|
||
|
type GenericTestSuite struct {
|
||
|
suite.Suite
|
||
|
|
||
|
Helper
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) AfterTest(suiteName, testName string) {
|
||
|
err := s.TearDown()
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) BeforeTest(suiteName, testName string) {
|
||
|
err := s.TearUp()
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) TestDatesAndUnicode() {
|
||
|
sess := s.Session()
|
||
|
|
||
|
testTimeZone := time.Local
|
||
|
switch s.Adapter() {
|
||
|
case "mysql", "cockroachdb", "postgresql":
|
||
|
testTimeZone = defaultTimeLocation
|
||
|
case "sqlite", "ql", "mssql":
|
||
|
testTimeZone = time.UTC
|
||
|
}
|
||
|
|
||
|
born := time.Date(1941, time.January, 5, 0, 0, 0, 0, testTimeZone)
|
||
|
|
||
|
controlItem := birthday{
|
||
|
Name: "Hayao Miyazaki",
|
||
|
Born: born,
|
||
|
BornUT: newUnixTimestamp(born),
|
||
|
}
|
||
|
|
||
|
col := sess.Collection(`birthdays`)
|
||
|
|
||
|
record, err := col.Insert(controlItem)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(record.ID())
|
||
|
|
||
|
var res mydb.Result
|
||
|
switch s.Adapter() {
|
||
|
case "mongo":
|
||
|
res = col.Find(mydb.Cond{"_id": record.ID().(bson.ObjectId)})
|
||
|
case "ql":
|
||
|
res = col.Find(mydb.Cond{"id()": record.ID()})
|
||
|
default:
|
||
|
res = col.Find(mydb.Cond{"id": record.ID()})
|
||
|
}
|
||
|
|
||
|
var total uint64
|
||
|
total, err = res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(1), total)
|
||
|
|
||
|
switch s.Adapter() {
|
||
|
case "mongo":
|
||
|
s.T().Skip()
|
||
|
}
|
||
|
|
||
|
var testItem birthday
|
||
|
err = res.One(&testItem)
|
||
|
s.NoError(err)
|
||
|
|
||
|
switch s.Adapter() {
|
||
|
case "sqlite", "ql", "mssql":
|
||
|
testItem.Born = testItem.Born.In(time.UTC)
|
||
|
}
|
||
|
s.Equal(controlItem.Born, testItem.Born)
|
||
|
|
||
|
s.Equal(controlItem.BornUT, testItem.BornUT)
|
||
|
s.Equal(controlItem, testItem)
|
||
|
|
||
|
var testItems []birthday
|
||
|
err = res.All(&testItems)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(len(testItems))
|
||
|
|
||
|
for _, testItem = range testItems {
|
||
|
switch s.Adapter() {
|
||
|
case "sqlite", "ql", "mssql":
|
||
|
testItem.Born = testItem.Born.In(time.UTC)
|
||
|
}
|
||
|
s.Equal(controlItem, testItem)
|
||
|
}
|
||
|
|
||
|
controlItem.Name = `宮崎駿`
|
||
|
err = res.Update(controlItem)
|
||
|
s.NoError(err)
|
||
|
|
||
|
err = res.One(&testItem)
|
||
|
s.NoError(err)
|
||
|
|
||
|
switch s.Adapter() {
|
||
|
case "sqlite", "ql", "mssql":
|
||
|
testItem.Born = testItem.Born.In(time.UTC)
|
||
|
}
|
||
|
|
||
|
s.Equal(controlItem, testItem)
|
||
|
|
||
|
err = res.Delete()
|
||
|
s.NoError(err)
|
||
|
|
||
|
total, err = res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Zero(total)
|
||
|
|
||
|
err = res.Close()
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) TestFibonacci() {
|
||
|
var err error
|
||
|
var res mydb.Result
|
||
|
var total uint64
|
||
|
|
||
|
sess := s.Session()
|
||
|
|
||
|
col := sess.Collection("fibonacci")
|
||
|
|
||
|
// Adding some items.
|
||
|
var i uint64
|
||
|
for i = 0; i < 10; i++ {
|
||
|
item := fibonacci{Input: i, Output: fib(i)}
|
||
|
_, err = col.Insert(item)
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
// Testing sorting by function.
|
||
|
res = col.Find(
|
||
|
// 5, 6, 7, 3
|
||
|
mydb.Or(
|
||
|
mydb.And(
|
||
|
mydb.Cond{"input": mydb.Gte(5)},
|
||
|
mydb.Cond{"input": mydb.Lte(7)},
|
||
|
),
|
||
|
mydb.Cond{"input": mydb.Eq(3)},
|
||
|
),
|
||
|
)
|
||
|
|
||
|
// Testing sort by function.
|
||
|
switch s.Adapter() {
|
||
|
case "postgresql":
|
||
|
res = res.OrderBy(mydb.Raw("RANDOM()"))
|
||
|
case "sqlite":
|
||
|
res = res.OrderBy(mydb.Raw("RANDOM()"))
|
||
|
case "mysql":
|
||
|
res = res.OrderBy(mydb.Raw("RAND()"))
|
||
|
case "mssql":
|
||
|
res = res.OrderBy(mydb.Raw("NEWID()"))
|
||
|
}
|
||
|
|
||
|
total, err = res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(4), total)
|
||
|
|
||
|
// Find() with IN/$in
|
||
|
res = col.Find(mydb.Cond{"input IN": []int{3, 5, 6, 7}}).OrderBy("input")
|
||
|
|
||
|
total, err = res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(4), total)
|
||
|
|
||
|
res = res.Offset(1).Limit(2)
|
||
|
|
||
|
var item fibonacci
|
||
|
for res.Next(&item) {
|
||
|
switch item.Input {
|
||
|
case 5:
|
||
|
case 6:
|
||
|
s.Equal(fib(item.Input), item.Output)
|
||
|
default:
|
||
|
s.T().Errorf(`Unexpected item: %v.`, item)
|
||
|
}
|
||
|
}
|
||
|
s.NoError(res.Err())
|
||
|
|
||
|
// Find() with range
|
||
|
res = col.Find(
|
||
|
// 5, 6, 7, 3
|
||
|
mydb.Or(
|
||
|
mydb.And(
|
||
|
mydb.Cond{"input >=": 5},
|
||
|
mydb.Cond{"input <=": 7},
|
||
|
),
|
||
|
mydb.Cond{"input": 3},
|
||
|
),
|
||
|
).OrderBy("-input")
|
||
|
|
||
|
total, err = res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(4), total)
|
||
|
|
||
|
// Skipping.
|
||
|
res = res.Offset(1).Limit(2)
|
||
|
|
||
|
var item2 fibonacci
|
||
|
for res.Next(&item2) {
|
||
|
switch item2.Input {
|
||
|
case 5:
|
||
|
case 6:
|
||
|
s.Equal(fib(item2.Input), item2.Output)
|
||
|
default:
|
||
|
s.T().Errorf(`Unexpected item: %v.`, item2)
|
||
|
}
|
||
|
}
|
||
|
err = res.Err()
|
||
|
s.NoError(err)
|
||
|
|
||
|
err = res.Delete()
|
||
|
s.NoError(err)
|
||
|
|
||
|
{
|
||
|
total, err := res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Zero(total)
|
||
|
}
|
||
|
|
||
|
// Find() with no arguments.
|
||
|
res = col.Find()
|
||
|
{
|
||
|
total, err := res.Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(6), total)
|
||
|
}
|
||
|
|
||
|
// Skipping mongodb as the results of this are not defined there.
|
||
|
if s.Adapter() != `mongo` {
|
||
|
// Find() with empty mydb.Cond.
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(6), total)
|
||
|
}
|
||
|
|
||
|
// Find() with empty expression
|
||
|
{
|
||
|
total, err := col.Find(mydb.Or(mydb.And(mydb.Cond{}, mydb.Cond{}), mydb.Or(mydb.Cond{}))).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(6), total)
|
||
|
}
|
||
|
|
||
|
// Find() with explicit IS NULL
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{"input IS": nil}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(0), total)
|
||
|
}
|
||
|
|
||
|
// Find() with implicit IS NULL
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{"input": nil}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(0), total)
|
||
|
}
|
||
|
|
||
|
// Find() with explicit = NULL
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{"input =": nil}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(0), total)
|
||
|
}
|
||
|
|
||
|
// Find() with implicit IN
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{"input": []int{1, 2, 3, 4}}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(3), total)
|
||
|
}
|
||
|
|
||
|
// Find() with implicit NOT IN
|
||
|
{
|
||
|
total, err := col.Find(mydb.Cond{"input NOT IN": []int{1, 2, 3, 4}}).Count()
|
||
|
s.NoError(err)
|
||
|
s.Equal(uint64(3), total)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var items []fibonacci
|
||
|
err = res.All(&items)
|
||
|
s.NoError(err)
|
||
|
|
||
|
for _, item := range items {
|
||
|
switch item.Input {
|
||
|
case 0:
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 4:
|
||
|
case 8:
|
||
|
case 9:
|
||
|
s.Equal(fib(item.Input), item.Output)
|
||
|
default:
|
||
|
s.T().Errorf(`Unexpected item: %v`, item)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
err = res.Close()
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) TestOddEven() {
|
||
|
sess := s.Session()
|
||
|
|
||
|
col := sess.Collection("is_even")
|
||
|
|
||
|
// Adding some items.
|
||
|
var i int
|
||
|
for i = 1; i < 100; i++ {
|
||
|
item := oddEven{Input: i, IsEven: even(i)}
|
||
|
_, err := col.Insert(item)
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
// Retrieving items
|
||
|
res := col.Find(mydb.Cond{"is_even": true})
|
||
|
|
||
|
var item oddEven
|
||
|
for res.Next(&item) {
|
||
|
s.Zero(item.Input % 2)
|
||
|
}
|
||
|
|
||
|
err := res.Err()
|
||
|
s.NoError(err)
|
||
|
|
||
|
err = res.Delete()
|
||
|
s.NoError(err)
|
||
|
|
||
|
// Testing named inputs (using tags).
|
||
|
res = col.Find()
|
||
|
|
||
|
var item2 struct {
|
||
|
Value uint `db:"input" bson:"input"` // The "bson" tag is required by mgo.
|
||
|
}
|
||
|
for res.Next(&item2) {
|
||
|
s.NotZero(item2.Value % 2)
|
||
|
}
|
||
|
err = res.Err()
|
||
|
s.NoError(err)
|
||
|
|
||
|
// Testing inline tag.
|
||
|
res = col.Find()
|
||
|
|
||
|
var item3 struct {
|
||
|
OddEven oddEven `db:",inline" bson:",inline"`
|
||
|
}
|
||
|
for res.Next(&item3) {
|
||
|
s.NotZero(item3.OddEven.Input % 2)
|
||
|
s.NotZero(item3.OddEven.Input)
|
||
|
}
|
||
|
err = res.Err()
|
||
|
s.NoError(err)
|
||
|
|
||
|
// Testing inline tag.
|
||
|
type OddEven oddEven
|
||
|
res = col.Find()
|
||
|
|
||
|
var item31 struct {
|
||
|
OddEven `db:",inline" bson:",inline"`
|
||
|
}
|
||
|
for res.Next(&item31) {
|
||
|
s.NotZero(item31.Input % 2)
|
||
|
s.NotZero(item31.Input)
|
||
|
}
|
||
|
s.NoError(res.Err())
|
||
|
|
||
|
// Testing omision tag.
|
||
|
res = col.Find()
|
||
|
|
||
|
var item4 struct {
|
||
|
Value uint `db:"-"`
|
||
|
}
|
||
|
for res.Next(&item4) {
|
||
|
s.Zero(item4.Value)
|
||
|
}
|
||
|
s.NoError(res.Err())
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) TestExplicitAndDefaultMapping() {
|
||
|
var err error
|
||
|
var res mydb.Result
|
||
|
|
||
|
var testE mapE
|
||
|
var testN mapN
|
||
|
|
||
|
sess := s.Session()
|
||
|
|
||
|
col := sess.Collection("CaSe_TesT")
|
||
|
|
||
|
if err = col.Truncate(); err != nil {
|
||
|
if s.Adapter() != "mongo" {
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Testing explicit mapping.
|
||
|
testE = mapE{
|
||
|
CaseTest: "Hello!",
|
||
|
}
|
||
|
|
||
|
_, err = col.Insert(testE)
|
||
|
s.NoError(err)
|
||
|
|
||
|
res = col.Find(mydb.Cond{"case_test": "Hello!"})
|
||
|
if s.Adapter() == "ql" {
|
||
|
res = res.Select("id() as id", "case_test")
|
||
|
}
|
||
|
|
||
|
err = res.One(&testE)
|
||
|
s.NoError(err)
|
||
|
|
||
|
if s.Adapter() == "mongo" {
|
||
|
s.True(testE.MongoID.Valid())
|
||
|
} else {
|
||
|
s.NotZero(testE.ID)
|
||
|
}
|
||
|
|
||
|
// Testing default mapping.
|
||
|
testN = mapN{
|
||
|
Case_TEST: "World!",
|
||
|
}
|
||
|
|
||
|
_, err = col.Insert(testN)
|
||
|
s.NoError(err)
|
||
|
|
||
|
if s.Adapter() == `mongo` {
|
||
|
res = col.Find(mydb.Cond{"case_test": "World!"})
|
||
|
} else {
|
||
|
res = col.Find(mydb.Cond{"case_test": "World!"})
|
||
|
}
|
||
|
|
||
|
if s.Adapter() == `ql` {
|
||
|
res = res.Select(`id() as id`, `case_test`)
|
||
|
}
|
||
|
|
||
|
err = res.One(&testN)
|
||
|
s.NoError(err)
|
||
|
|
||
|
if s.Adapter() == `mongo` {
|
||
|
s.True(testN.MongoID.Valid())
|
||
|
} else {
|
||
|
s.NotZero(testN.ID)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *GenericTestSuite) TestComparisonOperators() {
|
||
|
sess := s.Session()
|
||
|
|
||
|
birthdays := sess.Collection("birthdays")
|
||
|
err := birthdays.Truncate()
|
||
|
if err != nil {
|
||
|
if s.Adapter() != "mongo" {
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Insert data for testing
|
||
|
birthdaysDataset := []birthday{
|
||
|
{
|
||
|
Name: "Marie Smith",
|
||
|
Born: time.Date(1956, time.August, 5, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Peter",
|
||
|
Born: time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Eve Smith",
|
||
|
Born: time.Date(1911, time.February, 8, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Alex López",
|
||
|
Born: time.Date(2001, time.May, 5, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Rose Smith",
|
||
|
Born: time.Date(1944, time.December, 9, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Daria López",
|
||
|
Born: time.Date(1923, time.March, 23, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "",
|
||
|
Born: time.Date(1945, time.December, 1, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
{
|
||
|
Name: "Colin",
|
||
|
Born: time.Date(2010, time.May, 6, 0, 0, 0, 0, defaultTimeLocation),
|
||
|
},
|
||
|
}
|
||
|
for _, birthday := range birthdaysDataset {
|
||
|
_, err := birthdays.Insert(birthday)
|
||
|
s.NoError(err)
|
||
|
}
|
||
|
|
||
|
// Test: equal
|
||
|
{
|
||
|
var item birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"name": mydb.Eq("Colin"),
|
||
|
}).One(&item)
|
||
|
s.NoError(err)
|
||
|
s.NotNil(item)
|
||
|
|
||
|
s.Equal("Colin", item.Name)
|
||
|
}
|
||
|
|
||
|
// Test: not equal
|
||
|
{
|
||
|
var item birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"name": mydb.NotEq("Colin"),
|
||
|
}).One(&item)
|
||
|
s.NoError(err)
|
||
|
s.NotNil(item)
|
||
|
|
||
|
s.NotEqual("Colin", item.Name)
|
||
|
}
|
||
|
|
||
|
// Test: greater than
|
||
|
{
|
||
|
var items []birthday
|
||
|
ref := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Gt(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(len(items))
|
||
|
s.Equal(2, len(items))
|
||
|
for _, item := range items {
|
||
|
s.True(item.Born.After(ref))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: less than
|
||
|
{
|
||
|
var items []birthday
|
||
|
ref := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Lt(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(len(items))
|
||
|
s.Equal(5, len(items))
|
||
|
for _, item := range items {
|
||
|
s.True(item.Born.Before(ref))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: greater than or equal to
|
||
|
{
|
||
|
var items []birthday
|
||
|
ref := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Gte(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(len(items))
|
||
|
s.Equal(3, len(items))
|
||
|
for _, item := range items {
|
||
|
s.True(item.Born.After(ref) || item.Born.Equal(ref))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: less than or equal to
|
||
|
{
|
||
|
var items []birthday
|
||
|
ref := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Lte(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.NotZero(len(items))
|
||
|
s.Equal(6, len(items))
|
||
|
for _, item := range items {
|
||
|
s.True(item.Born.Before(ref) || item.Born.Equal(ref))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: between
|
||
|
{
|
||
|
var items []birthday
|
||
|
dateA := time.Date(1911, time.February, 8, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
dateB := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Between(dateA, dateB),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(6, len(items))
|
||
|
for _, item := range items {
|
||
|
s.True(item.Born.After(dateA) || item.Born.Equal(dateA))
|
||
|
s.True(item.Born.Before(dateB) || item.Born.Equal(dateB))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: not between
|
||
|
{
|
||
|
var items []birthday
|
||
|
dateA := time.Date(1911, time.February, 8, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
dateB := time.Date(1967, time.July, 23, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.NotBetween(dateA, dateB),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(2, len(items))
|
||
|
for _, item := range items {
|
||
|
s.False(item.Born.Before(dateA) || item.Born.Equal(dateA))
|
||
|
s.False(item.Born.Before(dateB) || item.Born.Equal(dateB))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: in
|
||
|
{
|
||
|
var items []birthday
|
||
|
names := []interface{}{"Peter", "Eve Smith", "Daria López", "Alex López"}
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"name": mydb.In(names...),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(4, len(items))
|
||
|
for _, item := range items {
|
||
|
inArray := false
|
||
|
for _, name := range names {
|
||
|
if name == item.Name {
|
||
|
inArray = true
|
||
|
}
|
||
|
}
|
||
|
s.True(inArray)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: not in
|
||
|
{
|
||
|
var items []birthday
|
||
|
names := []interface{}{"Peter", "Eve Smith", "Daria López", "Alex López"}
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"name": mydb.NotIn(names...),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(4, len(items))
|
||
|
for _, item := range items {
|
||
|
inArray := false
|
||
|
for _, name := range names {
|
||
|
if name == item.Name {
|
||
|
inArray = true
|
||
|
}
|
||
|
}
|
||
|
s.False(inArray)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: not in
|
||
|
{
|
||
|
var items []birthday
|
||
|
names := []interface{}{"Peter", "Eve Smith", "Daria López", "Alex López"}
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"name": mydb.NotIn(names...),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(4, len(items))
|
||
|
for _, item := range items {
|
||
|
inArray := false
|
||
|
for _, name := range names {
|
||
|
if name == item.Name {
|
||
|
inArray = true
|
||
|
}
|
||
|
}
|
||
|
s.False(inArray)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: is and is not
|
||
|
{
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"name": mydb.Is(nil)},
|
||
|
mydb.Cond{"name": mydb.IsNot(nil)},
|
||
|
)).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(0, len(items))
|
||
|
}
|
||
|
|
||
|
// Test: is nil
|
||
|
{
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"born_ut": mydb.IsNull()},
|
||
|
)).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(8, len(items))
|
||
|
}
|
||
|
|
||
|
// Test: like and not like
|
||
|
{
|
||
|
var items []birthday
|
||
|
var q mydb.Result
|
||
|
|
||
|
switch s.Adapter() {
|
||
|
case "ql", "mongo":
|
||
|
q = birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"name": mydb.Like(".*ari.*")},
|
||
|
mydb.Cond{"name": mydb.NotLike(".*Smith")},
|
||
|
))
|
||
|
default:
|
||
|
q = birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"name": mydb.Like("%ari%")},
|
||
|
mydb.Cond{"name": mydb.NotLike("%Smith")},
|
||
|
))
|
||
|
}
|
||
|
|
||
|
err := q.All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(1, len(items))
|
||
|
|
||
|
s.Equal("Daria López", items[0].Name)
|
||
|
}
|
||
|
|
||
|
if s.Adapter() != "sqlite" && s.Adapter() != "mssql" {
|
||
|
// Test: regexp
|
||
|
{
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"name": mydb.RegExp("^[D|C|M]")},
|
||
|
)).OrderBy("name").All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(3, len(items))
|
||
|
|
||
|
s.Equal("Colin", items[0].Name)
|
||
|
s.Equal("Daria López", items[1].Name)
|
||
|
s.Equal("Marie Smith", items[2].Name)
|
||
|
}
|
||
|
|
||
|
// Test: not regexp
|
||
|
{
|
||
|
var items []birthday
|
||
|
names := []string{"Daria López", "Colin", "Marie Smith"}
|
||
|
err := birthdays.Find(mydb.And(
|
||
|
mydb.Cond{"name": mydb.NotRegExp("^[D|C|M]")},
|
||
|
)).OrderBy("name").All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(5, len(items))
|
||
|
|
||
|
for _, item := range items {
|
||
|
for _, name := range names {
|
||
|
s.NotEqual(item.Name, name)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test: after
|
||
|
{
|
||
|
ref := time.Date(1944, time.December, 9, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.After(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(5, len(items))
|
||
|
}
|
||
|
|
||
|
// Test: on or after
|
||
|
{
|
||
|
ref := time.Date(1944, time.December, 9, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.OnOrAfter(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(6, len(items))
|
||
|
}
|
||
|
|
||
|
// Test: before
|
||
|
{
|
||
|
ref := time.Date(1944, time.December, 9, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.Before(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(2, len(items))
|
||
|
}
|
||
|
|
||
|
// Test: on or before
|
||
|
{
|
||
|
ref := time.Date(1944, time.December, 9, 0, 0, 0, 0, defaultTimeLocation)
|
||
|
var items []birthday
|
||
|
err := birthdays.Find(mydb.Cond{
|
||
|
"born": mydb.OnOrBefore(ref),
|
||
|
}).All(&items)
|
||
|
s.NoError(err)
|
||
|
s.Equal(3, len(items))
|
||
|
}
|
||
|
}
|