mirror of
https://github.com/astaxie/beego.git
synced 2024-12-28 06:35:46 +00:00
193 lines
3.3 KiB
Go
193 lines
3.3 KiB
Go
package orm
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
func getResult(res sql.Result) (int64, error) {
|
|
if num, err := res.LastInsertId(); err != nil {
|
|
return 0, err
|
|
} else {
|
|
if num > 0 {
|
|
return num, nil
|
|
}
|
|
}
|
|
if num, err := res.RowsAffected(); err != nil {
|
|
return num, err
|
|
} else {
|
|
if num > 0 {
|
|
return num, nil
|
|
}
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
type rawPrepare struct {
|
|
rs *rawSet
|
|
stmt *sql.Stmt
|
|
closed bool
|
|
}
|
|
|
|
func (o *rawPrepare) Exec(args ...interface{}) (int64, error) {
|
|
if o.closed {
|
|
return 0, ErrStmtClosed
|
|
}
|
|
res, err := o.stmt.Exec(args...)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return getResult(res)
|
|
}
|
|
|
|
func (o *rawPrepare) Close() error {
|
|
o.closed = true
|
|
return o.stmt.Close()
|
|
}
|
|
|
|
func newRawPreparer(rs *rawSet) (RawPreparer, error) {
|
|
o := new(rawPrepare)
|
|
o.rs = rs
|
|
st, err := rs.orm.db.Prepare(rs.query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
o.stmt = st
|
|
return o, nil
|
|
}
|
|
|
|
type rawSet struct {
|
|
query string
|
|
args []interface{}
|
|
orm *orm
|
|
}
|
|
|
|
func (o rawSet) SetArgs(args ...interface{}) RawSeter {
|
|
o.args = args
|
|
return &o
|
|
}
|
|
|
|
func (o *rawSet) Exec() (int64, error) {
|
|
res, err := o.orm.db.Exec(o.query, o.args...)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return getResult(res)
|
|
}
|
|
|
|
func (o *rawSet) Mapper(...interface{}) (int64, error) {
|
|
//TODO
|
|
return 0, nil
|
|
}
|
|
|
|
func (o *rawSet) readValues(container interface{}) (int64, error) {
|
|
var (
|
|
maps []Params
|
|
lists []ParamsList
|
|
list ParamsList
|
|
)
|
|
|
|
typ := 0
|
|
switch container.(type) {
|
|
case *[]Params:
|
|
typ = 1
|
|
case *[]ParamsList:
|
|
typ = 2
|
|
case *ParamsList:
|
|
typ = 3
|
|
default:
|
|
panic(fmt.Sprintf("unsupport read values type `%T`", container))
|
|
}
|
|
|
|
var rs *sql.Rows
|
|
if r, err := o.orm.db.Query(o.query, o.args...); err != nil {
|
|
return 0, err
|
|
} else {
|
|
rs = r
|
|
}
|
|
|
|
var (
|
|
refs []interface{}
|
|
cnt int64
|
|
cols []string
|
|
)
|
|
for rs.Next() {
|
|
if cnt == 0 {
|
|
if columns, err := rs.Columns(); err != nil {
|
|
return 0, err
|
|
} else {
|
|
cols = columns
|
|
refs = make([]interface{}, len(cols))
|
|
for i, _ := range refs {
|
|
var ref string
|
|
refs[i] = &ref
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := rs.Scan(refs...); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
switch typ {
|
|
case 1:
|
|
params := make(Params, len(cols))
|
|
for i, ref := range refs {
|
|
value := reflect.Indirect(reflect.ValueOf(ref)).Interface()
|
|
params[cols[i]] = value
|
|
}
|
|
maps = append(maps, params)
|
|
case 2:
|
|
params := make(ParamsList, 0, len(cols))
|
|
for _, ref := range refs {
|
|
value := reflect.Indirect(reflect.ValueOf(ref)).Interface()
|
|
params = append(params, value)
|
|
}
|
|
lists = append(lists, params)
|
|
case 3:
|
|
for _, ref := range refs {
|
|
value := reflect.Indirect(reflect.ValueOf(ref)).Interface()
|
|
list = append(list, value)
|
|
}
|
|
}
|
|
|
|
cnt++
|
|
}
|
|
|
|
switch v := container.(type) {
|
|
case *[]Params:
|
|
*v = maps
|
|
case *[]ParamsList:
|
|
*v = lists
|
|
case *ParamsList:
|
|
*v = list
|
|
}
|
|
|
|
return cnt, nil
|
|
}
|
|
|
|
func (o *rawSet) Values(container *[]Params) (int64, error) {
|
|
return o.readValues(container)
|
|
}
|
|
|
|
func (o *rawSet) ValuesList(container *[]ParamsList) (int64, error) {
|
|
return o.readValues(container)
|
|
}
|
|
|
|
func (o *rawSet) ValuesFlat(container *ParamsList) (int64, error) {
|
|
return o.readValues(container)
|
|
}
|
|
|
|
func (o *rawSet) Prepare() (RawPreparer, error) {
|
|
return newRawPreparer(o)
|
|
}
|
|
|
|
func newRawSet(orm *orm, query string, args []interface{}) RawSeter {
|
|
o := new(rawSet)
|
|
o.query = query
|
|
o.args = args
|
|
o.orm = orm
|
|
return o
|
|
}
|