dbr/select_test.go

338 lines
10 KiB
Go

package dbr
import (
"testing"
"github.com/stretchr/testify/assert"
)
func BenchmarkSelectBasicSql(b *testing.B) {
s := createFakeSession()
// Do some allocations outside the loop so they don't affect the results
argEq := Eq{"a": []int{1, 2, 3}}
b.ResetTimer()
for i := 0; i < b.N; i++ {
s.Select("something_id", "user_id", "other").
From("some_table").
Where("d = ? OR e = ?", 1, "wat").
Where(argEq).
OrderDir("id", false).
Paginate(1, 20).
ToSql()
}
}
func BenchmarkSelectFullSql(b *testing.B) {
s := createFakeSession()
// Do some allocations outside the loop so they don't affect the results
argEq1 := Eq{"f": 2, "x": "hi"}
argEq2 := map[string]interface{}{"g": 3}
argEq3 := Eq{"h": []int{1, 2, 3}}
b.ResetTimer()
for i := 0; i < b.N; i++ {
s.Select("a", "b", "z", "y", "x").
Distinct().
From("c").
Where("d = ? OR e = ?", 1, "wat").
Where(argEq1).
Where(argEq2).
Where(argEq3).
GroupBy("i").
GroupBy("ii").
GroupBy("iii").
Having("j = k").
Having("jj = ?", 1).
Having("jjj = ?", 2).
OrderBy("l").
OrderBy("l").
OrderBy("l").
Limit(7).
Offset(8).
ToSql()
}
}
func TestSelectBasicToSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").From("c").Where("id = ?", 1).ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c WHERE (id = ?)")
assert.Equal(t, args, []interface{}{1})
}
func TestSelectFullToSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").
Distinct().
From("c").
Where("d = ? OR e = ?", 1, "wat").
Where(Eq{"f": 2}).
Where(map[string]interface{}{"g": 3}).
Where(Eq{"h": []int{4, 5, 6}}).
GroupBy("i").
Having("j = k").
OrderBy("l").
Limit(7).
Offset(8).
ToSql()
assert.Equal(t, sql, "SELECT DISTINCT a, b FROM c WHERE (d = ? OR e = ?) AND (`f` = ?) AND (`g` = ?) AND (`h` IN ?) GROUP BY i HAVING (j = k) ORDER BY l LIMIT 7 OFFSET 8")
assert.Equal(t, args, []interface{}{1, "wat", 2, 3, []int{4, 5, 6}})
}
func TestSelectPaginateOrderDirToSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").
From("c").
Where("d = ?", 1).
Paginate(1, 20).
OrderDir("id", false).
ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c WHERE (d = ?) ORDER BY id DESC LIMIT 20 OFFSET 0")
assert.Equal(t, args, []interface{}{1})
sql, args = s.Select("a", "b").
From("c").
Where("d = ?", 1).
Paginate(3, 30).
OrderDir("id", true).
ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c WHERE (d = ?) ORDER BY id ASC LIMIT 30 OFFSET 60")
assert.Equal(t, args, []interface{}{1})
}
func TestSelectNoWhereSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").From("c").ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c")
assert.Equal(t, args, []interface{}(nil))
}
func TestSelectMultiHavingSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").From("c").Where("p = ?", 1).GroupBy("z").Having("z = ?", 2).Having("y = ?", 3).ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c WHERE (p = ?) GROUP BY z HAVING (z = ?) AND (y = ?)")
assert.Equal(t, args, []interface{}{1, 2, 3})
}
func TestSelectMultiOrderSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a", "b").From("c").OrderBy("name ASC").OrderBy("id DESC").ToSql()
assert.Equal(t, sql, "SELECT a, b FROM c ORDER BY name ASC, id DESC")
assert.Equal(t, args, []interface{}(nil))
}
func TestSelectWhereMapSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a").From("b").Where(map[string]interface{}{"a": 1}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` = ?)")
assert.Equal(t, args, []interface{}{1})
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": 1, "b": true}).ToSql()
if sql == "SELECT a FROM b WHERE (`a` = ?) AND (`b` = ?)" {
assert.Equal(t, args, []interface{}{1, true})
} else {
assert.Equal(t, sql, "SELECT a FROM b WHERE (`b` = ?) AND (`a` = ?)")
assert.Equal(t, args, []interface{}{true, 1})
}
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": nil}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` IS NULL)")
assert.Equal(t, args, []interface{}(nil))
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": []int{1, 2, 3}}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` IN ?)")
assert.Equal(t, args, []interface{}{[]int{1, 2, 3}})
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": []int{1}}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` = ?)")
assert.Equal(t, args, []interface{}{1})
// NOTE: a has no valid values, we want a query that returns nothing
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": []int{}}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (1=0)")
assert.Equal(t, args, []interface{}(nil))
var aval []int
sql, args = s.Select("a").From("b").Where(map[string]interface{}{"a": aval}).ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` IS NULL)")
assert.Equal(t, args, []interface{}(nil))
sql, args = s.Select("a").From("b").
Where(map[string]interface{}{"a": []int(nil)}).
Where(map[string]interface{}{"b": false}).
ToSql()
assert.Equal(t, sql, "SELECT a FROM b WHERE (`a` IS NULL) AND (`b` = ?)")
assert.Equal(t, args, []interface{}{false})
}
func TestSelectWhereEqSql(t *testing.T) {
s := createFakeSession()
sql, args := s.Select("a").From("b").Where(Eq{"a": 1, "b": []int64{1, 2, 3}}).ToSql()
if sql == "SELECT a FROM b WHERE (`a` = ?) AND (`b` IN ?)" {
assert.Equal(t, args, []interface{}{1, []int64{1, 2, 3}})
} else {
assert.Equal(t, sql, "SELECT a FROM b WHERE (`b` IN ?) AND (`a` = ?)")
assert.Equal(t, args, []interface{}{[]int64{1, 2, 3}, 1})
}
}
func TestSelectBySql(t *testing.T) {
s := createFakeSession()
sql, args := s.SelectBySql("SELECT * FROM users WHERE x = 1").ToSql()
assert.Equal(t, sql, "SELECT * FROM users WHERE x = 1")
assert.Equal(t, args, []interface{}(nil))
sql, args = s.SelectBySql("SELECT * FROM users WHERE x = ? AND y IN ?", 9, []int{5, 6, 7}).ToSql()
assert.Equal(t, sql, "SELECT * FROM users WHERE x = ? AND y IN ?")
assert.Equal(t, args, []interface{}{9, []int{5, 6, 7}})
// Doesn't fix shit if it's broken:
sql, args = s.SelectBySql("wat", 9, []int{5, 6, 7}).ToSql()
assert.Equal(t, sql, "wat")
assert.Equal(t, args, []interface{}{9, []int{5, 6, 7}})
}
func TestSelectVarieties(t *testing.T) {
s := createFakeSession()
sql, _ := s.Select("id, name, email").From("users").ToSql()
sql2, _ := s.Select("id", "name", "email").From("users").ToSql()
assert.Equal(t, sql, sql2)
}
func TestSelectLoadStructs(t *testing.T) {
s := createRealSessionWithFixtures()
var people []*dbrPerson
count, err := s.Select("id", "name", "email").From("dbr_people").OrderBy("id ASC").LoadStructs(&people)
assert.NoError(t, err)
assert.Equal(t, count, 2)
assert.Equal(t, len(people), 2)
if len(people) == 2 {
// Make sure that the Ids are set. It's possible (maybe?) that different DBs set ids differently so
// don't assume they're 1 and 2.
assert.True(t, people[0].Id > 0)
assert.True(t, people[1].Id > people[0].Id)
assert.Equal(t, people[0].Name, "Jonathan")
assert.True(t, people[0].Email.Valid)
assert.Equal(t, people[0].Email.String, "jonathan@uservoice.com")
assert.Equal(t, people[1].Name, "Dmitri")
assert.True(t, people[1].Email.Valid)
assert.Equal(t, people[1].Email.String, "zavorotni@jadius.com")
}
// TODO: test map
}
func TestSelectLoadStruct(t *testing.T) {
s := createRealSessionWithFixtures()
// Found:
var person dbrPerson
err := s.Select("id", "name", "email").From("dbr_people").Where("email = ?", "jonathan@uservoice.com").LoadStruct(&person)
assert.NoError(t, err)
assert.True(t, person.Id > 0)
assert.Equal(t, person.Name, "Jonathan")
assert.True(t, person.Email.Valid)
assert.Equal(t, person.Email.String, "jonathan@uservoice.com")
// Not found:
var person2 dbrPerson
err = s.Select("id", "name", "email").From("dbr_people").Where("email = ?", "dontexist@uservoice.com").LoadStruct(&person2)
assert.Equal(t, err, ErrNotFound)
}
func TestSelectBySqlLoadStructs(t *testing.T) {
s := createRealSessionWithFixtures()
var people []*dbrPerson
count, err := s.SelectBySql("SELECT name FROM dbr_people WHERE email IN ?", []string{"jonathan@uservoice.com"}).LoadStructs(&people)
assert.NoError(t, err)
assert.Equal(t, count, 1)
if len(people) == 1 {
assert.Equal(t, people[0].Name, "Jonathan")
assert.Equal(t, people[0].Id, 0) // not set
assert.Equal(t, people[0].Email.Valid, false) // not set
assert.Equal(t, people[0].Email.String, "") // not set
}
}
func TestSelectLoadValue(t *testing.T) {
s := createRealSessionWithFixtures()
var name string
err := s.Select("name").From("dbr_people").Where("email = 'jonathan@uservoice.com'").LoadValue(&name)
assert.NoError(t, err)
assert.Equal(t, name, "Jonathan")
var id int64
err = s.Select("id").From("dbr_people").Limit(1).LoadValue(&id)
assert.NoError(t, err)
assert.True(t, id > 0)
}
func TestSelectLoadValues(t *testing.T) {
s := createRealSessionWithFixtures()
var names []string
count, err := s.Select("name").From("dbr_people").LoadValues(&names)
assert.NoError(t, err)
assert.Equal(t, count, 2)
assert.Equal(t, names, []string{"Jonathan", "Dmitri"})
var ids []int64
count, err = s.Select("id").From("dbr_people").Limit(1).LoadValues(&ids)
assert.NoError(t, err)
assert.Equal(t, count, 1)
assert.Equal(t, ids, []int64{1})
}
func TestSelectReturn(t *testing.T) {
s := createRealSessionWithFixtures()
name, err := s.Select("name").From("dbr_people").Where("email = 'jonathan@uservoice.com'").ReturnString()
assert.NoError(t, err)
assert.Equal(t, name, "Jonathan")
count, err := s.Select("COUNT(*)").From("dbr_people").ReturnInt64()
assert.NoError(t, err)
assert.Equal(t, count, 2)
names, err := s.Select("name").From("dbr_people").Where("email = 'jonathan@uservoice.com'").ReturnStrings()
assert.NoError(t, err)
assert.Equal(t, names, []string{"Jonathan"})
counts, err := s.Select("COUNT(*)").From("dbr_people").ReturnInt64s()
assert.NoError(t, err)
assert.Equal(t, counts, []int64{2})
}
// Series of tests that test mapping struct fields to columns