Cron_Admin/app/utils/excute/dbExecute.go

176 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package excute
import (
"cron_admin/app/utils"
"encoding/json"
"fmt"
"gorm.io/gorm"
"reflect"
"strings"
)
type ExecuteDb struct {
Db *gorm.DB
DbName string
}
func NewExecuteDb(source string, dbName string) (*ExecuteDb, error) {
db, err := ExecuteDbConn(source)
if err != nil {
return nil, fmt.Errorf("%s链接失败%v", dbName, err)
}
return &ExecuteDb{Db: db, DbName: dbName}, nil
}
func (db *ExecuteDb) ExecuteRead(execute string) (result []map[string]interface{}, err error) {
rows, err := db.Db.Raw(execute).Rows()
if err != nil {
return nil, fmt.Errorf("数据执行失败:%v", err.Error())
}
defer rows.Close()
for rows.Next() {
err = db.Db.ScanRows(rows, &result)
if err != nil {
return nil, fmt.Errorf("数据映射失败:%v", err)
}
}
return result, nil
}
func (db *ExecuteDb) ExecuteWriteV2(readData []map[string]interface{}, execute string) (dbString string, err error) {
var (
dbExecuteSql []string
)
for _, v := range readData {
dbExecuteSql = append(dbExecuteSql, db.replaceExecuteString(execute, v))
}
dbString = strings.Join(dbExecuteSql, ";")
for _, v := range dbExecuteSql {
d := db.Db.Exec(v)
if d.Error != nil {
return dbString, d.Error
}
}
return dbString, nil
}
func (db *ExecuteDb) replaceExecuteString(execute string, rowData map[string]interface{}) string {
executeString := execute
for key, value := range rowData {
key := fmt.Sprintf("${%s}", key)
executeString = strings.Replace(executeString, key, fmt.Sprintf("%v", value), -1)
}
return executeString
}
func FilterReadData(data *[]map[string]interface{}, matchJson string) (filteredData []map[string]interface{}, err error) {
if matchJson == "" {
return *data, nil
}
for _, v := range *data {
match, err := MatchJSON(v, &matchJson)
if err != nil {
return nil, err
}
if match {
filteredData = append(filteredData, v)
}
}
return filteredData, nil
}
func MatchJSON(mapData map[string]interface{}, jsonString *string) (bool, error) {
// 解析JSON字符串
var jsonData []Match
err := json.Unmarshal([]byte(*jsonString), &jsonData)
if err != nil {
return false, fmt.Errorf("解析Match_Json失败%v", err)
}
for _, v := range jsonData {
// 判断key值
mapData, err := judgeData(&v, mapData)
if err != nil {
return false, err
}
switch v.Op {
case "=":
if mapData[v.Key] != v.Val {
return false, nil
}
case "!=":
if mapData[v.Key] == v.Val {
return false, nil
}
case "<":
if mapData[v.Key].(int) >= v.Val.(int) {
return false, nil
}
case "<=":
if mapData[v.Key].(int) > v.Val.(int) {
return false, nil
}
case ">":
if mapData[v.Key].(int) <= v.Val.(int) {
return false, nil
}
case ">=":
if mapData[v.Key].(int) < v.Val.(int) {
return false, nil
}
case "regex":
if !utils.Regexp(mapData[v.Key].(string), v.Val.(string)) {
return false, nil
}
default:
return false, fmt.Errorf("未知的比较类型:%v", v.Op)
}
}
return true, nil
}
func judgeData(v *Match, mapData map[string]interface{}) (map[string]interface{}, error) {
if v.Key == "" {
return nil, fmt.Errorf("Match_Json的key值未映射")
}
if v.Op == "" {
return nil, fmt.Errorf("Match_Json的判断方式没找到")
}
if _, ok := mapData[v.Key]; !ok {
return nil, fmt.Errorf("Match_Json的key值没找到%s", v.Key)
}
// 判断类型
valueKind := reflect.TypeOf(mapData[v.Key]).Kind()
valKind := reflect.TypeOf(v.Val).Kind()
if valKind == reflect.Float64 {
v.Val = int(v.Val.(float64))
valKind = reflect.TypeOf(v.Val).Kind()
}
if valueKind == reflect.Int64 {
mapData[v.Key] = int(mapData[v.Key].(int64))
valueKind = reflect.TypeOf(mapData[v.Key]).Kind()
}
if valueKind != reflect.String && valueKind != reflect.Int {
return nil, fmt.Errorf("未知的val值类型%s", v.Key)
}
if v.Op != "regex" && (valueKind != valKind) {
return nil, fmt.Errorf("非正则模式Match_Json的val值类型不匹配%s", v.Key)
}
if v.Op == "regex" && (valKind != reflect.String || valueKind != reflect.String) {
return nil, fmt.Errorf("正则模式Match_Json的val值类型不匹配%s", v.Key)
}
if utils.ContainsStr([]string{">", "<", ">=", "<="}, v.Op) && (valueKind == reflect.String || valKind == reflect.String) {
return nil, fmt.Errorf("字符串类型val无法进行比较%s", v.Key)
}
return mapData, nil
}