mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 09:40:56 +00:00
orm 1. complete QueryRow/QueryRows api 2. QuerySeter.All support *[]Type and *[]*Type
This commit is contained in:
parent
22d2de9fc7
commit
41dd6e580d
20
orm/db.go
20
orm/db.go
@ -479,15 +479,19 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
||||
ind := reflect.Indirect(val)
|
||||
|
||||
errTyp := true
|
||||
|
||||
one := true
|
||||
isPtr := true
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
fn := ""
|
||||
if ind.Kind() == reflect.Slice {
|
||||
one = false
|
||||
if ind.Type().Elem().Kind() == reflect.Ptr {
|
||||
typ := ind.Type().Elem().Elem()
|
||||
typ := ind.Type().Elem()
|
||||
switch typ.Kind() {
|
||||
case reflect.Ptr:
|
||||
fn = getFullName(typ.Elem())
|
||||
case reflect.Struct:
|
||||
isPtr = false
|
||||
fn = getFullName(typ)
|
||||
}
|
||||
} else {
|
||||
@ -601,13 +605,21 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
||||
if one {
|
||||
ind.Set(mind)
|
||||
} else {
|
||||
if cnt == 0 {
|
||||
slice = reflect.New(ind.Type()).Elem()
|
||||
}
|
||||
|
||||
if isPtr {
|
||||
slice = reflect.Append(slice, mind.Addr())
|
||||
} else {
|
||||
slice = reflect.Append(slice, mind)
|
||||
}
|
||||
}
|
||||
}
|
||||
cnt++
|
||||
}
|
||||
|
||||
if one == false {
|
||||
if one == false && cnt > 0 {
|
||||
ind.Set(slice)
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ const (
|
||||
od_SET_DEFAULT = "set_default"
|
||||
od_DO_NOTHING = "do_nothing"
|
||||
defaultStructTagName = "orm"
|
||||
defaultStructTagDelim = ";"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -16,7 +16,7 @@ type Data struct {
|
||||
Char string `orm:"size(50)"`
|
||||
Text string `orm:"type(text)"`
|
||||
Date time.Time `orm:"type(date)"`
|
||||
DateTime time.Time
|
||||
DateTime time.Time `orm:"column(datetime)"`
|
||||
Byte byte
|
||||
Rune rune
|
||||
Int int
|
||||
@ -37,10 +37,10 @@ type Data struct {
|
||||
type DataNull struct {
|
||||
Id int
|
||||
Boolean bool `orm:"null"`
|
||||
Char string `orm:"size(50);null"`
|
||||
Text string `orm:"type(text);null"`
|
||||
Date time.Time `orm:"type(date);null"`
|
||||
DateTime time.Time `orm:"null"`
|
||||
Char string `orm:"null;size(50)"`
|
||||
Text string `orm:"null;type(text)"`
|
||||
Date time.Time `orm:"null;type(date)"`
|
||||
DateTime time.Time `orm:"null;column(datetime)""`
|
||||
Byte byte `orm:"null"`
|
||||
Rune rune `orm:"null"`
|
||||
Int int `orm:"null"`
|
||||
@ -174,7 +174,10 @@ var (
|
||||
IsPostgres = DBARGS.Driver == "postgres"
|
||||
)
|
||||
|
||||
var dORM Ormer
|
||||
var (
|
||||
dORM Ormer
|
||||
dDbBaser dbBaser
|
||||
)
|
||||
|
||||
func init() {
|
||||
Debug, _ = StrTo(DBARGS.Debug).Bool()
|
||||
|
@ -114,7 +114,7 @@ func getFieldType(val reflect.Value) (ft int, err error) {
|
||||
func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) {
|
||||
attr := make(map[string]bool)
|
||||
tag := make(map[string]string)
|
||||
for _, v := range strings.Split(data, ";") {
|
||||
for _, v := range strings.Split(data, defaultStructTagDelim) {
|
||||
v = strings.TrimSpace(v)
|
||||
if supportTag[v] == 1 {
|
||||
attr[v] = true
|
||||
|
360
orm/orm_raw.go
360
orm/orm_raw.go
@ -4,6 +4,8 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type rawPrepare struct {
|
||||
@ -64,14 +66,362 @@ func (o *rawSet) Exec() (sql.Result, error) {
|
||||
return o.orm.db.Exec(query, args...)
|
||||
}
|
||||
|
||||
func (o *rawSet) QueryRow(...interface{}) error {
|
||||
//TODO
|
||||
func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
|
||||
switch ind.Kind() {
|
||||
case reflect.Bool:
|
||||
if value == nil {
|
||||
ind.SetBool(false)
|
||||
} else if v, ok := value.(bool); ok {
|
||||
ind.SetBool(v)
|
||||
} else {
|
||||
v, _ := StrTo(ToStr(value)).Bool()
|
||||
ind.SetBool(v)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
if value == nil {
|
||||
ind.SetString("")
|
||||
} else {
|
||||
ind.SetString(ToStr(value))
|
||||
}
|
||||
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
if value == nil {
|
||||
ind.SetInt(0)
|
||||
} else {
|
||||
val := reflect.ValueOf(value)
|
||||
switch val.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
ind.SetInt(val.Int())
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
ind.SetInt(int64(val.Uint()))
|
||||
default:
|
||||
v, _ := StrTo(ToStr(value)).Int64()
|
||||
ind.SetInt(v)
|
||||
}
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
if value == nil {
|
||||
ind.SetUint(0)
|
||||
} else {
|
||||
val := reflect.ValueOf(value)
|
||||
switch val.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
ind.SetUint(uint64(val.Int()))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
ind.SetUint(val.Uint())
|
||||
default:
|
||||
v, _ := StrTo(ToStr(value)).Uint64()
|
||||
ind.SetUint(v)
|
||||
}
|
||||
}
|
||||
case reflect.Float64, reflect.Float32:
|
||||
if value == nil {
|
||||
ind.SetFloat(0)
|
||||
} else {
|
||||
val := reflect.ValueOf(value)
|
||||
switch val.Kind() {
|
||||
case reflect.Float64:
|
||||
ind.SetFloat(val.Float())
|
||||
default:
|
||||
v, _ := StrTo(ToStr(value)).Float64()
|
||||
ind.SetFloat(v)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
if value == nil {
|
||||
ind.Set(reflect.Zero(ind.Type()))
|
||||
|
||||
} else if _, ok := ind.Interface().(time.Time); ok {
|
||||
var str string
|
||||
switch d := value.(type) {
|
||||
case time.Time:
|
||||
o.orm.alias.DbBaser.TimeFromDB(&d, o.orm.alias.TZ)
|
||||
ind.Set(reflect.ValueOf(d))
|
||||
case []byte:
|
||||
str = string(d)
|
||||
case string:
|
||||
str = d
|
||||
}
|
||||
if str != "" {
|
||||
if len(str) >= 19 {
|
||||
str = str[:19]
|
||||
t, err := time.ParseInLocation(format_DateTime, str, o.orm.alias.TZ)
|
||||
if err == nil {
|
||||
t = t.In(DefaultTimeLoc)
|
||||
ind.Set(reflect.ValueOf(t))
|
||||
}
|
||||
} else if len(str) >= 10 {
|
||||
str = str[:10]
|
||||
t, err := time.ParseInLocation(format_Date, str, DefaultTimeLoc)
|
||||
if err == nil {
|
||||
ind.Set(reflect.ValueOf(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *rawSet) loopInitRefs(typ reflect.Type, refsPtr *[]interface{}, sIdxesPtr *[][]int) {
|
||||
sIdxes := *sIdxesPtr
|
||||
refs := *refsPtr
|
||||
|
||||
if typ.Kind() == reflect.Struct {
|
||||
if typ.String() == "time.Time" {
|
||||
var ref interface{}
|
||||
refs = append(refs, &ref)
|
||||
sIdxes = append(sIdxes, []int{0})
|
||||
} else {
|
||||
idxs := []int{}
|
||||
outFor:
|
||||
for idx := 0; idx < typ.NumField(); idx++ {
|
||||
ctyp := typ.Field(idx)
|
||||
|
||||
tag := ctyp.Tag.Get(defaultStructTagName)
|
||||
for _, v := range strings.Split(tag, defaultStructTagDelim) {
|
||||
if v == "-" {
|
||||
continue outFor
|
||||
}
|
||||
}
|
||||
|
||||
tp := ctyp.Type
|
||||
if tp.Kind() == reflect.Ptr {
|
||||
tp = tp.Elem()
|
||||
}
|
||||
|
||||
if tp.String() == "time.Time" {
|
||||
var ref interface{}
|
||||
refs = append(refs, &ref)
|
||||
|
||||
} else if tp.Kind() != reflect.Struct {
|
||||
var ref interface{}
|
||||
refs = append(refs, &ref)
|
||||
|
||||
} else {
|
||||
// skip other type
|
||||
continue
|
||||
}
|
||||
|
||||
idxs = append(idxs, idx)
|
||||
}
|
||||
sIdxes = append(sIdxes, idxs)
|
||||
}
|
||||
} else {
|
||||
var ref interface{}
|
||||
refs = append(refs, &ref)
|
||||
sIdxes = append(sIdxes, []int{0})
|
||||
}
|
||||
|
||||
*sIdxesPtr = sIdxes
|
||||
*refsPtr = refs
|
||||
}
|
||||
|
||||
func (o *rawSet) loopSetRefs(refs []interface{}, sIdxes [][]int, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) {
|
||||
nInds := *nIndsPtr
|
||||
|
||||
cur := 0
|
||||
for i, idxs := range sIdxes {
|
||||
sInd := sInds[i]
|
||||
eTyp := eTyps[i]
|
||||
|
||||
typ := eTyp
|
||||
isPtr := false
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
isPtr = true
|
||||
typ = typ.Elem()
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
isPtr = true
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
var nInd reflect.Value
|
||||
if init {
|
||||
nInd = reflect.New(sInd.Type()).Elem()
|
||||
} else {
|
||||
nInd = nInds[i]
|
||||
}
|
||||
|
||||
val := reflect.New(typ)
|
||||
ind := val.Elem()
|
||||
|
||||
tpName := ind.Type().String()
|
||||
|
||||
if ind.Kind() == reflect.Struct {
|
||||
if tpName == "time.Time" {
|
||||
value := reflect.ValueOf(refs[cur]).Elem().Interface()
|
||||
if isPtr && value == nil {
|
||||
val = reflect.New(val.Type()).Elem()
|
||||
} else {
|
||||
o.setFieldValue(ind, value)
|
||||
}
|
||||
cur++
|
||||
} else {
|
||||
hasValue := false
|
||||
for _, idx := range idxs {
|
||||
tind := ind.Field(idx)
|
||||
value := reflect.ValueOf(refs[cur]).Elem().Interface()
|
||||
if value != nil {
|
||||
hasValue = true
|
||||
}
|
||||
if tind.Kind() == reflect.Ptr {
|
||||
if value == nil {
|
||||
tindV := reflect.New(tind.Type()).Elem()
|
||||
tind.Set(tindV)
|
||||
} else {
|
||||
tindV := reflect.New(tind.Type().Elem())
|
||||
o.setFieldValue(tindV.Elem(), value)
|
||||
tind.Set(tindV)
|
||||
}
|
||||
} else {
|
||||
o.setFieldValue(tind, value)
|
||||
}
|
||||
cur++
|
||||
}
|
||||
if hasValue == false && isPtr {
|
||||
val = reflect.New(val.Type()).Elem()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value := reflect.ValueOf(refs[cur]).Elem().Interface()
|
||||
if isPtr && value == nil {
|
||||
val = reflect.New(val.Type()).Elem()
|
||||
} else {
|
||||
o.setFieldValue(ind, value)
|
||||
}
|
||||
cur++
|
||||
}
|
||||
|
||||
if nInd.Kind() == reflect.Slice {
|
||||
if isPtr {
|
||||
nInd = reflect.Append(nInd, val)
|
||||
} else {
|
||||
nInd = reflect.Append(nInd, ind)
|
||||
}
|
||||
} else {
|
||||
if isPtr {
|
||||
nInd.Set(val)
|
||||
} else {
|
||||
nInd.Set(ind)
|
||||
}
|
||||
}
|
||||
|
||||
nInds[i] = nInd
|
||||
}
|
||||
}
|
||||
|
||||
func (o *rawSet) QueryRow(containers ...interface{}) error {
|
||||
if len(containers) == 0 {
|
||||
panic("<RawSeter.QueryRow> need at least one arg")
|
||||
}
|
||||
|
||||
refs := make([]interface{}, 0, len(containers))
|
||||
sIdxes := make([][]int, 0)
|
||||
sInds := make([]reflect.Value, 0)
|
||||
eTyps := make([]reflect.Type, 0)
|
||||
|
||||
for _, container := range containers {
|
||||
val := reflect.ValueOf(container)
|
||||
ind := reflect.Indirect(val)
|
||||
|
||||
if val.Kind() != reflect.Ptr {
|
||||
panic("<RawSeter.QueryRow> all args must be use ptr")
|
||||
}
|
||||
|
||||
etyp := ind.Type()
|
||||
typ := etyp
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
sInds = append(sInds, ind)
|
||||
eTyps = append(eTyps, etyp)
|
||||
|
||||
o.loopInitRefs(typ, &refs, &sIdxes)
|
||||
}
|
||||
|
||||
query := o.query
|
||||
o.orm.alias.DbBaser.ReplaceMarks(&query)
|
||||
|
||||
args := getFlatParams(nil, o.args, o.orm.alias.TZ)
|
||||
row := o.orm.db.QueryRow(query, args...)
|
||||
|
||||
if err := row.Scan(refs...); err == sql.ErrNoRows {
|
||||
return ErrNoRows
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nInds := make([]reflect.Value, len(sInds))
|
||||
o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, true)
|
||||
for i, sInd := range sInds {
|
||||
nInd := nInds[i]
|
||||
sInd.Set(nInd)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *rawSet) QueryRows(...interface{}) (int64, error) {
|
||||
//TODO
|
||||
return 0, nil
|
||||
func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
|
||||
refs := make([]interface{}, 0)
|
||||
sIdxes := make([][]int, 0)
|
||||
sInds := make([]reflect.Value, 0)
|
||||
eTyps := make([]reflect.Type, 0)
|
||||
|
||||
for _, container := range containers {
|
||||
val := reflect.ValueOf(container)
|
||||
sInd := reflect.Indirect(val)
|
||||
if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice {
|
||||
panic("<RawSeter.QueryRows> all args must be use ptr slice")
|
||||
}
|
||||
|
||||
etyp := sInd.Type().Elem()
|
||||
typ := etyp
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
sInds = append(sInds, sInd)
|
||||
eTyps = append(eTyps, etyp)
|
||||
|
||||
o.loopInitRefs(typ, &refs, &sIdxes)
|
||||
}
|
||||
|
||||
query := o.query
|
||||
o.orm.alias.DbBaser.ReplaceMarks(&query)
|
||||
|
||||
args := getFlatParams(nil, o.args, o.orm.alias.TZ)
|
||||
rows, err := o.orm.db.Query(query, args...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
nInds := make([]reflect.Value, len(sInds))
|
||||
|
||||
var cnt int64
|
||||
for rows.Next() {
|
||||
if err := rows.Scan(refs...); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, cnt == 0)
|
||||
|
||||
cnt++
|
||||
}
|
||||
|
||||
if cnt > 0 {
|
||||
for i, sInd := range sInds {
|
||||
nInd := nInds[i]
|
||||
sInd.Set(nInd)
|
||||
}
|
||||
}
|
||||
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
func (o *rawSet) readValues(container interface{}) (int64, error) {
|
||||
|
351
orm/orm_test.go
351
orm/orm_test.go
@ -216,6 +216,7 @@ func TestRegisterModels(t *testing.T) {
|
||||
BootStrap()
|
||||
|
||||
dORM = NewOrm()
|
||||
dDbBaser = getDbAlias("default").DbBaser
|
||||
}
|
||||
|
||||
func TestModelSyntax(t *testing.T) {
|
||||
@ -629,9 +630,23 @@ func TestOperators(t *testing.T) {
|
||||
func TestAll(t *testing.T) {
|
||||
var users []*User
|
||||
qs := dORM.QueryTable("user")
|
||||
num, err := qs.All(&users)
|
||||
num, err := qs.OrderBy("Id").All(&users)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 3))
|
||||
throwFailNow(t, AssertIs(num, T_Equal, 3))
|
||||
|
||||
throwFail(t, AssertIs(users[0].UserName, T_Equal, "slene"))
|
||||
throwFail(t, AssertIs(users[1].UserName, T_Equal, "astaxie"))
|
||||
throwFail(t, AssertIs(users[2].UserName, T_Equal, "nobody"))
|
||||
|
||||
var users2 []User
|
||||
qs = dORM.QueryTable("user")
|
||||
num, err = qs.OrderBy("Id").All(&users2)
|
||||
throwFail(t, err)
|
||||
throwFailNow(t, AssertIs(num, T_Equal, 3))
|
||||
|
||||
throwFailNow(t, AssertIs(users2[0].UserName, T_Equal, "slene"))
|
||||
throwFailNow(t, AssertIs(users2[1].UserName, T_Equal, "astaxie"))
|
||||
throwFailNow(t, AssertIs(users2[2].UserName, T_Equal, "nobody"))
|
||||
|
||||
qs = dORM.QueryTable("user")
|
||||
num, err = qs.Filter("user_name", "nothing").All(&users)
|
||||
@ -645,8 +660,14 @@ func TestOne(t *testing.T) {
|
||||
err := qs.One(&user)
|
||||
throwFail(t, AssertIs(err, T_Equal, ErrMultiRows))
|
||||
|
||||
user = User{}
|
||||
err = qs.OrderBy("Id").Limit(1).One(&user)
|
||||
throwFailNow(t, err)
|
||||
throwFail(t, AssertIs(user.UserName, T_Equal, "slene"))
|
||||
|
||||
err = qs.Filter("user_name", "nothing").One(&user)
|
||||
throwFail(t, AssertIs(err, T_Equal, ErrNoRows))
|
||||
|
||||
}
|
||||
|
||||
func TestValues(t *testing.T) {
|
||||
@ -836,30 +857,282 @@ func TestPrepareInsert(t *testing.T) {
|
||||
throwFail(t, AssertIs(err, T_Equal, ErrStmtClosed))
|
||||
}
|
||||
|
||||
func TestRawQueryRow(t *testing.T) {
|
||||
func TestRawExec(t *testing.T) {
|
||||
Q := dDbBaser.TableQuote()
|
||||
|
||||
query := fmt.Sprintf("UPDATE %suser%s SET %suser_name%s = ? WHERE %suser_name%s = ?", Q, Q, Q, Q, Q, Q)
|
||||
res, err := dORM.Raw(query, "testing", "slene").Exec()
|
||||
throwFail(t, err)
|
||||
num, err := res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
|
||||
res, err = dORM.Raw(query, "slene", "testing").Exec()
|
||||
throwFail(t, err)
|
||||
num, err = res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
}
|
||||
|
||||
func TestRawQueryRows(t *testing.T) {
|
||||
func TestRawQueryRow(t *testing.T) {
|
||||
var (
|
||||
Boolean bool
|
||||
Char string
|
||||
Text string
|
||||
Date time.Time
|
||||
DateTime time.Time
|
||||
Byte byte
|
||||
Rune rune
|
||||
Int int
|
||||
Int8 int
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint uint
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
Decimal float64
|
||||
)
|
||||
|
||||
data_values := make(map[string]interface{}, len(Data_Values))
|
||||
|
||||
for k, v := range Data_Values {
|
||||
data_values[strings.ToLower(k)] = v
|
||||
}
|
||||
|
||||
Q := dDbBaser.TableQuote()
|
||||
|
||||
cols := []string{
|
||||
"id", "boolean", "char", "text", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32",
|
||||
"int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal",
|
||||
}
|
||||
sep := fmt.Sprintf("%s, %s", Q, Q)
|
||||
query := fmt.Sprintf("SELECT %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q)
|
||||
var id int
|
||||
values := []interface{}{
|
||||
&id, &Boolean, &Char, &Text, &Date, &DateTime, &Byte, &Rune, &Int, &Int8, &Int16, &Int32,
|
||||
&Int64, &Uint, &Uint8, &Uint16, &Uint32, &Uint64, &Float32, &Float64, &Decimal,
|
||||
}
|
||||
err := dORM.Raw(query, 1).QueryRow(values...)
|
||||
throwFailNow(t, err)
|
||||
for i, col := range cols {
|
||||
vu := values[i]
|
||||
v := reflect.ValueOf(vu).Elem().Interface()
|
||||
switch col {
|
||||
case "id":
|
||||
throwFail(t, AssertIs(id, T_Equal, 1))
|
||||
case "date":
|
||||
v = v.(time.Time).In(DefaultTimeLoc)
|
||||
value := data_values[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, T_Equal, value, test_Date))
|
||||
case "datetime":
|
||||
v = v.(time.Time).In(DefaultTimeLoc)
|
||||
value := data_values[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, T_Equal, value, test_DateTime))
|
||||
default:
|
||||
throwFail(t, AssertIs(v, T_Equal, data_values[col]))
|
||||
}
|
||||
}
|
||||
|
||||
type Tmp struct {
|
||||
Skip0 string
|
||||
Id int
|
||||
Char *string
|
||||
Skip1 int `orm:"-"`
|
||||
Date time.Time
|
||||
DateTime time.Time
|
||||
}
|
||||
|
||||
Boolean = false
|
||||
Text = ""
|
||||
Int64 = 0
|
||||
Uint = 0
|
||||
|
||||
tmp := new(Tmp)
|
||||
|
||||
cols = []string{
|
||||
"int", "char", "date", "datetime", "boolean", "text", "int64", "uint",
|
||||
}
|
||||
query = fmt.Sprintf("SELECT NULL, %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q)
|
||||
values = []interface{}{
|
||||
tmp, &Boolean, &Text, &Int64, &Uint,
|
||||
}
|
||||
err = dORM.Raw(query, 1).QueryRow(values...)
|
||||
throwFailNow(t, err)
|
||||
|
||||
for _, col := range cols {
|
||||
switch col {
|
||||
case "id":
|
||||
throwFail(t, AssertIs(tmp.Id, T_Equal, data_values[col]))
|
||||
case "char":
|
||||
c := tmp.Char
|
||||
throwFail(t, AssertIs(*c, T_Equal, data_values[col]))
|
||||
case "date":
|
||||
v := tmp.Date.In(DefaultTimeLoc)
|
||||
value := data_values[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, T_Equal, value, test_Date))
|
||||
case "datetime":
|
||||
v := tmp.DateTime.In(DefaultTimeLoc)
|
||||
value := data_values[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, T_Equal, value, test_DateTime))
|
||||
case "boolean":
|
||||
throwFail(t, AssertIs(Boolean, T_Equal, data_values[col]))
|
||||
case "text":
|
||||
throwFail(t, AssertIs(Text, T_Equal, data_values[col]))
|
||||
case "int64":
|
||||
throwFail(t, AssertIs(Int64, T_Equal, data_values[col]))
|
||||
case "uint":
|
||||
throwFail(t, AssertIs(Uint, T_Equal, data_values[col]))
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
uid int
|
||||
status *int
|
||||
pid *int
|
||||
)
|
||||
|
||||
cols = []string{
|
||||
"id", "status", "profile_id",
|
||||
}
|
||||
query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q)
|
||||
err = dORM.Raw(query, 4).QueryRow(&uid, &status, &pid)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(uid, T_Equal, 4))
|
||||
throwFail(t, AssertIs(*status, T_Equal, 3))
|
||||
throwFail(t, AssertIs(pid, T_Equal, nil))
|
||||
}
|
||||
|
||||
func TestQueryRows(t *testing.T) {
|
||||
Q := dDbBaser.TableQuote()
|
||||
|
||||
cols := []string{
|
||||
"id", "boolean", "char", "text", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32",
|
||||
"int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal",
|
||||
}
|
||||
|
||||
var datas []*Data
|
||||
var dids []int
|
||||
|
||||
sep := fmt.Sprintf("%s, %s", Q, Q)
|
||||
query := fmt.Sprintf("SELECT %s%s%s, id FROM %sdata%s", Q, strings.Join(cols, sep), Q, Q, Q)
|
||||
num, err := dORM.Raw(query).QueryRows(&datas, &dids)
|
||||
throwFailNow(t, err)
|
||||
throwFailNow(t, AssertIs(num, T_Equal, 1))
|
||||
throwFailNow(t, AssertIs(len(datas), T_Equal, 1))
|
||||
throwFailNow(t, AssertIs(len(dids), T_Equal, 1))
|
||||
throwFailNow(t, AssertIs(dids[0], T_Equal, 1))
|
||||
|
||||
ind := reflect.Indirect(reflect.ValueOf(datas[0]))
|
||||
|
||||
for name, value := range Data_Values {
|
||||
e := ind.FieldByName(name)
|
||||
vu := e.Interface()
|
||||
switch name {
|
||||
case "Date":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date)
|
||||
case "DateTime":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
|
||||
}
|
||||
throwFail(t, AssertIs(vu == value, T_Equal, true), value, vu)
|
||||
}
|
||||
|
||||
type Tmp struct {
|
||||
Id int
|
||||
Name string
|
||||
Skiped0 string `orm:"-"`
|
||||
Pid *int
|
||||
Skiped1 Data
|
||||
Skiped2 *Data
|
||||
}
|
||||
|
||||
var (
|
||||
ids []int
|
||||
userNames []string
|
||||
profileIds1 []int
|
||||
profileIds2 []*int
|
||||
createds []time.Time
|
||||
updateds []time.Time
|
||||
tmps1 []*Tmp
|
||||
tmps2 []Tmp
|
||||
)
|
||||
cols = []string{
|
||||
"id", "user_name", "profile_id", "profile_id", "id", "user_name", "profile_id", "id", "user_name", "profile_id", "created", "updated",
|
||||
}
|
||||
query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s ORDER BY id", Q, strings.Join(cols, sep), Q, Q, Q)
|
||||
num, err = dORM.Raw(query).QueryRows(&ids, &userNames, &profileIds1, &profileIds2, &tmps1, &tmps2, &createds, &updateds)
|
||||
throwFailNow(t, err)
|
||||
throwFailNow(t, AssertIs(num, T_Equal, 3))
|
||||
|
||||
var users []User
|
||||
dORM.QueryTable("user").OrderBy("Id").All(&users)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
id := ids[i]
|
||||
name := userNames[i]
|
||||
pid1 := profileIds1[i]
|
||||
pid2 := profileIds2[i]
|
||||
created := createds[i]
|
||||
updated := updateds[i]
|
||||
|
||||
user := users[i]
|
||||
throwFailNow(t, AssertIs(id, T_Equal, user.Id))
|
||||
throwFailNow(t, AssertIs(name, T_Equal, user.UserName))
|
||||
if user.Profile != nil {
|
||||
throwFailNow(t, AssertIs(pid1, T_Equal, user.Profile.Id))
|
||||
throwFailNow(t, AssertIs(*pid2, T_Equal, user.Profile.Id))
|
||||
} else {
|
||||
throwFailNow(t, AssertIs(pid1, T_Equal, 0))
|
||||
throwFailNow(t, AssertIs(pid2, T_Equal, nil))
|
||||
}
|
||||
throwFailNow(t, AssertIs(created, T_Equal, user.Created, test_Date))
|
||||
throwFailNow(t, AssertIs(updated, T_Equal, user.Updated, test_DateTime))
|
||||
|
||||
tmp := tmps1[i]
|
||||
tmp1 := *tmp
|
||||
throwFailNow(t, AssertIs(tmp1.Id, T_Equal, user.Id))
|
||||
throwFailNow(t, AssertIs(tmp1.Name, T_Equal, user.UserName))
|
||||
if user.Profile != nil {
|
||||
pid := tmp1.Pid
|
||||
throwFailNow(t, AssertIs(*pid, T_Equal, user.Profile.Id))
|
||||
} else {
|
||||
throwFailNow(t, AssertIs(tmp1.Pid, T_Equal, nil))
|
||||
}
|
||||
|
||||
tmp2 := tmps2[i]
|
||||
throwFailNow(t, AssertIs(tmp2.Id, T_Equal, user.Id))
|
||||
throwFailNow(t, AssertIs(tmp2.Name, T_Equal, user.UserName))
|
||||
if user.Profile != nil {
|
||||
pid := tmp2.Pid
|
||||
throwFailNow(t, AssertIs(*pid, T_Equal, user.Profile.Id))
|
||||
} else {
|
||||
throwFailNow(t, AssertIs(tmp2.Pid, T_Equal, nil))
|
||||
}
|
||||
}
|
||||
|
||||
type Sec struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
|
||||
var tmp []*Sec
|
||||
query = fmt.Sprintf("SELECT NULL, NULL FROM %suser%s LIMIT 1", Q, Q)
|
||||
num, err = dORM.Raw(query).QueryRows(&tmp)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||
throwFail(t, AssertIs(tmp[0], T_Equal, nil))
|
||||
}
|
||||
|
||||
func TestRawValues(t *testing.T) {
|
||||
switch {
|
||||
case IsMysql || IsSqlite:
|
||||
|
||||
res, err := dORM.Raw("UPDATE user SET user_name = ? WHERE user_name = ?", "testing", "slene").Exec()
|
||||
throwFail(t, err)
|
||||
num, err := res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
|
||||
res, err = dORM.Raw("UPDATE user SET user_name = ? WHERE user_name = ?", "slene", "testing").Exec()
|
||||
throwFail(t, err)
|
||||
num, err = res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
Q := dDbBaser.TableQuote()
|
||||
|
||||
var maps []Params
|
||||
num, err = dORM.Raw("SELECT user_name FROM user WHERE status = ?", 1).Values(&maps)
|
||||
query := fmt.Sprintf("SELECT %suser_name%s FROM %suser%s WHERE %sstatus%s = ?", Q, Q, Q, Q, Q, Q)
|
||||
num, err := dORM.Raw(query, 1).Values(&maps)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||
if num == 1 {
|
||||
@ -867,15 +1140,16 @@ func TestRawValues(t *testing.T) {
|
||||
}
|
||||
|
||||
var lists []ParamsList
|
||||
num, err = dORM.Raw("SELECT user_name FROM user WHERE status = ?", 1).ValuesList(&lists)
|
||||
num, err = dORM.Raw(query, 1).ValuesList(&lists)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||
if num == 1 {
|
||||
throwFail(t, AssertIs(lists[0][0], T_Equal, "slene"))
|
||||
}
|
||||
|
||||
query = fmt.Sprintf("SELECT %sprofile_id%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q)
|
||||
var list ParamsList
|
||||
num, err = dORM.Raw("SELECT profile_id FROM user ORDER BY id ASC").ValuesFlat(&list)
|
||||
num, err = dORM.Raw(query).ValuesFlat(&list)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 3))
|
||||
if num == 3 {
|
||||
@ -883,45 +1157,6 @@ func TestRawValues(t *testing.T) {
|
||||
throwFail(t, AssertIs(list[1], T_Equal, "3"))
|
||||
throwFail(t, AssertIs(list[2], T_Equal, nil))
|
||||
}
|
||||
|
||||
case IsPostgres:
|
||||
|
||||
res, err := dORM.Raw(`UPDATE "user" SET "user_name" = ? WHERE "user_name" = ?`, "testing", "slene").Exec()
|
||||
throwFail(t, err)
|
||||
num, err := res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
|
||||
res, err = dORM.Raw(`UPDATE "user" SET "user_name" = ? WHERE "user_name" = ?`, "slene", "testing").Exec()
|
||||
throwFail(t, err)
|
||||
num, err = res.RowsAffected()
|
||||
throwFail(t, AssertIs(num, T_Equal, 1), err)
|
||||
|
||||
var maps []Params
|
||||
num, err = dORM.Raw(`SELECT "user_name" FROM "user" WHERE "status" = ?`, 1).Values(&maps)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||
if num == 1 {
|
||||
throwFail(t, AssertIs(maps[0]["user_name"], T_Equal, "slene"))
|
||||
}
|
||||
|
||||
var lists []ParamsList
|
||||
num, err = dORM.Raw(`SELECT "user_name" FROM "user" WHERE "status" = ?`, 1).ValuesList(&lists)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||
if num == 1 {
|
||||
throwFail(t, AssertIs(lists[0][0], T_Equal, "slene"))
|
||||
}
|
||||
|
||||
var list ParamsList
|
||||
num, err = dORM.Raw(`SELECT "profile_id" FROM "user" ORDER BY id ASC`).ValuesFlat(&list)
|
||||
throwFail(t, err)
|
||||
throwFail(t, AssertIs(num, T_Equal, 3))
|
||||
if num == 3 {
|
||||
throwFail(t, AssertIs(list[0], T_Equal, "2"))
|
||||
throwFail(t, AssertIs(list[1], T_Equal, "3"))
|
||||
throwFail(t, AssertIs(list[2], T_Equal, nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawPrepare(t *testing.T) {
|
||||
|
@ -115,6 +115,8 @@ func ToStr(value interface{}, args ...int) (s string) {
|
||||
s = strconv.FormatUint(v, argInt(args).Get(0, 10))
|
||||
case string:
|
||||
s = v
|
||||
case []byte:
|
||||
s = string(v)
|
||||
default:
|
||||
s = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user