Merge pull request #270 from winxxp/master

add support sql.NullString sql.NullInt64 ...
This commit is contained in:
Lunny Xiao 2015-07-27 09:44:30 +08:00
commit a4765bce78
2 changed files with 135 additions and 106 deletions

View File

@ -6,6 +6,7 @@ package xorm
import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
@ -1314,7 +1315,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
}
table := session.Engine.autoMapType(dataStruct)
return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc)
} else {
resultsSlice, err := session.query(sqlStr, args...)
@ -1755,6 +1755,14 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
vv = reflect.ValueOf(t)
fieldValue.Set(vv)
}
} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
// !<winxxp>! 增加支持sql.Scanner接口的结构如sql.NullString
hasAssigned = true
if err := nulVal.Scan(vv.Interface()); err != nil {
fmt.Println("sql.Sanner error:", err.Error())
session.Engine.LogError("sql.Sanner error:", err.Error())
hasAssigned = false
}
} else if session.Statement.UseCascade {
table := session.Engine.autoMapType(*fieldValue)
if table != nil {
@ -1762,6 +1770,7 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
panic("unsupported composited primary key cascade")
}
var pk = make(core.PK, len(table.PrimaryKeys))
switch rawValueType.Kind() {
case reflect.Int64:
pk[0] = vv.Int()
@ -2416,6 +2425,12 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
fieldValue.SetUint(x)
//Currently only support Time type
case reflect.Struct:
// !<winxxp>! 增加支持sql.Scanner接口的结构如sql.NullString
if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
if err := nulVal.Scan(data); err != nil {
return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error())
}
} else {
if fieldType.ConvertibleTo(core.TimeType) {
x, err := session.byte2Time(col, data)
if err != nil {
@ -2520,6 +2535,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
}
}
}
case reflect.Ptr:
// !nashtsai! TODO merge duplicated codes above
//typeStr := fieldType.String()
@ -2931,6 +2947,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
tf := session.Engine.FormatTime(col.SQLType.Name, t)
return tf, nil
}
if fieldTable, ok := session.Engine.Tables[fieldValue.Type()]; ok {
if len(fieldTable.PrimaryKeys) == 1 {
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
@ -2939,6 +2956,11 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
return 0, fmt.Errorf("no primary key for col %v", col.Name)
}
} else {
// !<winxxp>! 增加支持driver.Valuer接口的结构如sql.NullString
if v, ok := fieldValue.Interface().(driver.Valuer); ok {
return v.Value()
}
return 0, fmt.Errorf("Unsupported type %v", fieldValue.Type())
}
case reflect.Complex64, reflect.Complex128:
@ -2998,12 +3020,10 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
processor.BeforeInsert()
}
// --
colNames, args, err := genCols(table, session, bean, false, false)
if err != nil {
return 0, err
}
// insert expr columns, override if exists
exprColumns := session.Statement.getExpr()
exprColVals := make([]string, 0, len(exprColumns))

View File

@ -5,6 +5,7 @@
package xorm
import (
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
@ -219,6 +220,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
requiredField := useAllCols
includeNil := useAllCols
lColName := strings.ToLower(col.Name)
if b, ok := mustColumnMap[lColName]; ok {
if b {
requiredField = true
@ -320,6 +322,8 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
continue
}
val = engine.FormatTime(col.SQLType.Name, t)
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
val, _ = nulType.Value()
} else {
engine.autoMapType(fieldValue)
if table, ok := engine.Tables[fieldValue.Type()]; ok {
@ -509,6 +513,11 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
val = engine.FormatTime(col.SQLType.Name, t)
} else if _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok {
continue
} else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok {
val, _ = valNul.Value()
if val == nil {
continue
}
} else {
engine.autoMapType(fieldValue)
if table, ok := engine.Tables[fieldValue.Type()]; ok {