forked from yunionio/sqlchemy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.go
More file actions
108 lines (103 loc) · 3.17 KB
/
parser.go
File metadata and controls
108 lines (103 loc) · 3.17 KB
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
package sqlchemy
import (
"reflect"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/reflectutils"
)
func structField2ColumnSpec(field *reflectutils.SStructFieldValue) IColumnSpec {
fieldname := field.Info.MarshalName()
tagmap := field.Info.Tags
if _, ok := tagmap[TAG_IGNORE]; ok {
return nil
}
fieldType := field.Value.Type()
var retCol = getFiledTypeCol(fieldType, fieldname, tagmap, false)
if retCol == nil && fieldType.Kind() == reflect.Ptr {
retCol = getFiledTypeCol(fieldType.Elem(), fieldname, tagmap, true)
}
if retCol == nil {
panic("unsupported colume data type %s" + fieldType.Name())
}
return retCol
}
func getFiledTypeCol(fieldType reflect.Type, fieldname string, tagmap map[string]string, isPointer bool) IColumnSpec {
switch fieldType {
case gotypes.StringType:
col := NewTextColumn(fieldname, tagmap, isPointer)
return &col
case gotypes.IntType, gotypes.Int32Type:
tagmap[TAG_WIDTH] = "11"
col := NewIntegerColumn(fieldname, "INT", false, tagmap, isPointer)
return &col
case gotypes.Int8Type:
tagmap[TAG_WIDTH] = "4"
col := NewIntegerColumn(fieldname, "TINYINT", false, tagmap, isPointer)
return &col
case gotypes.Int16Type:
tagmap[TAG_WIDTH] = "6"
col := NewIntegerColumn(fieldname, "SMALLINT", false, tagmap, isPointer)
return &col
case gotypes.Int64Type:
tagmap[TAG_WIDTH] = "20"
col := NewIntegerColumn(fieldname, "BIGINT", false, tagmap, isPointer)
return &col
case gotypes.UintType, gotypes.Uint32Type:
tagmap[TAG_WIDTH] = "11"
col := NewIntegerColumn(fieldname, "INT", true, tagmap, isPointer)
return &col
case gotypes.Uint8Type:
tagmap[TAG_WIDTH] = "4"
col := NewIntegerColumn(fieldname, "TINYINT", true, tagmap, isPointer)
return &col
case gotypes.Uint16Type:
tagmap[TAG_WIDTH] = "6"
col := NewIntegerColumn(fieldname, "SMALLINT", true, tagmap, isPointer)
return &col
case gotypes.Uint64Type:
tagmap[TAG_WIDTH] = "20"
col := NewIntegerColumn(fieldname, "BIGINT", true, tagmap, isPointer)
return &col
case gotypes.BoolType:
tagmap[TAG_WIDTH] = "1"
col := NewBooleanColumn(fieldname, tagmap, isPointer)
return &col
case tristate.TriStateType:
tagmap[TAG_WIDTH] = "1"
col := NewTristateColumn(fieldname, tagmap, isPointer)
return &col
case gotypes.Float32Type, gotypes.Float64Type:
if _, ok := tagmap[TAG_WIDTH]; ok {
col := NewDecimalColumn(fieldname, tagmap, isPointer)
return &col
} else {
colType := "FLOAT"
if fieldType == gotypes.Float64Type {
colType = "DOUBLE"
}
col := NewFloatColumn(fieldname, colType, tagmap, isPointer)
return &col
}
case gotypes.TimeType:
col := NewDateTimeColumn(fieldname, tagmap, isPointer)
return &col
default:
if fieldType.Implements(gotypes.ISerializableType) {
col := NewCompoundColumn(fieldname, tagmap, isPointer)
return &col
}
}
return nil
}
func struct2TableSpec(sv reflect.Value, table *STableSpec) {
fields := reflectutils.FetchStructFieldValueSet(sv)
for i := 0; i < len(fields); i += 1 {
column := structField2ColumnSpec(&fields[i])
if column != nil {
if column.IsIndex() {
table.AddIndex(column.IsUnique(), column.Name())
}
table.columns = append(table.columns, column)
}
}
}