package excute import ( "cron_admin/app/utils" "encoding/json" "fmt" "gorm.io/gorm" "reflect" "strings" "time" ) 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 { formatValue := FormatValueData(value) key := fmt.Sprintf("${%s}", key) executeString = strings.Replace(executeString, key, fmt.Sprintf("%v", formatValue), -1) } return executeString } func FormatValueData(v interface{}) interface{} { var format interface{} switch v.(type) { case nil: format = "NULL" case time.Time: format = fmt.Sprintf("'%v'", v.(time.Time).Format("2006-01-02 15:04:05")) case []uint8: format = fmt.Sprintf("'%v'", string(v.([]uint8))) case string: format = fmt.Sprintf("'%v'", v) default: format = v } return format } 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 }