/
types.go
207 lines (189 loc) · 5.35 KB
/
types.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package model
import (
"fmt"
)
const (
// TypePGInt2 is a postgres type
TypePGInt2 = "int2"
// TypePGInt4 is a postgres type
TypePGInt4 = "int4"
// TypePGInt8 is a postgres type
TypePGInt8 = "int8"
// TypePGNumeric is a postgres type
TypePGNumeric = "numeric"
// TypePGFloat4 is a postgres type
TypePGFloat4 = "float4"
// TypePGFloat8 is a postgres type
TypePGFloat8 = "float8"
// TypePGText is a postgres type
TypePGText = "text"
// TypePGVarchar is a postgres type
TypePGVarchar = "varchar"
// TypePGUuid is a postgres type
TypePGUuid = "uuid"
// TypePGBpchar is a postgres type
TypePGBpchar = "bpchar"
// TypePGBytea is a postgres type
TypePGBytea = "bytea"
// TypePGBool is a postgres type
TypePGBool = "bool"
// TypePGTimestamp is a postgres type
TypePGTimestamp = "timestamp"
// TypePGTimestamptz is a postgres type
TypePGTimestamptz = "timestamptz"
// TypePGDate is a postgres type
TypePGDate = "date"
// TypePGTime is a postgres type
TypePGTime = "time"
// TypePGTimetz is a postgres type
TypePGTimetz = "timetz"
// TypePGInterval is a postgres type
TypePGInterval = "interval"
// TypePGJSONB is a postgres type
TypePGJSONB = "jsonb"
// TypePGJSON is a postgres type
TypePGJSON = "json"
// TypePGHstore is a postgres type
TypePGHstore = "hstore"
// TypePGInet is a postgres type
TypePGInet = "inet"
// TypePGCidr is a postgres type
TypePGCidr = "cidr"
// TypePGPoint is a postgres type
TypePGPoint = "point"
// TypeInt is a go type
TypeInt = "int"
// TypeInt32 is a go type
TypeInt32 = "int32"
// TypeInt64 is a go type
TypeInt64 = "int64"
// TypeFloat32 is a go type
TypeFloat32 = "float32"
// TypeFloat64 is a go type
TypeFloat64 = "float64"
// TypeString is a go type
TypeString = "string"
// TypeByteSlice is a go type
TypeByteSlice = "[]byte"
// TypeBool is a go type
TypeBool = "bool"
// TypeTime is a go type
TypeTime = "time.Time"
// TypeDuration is a go type
TypeDuration = "time.Duration"
// TypeMapInterface is a go type
TypeMapInterface = "map[string]interface{}"
// TypeMapString is a go type
TypeMapString = "map[string]string"
// TypeIP is a go type
TypeIP = "net.IP"
// TypeIPNet is a go type
TypeIPNet = "net.IPNet"
// TypeInterface is a go type
TypeInterface = "interface{}"
)
// GoType generates simple go type from Postgres type
func GoType(pgType string) (string, error) {
switch pgType {
case TypePGInt2, TypePGInt4:
return TypeInt, nil
case TypePGInt8:
return TypeInt64, nil
case TypePGFloat4:
return TypeFloat32, nil
case TypePGNumeric, TypePGFloat8:
return TypeFloat64, nil
case TypePGText, TypePGVarchar, TypePGUuid, TypePGBpchar, TypePGPoint:
return TypeString, nil
case TypePGBytea:
return TypeByteSlice, nil
case TypePGBool:
return TypeBool, nil
case TypePGTimestamp, TypePGTimestamptz, TypePGDate, TypePGTime, TypePGTimetz:
return TypeTime, nil
case TypePGInterval:
return TypeDuration, nil
case TypePGJSONB, TypePGJSON:
return TypeMapInterface, nil
case TypePGHstore:
return TypeMapString, nil
case TypePGInet:
return TypeIP, nil
case TypePGCidr:
return TypeIPNet, nil
}
return "", fmt.Errorf("unsupported type: %s", pgType)
}
// GoSlice generates go slice type from Postgres array
func GoSlice(pgType string, dimensions int) (string, error) {
switch pgType {
case TypePGTimestamp, TypePGTimestamptz, TypePGDate, TypePGTime, TypePGTimetz,
TypePGInterval, TypePGHstore, TypePGInet, TypePGCidr:
return "", fmt.Errorf("unsupported array type: %s", pgType)
}
typ, err := GoType(pgType)
if err != nil {
return "", err
}
// slice can not have 0 dimensions
if dimensions == 0 {
dimensions = 1
}
for i := 0; i < dimensions; i++ {
typ = fmt.Sprintf("[]%s", typ)
}
return typ, nil
}
// GoNullable generates all go types from Postgres type with pointer
func GoNullable(pgType string, useSQLNull bool, customTypes CustomTypeMapping) (string, error) {
// avoiding pointers with sql.Null... types
if useSQLNull {
switch pgType {
case TypePGInt2, TypePGInt4, TypePGInt8:
return "sql.NullInt64", nil
case TypePGNumeric, TypePGFloat4, TypePGFloat8:
return "sql.NullFloat64", nil
case TypePGBool:
return "sql.NullBool", nil
case TypePGText, TypePGVarchar, TypePGUuid, TypePGBpchar, TypePGPoint:
return "sql.NullString", nil
case TypePGTimestamp, TypePGTimestamptz, TypePGDate, TypePGTime, TypePGTimetz:
return "bun.NullTime", nil
}
}
if typ, ok := customTypes.GoType(pgType); ok && typ != "" {
return fmt.Sprintf("*%s", typ), nil
}
typ, err := GoType(pgType)
if err != nil {
return "", err
}
switch pgType {
case TypePGHstore, TypePGJSON, TypePGJSONB, TypePGBytea:
// hstore & json & bytea types without pointers
return typ, nil
default:
return fmt.Sprintf("*%s", typ), nil
}
}
// GoImport generates import from go type
func GoImport(pgType string, nullable, useSQLNull bool) string {
if nullable && useSQLNull {
switch pgType {
case TypePGInt2, TypePGInt4, TypePGInt8,
TypePGNumeric, TypePGFloat4, TypePGFloat8,
TypePGBool,
TypePGText, TypePGVarchar, TypePGUuid, TypePGBpchar, TypePGPoint:
return "database/sql"
case TypePGTimestamp, TypePGTimestamptz, TypePGDate, TypePGTime, TypePGTimetz:
return "github.com/uptrace/bun"
}
}
switch pgType {
case TypePGInet, TypePGCidr:
return "net"
case TypePGTimestamp, TypePGTimestamptz, TypePGDate, TypePGTime, TypePGTimetz, TypePGInterval:
return "time"
}
return ""
}