forked from yunionio/sqlchemy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reflect.go
144 lines (140 loc) · 4.1 KB
/
reflect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package sqlchemy
import (
"fmt"
"reflect"
"strconv"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/timeutils"
)
func getStringValue(dat interface{}) string {
value := reflect.ValueOf(dat)
switch value.Type() {
case gotypes.BoolType:
if value.Bool() {
return "true"
} else {
return "false"
}
case gotypes.IntType, gotypes.Int8Type, gotypes.Int16Type, gotypes.Int32Type, gotypes.Int64Type:
return fmt.Sprintf("%d", value.Int())
case gotypes.UintType, gotypes.Uint8Type, gotypes.Uint16Type, gotypes.Uint32Type, gotypes.Uint64Type:
return fmt.Sprintf("%d", value.Uint())
case gotypes.Float32Type, gotypes.Float64Type:
return fmt.Sprintf("%f", value.Float())
case gotypes.StringType:
return value.String()
case gotypes.TimeType:
tm, ok := value.Interface().(time.Time)
if !ok {
log.Errorf("Fail to convert to time.Time %s", value)
} else {
return timeutils.MysqlTime(tm)
}
/*case jsonutils.JSONStringType, jsonutils.JSONIntType, jsonutils.JSONFloatType, jsonutils.JSONBoolType,
jsonutils.JSONDictType, jsonutils.JSONArrayType:
json, ok := value.Interface().(jsonutils.JSONObject)
if !ok {
log.Errorf("fail to convert to JSONObject", value)
}else {
return json.String()
}*/
case gotypes.Uint8SliceType:
rawBytes, ok := value.Interface().([]byte)
if !ok {
log.Errorf("Fail to convert to bytes %s", value)
} else {
return string(rawBytes)
}
default:
serializable, ok := value.Interface().(gotypes.ISerializable)
if !ok {
log.Errorf("cannot convert %v to string", value)
return ""
}
return serializable.String()
}
return ""
}
func setValueBySQLString(value reflect.Value, val string) error {
if !value.CanSet() {
return fmt.Errorf("value is not settable")
}
switch value.Type() {
case gotypes.BoolType:
if val == "0" {
value.SetBool(false)
} else {
value.SetBool(true)
}
case tristate.TriStateType:
if val == "0" {
value.Set(tristate.TriStateFalseValue)
} else if val == "1" {
value.Set(tristate.TriStateTrueValue)
} else {
value.Set(tristate.TriStateNoneValue)
}
case gotypes.IntType, gotypes.Int8Type, gotypes.Int16Type, gotypes.Int32Type, gotypes.Int64Type:
valInt, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return err
}
value.SetInt(valInt)
case gotypes.UintType, gotypes.Uint8Type, gotypes.Uint16Type, gotypes.Uint32Type, gotypes.Uint64Type:
valUint, err := strconv.ParseUint(val, 10, 64)
if err != nil {
return err
}
value.SetUint(valUint)
case gotypes.Float32Type, gotypes.Float64Type:
valFloat, err := strconv.ParseFloat(val, 64)
if err != nil {
return err
}
value.SetFloat(valFloat)
case gotypes.StringType:
value.SetString(val)
case gotypes.TimeType:
if val != "0000-00-00 00:00:00" {
tm, err := timeutils.ParseTimeStr(val)
if err != nil {
return err
}
value.Set(reflect.ValueOf(tm))
}
/*case jsonutils.JSONDictType, jsonutils.JSONArrayType, jsonutils.JSONStringType, jsonutils.JSONIntType,
jsonutils.JSONFloatType, jsonutils.JSONBoolType, jsonutils.JSONObjectType:
log.Debugf("Decode JSON value: $%s$", val)
json, err := jsonutils.ParseString(val)
if err != nil {
return err
}
value.Set(reflect.ValueOf(json))*/
case gotypes.BoolSliceType, gotypes.IntSliceType, gotypes.Int8SliceType, gotypes.Int16SliceType,
gotypes.Int32SliceType, gotypes.Int64SliceType, gotypes.UintSliceType, gotypes.Uint8SliceType,
gotypes.Uint16SliceType, gotypes.Uint32SliceType, gotypes.Uint64SliceType,
gotypes.Float32SliceType, gotypes.Float64SliceType, gotypes.StringSliceType:
reflect.Append(value, reflect.ValueOf(val))
default:
valueType := value.Type()
if valueType.Implements(gotypes.ISerializableType) {
serializable, err := jsonutils.JSONDeserialize(valueType, val)
if err != nil {
return err
}
value.Set(reflect.ValueOf(serializable))
return nil
} else if value.Kind() == reflect.Ptr {
if value.IsNil() {
value.Set(reflect.New(value.Type().Elem()))
}
return setValueBySQLString(value.Elem(), val)
}
return fmt.Errorf("not supported type: %s", valueType)
}
return nil
}