add Session.row2Bean

This commit is contained in:
Nash Tsai 2013-12-27 02:14:30 +08:00
parent 5d1ea229a4
commit 7bbabe72f0
4 changed files with 361 additions and 97 deletions

View File

@ -1,8 +1,12 @@
package xorm package xorm
import ( import (
"database/sql"
"fmt"
"reflect" "reflect"
"strconv"
"strings" "strings"
"time"
) )
func indexNoCase(s, sep string) int { func indexNoCase(s, sep string) int {
@ -61,3 +65,72 @@ func sliceEq(left, right []string) bool {
return true return true
} }
func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
aa := reflect.TypeOf((*rawValue).Interface())
vv := reflect.ValueOf((*rawValue).Interface())
var str string
switch aa.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
str = strconv.FormatInt(vv.Int(), 10)
data = []byte(str)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
str = strconv.FormatUint(vv.Uint(), 10)
data = []byte(str)
case reflect.Float32, reflect.Float64:
str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
data = []byte(str)
case reflect.String:
str = vv.String()
data = []byte(str)
case reflect.Array, reflect.Slice:
switch aa.Elem().Kind() {
case reflect.Uint8:
data = rawValue.Interface().([]byte)
default:
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
}
//时间类型
case reflect.Struct:
if aa == reflect.TypeOf(c_TIME_DEFAULT) {
str = rawValue.Interface().(time.Time).Format(time.RFC3339Nano)
data = []byte(str)
} else {
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
}
case reflect.Bool:
str = strconv.FormatBool(vv.Bool())
data = []byte(str)
case reflect.Complex128, reflect.Complex64:
str = fmt.Sprintf("%v", vv.Complex())
data = []byte(str)
/* TODO: unsupported types below
case reflect.Map:
case reflect.Ptr:
case reflect.Uintptr:
case reflect.UnsafePointer:
case reflect.Chan, reflect.Func, reflect.Interface:
*/
default:
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
}
return
}
func rows2maps(rows *sql.Rows) (resultsSlice []map[string][]byte, err error) {
fields, err := rows.Columns()
if err != nil {
return nil, err
}
for rows.Next() {
result, err := row2map(rows, fields)
if err != nil {
return nil, err
}
resultsSlice = append(resultsSlice, result)
}
return resultsSlice, nil
}

14
rows.go
View File

@ -13,6 +13,7 @@ type Rows struct {
stmt *sql.Stmt stmt *sql.Stmt
rows *sql.Rows rows *sql.Rows
fields []string fields []string
fieldsCount int
beanType reflect.Type beanType reflect.Type
lastError error lastError error
} }
@ -66,6 +67,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
defer rows.Close() defer rows.Close()
return nil, err return nil, err
} }
rows.fieldsCount = len(rows.fields)
return rows, nil return rows, nil
} }
@ -97,11 +99,13 @@ func (rows *Rows) Scan(bean interface{}) error {
return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType) return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType)
} }
result, err := row2map(rows.rows, rows.fields) // !nashtsai! TODO remove row2map then scanMapIntoStruct conversation for better performance return rows.session.row2Bean(rows.rows, rows.fields, rows.fieldsCount, bean)
if err == nil {
err = rows.session.scanMapIntoStruct(bean, result) // result, err := row2map(rows.rows, rows.fields) // !nashtsai! TODO remove row2map then scanMapIntoStruct conversation for better performance
} // if err == nil {
return err // err = rows.session.scanMapIntoStruct(bean, result)
// }
// return err
} }
// // Columns returns the column names. Columns returns an error if the rows are closed, or if the rows are from QueryRow and there was a deferred error. // // Columns returns the column names. Columns returns an error if the rows are closed, or if the rows are from QueryRow and there was a deferred error.

View File

@ -1220,8 +1220,6 @@ func row2map(rows *sql.Rows, fields []string) (resultsMap map[string][]byte, err
return nil, err return nil, err
} }
// !nashtsai! TODO optimization for query performance, where current process has gone from
// sql driver converted type back to []bytes then to ORM's fields
for ii, key := range fields { for ii, key := range fields {
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
@ -1230,72 +1228,261 @@ func row2map(rows *sql.Rows, fields []string) (resultsMap map[string][]byte, err
//fmt.Println("ignore ...", key, rawValue) //fmt.Println("ignore ...", key, rawValue)
continue continue
} }
aa := reflect.TypeOf(rawValue.Interface())
vv := reflect.ValueOf(rawValue.Interface()) if data, err := value2Bytes(&rawValue); err == nil {
var str string result[key] = data
switch aa.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
str = strconv.FormatInt(vv.Int(), 10)
result[key] = []byte(str)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
str = strconv.FormatUint(vv.Uint(), 10)
result[key] = []byte(str)
case reflect.Float32, reflect.Float64:
str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
result[key] = []byte(str)
case reflect.String:
str = vv.String()
result[key] = []byte(str)
case reflect.Array, reflect.Slice:
switch aa.Elem().Kind() {
case reflect.Uint8:
result[key] = rawValue.Interface().([]byte)
str = string(result[key])
default:
return nil, errors.New(fmt.Sprintf("Unsupported struct type %v", vv.Type().Name()))
}
//时间类型
case reflect.Struct:
if aa == reflect.TypeOf(c_TIME_DEFAULT) {
str = rawValue.Interface().(time.Time).Format(time.RFC3339Nano)
result[key] = []byte(str)
} else { } else {
return nil, errors.New(fmt.Sprintf("Unsupported struct type %v", vv.Type().Name())) return nil, err // !nashtsai! REVIEW, should return err or just error log?
}
case reflect.Bool:
str = strconv.FormatBool(vv.Bool())
result[key] = []byte(str)
case reflect.Complex128, reflect.Complex64:
str = fmt.Sprintf("%v", vv.Complex())
result[key] = []byte(str)
/* TODO: unsupported types below
case reflect.Map:
case reflect.Ptr:
case reflect.Uintptr:
case reflect.UnsafePointer:
case reflect.Chan, reflect.Func, reflect.Interface:
*/
default:
return nil, errors.New(fmt.Sprintf("Unsupported struct type %v", vv.Type().Name()))
} }
} }
return result, nil return result, nil
} }
func rows2maps(rows *sql.Rows) (resultsSlice []map[string][]byte, err error) { func (session *Session) getField(dataStruct *reflect.Value, key string, table *Table) *reflect.Value {
fields, err := rows.Columns()
if err != nil { key = strings.ToLower(key)
return nil, err if _, ok := table.Columns[key]; !ok {
session.Engine.LogWarn(fmt.Sprintf("table %v's has not column %v. %v", table.Name, key, table.ColumnsSeq))
return nil
} }
for rows.Next() { col := table.Columns[key]
result, err := row2map(rows, fields) fieldName := col.FieldName
if err != nil { fieldPath := strings.Split(fieldName, ".")
return nil, err var fieldValue reflect.Value
if len(fieldPath) > 2 {
session.Engine.LogError("Unsupported mutliderive", fieldName)
return nil
} else if len(fieldPath) == 2 {
parentField := dataStruct.FieldByName(fieldPath[0])
if parentField.IsValid() {
fieldValue = parentField.FieldByName(fieldPath[1])
} }
resultsSlice = append(resultsSlice, result) } else {
fieldValue = dataStruct.FieldByName(fieldName)
}
if !fieldValue.IsValid() || !fieldValue.CanSet() {
session.Engine.LogWarn("table %v's column %v is not valid or cannot set",
table.Name, key)
return nil
}
return &fieldValue
} }
return resultsSlice, nil func (session *Session) row2Bean(rows *sql.Rows, fields []string, fieldsCount int, bean interface{}) error {
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
if dataStruct.Kind() != reflect.Struct {
return errors.New("Expected a pointer to a struct")
}
table := session.Engine.autoMapType(rType(bean))
var scanResultContainers []interface{}
for i := 0; i < fieldsCount; i++ {
var scanResultContainer interface{}
scanResultContainers = append(scanResultContainers, &scanResultContainer)
}
if err := rows.Scan(scanResultContainers...); err != nil {
return err
}
for ii, key := range fields {
if fieldValue := session.getField(&dataStruct, key, table); fieldValue != nil {
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
//if row is null then ignore
if rawValue.Interface() == nil {
//fmt.Println("ignore ...", key, rawValue)
continue
}
if structConvert, ok := fieldValue.Addr().Interface().(Conversion); ok {
if data, err := value2Bytes(&rawValue); err == nil {
structConvert.FromDB(data)
} else {
session.Engine.LogError(err)
}
continue
}
aa := reflect.TypeOf(rawValue.Interface())
vv := reflect.ValueOf(rawValue.Interface())
fieldType := fieldValue.Type()
//fmt.Println("column name:", key, ", fieldType:", fieldType.String())
hasAssigned := false
switch fieldType.Kind() {
case reflect.Complex64, reflect.Complex128:
if aa.Kind() == reflect.String {
hasAssigned = true
x := reflect.New(fieldType)
err := json.Unmarshal([]byte(vv.String()), x.Interface())
if err != nil {
session.Engine.LogSQL(err)
return err
}
fieldValue.Set(x.Elem())
}
case reflect.Slice, reflect.Array:
switch aa.Kind() {
case reflect.Slice, reflect.Array:
switch aa.Elem().Kind() {
case reflect.Uint8:
hasAssigned = true
fieldValue.Set(rawValue)
}
}
case reflect.String:
if aa.Kind() == reflect.String {
hasAssigned = true
fieldValue.SetString(vv.String())
}
case reflect.Bool:
if aa.Kind() == reflect.Bool {
hasAssigned = true
fieldValue.SetBool(vv.Bool())
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch aa.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
hasAssigned = true
fieldValue.SetInt(vv.Int())
}
case reflect.Float32, reflect.Float64:
switch aa.Kind() {
case reflect.Float32, reflect.Float64:
hasAssigned = true
fieldValue.SetFloat(vv.Float())
}
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
switch aa.Kind() {
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
hasAssigned = true
fieldValue.SetUint(vv.Uint())
}
//Currently only support Time type
case reflect.Struct:
if fieldType == reflect.TypeOf(c_TIME_DEFAULT) {
if aa == reflect.TypeOf(c_TIME_DEFAULT) {
hasAssigned = true
fieldValue.Set(rawValue)
}
}
// else if session.Statement.UseCascade { // TODO
// table := session.Engine.autoMapType(fieldValue.Type())
// if table != nil {
// x, err := strconv.ParseInt(string(data), 10, 64)
// if err != nil {
// return errors.New("arg " + key + " as int: " + er1r.Error())
// }
// if x != 0 {
// // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
// // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
// // property to be fetched lazily
// structInter := reflect.New(fieldValue.Type())
// newsession := session.Engine.NewSession()
// defer newsession.Close()
// has, err := newsession.Id(x).Get(structInter.Interface())
// if err != nil {
// return err
// }
// if has {
// v = structInter.Elem().Interface()
// fieldValue.Set(reflect.ValueOf(v))
// } else {
// return errors.New("cascade obj is not exist!")
// }
// }
// } else {
// session.Engine.LogError("unsupported struct type in Scan: ", fieldValue.Type().String())
// }
// }
case reflect.Ptr:
// !nashtsai! TODO merge duplicated codes above
//typeStr := fieldType.String()
switch fieldType {
// following types case matching ptr's native type, therefore assign ptr directly
case reflect.TypeOf(&c_EMPTY_STRING), reflect.TypeOf(&c_BOOL_DEFAULT), reflect.TypeOf(&c_TIME_DEFAULT),
reflect.TypeOf(&c_FLOAT64_DEFAULT), reflect.TypeOf(&c_UINT64_DEFAULT), reflect.TypeOf(&c_INT64_DEFAULT):
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&rawValue))
case reflect.TypeOf(&c_FLOAT32_DEFAULT):
var x float32 = float32(vv.Float())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_INT_DEFAULT):
var x int = int(vv.Int())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_INT32_DEFAULT):
var x int32 = int32(vv.Int())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_INT8_DEFAULT):
var x int8 = int8(vv.Int())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_INT16_DEFAULT):
var x int16 = int16(vv.Int())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_UINT_DEFAULT):
var x uint = uint(vv.Uint())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_UINT32_DEFAULT):
var x uint32 = uint32(vv.Uint())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_UINT8_DEFAULT):
var x uint8 = uint8(vv.Uint())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_UINT16_DEFAULT):
var x uint16 = uint16(vv.Uint())
hasAssigned = true
fieldValue.Set(reflect.ValueOf(&x))
case reflect.TypeOf(&c_COMPLEX64_DEFAULT):
var x complex64
err := json.Unmarshal([]byte(vv.String()), &x)
if err != nil {
session.Engine.LogError(err)
} else {
fieldValue.Set(reflect.ValueOf(&x))
}
hasAssigned = true
case reflect.TypeOf(&c_COMPLEX128_DEFAULT):
var x complex128
err := json.Unmarshal([]byte(vv.String()), &x)
if err != nil {
session.Engine.LogError(err)
} else {
fieldValue.Set(reflect.ValueOf(&x))
}
hasAssigned = true
} // switch fieldType
// default:
// session.Engine.LogError("unsupported type in Scan: ", reflect.TypeOf(v).String())
} // switch fieldType.Kind()
// !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
if !hasAssigned {
data, err := value2Bytes(&rawValue)
if err == nil {
session.bytes2Value(table.Columns[key], fieldValue, data)
} else {
session.Engine.LogError(err.Error())
}
}
}
}
return nil
} }
func (session *Session) query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) { func (session *Session) query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
@ -1334,7 +1521,6 @@ func query(db *sql.DB, sql string, params ...interface{}) (resultsSlice []map[st
} }
defer rows.Close() defer rows.Close()
//fmt.Println(rows) //fmt.Println(rows)
return rows2maps(rows) return rows2maps(rows)
} }
@ -1619,7 +1805,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
err := json.Unmarshal(data, x.Interface()) err := json.Unmarshal(data, x.Interface())
if err != nil { if err != nil {
session.Engine.LogSQL(err) session.Engine.LogError(err)
return err return err
} }
fieldValue.Set(x.Elem()) fieldValue.Set(x.Elem())
@ -1631,7 +1817,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x := reflect.New(fieldType) x := reflect.New(fieldType)
err := json.Unmarshal(data, x.Interface()) err := json.Unmarshal(data, x.Interface())
if err != nil { if err != nil {
session.Engine.LogSQL(err) session.Engine.LogError(err)
return err return err
} }
fieldValue.Set(x.Elem()) fieldValue.Set(x.Elem())
@ -1642,7 +1828,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x := reflect.New(fieldType) x := reflect.New(fieldType)
err := json.Unmarshal(data, x.Interface()) err := json.Unmarshal(data, x.Interface())
if err != nil { if err != nil {
session.Engine.LogSQL(err) session.Engine.LogError(err)
return err return err
} }
fieldValue.Set(x.Elem()) fieldValue.Set(x.Elem())
@ -1656,7 +1842,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
d := string(data) d := string(data)
v, err := strconv.ParseBool(d) v, err := strconv.ParseBool(d)
if err != nil { if err != nil {
return errors.New("arg " + key + " as bool: " + err.Error()) return fmt.Errorf("arg %v as bool: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(v)) fieldValue.Set(reflect.ValueOf(v))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@ -1684,19 +1870,19 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x, err = strconv.ParseInt(sdata, 10, 64) x, err = strconv.ParseInt(sdata, 10, 64)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.SetInt(x) fieldValue.SetInt(x)
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
x, err := strconv.ParseFloat(string(data), 64) x, err := strconv.ParseFloat(string(data), 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as float64: " + err.Error()) return fmt.Errorf("arg %v as float64: %s", key, err.Error())
} }
fieldValue.SetFloat(x) fieldValue.SetFloat(x)
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
x, err := strconv.ParseUint(string(data), 10, 64) x, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.SetUint(x) fieldValue.SetUint(x)
//Currently only support Time type //Currently only support Time type
@ -1713,7 +1899,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
if table != nil { if table != nil {
x, err := strconv.ParseInt(string(data), 10, 64) x, err := strconv.ParseInt(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
if x != 0 { if x != 0 {
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
@ -1734,7 +1920,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
} }
} }
} else { } else {
return errors.New("unsupported struct type in Scan: " + fieldValue.Type().String()) return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
} }
} }
case reflect.Ptr: case reflect.Ptr:
@ -1750,7 +1936,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
d := string(data) d := string(data)
v, err := strconv.ParseBool(d) v, err := strconv.ParseBool(d)
if err != nil { if err != nil {
return errors.New("arg " + key + " as bool: " + err.Error()) return fmt.Errorf("arg %v as bool: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&v)) fieldValue.Set(reflect.ValueOf(&v))
// case "*complex64": // case "*complex64":
@ -1758,7 +1944,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x complex64 var x complex64
err := json.Unmarshal(data, &x) err := json.Unmarshal(data, &x)
if err != nil { if err != nil {
session.Engine.LogSQL(err) session.Engine.LogError(err)
return err return err
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1767,7 +1953,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x complex128 var x complex128
err := json.Unmarshal(data, &x) err := json.Unmarshal(data, &x)
if err != nil { if err != nil {
session.Engine.LogSQL(err) session.Engine.LogError(err)
return err return err
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1775,7 +1961,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
case reflect.TypeOf(&c_FLOAT64_DEFAULT): case reflect.TypeOf(&c_FLOAT64_DEFAULT):
x, err := strconv.ParseFloat(string(data), 64) x, err := strconv.ParseFloat(string(data), 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as float64: " + err.Error()) return fmt.Errorf("arg %v as float64: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*float32": // case "*float32":
@ -1783,7 +1969,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x float32 var x float32
x1, err := strconv.ParseFloat(string(data), 32) x1, err := strconv.ParseFloat(string(data), 32)
if err != nil { if err != nil {
return errors.New("arg " + key + " as float32: " + err.Error()) return fmt.Errorf("arg %v as float32: %s", key, err.Error())
} }
x = float32(x1) x = float32(x1)
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1800,7 +1986,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x uint64 var x uint64
x, err := strconv.ParseUint(string(data), 10, 64) x, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*uint": // case "*uint":
@ -1808,7 +1994,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x uint var x uint
x1, err := strconv.ParseUint(string(data), 10, 64) x1, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
x = uint(x1) x = uint(x1)
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1817,7 +2003,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x uint32 var x uint32
x1, err := strconv.ParseUint(string(data), 10, 64) x1, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
x = uint32(x1) x = uint32(x1)
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1826,7 +2012,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x uint8 var x uint8
x1, err := strconv.ParseUint(string(data), 10, 64) x1, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
x = uint8(x1) x = uint8(x1)
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1835,7 +2021,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
var x uint16 var x uint16
x1, err := strconv.ParseUint(string(data), 10, 64) x1, err := strconv.ParseUint(string(data), 10, 64)
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
x = uint16(x1) x = uint16(x1)
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
@ -1861,7 +2047,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x, err = strconv.ParseInt(sdata, 10, 64) x, err = strconv.ParseInt(sdata, 10, 64)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*int": // case "*int":
@ -1890,7 +2076,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x = int(x1) x = int(x1)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*int32": // case "*int32":
@ -1919,7 +2105,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x = int32(x1) x = int32(x1)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*int8": // case "*int8":
@ -1948,7 +2134,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x = int8(x1) x = int8(x1)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
// case "*int16": // case "*int16":
@ -1977,14 +2163,14 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
x = int16(x1) x = int16(x1)
} }
if err != nil { if err != nil {
return errors.New("arg " + key + " as int: " + err.Error()) return fmt.Errorf("arg %v as int: %s", key, err.Error())
} }
fieldValue.Set(reflect.ValueOf(&x)) fieldValue.Set(reflect.ValueOf(&x))
default: default:
return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String()) return fmt.Errorf("unsupported type in Scan: %s", reflect.TypeOf(v).String())
} }
default: default:
return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String()) return fmt.Errorf("unsupported type in Scan: %s", reflect.TypeOf(v).String())
} }
return nil return nil

View File

@ -163,6 +163,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
if t == reflect.TypeOf(c_TIME_DEFAULT) { if t == reflect.TypeOf(c_TIME_DEFAULT) {
st = SQLType{DateTime, 0, 0} st = SQLType{DateTime, 0, 0}
} else { } else {
// TODO need to handle association struct
st = SQLType{Text, 0, 0} st = SQLType{Text, 0, 0}
} }
case reflect.Ptr: case reflect.Ptr: