refactor conversion #2001
2
Makefile
2
Makefile
|
@ -6,7 +6,7 @@ GOFMT ?= gofmt -s
|
||||||
TAGS ?=
|
TAGS ?=
|
||||||
SED_INPLACE := sed -i
|
SED_INPLACE := sed -i
|
||||||
|
|
||||||
GO_DIRS := caches contexts integrations convert core dialects internal log migrate names schemas tags
|
GO_DIRS := caches contexts integrations core dialects internal log migrate names schemas tags
|
||||||
GOFILES := $(wildcard *.go)
|
GOFILES := $(wildcard *.go)
|
||||||
GOFILES += $(shell find $(GO_DIRS) -name "*.go" -type f)
|
GOFILES += $(shell find $(GO_DIRS) -name "*.go" -type f)
|
||||||
INTEGRATION_PACKAGES := xorm.io/xorm/integrations
|
INTEGRATION_PACKAGES := xorm.io/xorm/integrations
|
||||||
|
|
561
convert.go
561
convert.go
|
@ -15,7 +15,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/convert"
|
"xorm.io/xorm/internal/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
|
var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
|
||||||
|
@ -36,347 +36,6 @@ func cloneBytes(b []byte) []byte {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func asString(src interface{}) string {
|
|
||||||
switch v := src.(type) {
|
|
||||||
case string:
|
|
||||||
return v
|
|
||||||
case []byte:
|
|
||||||
return string(v)
|
|
||||||
case *sql.NullString:
|
|
||||||
return v.String
|
|
||||||
case *sql.NullInt32:
|
|
||||||
return fmt.Sprintf("%d", v.Int32)
|
|
||||||
case *sql.NullInt64:
|
|
||||||
return fmt.Sprintf("%d", v.Int64)
|
|
||||||
}
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return strconv.FormatInt(rv.Int(), 10)
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return strconv.FormatUint(rv.Uint(), 10)
|
|
||||||
case reflect.Float64:
|
|
||||||
return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
|
|
||||||
case reflect.Float32:
|
|
||||||
return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
|
|
||||||
case reflect.Bool:
|
|
||||||
return strconv.FormatBool(rv.Bool())
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%v", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func asInt64(src interface{}) (int64, error) {
|
|
||||||
switch v := src.(type) {
|
|
||||||
case int:
|
|
||||||
return int64(v), nil
|
|
||||||
case int16:
|
|
||||||
return int64(v), nil
|
|
||||||
case int32:
|
|
||||||
return int64(v), nil
|
|
||||||
case int8:
|
|
||||||
return int64(v), nil
|
|
||||||
case int64:
|
|
||||||
return v, nil
|
|
||||||
case uint:
|
|
||||||
return int64(v), nil
|
|
||||||
case uint8:
|
|
||||||
return int64(v), nil
|
|
||||||
case uint16:
|
|
||||||
return int64(v), nil
|
|
||||||
case uint32:
|
|
||||||
return int64(v), nil
|
|
||||||
case uint64:
|
|
||||||
return int64(v), nil
|
|
||||||
case []byte:
|
|
||||||
return strconv.ParseInt(string(v), 10, 64)
|
|
||||||
case string:
|
|
||||||
return strconv.ParseInt(v, 10, 64)
|
|
||||||
case *sql.NullString:
|
|
||||||
return strconv.ParseInt(v.String, 10, 64)
|
|
||||||
case *sql.NullInt32:
|
|
||||||
return int64(v.Int32), nil
|
|
||||||
case *sql.NullInt64:
|
|
||||||
return int64(v.Int64), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return rv.Int(), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return int64(rv.Uint()), nil
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
return int64(rv.Float()), nil
|
|
||||||
case reflect.String:
|
|
||||||
return strconv.ParseInt(rv.String(), 10, 64)
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unsupported value %T as int64", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func asUint64(src interface{}) (uint64, error) {
|
|
||||||
switch v := src.(type) {
|
|
||||||
case int:
|
|
||||||
return uint64(v), nil
|
|
||||||
case int16:
|
|
||||||
return uint64(v), nil
|
|
||||||
case int32:
|
|
||||||
return uint64(v), nil
|
|
||||||
case int8:
|
|
||||||
return uint64(v), nil
|
|
||||||
case int64:
|
|
||||||
return uint64(v), nil
|
|
||||||
case uint:
|
|
||||||
return uint64(v), nil
|
|
||||||
case uint8:
|
|
||||||
return uint64(v), nil
|
|
||||||
case uint16:
|
|
||||||
return uint64(v), nil
|
|
||||||
case uint32:
|
|
||||||
return uint64(v), nil
|
|
||||||
case uint64:
|
|
||||||
return v, nil
|
|
||||||
case []byte:
|
|
||||||
return strconv.ParseUint(string(v), 10, 64)
|
|
||||||
case string:
|
|
||||||
return strconv.ParseUint(v, 10, 64)
|
|
||||||
case *sql.NullString:
|
|
||||||
return strconv.ParseUint(v.String, 10, 64)
|
|
||||||
case *sql.NullInt32:
|
|
||||||
return uint64(v.Int32), nil
|
|
||||||
case *sql.NullInt64:
|
|
||||||
return uint64(v.Int64), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return uint64(rv.Int()), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return uint64(rv.Uint()), nil
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
return uint64(rv.Float()), nil
|
|
||||||
case reflect.String:
|
|
||||||
return strconv.ParseUint(rv.String(), 10, 64)
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unsupported value %T as uint64", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func asFloat64(src interface{}) (float64, error) {
|
|
||||||
switch v := src.(type) {
|
|
||||||
case int:
|
|
||||||
return float64(v), nil
|
|
||||||
case int16:
|
|
||||||
return float64(v), nil
|
|
||||||
case int32:
|
|
||||||
return float64(v), nil
|
|
||||||
case int8:
|
|
||||||
return float64(v), nil
|
|
||||||
case int64:
|
|
||||||
return float64(v), nil
|
|
||||||
case uint:
|
|
||||||
return float64(v), nil
|
|
||||||
case uint8:
|
|
||||||
return float64(v), nil
|
|
||||||
case uint16:
|
|
||||||
return float64(v), nil
|
|
||||||
case uint32:
|
|
||||||
return float64(v), nil
|
|
||||||
case uint64:
|
|
||||||
return float64(v), nil
|
|
||||||
case []byte:
|
|
||||||
return strconv.ParseFloat(string(v), 64)
|
|
||||||
case string:
|
|
||||||
return strconv.ParseFloat(v, 64)
|
|
||||||
case *sql.NullString:
|
|
||||||
return strconv.ParseFloat(v.String, 64)
|
|
||||||
case *sql.NullInt32:
|
|
||||||
return float64(v.Int32), nil
|
|
||||||
case *sql.NullInt64:
|
|
||||||
return float64(v.Int64), nil
|
|
||||||
case *sql.NullFloat64:
|
|
||||||
return v.Float64, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return float64(rv.Int()), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return float64(rv.Uint()), nil
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
return float64(rv.Float()), nil
|
|
||||||
case reflect.String:
|
|
||||||
return strconv.ParseFloat(rv.String(), 64)
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unsupported value %T as int64", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func asBigFloat(src interface{}) (*big.Float, error) {
|
|
||||||
res := big.NewFloat(0)
|
|
||||||
switch v := src.(type) {
|
|
||||||
case int:
|
|
||||||
res.SetInt64(int64(v))
|
|
||||||
return res, nil
|
|
||||||
case int16:
|
|
||||||
res.SetInt64(int64(v))
|
|
||||||
return res, nil
|
|
||||||
case int32:
|
|
||||||
res.SetInt64(int64(v))
|
|
||||||
return res, nil
|
|
||||||
case int8:
|
|
||||||
res.SetInt64(int64(v))
|
|
||||||
return res, nil
|
|
||||||
case int64:
|
|
||||||
res.SetInt64(int64(v))
|
|
||||||
return res, nil
|
|
||||||
case uint:
|
|
||||||
res.SetUint64(uint64(v))
|
|
||||||
return res, nil
|
|
||||||
case uint8:
|
|
||||||
res.SetUint64(uint64(v))
|
|
||||||
return res, nil
|
|
||||||
case uint16:
|
|
||||||
res.SetUint64(uint64(v))
|
|
||||||
return res, nil
|
|
||||||
case uint32:
|
|
||||||
res.SetUint64(uint64(v))
|
|
||||||
return res, nil
|
|
||||||
case uint64:
|
|
||||||
res.SetUint64(uint64(v))
|
|
||||||
return res, nil
|
|
||||||
case []byte:
|
|
||||||
res.SetString(string(v))
|
|
||||||
return res, nil
|
|
||||||
case string:
|
|
||||||
res.SetString(v)
|
|
||||||
return res, nil
|
|
||||||
case *sql.NullString:
|
|
||||||
if v.Valid {
|
|
||||||
res.SetString(v.String)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
case *sql.NullInt32:
|
|
||||||
if v.Valid {
|
|
||||||
res.SetInt64(int64(v.Int32))
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
case *sql.NullInt64:
|
|
||||||
if v.Valid {
|
|
||||||
res.SetInt64(int64(v.Int64))
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
res.SetInt64(rv.Int())
|
|
||||||
return res, nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
res.SetUint64(rv.Uint())
|
|
||||||
return res, nil
|
|
||||||
case reflect.Float64, reflect.Float32:
|
|
||||||
res.SetFloat64(rv.Float())
|
|
||||||
return res, nil
|
|
||||||
case reflect.String:
|
|
||||||
res.SetString(rv.String())
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("unsupported value %T as big.Float", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func asBytes(src interface{}) ([]byte, bool) {
|
|
||||||
switch t := src.(type) {
|
|
||||||
case []byte:
|
|
||||||
return t, true
|
|
||||||
case *sql.NullString:
|
|
||||||
if !t.Valid {
|
|
||||||
return nil, true
|
|
||||||
}
|
|
||||||
return []byte(t.String), true
|
|
||||||
case *sql.RawBytes:
|
|
||||||
return *t, true
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(src)
|
|
||||||
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return strconv.AppendInt(nil, rv.Int(), 10), true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return strconv.AppendUint(nil, rv.Uint(), 10), true
|
|
||||||
case reflect.Float32:
|
|
||||||
return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 32), true
|
|
||||||
case reflect.Float64:
|
|
||||||
return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 64), true
|
|
||||||
case reflect.Bool:
|
|
||||||
return strconv.AppendBool(nil, rv.Bool()), true
|
|
||||||
case reflect.String:
|
|
||||||
return []byte(rv.String()), true
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func asTime(src interface{}, dbLoc *time.Location, uiLoc *time.Location) (*time.Time, error) {
|
|
||||||
switch t := src.(type) {
|
|
||||||
case string:
|
|
||||||
return convert.String2Time(t, dbLoc, uiLoc)
|
|
||||||
case *sql.NullString:
|
|
||||||
if !t.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return convert.String2Time(t.String, dbLoc, uiLoc)
|
|
||||||
case []uint8:
|
|
||||||
if t == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return convert.String2Time(string(t), dbLoc, uiLoc)
|
|
||||||
case *sql.NullTime:
|
|
||||||
if !t.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
z, _ := t.Time.Zone()
|
|
||||||
if len(z) == 0 || t.Time.Year() == 0 || t.Time.Location().String() != dbLoc.String() {
|
|
||||||
tm := time.Date(t.Time.Year(), t.Time.Month(), t.Time.Day(), t.Time.Hour(),
|
|
||||||
t.Time.Minute(), t.Time.Second(), t.Time.Nanosecond(), dbLoc).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
}
|
|
||||||
tm := t.Time.In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
case *time.Time:
|
|
||||||
z, _ := t.Zone()
|
|
||||||
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
|
|
||||||
tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
|
||||||
t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
}
|
|
||||||
tm := t.In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
case time.Time:
|
|
||||||
z, _ := t.Zone()
|
|
||||||
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
|
|
||||||
tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
|
||||||
t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
}
|
|
||||||
tm := t.In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
case int:
|
|
||||||
tm := time.Unix(int64(t), 0).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
case int64:
|
|
||||||
tm := time.Unix(t, 0).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
case *sql.NullInt64:
|
|
||||||
tm := time.Unix(t.Int64, 0).In(uiLoc)
|
|
||||||
return &tm, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("unsupported value %#v as time", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertAssign copies to dest the value in src, converting it if possible.
|
// convertAssign copies to dest the value in src, converting it if possible.
|
||||||
// An error is returned if the copy would result in loss of information.
|
// An error is returned if the copy would result in loss of information.
|
||||||
// dest should be a pointer type.
|
// dest should be a pointer type.
|
||||||
|
@ -585,7 +244,7 @@ func convertAssign(dest, src interface{}, originalLocation *time.Location, conve
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case *NullUint32:
|
case *convert.NullUint32:
|
||||||
switch d := dest.(type) {
|
switch d := dest.(type) {
|
||||||
case *uint8:
|
case *uint8:
|
||||||
if s.Valid {
|
if s.Valid {
|
||||||
|
@ -603,7 +262,7 @@ func convertAssign(dest, src interface{}, originalLocation *time.Location, conve
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case *NullUint64:
|
case *convert.NullUint64:
|
||||||
switch d := dest.(type) {
|
switch d := dest.(type) {
|
||||||
case *uint64:
|
case *uint64:
|
||||||
if s.Valid {
|
if s.Valid {
|
||||||
|
@ -628,11 +287,11 @@ func convertAssign(dest, src interface{}, originalLocation *time.Location, conve
|
||||||
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||||
reflect.Float32, reflect.Float64:
|
reflect.Float32, reflect.Float64:
|
||||||
*d = asString(src)
|
*d = convert.AsString(src)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case *[]byte:
|
case *[]byte:
|
||||||
if b, ok := asBytes(src); ok {
|
if b, ok := convert.AsBytes(src); ok {
|
||||||
*d = b
|
*d = b
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -666,7 +325,7 @@ func convertAssignV(dv reflect.Value, src interface{}) error {
|
||||||
}
|
}
|
||||||
return convertAssignV(dv.Elem(), src)
|
return convertAssignV(dv.Elem(), src)
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
i64, err := asInt64(src)
|
i64, err := convert.AsInt64(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = strconvErr(err)
|
err = strconvErr(err)
|
||||||
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
||||||
|
@ -674,7 +333,7 @@ func convertAssignV(dv reflect.Value, src interface{}) error {
|
||||||
dv.SetInt(i64)
|
dv.SetInt(i64)
|
||||||
return nil
|
return nil
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
u64, err := asUint64(src)
|
u64, err := convert.AsUint64(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = strconvErr(err)
|
err = strconvErr(err)
|
||||||
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
||||||
|
@ -682,7 +341,7 @@ func convertAssignV(dv reflect.Value, src interface{}) error {
|
||||||
dv.SetUint(u64)
|
dv.SetUint(u64)
|
||||||
return nil
|
return nil
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
f64, err := asFloat64(src)
|
f64, err := convert.AsFloat64(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = strconvErr(err)
|
err = strconvErr(err)
|
||||||
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
||||||
|
@ -690,17 +349,17 @@ func convertAssignV(dv reflect.Value, src interface{}) error {
|
||||||
dv.SetFloat(f64)
|
dv.SetFloat(f64)
|
||||||
return nil
|
return nil
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
dv.SetString(asString(src))
|
dv.SetString(convert.AsString(src))
|
||||||
return nil
|
return nil
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
b, err := asBool(src)
|
b, err := convert.AsBool(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dv.SetBool(b)
|
dv.SetBool(b)
|
||||||
return nil
|
return nil
|
||||||
case reflect.Slice, reflect.Map, reflect.Struct, reflect.Array:
|
case reflect.Slice, reflect.Map, reflect.Struct, reflect.Array:
|
||||||
data, ok := asBytes(src)
|
data, ok := convert.AsBytes(src)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("onvertAssignV: src cannot be as bytes %#v", src)
|
return fmt.Errorf("onvertAssignV: src cannot be as bytes %#v", src)
|
||||||
}
|
}
|
||||||
|
@ -753,201 +412,3 @@ func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) {
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
|
return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asBool(src interface{}) (bool, error) {
|
|
||||||
switch v := src.(type) {
|
|
||||||
case bool:
|
|
||||||
return v, nil
|
|
||||||
case *bool:
|
|
||||||
return *v, nil
|
|
||||||
case *sql.NullBool:
|
|
||||||
return v.Bool, nil
|
|
||||||
case int64:
|
|
||||||
return v > 0, nil
|
|
||||||
case int:
|
|
||||||
return v > 0, nil
|
|
||||||
case int8:
|
|
||||||
return v > 0, nil
|
|
||||||
case int16:
|
|
||||||
return v > 0, nil
|
|
||||||
case int32:
|
|
||||||
return v > 0, nil
|
|
||||||
case []byte:
|
|
||||||
if len(v) == 0 {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if v[0] == 0x00 {
|
|
||||||
return false, nil
|
|
||||||
} else if v[0] == 0x01 {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return strconv.ParseBool(string(v))
|
|
||||||
case string:
|
|
||||||
return strconv.ParseBool(v)
|
|
||||||
case *sql.NullInt64:
|
|
||||||
return v.Int64 > 0, nil
|
|
||||||
case *sql.NullInt32:
|
|
||||||
return v.Int32 > 0, nil
|
|
||||||
default:
|
|
||||||
return false, fmt.Errorf("unknow type %T as bool", src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// str2PK convert string value to primary key value according to tp
|
|
||||||
func str2PKValue(s string, tp reflect.Type) (reflect.Value, error) {
|
|
||||||
var err error
|
|
||||||
var result interface{}
|
|
||||||
var defReturn = reflect.Zero(tp)
|
|
||||||
|
|
||||||
switch tp.Kind() {
|
|
||||||
case reflect.Int:
|
|
||||||
result, err = strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as int: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
case reflect.Int8:
|
|
||||||
x, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as int8: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = int8(x)
|
|
||||||
case reflect.Int16:
|
|
||||||
x, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as int16: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = int16(x)
|
|
||||||
case reflect.Int32:
|
|
||||||
x, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as int32: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = int32(x)
|
|
||||||
case reflect.Int64:
|
|
||||||
result, err = strconv.ParseInt(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as int64: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
case reflect.Uint:
|
|
||||||
x, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as uint: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = uint(x)
|
|
||||||
case reflect.Uint8:
|
|
||||||
x, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as uint8: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = uint8(x)
|
|
||||||
case reflect.Uint16:
|
|
||||||
x, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as uint16: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = uint16(x)
|
|
||||||
case reflect.Uint32:
|
|
||||||
x, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as uint32: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
result = uint32(x)
|
|
||||||
case reflect.Uint64:
|
|
||||||
result, err = strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return defReturn, fmt.Errorf("convert %s as uint64: %s", s, err.Error())
|
|
||||||
}
|
|
||||||
case reflect.String:
|
|
||||||
result = s
|
|
||||||
default:
|
|
||||||
return defReturn, errors.New("unsupported convert type")
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(result).Convert(tp), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func str2PK(s string, tp reflect.Type) (interface{}, error) {
|
|
||||||
v, err := str2PKValue(s, tp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return v.Interface(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ sql.Scanner = &NullUint64{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// NullUint64 represents an uint64 that may be null.
|
|
||||||
// NullUint64 implements the Scanner interface so
|
|
||||||
// it can be used as a scan destination, similar to NullString.
|
|
||||||
type NullUint64 struct {
|
|
||||||
Uint64 uint64
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan implements the Scanner interface.
|
|
||||||
func (n *NullUint64) Scan(value interface{}) error {
|
|
||||||
if value == nil {
|
|
||||||
n.Uint64, n.Valid = 0, false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
n.Valid = true
|
|
||||||
var err error
|
|
||||||
n.Uint64, err = asUint64(value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the driver Valuer interface.
|
|
||||||
func (n NullUint64) Value() (driver.Value, error) {
|
|
||||||
if !n.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return n.Uint64, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ sql.Scanner = &NullUint32{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// NullUint32 represents an uint32 that may be null.
|
|
||||||
// NullUint32 implements the Scanner interface so
|
|
||||||
// it can be used as a scan destination, similar to NullString.
|
|
||||||
type NullUint32 struct {
|
|
||||||
Uint32 uint32
|
|
||||||
Valid bool // Valid is true if Uint32 is not NULL
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan implements the Scanner interface.
|
|
||||||
func (n *NullUint32) Scan(value interface{}) error {
|
|
||||||
if value == nil {
|
|
||||||
n.Uint32, n.Valid = 0, false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
n.Valid = true
|
|
||||||
i64, err := asUint64(value)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n.Uint32 = uint32(i64)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the driver Valuer interface.
|
|
||||||
func (n NullUint32) Value() (driver.Value, error) {
|
|
||||||
if !n.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return int64(n.Uint32), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ sql.Scanner = &EmptyScanner{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// EmptyScanner represents an empty scanner which will ignore the scan
|
|
||||||
type EmptyScanner struct{}
|
|
||||||
|
|
||||||
// Scan implements sql.Scanner
|
|
||||||
func (EmptyScanner) Scan(value interface{}) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright 2021 The Xorm Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package convert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
// String2Time converts a string to time with original location
|
|
||||||
func String2Time(s string, originalLocation *time.Location, convertedLocation *time.Location) (*time.Time, error) {
|
|
||||||
if len(s) == 19 {
|
|
||||||
if s == utils.ZeroTime0 || s == utils.ZeroTime1 {
|
|
||||||
return &time.Time{}, nil
|
|
||||||
}
|
|
||||||
dt, err := time.ParseInLocation("2006-01-02 15:04:05", s, originalLocation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dt = dt.In(convertedLocation)
|
|
||||||
return &dt, nil
|
|
||||||
} else if len(s) == 20 && s[10] == 'T' && s[19] == 'Z' {
|
|
||||||
dt, err := time.ParseInLocation("2006-01-02T15:04:05", s[:19], originalLocation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dt = dt.In(convertedLocation)
|
|
||||||
return &dt, nil
|
|
||||||
} else if len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':' {
|
|
||||||
dt, err := time.Parse(time.RFC3339, s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dt = dt.In(convertedLocation)
|
|
||||||
return &dt, nil
|
|
||||||
} else {
|
|
||||||
i, err := strconv.ParseInt(s, 10, 64)
|
|
||||||
if err == nil {
|
|
||||||
tm := time.Unix(i, 0).In(convertedLocation)
|
|
||||||
return &tm, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("unsupported conversion from %s to time", s)
|
|
||||||
}
|
|
|
@ -9,68 +9,18 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
"xorm.io/xorm/contexts"
|
"xorm.io/xorm/contexts"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertInt(v interface{}) (int64, error) {
|
|
||||||
switch v.(type) {
|
|
||||||
case int:
|
|
||||||
return int64(v.(int)), nil
|
|
||||||
case int8:
|
|
||||||
return int64(v.(int8)), nil
|
|
||||||
case int16:
|
|
||||||
return int64(v.(int16)), nil
|
|
||||||
case int32:
|
|
||||||
return int64(v.(int32)), nil
|
|
||||||
case int64:
|
|
||||||
return v.(int64), nil
|
|
||||||
case []byte:
|
|
||||||
i, err := strconv.ParseInt(string(v.([]byte)), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
case string:
|
|
||||||
i, err := strconv.ParseInt(v.(string), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unsupported type: %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertFloat(v interface{}) (float64, error) {
|
|
||||||
switch v.(type) {
|
|
||||||
case float32:
|
|
||||||
return float64(v.(float32)), nil
|
|
||||||
case float64:
|
|
||||||
return v.(float64), nil
|
|
||||||
case string:
|
|
||||||
i, err := strconv.ParseFloat(v.(string), 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
case []byte:
|
|
||||||
i, err := strconv.ParseFloat(string(v.([]byte)), 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unsupported type: %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetVar(t *testing.T) {
|
func TestGetVar(t *testing.T) {
|
||||||
assert.NoError(t, PrepareEngine())
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
@ -261,17 +211,17 @@ func TestGetVar(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, true, has)
|
assert.Equal(t, true, has)
|
||||||
|
|
||||||
v1, err := convertInt(valuesSliceInter[0])
|
v1, err := convert.AsInt64(valuesSliceInter[0])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, v1)
|
assert.EqualValues(t, 1, v1)
|
||||||
|
|
||||||
assert.Equal(t, "hi", fmt.Sprintf("%s", valuesSliceInter[1]))
|
assert.Equal(t, "hi", fmt.Sprintf("%s", valuesSliceInter[1]))
|
||||||
|
|
||||||
v3, err := convertInt(valuesSliceInter[2])
|
v3, err := convert.AsInt64(valuesSliceInter[2])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 28, v3)
|
assert.EqualValues(t, 28, v3)
|
||||||
|
|
||||||
v4, err := convertFloat(valuesSliceInter[3])
|
v4, err := convert.AsFloat64(valuesSliceInter[3])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "1.5", fmt.Sprintf("%v", v4))
|
assert.Equal(t, "1.5", fmt.Sprintf("%v", v4))
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
"xorm.io/xorm/convert"
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/json"
|
"xorm.io/xorm/internal/json"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
|
||||||
|
|
51
internal/convert/bool.go
Normal file
51
internal/convert/bool.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsBool convert interface as bool
|
||||||
|
func AsBool(src interface{}) (bool, error) {
|
||||||
|
switch v := src.(type) {
|
||||||
|
case bool:
|
||||||
|
return v, nil
|
||||||
|
case *bool:
|
||||||
|
return *v, nil
|
||||||
|
case *sql.NullBool:
|
||||||
|
return v.Bool, nil
|
||||||
|
case int64:
|
||||||
|
return v > 0, nil
|
||||||
|
case int:
|
||||||
|
return v > 0, nil
|
||||||
|
case int8:
|
||||||
|
return v > 0, nil
|
||||||
|
case int16:
|
||||||
|
return v > 0, nil
|
||||||
|
case int32:
|
||||||
|
return v > 0, nil
|
||||||
|
case []byte:
|
||||||
|
if len(v) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if v[0] == 0x00 {
|
||||||
|
return false, nil
|
||||||
|
} else if v[0] == 0x01 {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return strconv.ParseBool(string(v))
|
||||||
|
case string:
|
||||||
|
return strconv.ParseBool(v)
|
||||||
|
case *sql.NullInt64:
|
||||||
|
return v.Int64 > 0, nil
|
||||||
|
case *sql.NullInt32:
|
||||||
|
return v.Int32 > 0, nil
|
||||||
|
default:
|
||||||
|
return false, fmt.Errorf("unknow type %T as bool", src)
|
||||||
|
}
|
||||||
|
}
|
142
internal/convert/float.go
Normal file
142
internal/convert/float.go
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsFloat64 convets interface as float64
|
||||||
|
func AsFloat64(src interface{}) (float64, error) {
|
||||||
|
switch v := src.(type) {
|
||||||
|
case int:
|
||||||
|
return float64(v), nil
|
||||||
|
case int16:
|
||||||
|
return float64(v), nil
|
||||||
|
case int32:
|
||||||
|
return float64(v), nil
|
||||||
|
case int8:
|
||||||
|
return float64(v), nil
|
||||||
|
case int64:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return float64(v), nil
|
||||||
|
case []byte:
|
||||||
|
return strconv.ParseFloat(string(v), 64)
|
||||||
|
case string:
|
||||||
|
return strconv.ParseFloat(v, 64)
|
||||||
|
case *sql.NullString:
|
||||||
|
return strconv.ParseFloat(v.String, 64)
|
||||||
|
case *sql.NullInt32:
|
||||||
|
return float64(v.Int32), nil
|
||||||
|
case *sql.NullInt64:
|
||||||
|
return float64(v.Int64), nil
|
||||||
|
case *sql.NullFloat64:
|
||||||
|
return v.Float64, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return float64(rv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return float64(rv.Uint()), nil
|
||||||
|
case reflect.Float64, reflect.Float32:
|
||||||
|
return float64(rv.Float()), nil
|
||||||
|
case reflect.String:
|
||||||
|
return strconv.ParseFloat(rv.String(), 64)
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unsupported value %T as int64", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsBigFloat converts interface as big.Float
|
||||||
|
func AsBigFloat(src interface{}) (*big.Float, error) {
|
||||||
|
res := big.NewFloat(0)
|
||||||
|
switch v := src.(type) {
|
||||||
|
case int:
|
||||||
|
res.SetInt64(int64(v))
|
||||||
|
return res, nil
|
||||||
|
case int16:
|
||||||
|
res.SetInt64(int64(v))
|
||||||
|
return res, nil
|
||||||
|
case int32:
|
||||||
|
res.SetInt64(int64(v))
|
||||||
|
return res, nil
|
||||||
|
case int8:
|
||||||
|
res.SetInt64(int64(v))
|
||||||
|
return res, nil
|
||||||
|
case int64:
|
||||||
|
res.SetInt64(int64(v))
|
||||||
|
return res, nil
|
||||||
|
case uint:
|
||||||
|
res.SetUint64(uint64(v))
|
||||||
|
return res, nil
|
||||||
|
case uint8:
|
||||||
|
res.SetUint64(uint64(v))
|
||||||
|
return res, nil
|
||||||
|
case uint16:
|
||||||
|
res.SetUint64(uint64(v))
|
||||||
|
return res, nil
|
||||||
|
case uint32:
|
||||||
|
res.SetUint64(uint64(v))
|
||||||
|
return res, nil
|
||||||
|
case uint64:
|
||||||
|
res.SetUint64(uint64(v))
|
||||||
|
return res, nil
|
||||||
|
case []byte:
|
||||||
|
res.SetString(string(v))
|
||||||
|
return res, nil
|
||||||
|
case string:
|
||||||
|
res.SetString(v)
|
||||||
|
return res, nil
|
||||||
|
case *sql.NullString:
|
||||||
|
if v.Valid {
|
||||||
|
res.SetString(v.String)
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
case *sql.NullInt32:
|
||||||
|
if v.Valid {
|
||||||
|
res.SetInt64(int64(v.Int32))
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
case *sql.NullInt64:
|
||||||
|
if v.Valid {
|
||||||
|
res.SetInt64(int64(v.Int64))
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
res.SetInt64(rv.Int())
|
||||||
|
return res, nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
res.SetUint64(rv.Uint())
|
||||||
|
return res, nil
|
||||||
|
case reflect.Float64, reflect.Float32:
|
||||||
|
res.SetFloat64(rv.Float())
|
||||||
|
return res, nil
|
||||||
|
case reflect.String:
|
||||||
|
res.SetString(rv.String())
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported value %T as big.Float", src)
|
||||||
|
}
|
178
internal/convert/int.go
Normal file
178
internal/convert/int.go
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsInt64 converts interface as int64
|
||||||
|
func AsInt64(src interface{}) (int64, error) {
|
||||||
|
switch v := src.(type) {
|
||||||
|
case int:
|
||||||
|
return int64(v), nil
|
||||||
|
case int16:
|
||||||
|
return int64(v), nil
|
||||||
|
case int32:
|
||||||
|
return int64(v), nil
|
||||||
|
case int8:
|
||||||
|
return int64(v), nil
|
||||||
|
case int64:
|
||||||
|
return v, nil
|
||||||
|
case uint:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return int64(v), nil
|
||||||
|
case []byte:
|
||||||
|
return strconv.ParseInt(string(v), 10, 64)
|
||||||
|
case string:
|
||||||
|
return strconv.ParseInt(v, 10, 64)
|
||||||
|
case *sql.NullString:
|
||||||
|
return strconv.ParseInt(v.String, 10, 64)
|
||||||
|
case *sql.NullInt32:
|
||||||
|
return int64(v.Int32), nil
|
||||||
|
case *sql.NullInt64:
|
||||||
|
return int64(v.Int64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return rv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return int64(rv.Uint()), nil
|
||||||
|
case reflect.Float64, reflect.Float32:
|
||||||
|
return int64(rv.Float()), nil
|
||||||
|
case reflect.String:
|
||||||
|
return strconv.ParseInt(rv.String(), 10, 64)
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unsupported value %T as int64", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsUint64 converts interface as uint64
|
||||||
|
func AsUint64(src interface{}) (uint64, error) {
|
||||||
|
switch v := src.(type) {
|
||||||
|
case int:
|
||||||
|
return uint64(v), nil
|
||||||
|
case int16:
|
||||||
|
return uint64(v), nil
|
||||||
|
case int32:
|
||||||
|
return uint64(v), nil
|
||||||
|
case int8:
|
||||||
|
return uint64(v), nil
|
||||||
|
case int64:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return v, nil
|
||||||
|
case []byte:
|
||||||
|
return strconv.ParseUint(string(v), 10, 64)
|
||||||
|
case string:
|
||||||
|
return strconv.ParseUint(v, 10, 64)
|
||||||
|
case *sql.NullString:
|
||||||
|
return strconv.ParseUint(v.String, 10, 64)
|
||||||
|
case *sql.NullInt32:
|
||||||
|
return uint64(v.Int32), nil
|
||||||
|
case *sql.NullInt64:
|
||||||
|
return uint64(v.Int64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return uint64(rv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return uint64(rv.Uint()), nil
|
||||||
|
case reflect.Float64, reflect.Float32:
|
||||||
|
return uint64(rv.Float()), nil
|
||||||
|
case reflect.String:
|
||||||
|
return strconv.ParseUint(rv.String(), 10, 64)
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unsupported value %T as uint64", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ sql.Scanner = &NullUint64{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NullUint64 represents an uint64 that may be null.
|
||||||
|
// NullUint64 implements the Scanner interface so
|
||||||
|
// it can be used as a scan destination, similar to NullString.
|
||||||
|
type NullUint64 struct {
|
||||||
|
Uint64 uint64
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the Scanner interface.
|
||||||
|
func (n *NullUint64) Scan(value interface{}) error {
|
||||||
|
if value == nil {
|
||||||
|
n.Uint64, n.Valid = 0, false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n.Valid = true
|
||||||
|
var err error
|
||||||
|
n.Uint64, err = AsUint64(value)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver Valuer interface.
|
||||||
|
func (n NullUint64) Value() (driver.Value, error) {
|
||||||
|
if !n.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return n.Uint64, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ sql.Scanner = &NullUint32{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NullUint32 represents an uint32 that may be null.
|
||||||
|
// NullUint32 implements the Scanner interface so
|
||||||
|
// it can be used as a scan destination, similar to NullString.
|
||||||
|
type NullUint32 struct {
|
||||||
|
Uint32 uint32
|
||||||
|
Valid bool // Valid is true if Uint32 is not NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the Scanner interface.
|
||||||
|
func (n *NullUint32) Scan(value interface{}) error {
|
||||||
|
if value == nil {
|
||||||
|
n.Uint32, n.Valid = 0, false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n.Valid = true
|
||||||
|
i64, err := AsUint64(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
n.Uint32 = uint32(i64)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver Valuer interface.
|
||||||
|
func (n NullUint32) Value() (driver.Value, error) {
|
||||||
|
if !n.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return int64(n.Uint32), nil
|
||||||
|
}
|
19
internal/convert/scanner.go
Normal file
19
internal/convert/scanner.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import "database/sql"
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ sql.Scanner = &EmptyScanner{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// EmptyScanner represents an empty scanner which will ignore the scan
|
||||||
|
type EmptyScanner struct{}
|
||||||
|
|
||||||
|
// Scan implements sql.Scanner
|
||||||
|
func (EmptyScanner) Scan(value interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
75
internal/convert/string.go
Normal file
75
internal/convert/string.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsString converts interface as string
|
||||||
|
func AsString(src interface{}) string {
|
||||||
|
switch v := src.(type) {
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
case []byte:
|
||||||
|
return string(v)
|
||||||
|
case *sql.NullString:
|
||||||
|
return v.String
|
||||||
|
case *sql.NullInt32:
|
||||||
|
return fmt.Sprintf("%d", v.Int32)
|
||||||
|
case *sql.NullInt64:
|
||||||
|
return fmt.Sprintf("%d", v.Int64)
|
||||||
|
}
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return strconv.FormatInt(rv.Int(), 10)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return strconv.FormatUint(rv.Uint(), 10)
|
||||||
|
case reflect.Float64:
|
||||||
|
return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
|
||||||
|
case reflect.Float32:
|
||||||
|
return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
|
||||||
|
case reflect.Bool:
|
||||||
|
return strconv.FormatBool(rv.Bool())
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsBytes converts interface as bytes
|
||||||
|
func AsBytes(src interface{}) ([]byte, bool) {
|
||||||
|
switch t := src.(type) {
|
||||||
|
case []byte:
|
||||||
|
return t, true
|
||||||
|
case *sql.NullString:
|
||||||
|
if !t.Valid {
|
||||||
|
return nil, true
|
||||||
|
}
|
||||||
|
return []byte(t.String), true
|
||||||
|
case *sql.RawBytes:
|
||||||
|
return *t, true
|
||||||
|
}
|
||||||
|
|
||||||
|
rv := reflect.ValueOf(src)
|
||||||
|
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return strconv.AppendInt(nil, rv.Int(), 10), true
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return strconv.AppendUint(nil, rv.Uint(), 10), true
|
||||||
|
case reflect.Float32:
|
||||||
|
return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 32), true
|
||||||
|
case reflect.Float64:
|
||||||
|
return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 64), true
|
||||||
|
case reflect.Bool:
|
||||||
|
return strconv.AppendBool(nil, rv.Bool()), true
|
||||||
|
case reflect.String:
|
||||||
|
return []byte(rv.String()), true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
108
internal/convert/time.go
Normal file
108
internal/convert/time.go
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"xorm.io/xorm/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String2Time converts a string to time with original location
|
||||||
|
func String2Time(s string, originalLocation *time.Location, convertedLocation *time.Location) (*time.Time, error) {
|
||||||
|
if len(s) == 19 {
|
||||||
|
if s == utils.ZeroTime0 || s == utils.ZeroTime1 {
|
||||||
|
return &time.Time{}, nil
|
||||||
|
}
|
||||||
|
dt, err := time.ParseInLocation("2006-01-02 15:04:05", s, originalLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
|
} else if len(s) == 20 && s[10] == 'T' && s[19] == 'Z' {
|
||||||
|
dt, err := time.ParseInLocation("2006-01-02T15:04:05", s[:19], originalLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
|
} else if len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':' {
|
||||||
|
dt, err := time.Parse(time.RFC3339, s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
|
} else {
|
||||||
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
tm := time.Unix(i, 0).In(convertedLocation)
|
||||||
|
return &tm, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported conversion from %s to time", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsTime converts interface as time
|
||||||
|
func AsTime(src interface{}, dbLoc *time.Location, uiLoc *time.Location) (*time.Time, error) {
|
||||||
|
switch t := src.(type) {
|
||||||
|
case string:
|
||||||
|
return String2Time(t, dbLoc, uiLoc)
|
||||||
|
case *sql.NullString:
|
||||||
|
if !t.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return String2Time(t.String, dbLoc, uiLoc)
|
||||||
|
case []uint8:
|
||||||
|
if t == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return String2Time(string(t), dbLoc, uiLoc)
|
||||||
|
case *sql.NullTime:
|
||||||
|
if !t.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
z, _ := t.Time.Zone()
|
||||||
|
if len(z) == 0 || t.Time.Year() == 0 || t.Time.Location().String() != dbLoc.String() {
|
||||||
|
tm := time.Date(t.Time.Year(), t.Time.Month(), t.Time.Day(), t.Time.Hour(),
|
||||||
|
t.Time.Minute(), t.Time.Second(), t.Time.Nanosecond(), dbLoc).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
}
|
||||||
|
tm := t.Time.In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
case *time.Time:
|
||||||
|
z, _ := t.Zone()
|
||||||
|
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
|
||||||
|
tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
||||||
|
t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
}
|
||||||
|
tm := t.In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
case time.Time:
|
||||||
|
z, _ := t.Zone()
|
||||||
|
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
|
||||||
|
tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
||||||
|
t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
}
|
||||||
|
tm := t.In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
case int:
|
||||||
|
tm := time.Unix(int64(t), 0).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
case int64:
|
||||||
|
tm := time.Unix(t, 0).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
case *sql.NullInt64:
|
||||||
|
tm := time.Unix(t.Int64, 0).In(uiLoc)
|
||||||
|
return &tm, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported value %#v as time", src)
|
||||||
|
}
|
|
@ -15,8 +15,8 @@ import (
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/xorm/contexts"
|
"xorm.io/xorm/contexts"
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/dialects"
|
"xorm.io/xorm/dialects"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/json"
|
"xorm.io/xorm/internal/json"
|
||||||
"xorm.io/xorm/internal/utils"
|
"xorm.io/xorm/internal/utils"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/dialects"
|
"xorm.io/xorm/dialects"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/json"
|
"xorm.io/xorm/internal/json"
|
||||||
"xorm.io/xorm/internal/utils"
|
"xorm.io/xorm/internal/utils"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/dialects"
|
"xorm.io/xorm/dialects"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/json"
|
"xorm.io/xorm/internal/json"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
10
scan.go
10
scan.go
|
@ -11,9 +11,9 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
"xorm.io/xorm/dialects"
|
"xorm.io/xorm/dialects"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ func genScanResultsByBeanNullable(bean interface{}) (interface{}, bool, error) {
|
||||||
case *int64:
|
case *int64:
|
||||||
return &sql.NullInt64{}, true, nil
|
return &sql.NullInt64{}, true, nil
|
||||||
case *uint, *uint8, *uint16, *uint32:
|
case *uint, *uint8, *uint16, *uint32:
|
||||||
return &NullUint32{}, true, nil
|
return &convert.NullUint32{}, true, nil
|
||||||
case *uint64:
|
case *uint64:
|
||||||
return &NullUint64{}, true, nil
|
return &convert.NullUint64{}, true, nil
|
||||||
case *float32, *float64:
|
case *float32, *float64:
|
||||||
return &sql.NullFloat64{}, true, nil
|
return &sql.NullFloat64{}, true, nil
|
||||||
case *bool:
|
case *bool:
|
||||||
|
@ -63,9 +63,9 @@ func genScanResultsByBeanNullable(bean interface{}) (interface{}, bool, error) {
|
||||||
case reflect.Int32, reflect.Int, reflect.Int16, reflect.Int8:
|
case reflect.Int32, reflect.Int, reflect.Int16, reflect.Int8:
|
||||||
return &sql.NullInt32{}, true, nil
|
return &sql.NullInt32{}, true, nil
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
return &NullUint64{}, true, nil
|
return &convert.NullUint64{}, true, nil
|
||||||
case reflect.Uint32, reflect.Uint, reflect.Uint16, reflect.Uint8:
|
case reflect.Uint32, reflect.Uint, reflect.Uint16, reflect.Uint8:
|
||||||
return &NullUint32{}, true, nil
|
return &convert.NullUint32{}, true, nil
|
||||||
default:
|
default:
|
||||||
return nil, false, fmt.Errorf("unsupported type: %#v", bean)
|
return nil, false, fmt.Errorf("unsupported type: %#v", bean)
|
||||||
}
|
}
|
||||||
|
|
14
session.go
14
session.go
|
@ -18,8 +18,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"xorm.io/xorm/contexts"
|
"xorm.io/xorm/contexts"
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/json"
|
"xorm.io/xorm/internal/json"
|
||||||
"xorm.io/xorm/internal/statements"
|
"xorm.io/xorm/internal/statements"
|
||||||
"xorm.io/xorm/log"
|
"xorm.io/xorm/log"
|
||||||
|
@ -435,7 +435,7 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, types []*sql
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) setJSON(fieldValue *reflect.Value, fieldType reflect.Type, scanResult interface{}) error {
|
func (session *Session) setJSON(fieldValue *reflect.Value, fieldType reflect.Type, scanResult interface{}) error {
|
||||||
bs, ok := asBytes(scanResult)
|
bs, ok := convert.AsBytes(scanResult)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unsupported database data type: %#v", scanResult)
|
return fmt.Errorf("unsupported database data type: %#v", scanResult)
|
||||||
}
|
}
|
||||||
|
@ -476,7 +476,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
|
|
||||||
if fieldValue.CanAddr() {
|
if fieldValue.CanAddr() {
|
||||||
if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
|
if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
|
||||||
data, ok := asBytes(scanResult)
|
data, ok := convert.AsBytes(scanResult)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("cannot convert %#v as bytes", scanResult)
|
return fmt.Errorf("cannot convert %#v as bytes", scanResult)
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
}
|
}
|
||||||
|
|
||||||
if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok {
|
if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok {
|
||||||
data, ok := asBytes(scanResult)
|
data, ok := convert.AsBytes(scanResult)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("cannot convert %#v as bytes", scanResult)
|
return fmt.Errorf("cannot convert %#v as bytes", scanResult)
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
case reflect.Complex64, reflect.Complex128:
|
case reflect.Complex64, reflect.Complex128:
|
||||||
return session.setJSON(fieldValue, fieldType, scanResult)
|
return session.setJSON(fieldValue, fieldType, scanResult)
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
bs, ok := asBytes(scanResult)
|
bs, ok := convert.AsBytes(scanResult)
|
||||||
if ok && fieldType.Elem().Kind() == reflect.Uint8 {
|
if ok && fieldType.Elem().Kind() == reflect.Uint8 {
|
||||||
if col.SQLType.IsText() {
|
if col.SQLType.IsText() {
|
||||||
x := reflect.New(fieldType)
|
x := reflect.New(fieldType)
|
||||||
|
@ -551,7 +551,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
if fieldType.ConvertibleTo(schemas.BigFloatType) {
|
if fieldType.ConvertibleTo(schemas.BigFloatType) {
|
||||||
v, err := asBigFloat(scanResult)
|
v, err := convert.AsBigFloat(scanResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
dbTZ = col.TimeZone
|
dbTZ = col.TimeZone
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := asTime(scanResult, dbTZ, session.engine.TZLocation)
|
t, err := convert.AsTime(scanResult, dbTZ, session.engine.TZLocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
|
@ -476,12 +475,13 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
} else if sliceValue.Kind() == reflect.Map {
|
} else if sliceValue.Kind() == reflect.Map {
|
||||||
var key = ids[j]
|
var key = ids[j]
|
||||||
keyType := sliceValue.Type().Key()
|
keyType := sliceValue.Type().Key()
|
||||||
|
keyValue := reflect.New(keyType)
|
||||||
var ikey interface{}
|
var ikey interface{}
|
||||||
if len(key) == 1 {
|
if len(key) == 1 {
|
||||||
ikey, err = str2PK(fmt.Sprintf("%v", key[0]), keyType)
|
if err := convertAssignV(keyValue, key[0]); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ikey = keyValue.Elem().Interface()
|
||||||
} else {
|
} else {
|
||||||
if keyType.Kind() != reflect.Slice {
|
if keyType.Kind() != reflect.Slice {
|
||||||
return errors.New("table have multiple primary keys, key is not schemas.PK or slice")
|
return errors.New("table have multiple primary keys, key is not schemas.PK or slice")
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"xorm.io/xorm/caches"
|
"xorm.io/xorm/caches"
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/internal/utils"
|
"xorm.io/xorm/internal/utils"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,8 +14,8 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"xorm.io/xorm/caches"
|
"xorm.io/xorm/caches"
|
||||||
"xorm.io/xorm/convert"
|
|
||||||
"xorm.io/xorm/dialects"
|
"xorm.io/xorm/dialects"
|
||||||
|
"xorm.io/xorm/internal/convert"
|
||||||
"xorm.io/xorm/names"
|
"xorm.io/xorm/names"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user