Forráskód Böngészése

增加sql的通用查询方法

kobe6258 2 hónapja
szülő
commit
04c09b2b33

+ 5 - 1
models/data_manage/base_from_hisugar.go

@@ -423,7 +423,11 @@ func GetHisugarIndexInfoPage(condition string, pars []interface{}, size int, pag
 // 获取所有分类
 func GetHisugarClassifyById(classifyId int) (ClassifyIds string, err error) {
 	o := global.DbMap[utils.DbNameIndex]
-	sql := fmt.Sprintf("SELECT %s AS classify_ids FROM base_from_hisugar_classify WHERE base_from_hisugar_classify_id=? OR parent_id=?", utils.GroupUnitFunc(utils.DbDriverName, "base_from_hisugar_classify_id", ",", false, "", "", false))
+	//sql := fmt.Sprintf("SELECT %s AS classify_ids FROM base_from_hisugar_classify WHERE base_from_hisugar_classify_id=? OR parent_id=?", utils.GroupUnitFunc(utils.DbDriverName, "base_from_hisugar_classify_id", ",", false, "", "", false))
+
+	sql := fmt.Sprintf("SELECT %s AS classify_ids FROM base_from_hisugar_classify WHERE base_from_hisugar_classify_id=? OR parent_id=?", utils.GenerateQuerySql(utils.GroupUnit, &utils.QueryParam{Column: "base_from_hisugar_classify_id",
+		HasDistinct: false,
+	}))
 	//sql := ` SELECT GROUP_CONCAT(base_from_hisugar_classify_id) AS classify_ids FROM base_from_hisugar_classify WHERE base_from_hisugar_classify_id=? OR parent_id=?`
 	//sql := ` SELECT AS classify_ids FROM base_from_hisugar_classify WHERE base_from_hisugar_classify_id=? OR parent_id=?`
 	err = o.Raw(sql, classifyId, classifyId).Scan(&ClassifyIds).Error

+ 3 - 0
models/data_manage/base_from_trade_index.go

@@ -144,6 +144,9 @@ func GetLatestDate(exchange string) (dataTime string, err error) {
 	o := global.DbMap[utils.DbNameIndex]
 	sql := "SELECT data_time FROM base_from_trade_" + exchange + "_index ORDER BY data_time desc limit 1"
 	err = o.Raw(sql).Scan(&dataTime).Error
+	if utils.NeedDateOrTimeFormat(utils.DbDriverName) {
+		dataTime = utils.GormDateStrToDateStr(dataTime)
+	}
 	return
 }
 

+ 184 - 23
utils/sql.go

@@ -1,21 +1,193 @@
 package utils
 
 import (
+	"bytes"
 	"errors"
 	"fmt"
+	"reflect"
 	"regexp"
+	"text/template"
 )
 
 type Driver string
+type SqlCondition string
 
 const (
-	DM    Driver = "dm"
-	MySql Driver = "mysql"
+	DM        Driver       = "dm"
+	MySql     Driver       = "mysql"
+	GroupUnit SqlCondition = "GroupUnit"
+	Distinct  SqlCondition = "Distinct"
+	Order     SqlCondition = "Order"
+	Delimiter SqlCondition = "Delimiter"
 )
 
+var TemplateMap = map[SqlCondition]map[Driver]string{
+	GroupUnit: {
+		MySql: `GROUP_CONCAT({{.Distinct}} {{.Column}} {{.Order}} SEPARATOR '{{.Delimiter}}')`,
+		DM:    `LISTAGG({{.Distinct}} {{.Column}},'{{.Delimiter}}') WITHIN GROUP ({{.Order}})`,
+	},
+}
+
 var supportDriverMap = map[string]Driver{
 	"mysql": MySql,
 	"dm":    DM,
+	//"postgres": Postgres,
+}
+
+type QueryParam struct {
+	Driver      string
+	Column      string
+	Order       string
+	Distinct    string
+	Delimiter   string
+	OrderField  string
+	OrderRule   string
+	HasDistinct bool
+}
+type SqlParam interface {
+	GetParamName() string
+	GetFormatConditionStr(param *QueryParam) string
+}
+type DistinctParam struct {
+}
+
+func (distinctParam *DistinctParam) GetParamName() string {
+	return "Distinct"
+}
+func (distinctParam *DistinctParam) GetFormatConditionStr(param *QueryParam) string {
+	if param.HasDistinct {
+		return "DISTINCT"
+	}
+	return ""
+}
+
+var sqlGeneratorFactory = map[SqlCondition]SqlParam{
+	// 添加支持的语法
+	GroupUnit: &GroupUnitParam{
+		supportGrams: []SqlCondition{
+			Distinct,
+			Order,
+			Delimiter,
+		},
+	},
+	Order:     &OrderParam{},
+	Delimiter: &DelimiterParam{},
+	Distinct:  &DistinctParam{},
+}
+
+type DelimiterParam struct {
+}
+
+func (delimiterParam *DelimiterParam) GetParamName() string {
+	return "Delimiter"
+}
+func (delimiterParam *DelimiterParam) GetFormatConditionStr(param *QueryParam) string {
+	if param.Delimiter == "" {
+		return ","
+	}
+	return param.Delimiter
+}
+
+type OrderParam struct {
+	Field string
+	Rule  string
+}
+
+func (orderParam *OrderParam) GetParamName() string {
+	return "Order"
+}
+
+func (orderParam *OrderParam) GetFormatConditionStr(param *QueryParam) string {
+	if param.OrderField == "" {
+		orderParam.Field = param.Column
+	} else {
+		orderParam.Field = param.OrderField
+	}
+	if param.OrderRule != "" {
+		if param.OrderRule == "ASC" || param.OrderRule == "DESC" {
+			orderParam.Rule = param.OrderRule
+		}
+	}
+	return fmt.Sprintf("ORDER BY %s %s", orderParam.Field, orderParam.Rule)
+}
+
+// 高级语法聚合
+type GroupUnitParam struct {
+	supportGrams []SqlCondition
+}
+
+func (groupUnitParam *GroupUnitParam) GetParamName() string {
+	return "GroupUnit"
+}
+
+func (groupUnitParam *GroupUnitParam) GetFormatConditionStr(param *QueryParam) (sqlStr string) {
+	dbDriver, _ := getDriverInstance(param.Driver)
+	if param.Column == "" {
+		FileLog.Error("聚合字段为空,无法生成聚合sql")
+		return
+	}
+	var templateSqlStr string
+	if _, ok := TemplateMap[GroupUnit][dbDriver]; !ok {
+		templateSqlStr = TemplateMap[GroupUnit][MySql]
+	} else {
+		templateSqlStr = TemplateMap[GroupUnit][dbDriver]
+	}
+	if templateSqlStr == "" {
+		FileLog.Error("聚合sql模板不存在,无法生成聚合sql")
+		return
+	}
+	templateSql, err := template.New("GroupUnit").Parse(templateSqlStr)
+	if err != nil {
+		FileLog.Error("failed to parse template: %v", err)
+		return
+	}
+	//反射获取结构体的值
+	value := reflect.ValueOf(param)
+	// 检查是否是指针
+	if value.Kind() != reflect.Ptr {
+		fmt.Println("请求参数必须是一个结构体")
+		return
+	}
+	// 获取结构体的元素
+	elem := value.Elem()
+	// 检查是否是结构体
+	if elem.Kind() != reflect.Struct {
+		fmt.Println("请求参数必须是一个结构体")
+		return
+	}
+	for _, supportGram := range groupUnitParam.supportGrams {
+		// 获取字段的值
+		fieldValue := elem.FieldByName(string(supportGram))
+		// 检查字段是否存在
+		if !fieldValue.IsValid() {
+			fmt.Printf("Error: field %s not found\n", supportGram)
+			continue
+		}
+		// 检查字段是否可导出
+		if !fieldValue.CanSet() {
+			fmt.Printf("Error: field %s is not exported and cannot be set\n", supportGram)
+			continue
+		}
+		newValue := sqlGeneratorFactory[supportGram].GetFormatConditionStr(param)
+		// 检查新值的类型是否匹配
+		newValueValue := reflect.ValueOf(newValue)
+		if fieldValue.Type() != newValueValue.Type() {
+			fmt.Printf("字段%s类型不匹配 : 期望的类型是 %s, 传入的类型为: %s", supportGram, fieldValue.Type(), newValueValue.Type())
+			return
+		}
+		// 设置字段的值
+		fieldValue.Set(newValueValue)
+	}
+	// 渲染模板
+	var buf bytes.Buffer
+	err = templateSql.Execute(&buf, param)
+	if err != nil {
+		fmt.Sprintf("执行模板填充失败: %v", err)
+		return
+	}
+	sqlStr = buf.String()
+	fmt.Printf("生成的聚合语句为:%s\n", sqlStr)
+	return sqlStr
 }
 
 func GroupUnitFunc(driver string, column, delimiter string, columnOrder bool, orderField, orderRule string, hasDistinct bool) (sqlStr string) {
@@ -52,27 +224,6 @@ func GroupUnitFunc(driver string, column, delimiter string, columnOrder bool, or
 	return sqlStr
 }
 
-func GroupUnitDistinctFunc(driver string, column, delimiter string) (sqlStr string) {
-	dbDriver, _ := getDriverInstance(driver)
-	if delimiter == "" {
-		delimiter = ","
-	}
-	if column == "" {
-		column = "[UNKNOWN COLUMN]"
-	}
-	//if tableAlia != "" {
-	//	column = fmt.Sprintf("%s.%s", tableAlia, column)
-	//}
-	switch dbDriver {
-	case MySql:
-		sqlStr = fmt.Sprintf("GROUP_CONCAT(DISTINCT %s SEPARATOR '%s')", column, delimiter)
-	case DM:
-		sqlStr = fmt.Sprintf("LISTAGG(DISTINCT %s, '%s') WITHIN GROUP (ORDER BY %s)", column, delimiter, column)
-	default:
-		sqlStr = fmt.Sprintf("GROUP_CONCAT(DISTINCT  %s SEPARATOR '%s')", column, delimiter) // 默认使用 MySQL 的语法
-	}
-	return sqlStr
-}
 func getDriverInstance(driver string) (dbDriver Driver, err error) {
 	if driver == "" {
 		dbDriver = supportDriverMap[DbDriverName]
@@ -120,3 +271,13 @@ func ReplaceDriverKeywords(driver string, sql string) string {
 	}
 	return sql
 }
+
+func GenerateQuerySql(gram SqlCondition, param *QueryParam) (sqlGenerator string) {
+	if exec, ok := sqlGeneratorFactory[gram]; !ok {
+		FileLog.Error("不支持的语法:%s", gram)
+		return
+	} else {
+		sqlGenerator = exec.GetFormatConditionStr(param)
+	}
+	return
+}