-
Notifications
You must be signed in to change notification settings - Fork 6
/
function.go
executable file
·398 lines (359 loc) · 9.67 KB
/
function.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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
package tto
import (
"fmt"
"os"
"reflect"
"strings"
ht "text/template"
"github.com/ixre/gof/db/db"
"github.com/ixre/gof/typeconv"
lang2 "github.com/ixre/tto/lang"
)
type internalFunc struct {
}
// 返回模板函数
func (t *internalFunc) funcMap() ht.FuncMap {
fm := make(map[string]interface{})
fm["env"] = t.getEnv
fm["boolInt"] = t.boolInt
fm["isEmpty"] = t.isEmpty
fm["add"] = t.plus
fm["plus"] = t.plus
fm["multi"] = t.multi
fm["mathRemain"] = t.mathRemain
// 单词首字大写
fm["title"] = t.title
// 将名称转为路径,规则: 替换首个"_"为"/"
fm["name_path"] = t.nameToPath
// 小写
fm["lower"] = t.lower
// 大写
fm["upper"] = t.upper
// 首字母小写: 如:{{lower_title .table.Name}}
fm["lower_title"] = t.lowerTitle
// 类型: 如:{{type "go" .columns[0].AdType}}
fm["type"] = t.langType
// 返回SQL/ORM类型, 如:{{sql_type "py" .columns[0].AdType}}
fm["sql_type"] = t.ormSqlType
// 返回主键代码类型
fm["pk_type"] = t.ormLangType
// 返回ORM的类型
fm["orm_type"] = t.ormLangType
// 判断是否为数字类型
fm["num_type"] = t.isMatchNumberField
// 转换为路径, 如:{{path .table.Name}}
fm["path"] = t.parsePath
// 包: {{pkg "go" "com/tto/pkg"}}
fm["pkg"] = t.langPkg
// 包名: {{pkg "go" "github/com/ixre"}} => github.com/ixre
fm["pkg_name"] = t.langPkgName
// 默认值, 如:{{default "go" .columns[0].AdType}}
fm["default"] = t.langDefaultValue
// 是否相等,如:{{equal "go" "rust"}
fm["equal"] = t.equal
// 是否与任意值相等, 如:{{equal_any 1 2 3 4}}, 1是否与2,3,4相等
fm["equal_any"] = t.equalAnyValue
// 替换,如: {{replace "table_name" "_" "-"}}
fm["replace"] = t.replace
// 替换N次,如: {{replace_n "table_name" "_" "-" 1}}
fm["replace_n"] = t.replaceN
// 截取字符串
fm["substr"] = t.substr
// 截取第N个字符位置后的字符串,如:{{substr_n "sys_user_list" "_" 1}}得到:user_list
fm["substr_n"] = t.substrN
// 截取索引为N的元素,如:{{get_n .tables 0}}
fm["get_n"] = t.getN
// 字符组合,如:{{str_join "1" "2" "3" ","}}结果为:1,2,3
fm["join"] = t.strJoin
fm["str_join"] = t.strJoin
// 包含函数, 如:{{contain .table.Pk "id"}}
fm["contain"] = t.contain
// 是否以指定字符开始, 如:{{starts_with .table.Pk "id"}}
fm["starts_with"] = t.startsWith
// 是否以指定字符结束, 如:{{ends_with .table.Pk "id"}}
fm["ends_with"] = t.endsWith
// 返回是否为数组中的最后一个元素索引
fm["is_last"] = t.isLast
// 排除列元素, 组成新的列数组, 如:{{ $columns := exclude .columns "id","create_time" }}
fm["exclude"] = t.exclude
// 尝试获取一个列,返回列及是否存在的Boolean, 如: {{ $c,$exist := try_get .columns "update_time" }}
fm["try_get"] = t.tryGet
return fm
}
// 小写
func (t *internalFunc) lower(s string) string {
return strings.ToLower(s)
}
// 大写
func (t *internalFunc) upper(s string) string {
return strings.ToUpper(s)
}
// 将首字母小写
func (t *internalFunc) lowerTitle(s string) string {
return lowerTitle(s)
}
// 将字符串单词首字母大写
func (t *internalFunc) title(s string) string {
return strings.Title(s)
}
// 将名称转为路径,规则: 替换首个"_"为"/"
func (t *internalFunc) nameToPath(s string) string {
return strings.Replace(s, "_", "/", 1)
}
// 转换为路径, 如:{{path .table.Name}}
func (t *internalFunc) parsePath(s string) string {
return strings.Replace(s, "_", "/", -1)
}
func (t *internalFunc) langType(lang string, typeId int) string {
return lang2.Get(lang).ParseType(typeId)
//switch lang {
//case "go":
// return l.GoTypes(typeId)
//case "java":
// return l.javaTypes(typeId)
//case "kotlin":
// return l.KotlinTypes(typeId)
//case "thrift":
// return l.ThriftTypes(typeId)
//case "protobuf":
// return l.ProtobufTypes(typeId)
//case "ts":
// return l.TsTypes(typeId)
//case "py":
// return l.PyTypes(typeId)
//}
//return strconv.Itoa(typeId)
}
func (t *internalFunc) ormLangType(lang string, typeId int) string {
// JAVA ORM框架要求为包装类
if lang == "java" {
return (lang2.Java{}).ParsePkType(typeId)
}
return lang2.Get(lang).ParseType(typeId)
}
// 返回SQL/ORM类型
func (t *internalFunc) ormSqlType(lang string, typeId int, len int) string {
return lang2.Get(lang).SqlMapType(typeId, len)
}
// 是否为数字字段
func (t *internalFunc) isMatchNumberField(typeId interface{}) bool {
v, ok := typeId.(int)
if ok {
for _, val := range []int{db.TypeInt16, db.TypeInt32, db.TypeInt64} {
if val == v {
return true
}
}
}
return false
}
// 将包名替换为.分割, 通常C#,JAVA语言使用"."分割包名
func (t *internalFunc) langPkg(lang string, pkg string) string {
return lang2.Get(lang).PkgPath(pkg)
}
func (t *internalFunc) langPkgName(lang string, pkg string) string {
return lang2.Get(lang).PkgName(pkg)
}
// 返回类型默认值
func (t *internalFunc) langDefaultValue(lang string, typeId int) string {
return lang2.Get(lang).DefaultValue(typeId)
//switch lang {
//case "go", "thrift","protobuf","ts":
// return l.GoValues(typeId)
//case "java","kotlin":
// return l.javaValues(typeId)
//case "py":
// return l.PythonValues(typeId)
//}
//return l.CommonValues(typeId)
}
// 是否相等,如:{{equal "go" "rust"}
func (t *internalFunc) equal(v1, v2 interface{}) bool {
return v1 == v2
}
// 是否与任意值相等, 如:{{equal_any 1 2 3 4}}, 1是否与2,3,4相等
func (t *internalFunc) equalAnyValue(src interface{}, args ...interface{}) bool {
for _, v := range args {
if v == src {
return true
}
}
return false
}
// 替换,如: {{replace "table_name" "_" "-"}}
func (t *internalFunc) replace(s, oldStr, newStr string) string {
return t.replaceN(s, oldStr, newStr, -1)
}
// 替换N次,如: {{replace_n "table_name" "_" "-" 1}}
func (t *internalFunc) replaceN(s, oldStr, newStr string, n int) string {
return strings.Replace(s, oldStr, newStr, n)
}
// 截取字符串,如:{{substr "sys_user_list" 0 3}}结果:sys
// 如:{{substr "sys_user_list" 4 }} 结果:sys_list
func (t *internalFunc) substr(s string, n ...int) string {
l := len(s)
for v := range n {
if v >= l {
return fmt.Sprintf("超出索引%d/%d", v, l)
}
}
switch len(n) {
case 1:
return s[n[0]:]
case 2:
return s[n[0]:n[1]]
}
return s
}
// 截取第N个字符位置后的字符串,如:{{substr_n "sys_user_list" "_" 1}}得到:user_list
func (t *internalFunc) substrN(s, char string, n int) string {
i, times := 0, 0
for {
i = strings.Index(s, char)
if i == -1 {
break
}
s = s[i+1:]
if times++; times == n {
break
}
}
return s
}
// 截取索引为N的元素,如:{{get_n .tables 0}}
func (t *internalFunc) getN(args interface{}, n int) interface{} {
kind := reflect.TypeOf(args).Kind()
if kind == reflect.Slice || kind == reflect.Array {
value := reflect.ValueOf(args)
if value.Len()-1 < n {
return nil
}
return value.Index(n).Interface()
}
return nil
//if len(args)-1 < n{
// return nil
//}
//return args[n]
}
// 字符组合,如:{{str_join "1","2","3" ","}}结果为:1,2,3
func (t *internalFunc) strJoin(s string, args ...string) string {
l := len(args)
if l == 0 {
return s
}
if l == 1 {
return s + args[0]
}
n := append([]string{s}, args[:len(args)-1]...)
return strings.Join(n, args[l-1])
}
// 是否包含
func (t *internalFunc) contain(v interface{}, s string) bool {
if v == nil {
return false
}
return strings.Contains(t.str(v), s)
}
// 是否以指定字符开始
func (t *internalFunc) startsWith(v interface{}, s string) bool {
if v == nil {
return false
}
return strings.HasPrefix(t.str(v), s)
}
// 是否以指定字符结束
func (t *internalFunc) endsWith(v interface{}, s string) bool {
if v == nil {
return false
}
return strings.HasSuffix(t.str(v), s)
}
// 返回是否为数组中的最后一个元素索引,如:
// {{$columns := .columns}}
// {{range $,$v := .columns}}
//
// {{if is_last $i .columns}}
// last column
// {{end}}
//
// {{end}}
func (t *internalFunc) isLast(i int, arr interface{}) bool {
kind := reflect.TypeOf(arr).Kind()
if kind == reflect.Slice || kind == reflect.Array {
return i == reflect.ValueOf(arr).Len()-1
}
return false
}
// 排除列元素, 组成新的列数组, 如:{{ $columns := exclude .columns "id","create_time" }}
func (t *internalFunc) exclude(columns []*Column, names ...string) []*Column {
arr := make([]*Column, 0)
for _, c := range columns {
b := false
for _, n := range names {
if c.Name == n {
b = true
break
}
}
if !b {
arr = append(arr, c)
}
}
return arr
}
// 尝试获取一个列,返回列. 如果不存在,返回空, 如: {{ $c := try_get .columns "update_time" }}
func (t *internalFunc) tryGet(columns []*Column, name string) *Column {
for _, c := range columns {
if c.Name == name {
return c
}
}
return nil
}
// 获取用户环境变量
func (t *internalFunc) getEnv(key string) string {
return os.Getenv(key)
}
// 判断是否为true
func (t *internalFunc) boolInt(i int32) bool {
return i > 0
}
// 加法
func (t *internalFunc) plus(x, y int) int {
return x + y
}
// 乘法
func (t *internalFunc) multi(x, y interface{}) interface{} {
fx, ok := x.(float64)
if ok {
switch y.(type) {
case float32:
return fx * float64(y.(float32))
case float64:
return fx * y.(float64)
case int:
return fx * float64(y.(int))
case int32:
return fx * float64(y.(int32))
case int64:
return fx * float64(y.(int64))
}
}
panic("not support")
}
// I32转为字符
func (t *internalFunc) str(i interface{}) string {
return typeconv.Stringify(i)
}
// 是否为空
func (t *internalFunc) isEmpty(s string) bool {
if s == "" {
return true
}
return strings.TrimSpace(s) == ""
}
// 求余
func (t *internalFunc) mathRemain(i int, j int) int {
return i % j
}