-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrtype.go
161 lines (152 loc) · 4.15 KB
/
rtype.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package lsm3
import (
"bytes"
"encoding/gob"
"fmt"
"github.com/xia-Sang/bitcask_go/parse"
"reflect"
"strconv"
"strings"
"unsafe"
)
func evaluateCondition(op string, leftValue reflect.Value, rightValue interface{}) bool {
switch op {
case "=":
return reflect.DeepEqual(leftValue.Interface(), rightValue)
case ">":
return compare(leftValue, rightValue) > 0
case "<":
return compare(leftValue, rightValue) < 0
case ">=":
return compare(leftValue, rightValue) >= 0
case "<=":
return compare(leftValue, rightValue) <= 0
case "!=":
return !reflect.DeepEqual(leftValue.Interface(), rightValue)
default:
return false
}
}
func compare(a reflect.Value, b interface{}) int {
bValue := reflect.ValueOf(b)
switch a.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return int(a.Int() - bValue.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return int(a.Uint() - bValue.Uint())
case reflect.Float32, reflect.Float64:
diff := a.Float() - bValue.Float()
if diff > 0 {
return 1
} else if diff < 0 {
return -1
}
return 0
case reflect.String:
return strings.Compare(a.String(), bValue.String())
default:
panic(fmt.Sprintf("unsupported type for comparison: %v", a.Kind()))
}
}
func createStructType(columns []parse.ColumnDefinition) reflect.Type {
var structFields []reflect.StructField
for _, column := range columns {
structFields = append(structFields, reflect.StructField{
Name: strings.Title(column.Name),
Type: getFieldType(column.DataType),
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, column.Name)),
})
}
// 创建结构体类型
structType := reflect.StructOf(structFields)
return structType
}
func (ti *TableInfo) newTableStruct() interface{} {
return reflect.New(ti.TableStructType).Interface()
}
func (ti *TableInfo) NewStructValues(values map[string]interface{}) interface{} {
return fillStructValues(ti.newTableStruct(), ti.TableColumns, values)
}
func fillStructValues(instance interface{}, columns []parse.ColumnDefinition, values map[string]interface{}) interface{} {
val := reflect.ValueOf(instance).Elem()
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
column := columns[i]
if field.CanSet() {
ptr := unsafe.Pointer(field.UnsafeAddr())
if value, ok := values[column.Name]; ok {
switch field.Kind() {
case reflect.String:
*(*string)(ptr) = value.(string)
case reflect.Int:
*(*int)(ptr) = value.(int)
case reflect.Float64:
*(*float64)(ptr) = value.(float64)
case reflect.Bool:
*(*bool)(ptr) = value.(bool)
default:
*(*string)(ptr) = value.(string)
}
} else {
switch field.Kind() {
case reflect.String:
*(*string)(ptr) = "nil"
case reflect.Float64:
*(*float64)(ptr) = 0.0
case reflect.Int:
*(*float64)(ptr) = 0
case reflect.Bool:
*(*bool)(ptr) = false
default:
*(*string)(ptr) = "nil"
}
}
}
}
return val.Interface()
}
// getFieldType 将列的数据类型映射为Go的数据类型
func getFieldType(columnType string) reflect.Type {
switch columnType {
case "int":
return reflect.TypeOf(int(0))
case "string":
return reflect.TypeOf("")
case "bool":
return reflect.TypeOf(false)
case "float64":
return reflect.TypeOf(0.0)
default:
return reflect.TypeOf("")
}
}
// serialize 将interface{}类型的数据序列化为字节数组
func serialize(data interface{}) ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(data)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// deserialize 将字节数组反序列化为interface{}类型的数据
func deserialize(data []byte, v interface{}) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
return dec.Decode(v)
}
func convertToType(value string, targetType reflect.Type) (interface{}, error) {
switch targetType.Kind() {
case reflect.String:
return value, nil
case reflect.Int:
return strconv.Atoi(value)
case reflect.Float64:
return strconv.ParseFloat(value, 64)
case reflect.Bool:
return strconv.ParseBool(value)
default:
return nil, fmt.Errorf("unsupported type: %v", targetType)
}
}