github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/db/tpl/tpl.analyze.go (about) 1 package tpl 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 ) 8 9 func isNil(input interface{}) bool { 10 return input == nil || fmt.Sprintf("%v", input) == "" 11 } 12 13 type tplCache struct { 14 sql string 15 params []interface{} 16 names []string 17 } 18 19 //AnalyzeTPLFromCache 从缓存中获取已解析的SQL语句 20 func AnalyzeTPLFromCache(name string, tpl string, input map[string]interface{}, prefix func() string) (sql string, params []interface{}) { 21 sql, params, _ = AnalyzeTPL(tpl, input, prefix) 22 return 23 /*key := fmt.Sprintf("%s_%s", name, tpl) 24 b, cache, _ := tplCaches.SetIfAbsentCb(key, func(i ...interface{}) (interface{}, error) { 25 sql, params, names := AnalyzeTPL(tpl, input, prefix) 26 return &tplCache{sql: sql, params: params, names: names}, nil 27 }) 28 value := cache.(*tplCache) 29 if b { 30 return value.sql, value.params 31 } 32 params = make([]interface{}, 0, len(value.names)) 33 for _, v := range value.names { 34 va := input[v] 35 if !isNil(va) { 36 params = append(params, va) 37 } else { 38 params = append(params, nil) 39 } 40 } 41 return value.sql, params*/ 42 } 43 44 // AnalyzeTPL 解析模板内容,并返回解析后的SQL语句,入输入参数 45 // @ 表达式,替换为参数化字符如: :1,:2,:3 46 // # 表达式,替换为指定值,值为空时返回 NULL 47 // $ 表达式,替换为指定值,值为空时返回 "" 48 // [ 大于等于表达式,值为空时返回"",否则返回: and name >= value 49 // ] 小于等于表达式,值为空时返回"",否则返回: and name <= value 50 // ~ 表达式,检查值,值为空时返回"",否则返回: , name=value 51 // & 条件表达式,检查值,值为空时返回"",否则返回: and name=value 52 // | 条件表达式,检查值,值为空时返回"", 否则返回: or name=value 53 func AnalyzeTPL(tpl string, input map[string]interface{}, prefix func() string) (sql string, params []interface{}, names []string) { 54 params = make([]interface{}, 0) 55 names = make([]string, 0) 56 defer func() { 57 sql = strings.Replace(strings.Replace(strings.Replace(sql, " ", " ", -1), "where and ", "where ", -1), "where or ", "where ", -1) 58 sql = strings.Replace(strings.Replace(sql, "WHERE and ", "WHERE ", -1), "WHERE or ", "WHERE ", -1) 59 }() 60 word, _ := regexp.Compile(`[\\]?[@|#|&|~|\||!|\$|\?\[\]]\w{0,}[\.]?\w+`) 61 //@变量, 将数据放入params中 62 sql = word.ReplaceAllStringFunc(tpl, func(s string) string { 63 fullKey := s[1:] 64 key := s[1:] 65 name := s[1:] 66 if strings.Index(fullKey, ".") > 0 { 67 name = strings.Split(fullKey, ".")[1] 68 } 69 pre := s[:1] 70 value := input[name] 71 switch pre { 72 case "@": 73 if !isNil(value) { 74 names = append(names, key) 75 params = append(params, value) 76 } else { 77 names = append(names, key) 78 params = append(params, nil) 79 } 80 return prefix() 81 case "#": 82 if !isNil(value) { 83 return fmt.Sprintf("%v", value) 84 } 85 return "NULL" 86 case "?": 87 if !isNil(value) { 88 names = append(names, key) 89 params = append(params, value) 90 return "and " + key + " like '%" + prefix() + "%'" 91 } 92 return "" 93 case "[": 94 if !isNil(value) { 95 names = append(names, key) 96 params = append(params, value) 97 return fmt.Sprintf("and %s>=%s", key, prefix()) 98 } 99 return "" 100 case "]": 101 if !isNil(value) { 102 names = append(names, key) 103 params = append(params, value) 104 return fmt.Sprintf("and %s<=%s", key, prefix()) 105 } 106 return "" 107 case "$": 108 if !isNil(value) { 109 return fmt.Sprintf("%v", value) 110 } 111 return "" 112 case "&": 113 if !isNil(value) { 114 names = append(names, key) 115 params = append(params, value) 116 return fmt.Sprintf("and %s=%s", key, prefix()) 117 } 118 return "" 119 case "|": 120 if !isNil(value) { 121 names = append(names, key) 122 params = append(params, value) 123 return fmt.Sprintf("or %s=%s", key, prefix()) 124 } 125 return "" 126 case "~": 127 if !isNil(value) { 128 names = append(names, key) 129 params = append(params, value) 130 return fmt.Sprintf(",%s=%s", key, prefix()) 131 } 132 return "" 133 default: 134 return s 135 } 136 }) 137 138 word2, _ := regexp.Compile(`[\\][@|#|&|~|\||!|\$|\?|>=|<=]`) 139 //@变量, 将数据放入params中 140 sql = word2.ReplaceAllStringFunc(sql, func(s string) string { 141 return s[1:] 142 }) 143 return 144 }