mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 21:11:29 +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)
|
ind := reflect.Indirect(val)
|
||||||
|
|
||||||
errTyp := true
|
errTyp := true
|
||||||
|
|
||||||
one := true
|
one := true
|
||||||
|
isPtr := true
|
||||||
|
|
||||||
if val.Kind() == reflect.Ptr {
|
if val.Kind() == reflect.Ptr {
|
||||||
fn := ""
|
fn := ""
|
||||||
if ind.Kind() == reflect.Slice {
|
if ind.Kind() == reflect.Slice {
|
||||||
one = false
|
one = false
|
||||||
if ind.Type().Elem().Kind() == reflect.Ptr {
|
typ := ind.Type().Elem()
|
||||||
typ := ind.Type().Elem().Elem()
|
switch typ.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
fn = getFullName(typ.Elem())
|
||||||
|
case reflect.Struct:
|
||||||
|
isPtr = false
|
||||||
fn = getFullName(typ)
|
fn = getFullName(typ)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -601,13 +605,21 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
|||||||
if one {
|
if one {
|
||||||
ind.Set(mind)
|
ind.Set(mind)
|
||||||
} else {
|
} else {
|
||||||
|
if cnt == 0 {
|
||||||
|
slice = reflect.New(ind.Type()).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPtr {
|
||||||
slice = reflect.Append(slice, mind.Addr())
|
slice = reflect.Append(slice, mind.Addr())
|
||||||
|
} else {
|
||||||
|
slice = reflect.Append(slice, mind)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnt++
|
cnt++
|
||||||
}
|
}
|
||||||
|
|
||||||
if one == false {
|
if one == false && cnt > 0 {
|
||||||
ind.Set(slice)
|
ind.Set(slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const (
|
|||||||
od_SET_DEFAULT = "set_default"
|
od_SET_DEFAULT = "set_default"
|
||||||
od_DO_NOTHING = "do_nothing"
|
od_DO_NOTHING = "do_nothing"
|
||||||
defaultStructTagName = "orm"
|
defaultStructTagName = "orm"
|
||||||
|
defaultStructTagDelim = ";"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -16,7 +16,7 @@ type Data struct {
|
|||||||
Char string `orm:"size(50)"`
|
Char string `orm:"size(50)"`
|
||||||
Text string `orm:"type(text)"`
|
Text string `orm:"type(text)"`
|
||||||
Date time.Time `orm:"type(date)"`
|
Date time.Time `orm:"type(date)"`
|
||||||
DateTime time.Time
|
DateTime time.Time `orm:"column(datetime)"`
|
||||||
Byte byte
|
Byte byte
|
||||||
Rune rune
|
Rune rune
|
||||||
Int int
|
Int int
|
||||||
@ -37,10 +37,10 @@ type Data struct {
|
|||||||
type DataNull struct {
|
type DataNull struct {
|
||||||
Id int
|
Id int
|
||||||
Boolean bool `orm:"null"`
|
Boolean bool `orm:"null"`
|
||||||
Char string `orm:"size(50);null"`
|
Char string `orm:"null;size(50)"`
|
||||||
Text string `orm:"type(text);null"`
|
Text string `orm:"null;type(text)"`
|
||||||
Date time.Time `orm:"type(date);null"`
|
Date time.Time `orm:"null;type(date)"`
|
||||||
DateTime time.Time `orm:"null"`
|
DateTime time.Time `orm:"null;column(datetime)""`
|
||||||
Byte byte `orm:"null"`
|
Byte byte `orm:"null"`
|
||||||
Rune rune `orm:"null"`
|
Rune rune `orm:"null"`
|
||||||
Int int `orm:"null"`
|
Int int `orm:"null"`
|
||||||
@ -174,7 +174,10 @@ var (
|
|||||||
IsPostgres = DBARGS.Driver == "postgres"
|
IsPostgres = DBARGS.Driver == "postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dORM Ormer
|
var (
|
||||||
|
dORM Ormer
|
||||||
|
dDbBaser dbBaser
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Debug, _ = StrTo(DBARGS.Debug).Bool()
|
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) {
|
func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) {
|
||||||
attr := make(map[string]bool)
|
attr := make(map[string]bool)
|
||||||
tag := make(map[string]string)
|
tag := make(map[string]string)
|
||||||
for _, v := range strings.Split(data, ";") {
|
for _, v := range strings.Split(data, defaultStructTagDelim) {
|
||||||
v = strings.TrimSpace(v)
|
v = strings.TrimSpace(v)
|
||||||
if supportTag[v] == 1 {
|
if supportTag[v] == 1 {
|
||||||
attr[v] = true
|
attr[v] = true
|
||||||
|
360
orm/orm_raw.go
360
orm/orm_raw.go
@ -4,6 +4,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rawPrepare struct {
|
type rawPrepare struct {
|
||||||
@ -64,14 +66,362 @@ func (o *rawSet) Exec() (sql.Result, error) {
|
|||||||
return o.orm.db.Exec(query, args...)
|
return o.orm.db.Exec(query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *rawSet) QueryRow(...interface{}) error {
|
func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
|
||||||
//TODO
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *rawSet) QueryRows(...interface{}) (int64, error) {
|
func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
|
||||||
//TODO
|
refs := make([]interface{}, 0)
|
||||||
return 0, nil
|
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) {
|
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()
|
BootStrap()
|
||||||
|
|
||||||
dORM = NewOrm()
|
dORM = NewOrm()
|
||||||
|
dDbBaser = getDbAlias("default").DbBaser
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestModelSyntax(t *testing.T) {
|
func TestModelSyntax(t *testing.T) {
|
||||||
@ -629,9 +630,23 @@ func TestOperators(t *testing.T) {
|
|||||||
func TestAll(t *testing.T) {
|
func TestAll(t *testing.T) {
|
||||||
var users []*User
|
var users []*User
|
||||||
qs := dORM.QueryTable("user")
|
qs := dORM.QueryTable("user")
|
||||||
num, err := qs.All(&users)
|
num, err := qs.OrderBy("Id").All(&users)
|
||||||
throwFail(t, err)
|
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")
|
qs = dORM.QueryTable("user")
|
||||||
num, err = qs.Filter("user_name", "nothing").All(&users)
|
num, err = qs.Filter("user_name", "nothing").All(&users)
|
||||||
@ -645,8 +660,14 @@ func TestOne(t *testing.T) {
|
|||||||
err := qs.One(&user)
|
err := qs.One(&user)
|
||||||
throwFail(t, AssertIs(err, T_Equal, ErrMultiRows))
|
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)
|
err = qs.Filter("user_name", "nothing").One(&user)
|
||||||
throwFail(t, AssertIs(err, T_Equal, ErrNoRows))
|
throwFail(t, AssertIs(err, T_Equal, ErrNoRows))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValues(t *testing.T) {
|
func TestValues(t *testing.T) {
|
||||||
@ -836,30 +857,282 @@ func TestPrepareInsert(t *testing.T) {
|
|||||||
throwFail(t, AssertIs(err, T_Equal, ErrStmtClosed))
|
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) {
|
func TestRawValues(t *testing.T) {
|
||||||
switch {
|
Q := dDbBaser.TableQuote()
|
||||||
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)
|
|
||||||
|
|
||||||
var maps []Params
|
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, err)
|
||||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||||
if num == 1 {
|
if num == 1 {
|
||||||
@ -867,15 +1140,16 @@ func TestRawValues(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lists []ParamsList
|
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, err)
|
||||||
throwFail(t, AssertIs(num, T_Equal, 1))
|
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||||
if num == 1 {
|
if num == 1 {
|
||||||
throwFail(t, AssertIs(lists[0][0], T_Equal, "slene"))
|
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
|
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, err)
|
||||||
throwFail(t, AssertIs(num, T_Equal, 3))
|
throwFail(t, AssertIs(num, T_Equal, 3))
|
||||||
if num == 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[1], T_Equal, "3"))
|
||||||
throwFail(t, AssertIs(list[2], T_Equal, nil))
|
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) {
|
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))
|
s = strconv.FormatUint(v, argInt(args).Get(0, 10))
|
||||||
case string:
|
case string:
|
||||||
s = v
|
s = v
|
||||||
|
case []byte:
|
||||||
|
s = string(v)
|
||||||
default:
|
default:
|
||||||
s = fmt.Sprintf("%v", v)
|
s = fmt.Sprintf("%v", v)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user