mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
improve result data type converting for package gdb
This commit is contained in:
@ -155,7 +155,7 @@ type DB interface {
|
||||
// ===========================================================================
|
||||
|
||||
filterFields(schema, table string, data map[string]interface{}) map[string]interface{}
|
||||
convertValue(fieldValue []byte, fieldType string) interface{}
|
||||
convertValue(fieldValue interface{}, fieldType string) interface{}
|
||||
rowsToResult(rows *sql.Rows) (Result, error)
|
||||
}
|
||||
|
||||
|
||||
@ -737,7 +737,7 @@ func (c *Core) rowsToResult(rows *sql.Rows) (Result, error) {
|
||||
columnNames[k] = v.Name()
|
||||
}
|
||||
var (
|
||||
values = make([]sql.RawBytes, len(columnNames))
|
||||
values = make([]interface{}, len(columnNames))
|
||||
records = make(Result, 0)
|
||||
scanArgs = make([]interface{}, len(values))
|
||||
)
|
||||
@ -748,19 +748,12 @@ func (c *Core) rowsToResult(rows *sql.Rows) (Result, error) {
|
||||
if err := rows.Scan(scanArgs...); err != nil {
|
||||
return records, err
|
||||
}
|
||||
// Creates a new row object.
|
||||
row := make(Record)
|
||||
// Note that the internal looping variable <value> is type of []byte,
|
||||
// which points to the same memory address. So it should do a copy.
|
||||
for i, value := range values {
|
||||
if value == nil {
|
||||
row[columnNames[i]] = gvar.New(nil)
|
||||
} else {
|
||||
// As sql.RawBytes is type of slice,
|
||||
// it should do a copy of it.
|
||||
v := make([]byte, len(value))
|
||||
copy(v, value)
|
||||
row[columnNames[i]] = gvar.New(c.DB.convertValue(v, columnTypes[i]))
|
||||
row[columnNames[i]] = gvar.New(c.DB.convertValue(value, columnTypes[i]))
|
||||
}
|
||||
}
|
||||
records = append(records, row)
|
||||
|
||||
@ -21,7 +21,9 @@ import (
|
||||
|
||||
// convertValue automatically checks and converts field value from database type
|
||||
// to golang variable type.
|
||||
func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
func (c *Core) convertValue(fieldValue interface{}, fieldType string) interface{} {
|
||||
// If there's no type retrieved, it returns the <fieldValue> directly
|
||||
// to use its original data type, as <fieldValue> is type of interface{}.
|
||||
if fieldType == "" {
|
||||
return fieldValue
|
||||
}
|
||||
@ -35,7 +37,7 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
"tinyblob",
|
||||
"mediumblob",
|
||||
"longblob":
|
||||
return fieldValue
|
||||
return gconv.Bytes(fieldValue)
|
||||
|
||||
case
|
||||
"int",
|
||||
@ -46,21 +48,21 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
"mediumint",
|
||||
"serial":
|
||||
if gstr.ContainsI(fieldType, "unsigned") {
|
||||
gconv.Uint(string(fieldValue))
|
||||
gconv.Uint(gconv.String(fieldValue))
|
||||
}
|
||||
return gconv.Int(string(fieldValue))
|
||||
return gconv.Int(gconv.String(fieldValue))
|
||||
|
||||
case
|
||||
"big_int",
|
||||
"bigint",
|
||||
"bigserial":
|
||||
if gstr.ContainsI(fieldType, "unsigned") {
|
||||
gconv.Uint64(string(fieldValue))
|
||||
gconv.Uint64(gconv.String(fieldValue))
|
||||
}
|
||||
return gconv.Int64(string(fieldValue))
|
||||
return gconv.Int64(gconv.String(fieldValue))
|
||||
|
||||
case "real":
|
||||
return gconv.Float32(string(fieldValue))
|
||||
return gconv.Float32(gconv.String(fieldValue))
|
||||
|
||||
case
|
||||
"float",
|
||||
@ -69,10 +71,10 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
"money",
|
||||
"numeric",
|
||||
"smallmoney":
|
||||
return gconv.Float64(string(fieldValue))
|
||||
return gconv.Float64(gconv.String(fieldValue))
|
||||
|
||||
case "bit":
|
||||
s := string(fieldValue)
|
||||
s := gconv.String(fieldValue)
|
||||
// mssql is true|false string.
|
||||
if strings.EqualFold(s, "true") {
|
||||
return 1
|
||||
@ -80,41 +82,41 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
if strings.EqualFold(s, "false") {
|
||||
return 0
|
||||
}
|
||||
return gbinary.BeDecodeToInt64(fieldValue)
|
||||
return gbinary.BeDecodeToInt64(gconv.Bytes(fieldValue))
|
||||
|
||||
case "bool":
|
||||
return gconv.Bool(fieldValue)
|
||||
|
||||
case "date":
|
||||
t, _ := gtime.StrToTime(string(fieldValue))
|
||||
t, _ := gtime.StrToTime(gconv.String(fieldValue))
|
||||
return t.Format("Y-m-d")
|
||||
|
||||
case
|
||||
"datetime",
|
||||
"timestamp":
|
||||
t, _ := gtime.StrToTime(string(fieldValue))
|
||||
t, _ := gtime.StrToTime(gconv.String(fieldValue))
|
||||
return t.String()
|
||||
|
||||
default:
|
||||
// Auto detect field type, using key match.
|
||||
switch {
|
||||
case strings.Contains(t, "text") || strings.Contains(t, "char") || strings.Contains(t, "character"):
|
||||
return string(fieldValue)
|
||||
return gconv.String(fieldValue)
|
||||
|
||||
case strings.Contains(t, "float") || strings.Contains(t, "double") || strings.Contains(t, "numeric"):
|
||||
return gconv.Float64(string(fieldValue))
|
||||
return gconv.Float64(gconv.String(fieldValue))
|
||||
|
||||
case strings.Contains(t, "bool"):
|
||||
return gconv.Bool(string(fieldValue))
|
||||
return gconv.Bool(gconv.String(fieldValue))
|
||||
|
||||
case strings.Contains(t, "binary") || strings.Contains(t, "blob"):
|
||||
return fieldValue
|
||||
|
||||
case strings.Contains(t, "int"):
|
||||
return gconv.Int(string(fieldValue))
|
||||
return gconv.Int(gconv.String(fieldValue))
|
||||
|
||||
case strings.Contains(t, "time"):
|
||||
s := string(fieldValue)
|
||||
s := gconv.String(fieldValue)
|
||||
t, err := gtime.StrToTime(s)
|
||||
if err != nil {
|
||||
return s
|
||||
@ -122,7 +124,7 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
return t.String()
|
||||
|
||||
case strings.Contains(t, "date"):
|
||||
s := string(fieldValue)
|
||||
s := gconv.String(fieldValue)
|
||||
t, err := gtime.StrToTime(s)
|
||||
if err != nil {
|
||||
return s
|
||||
@ -130,7 +132,7 @@ func (c *Core) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
return t.Format("Y-m-d")
|
||||
|
||||
default:
|
||||
return fieldValue
|
||||
return gconv.String(fieldValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user