41dd6e58 by slene

orm 1. complete QueryRow/QueryRows api 2. QuerySeter.All support *[]Type and *[]*Type

1 parent 22d2de9f
......@@ -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 {
slice = reflect.Append(slice, mind.Addr())
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)
}
......
......@@ -5,11 +5,12 @@ import (
)
const (
od_CASCADE = "cascade"
od_SET_NULL = "set_null"
od_SET_DEFAULT = "set_default"
od_DO_NOTHING = "do_nothing"
defaultStructTagName = "orm"
od_CASCADE = "cascade"
od_SET_NULL = "set_null"
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
......
......@@ -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) {
......
......@@ -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,92 +857,306 @@ 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()
func TestRawValues(t *testing.T) {
switch {
case IsMysql || IsSqlite:
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]))
}
}
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)
type Tmp struct {
Skip0 string
Id int
Char *string
Skip1 int `orm:"-"`
Date time.Time
DateTime time.Time
}
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)
Boolean = false
Text = ""
Int64 = 0
Uint = 0
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"))
}
tmp := new(Tmp)
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"))
}
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)
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))
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]))
}
}
case IsPostgres:
var (
uid int
status *int
pid *int
)
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)
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))
}
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)
func TestQueryRows(t *testing.T) {
Q := dDbBaser.TableQuote()
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"))
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)
}
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"))
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))
}
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))
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) {
Q := dDbBaser.TableQuote()
var maps []Params
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 {
throwFail(t, AssertIs(maps[0]["user_name"], T_Equal, "slene"))
}
var lists []ParamsList
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(query).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)
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!