sql.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. package utils
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "reflect"
  7. "regexp"
  8. "text/template"
  9. )
  10. type Driver string
  11. type SqlCondition string
  12. const (
  13. DM Driver = "dm"
  14. MySql Driver = "mysql"
  15. GroupUnit SqlCondition = "GroupUnit"
  16. Distinct SqlCondition = "Distinct"
  17. Order SqlCondition = "Order"
  18. Delimiter SqlCondition = "Delimiter"
  19. ConvertColumn SqlCondition = "ConvertColumn"
  20. )
  21. var TemplateMap = map[SqlCondition]map[Driver]string{
  22. GroupUnit: {
  23. MySql: `GROUP_CONCAT({{.Distinct}} {{.Column}} {{.Order}} SEPARATOR '{{.Delimiter}}')`,
  24. DM: `LISTAGG({{.Distinct}} {{.Column}},'{{.Delimiter}}') WITHIN GROUP ({{.Order}})`,
  25. },
  26. ConvertColumn: {
  27. MySql: `CONVERT({{.ConvertColumn}} USING gbk )`,
  28. DM: `{{.ConvertColumn}}`,
  29. },
  30. }
  31. var supportDriverMap = map[string]Driver{
  32. "mysql": MySql,
  33. "dm": DM,
  34. //"postgres": Postgres,
  35. }
  36. type QueryParam struct {
  37. Driver string
  38. Column string
  39. Order string
  40. Distinct string
  41. Delimiter string
  42. OrderField string
  43. OrderRule string
  44. ConvertColumn string `description:"Convert指令传递的clounm"`
  45. HasDistinct bool
  46. }
  47. type SqlParam interface {
  48. GetParamName() string
  49. GetFormatConditionStr(param *QueryParam) string
  50. }
  51. type DistinctParam struct {
  52. }
  53. func (distinctParam *DistinctParam) GetParamName() string {
  54. return "Distinct"
  55. }
  56. func (distinctParam *DistinctParam) GetFormatConditionStr(param *QueryParam) string {
  57. if param.HasDistinct {
  58. return "DISTINCT"
  59. }
  60. return ""
  61. }
  62. type ConvertParam struct {
  63. }
  64. func (convertParam *ConvertParam) GetParamName() string {
  65. return "Convert"
  66. }
  67. func (convertParam *ConvertParam) GetFormatConditionStr(param *QueryParam) (sqlStr string) {
  68. dbDriver, _ := getDriverInstance(param.Driver)
  69. if param.ConvertColumn == "" {
  70. FileLog.Error("转换字段为空,无法生成聚合sql")
  71. return
  72. }
  73. var templateSqlStr string
  74. if _, ok := TemplateMap[ConvertColumn][dbDriver]; !ok {
  75. templateSqlStr = TemplateMap[ConvertColumn][MySql]
  76. } else {
  77. templateSqlStr = TemplateMap[ConvertColumn][dbDriver]
  78. }
  79. if templateSqlStr == "" {
  80. FileLog.Error("转换sql模板不存在,无法生成转换sql")
  81. return
  82. }
  83. templateSql, err := template.New("ConvertColumn").Parse(templateSqlStr)
  84. if err != nil {
  85. FileLog.Error("failed to parse template: %v", err)
  86. return
  87. }
  88. //反射获取结构体的值
  89. value := reflect.ValueOf(param)
  90. // 检查是否是指针
  91. if value.Kind() != reflect.Ptr {
  92. fmt.Println("请求参数必须是一个结构体")
  93. return
  94. }
  95. // 获取结构体的元素
  96. elem := value.Elem()
  97. // 检查是否是结构体
  98. if elem.Kind() != reflect.Struct {
  99. fmt.Println("请求参数必须是一个结构体")
  100. return
  101. }
  102. // 获取字段的值
  103. fieldValue := elem.FieldByName("ConvertColumn")
  104. // 检查字段是否存在
  105. if !fieldValue.IsValid() {
  106. fmt.Printf("Error: field %s not found\n", "ConvertColumn")
  107. return
  108. }
  109. // 检查字段是否可导出
  110. if !fieldValue.CanSet() {
  111. fmt.Printf("Error: field %s is not exported and cannot be set\n", "ConvertColumn")
  112. return
  113. }
  114. // 渲染模板
  115. var buf bytes.Buffer
  116. err = templateSql.Execute(&buf, param)
  117. if err != nil {
  118. fmt.Sprintf("执行模板填充失败: %v", err)
  119. return
  120. }
  121. sqlStr = buf.String()
  122. fmt.Printf("生成的准换编码语句为:%s\n", sqlStr)
  123. return sqlStr
  124. }
  125. var sqlGeneratorFactory = map[SqlCondition]SqlParam{
  126. // 添加支持的语法
  127. GroupUnit: &GroupUnitParam{
  128. supportGrams: []SqlCondition{
  129. Distinct,
  130. Order,
  131. Delimiter,
  132. },
  133. },
  134. Order: &OrderParam{},
  135. Delimiter: &DelimiterParam{},
  136. Distinct: &DistinctParam{},
  137. ConvertColumn: &ConvertParam{},
  138. }
  139. type DelimiterParam struct {
  140. }
  141. func (delimiterParam *DelimiterParam) GetParamName() string {
  142. return "Delimiter"
  143. }
  144. func (delimiterParam *DelimiterParam) GetFormatConditionStr(param *QueryParam) string {
  145. if param.Delimiter == "" {
  146. return ","
  147. }
  148. return param.Delimiter
  149. }
  150. type OrderParam struct {
  151. Field string
  152. Rule string
  153. }
  154. func (orderParam *OrderParam) GetParamName() string {
  155. return "Order"
  156. }
  157. func (orderParam *OrderParam) GetFormatConditionStr(param *QueryParam) string {
  158. if param.OrderField == "" {
  159. orderParam.Field = param.Column
  160. } else {
  161. orderParam.Field = param.OrderField
  162. }
  163. if param.OrderRule != "" {
  164. if param.OrderRule == "ASC" || param.OrderRule == "DESC" {
  165. orderParam.Rule = param.OrderRule
  166. }
  167. }
  168. return fmt.Sprintf("ORDER BY %s %s", orderParam.Field, orderParam.Rule)
  169. }
  170. // 高级语法聚合
  171. type GroupUnitParam struct {
  172. supportGrams []SqlCondition
  173. }
  174. func (groupUnitParam *GroupUnitParam) GetParamName() string {
  175. return "GroupUnit"
  176. }
  177. func (groupUnitParam *GroupUnitParam) GetFormatConditionStr(param *QueryParam) (sqlStr string) {
  178. dbDriver, _ := getDriverInstance(param.Driver)
  179. if param.Column == "" {
  180. FileLog.Error("聚合字段为空,无法生成聚合sql")
  181. return
  182. }
  183. var templateSqlStr string
  184. if _, ok := TemplateMap[GroupUnit][dbDriver]; !ok {
  185. templateSqlStr = TemplateMap[GroupUnit][MySql]
  186. } else {
  187. templateSqlStr = TemplateMap[GroupUnit][dbDriver]
  188. }
  189. if templateSqlStr == "" {
  190. FileLog.Error("聚合sql模板不存在,无法生成聚合sql")
  191. return
  192. }
  193. templateSql, err := template.New("GroupUnit").Parse(templateSqlStr)
  194. if err != nil {
  195. FileLog.Error("failed to parse template: %v", err)
  196. return
  197. }
  198. //反射获取结构体的值
  199. value := reflect.ValueOf(param)
  200. // 检查是否是指针
  201. if value.Kind() != reflect.Ptr {
  202. fmt.Println("请求参数必须是一个结构体")
  203. return
  204. }
  205. // 获取结构体的元素
  206. elem := value.Elem()
  207. // 检查是否是结构体
  208. if elem.Kind() != reflect.Struct {
  209. fmt.Println("请求参数必须是一个结构体")
  210. return
  211. }
  212. for _, supportGram := range groupUnitParam.supportGrams {
  213. // 获取字段的值
  214. fieldValue := elem.FieldByName(string(supportGram))
  215. // 检查字段是否存在
  216. if !fieldValue.IsValid() {
  217. fmt.Printf("Error: field %s not found\n", supportGram)
  218. continue
  219. }
  220. // 检查字段是否可导出
  221. if !fieldValue.CanSet() {
  222. fmt.Printf("Error: field %s is not exported and cannot be set\n", supportGram)
  223. continue
  224. }
  225. newValue := sqlGeneratorFactory[supportGram].GetFormatConditionStr(param)
  226. // 检查新值的类型是否匹配
  227. newValueValue := reflect.ValueOf(newValue)
  228. if fieldValue.Type() != newValueValue.Type() {
  229. fmt.Printf("字段%s类型不匹配 : 期望的类型是 %s, 传入的类型为: %s", supportGram, fieldValue.Type(), newValueValue.Type())
  230. return
  231. }
  232. // 设置字段的值
  233. fieldValue.Set(newValueValue)
  234. }
  235. // 渲染模板
  236. var buf bytes.Buffer
  237. err = templateSql.Execute(&buf, param)
  238. if err != nil {
  239. fmt.Sprintf("执行模板填充失败: %v", err)
  240. return
  241. }
  242. sqlStr = buf.String()
  243. fmt.Printf("生成的聚合语句为:%s\n", sqlStr)
  244. return sqlStr
  245. }
  246. func GroupUnitFunc(driver string, column, delimiter string, columnOrder bool, orderField, orderRule string, hasDistinct bool) (sqlStr string) {
  247. dbDriver, _ := getDriverInstance(driver)
  248. if delimiter == "" {
  249. delimiter = ","
  250. }
  251. if column == "" {
  252. column = "[UNKNOWN COLUMN]"
  253. }
  254. //if tableAlia != "" {
  255. // column = fmt.Sprintf("%s.%s", tableAlia, column)
  256. //}
  257. var sqlOrder, strDistinct string
  258. if hasDistinct {
  259. strDistinct = "DISTINCT"
  260. }
  261. if columnOrder && orderField == "" {
  262. orderField = column
  263. }
  264. switch dbDriver {
  265. case DM:
  266. if columnOrder {
  267. sqlOrder = fmt.Sprintf("WITHIN GROUP (ORDER BY %s %s)", orderField, orderRule)
  268. }
  269. sqlStr = fmt.Sprintf("LISTAGG(%s %s, '%s') %s", strDistinct, column, delimiter, sqlOrder)
  270. default:
  271. // 默认使用MySQL的语法
  272. if columnOrder {
  273. sqlOrder = fmt.Sprintf("ORDER BY %s %s", orderField, orderRule)
  274. }
  275. sqlStr = fmt.Sprintf("GROUP_CONCAT(%s %s %s SEPARATOR '%s')", strDistinct, column, sqlOrder, delimiter)
  276. }
  277. return sqlStr
  278. }
  279. func getDriverInstance(driver string) (dbDriver Driver, err error) {
  280. if driver == "" {
  281. dbDriver = supportDriverMap[DbDriverName]
  282. }
  283. if currentDriver, ok := supportDriverMap[driver]; !ok {
  284. err = errors.New("不支持的数据库驱动类型")
  285. return
  286. } else {
  287. dbDriver = currentDriver
  288. }
  289. return
  290. }
  291. func NeedDateOrTimeFormat(driver string) bool {
  292. var dbDriver Driver
  293. if driver == "" {
  294. dbDriver = supportDriverMap[DbDriverName]
  295. } else {
  296. dbDriver, _ = getDriverInstance(driver)
  297. }
  298. if dbDriver == DM {
  299. return true
  300. }
  301. return false
  302. }
  303. func ReplaceDriverKeywords(driver string, sql string) string {
  304. dbDriver, _ := getDriverInstance(driver)
  305. rules := map[Driver]map[string]string{
  306. DM: {
  307. "admin": `"admin"`,
  308. "value": `"value"`,
  309. "exchange": `"exchange"`,
  310. "b.from": `b."from"`,
  311. "size": `"size"`,
  312. "a.from": `a."from"`,
  313. "from": `"from"`,
  314. },
  315. MySql: {
  316. "from": "`from`",
  317. },
  318. }
  319. replacements, ok := rules[dbDriver]
  320. if !ok {
  321. return sql
  322. }
  323. for keyword, replace := range replacements {
  324. // 仅替换单独的单词,复合单词含关键词不管
  325. pattern := fmt.Sprintf(`\b%s\b`, regexp.QuoteMeta(keyword))
  326. re := regexp.MustCompile(pattern)
  327. sql = re.ReplaceAllString(sql, replace)
  328. }
  329. return sql
  330. }
  331. func GenerateQuerySql(gram SqlCondition, param *QueryParam) (sqlGenerator string) {
  332. if exec, ok := sqlGeneratorFactory[gram]; !ok {
  333. FileLog.Error("不支持的语法:%s", gram)
  334. return
  335. } else {
  336. sqlGenerator = exec.GetFormatConditionStr(param)
  337. }
  338. return
  339. }