diff --git a/sqle/api/app.go b/sqle/api/app.go index 46d09c5d6..f7f5520d2 100644 --- a/sqle/api/app.go +++ b/sqle/api/app.go @@ -450,6 +450,8 @@ func StartApi(net *gracenet.Net, exitChan chan struct{}, config *config.SqleOpti v1Router.GET("/custom_rules", v1.GetCustomRules) v1Router.GET("/custom_rules/:rule_id", v1.GetCustomRule) v1Router.GET("/custom_rules/:db_type/rule_types", v1.GetRuleTypeByDBType) + // rule category + v1Router.GET("/rules/categoryStatistics", v1.GetCategoryStatistics) // task v1Router.GET("/tasks/audits/:task_id/", v1.GetTask) diff --git a/sqle/api/controller/v1/rule.go b/sqle/api/controller/v1/rule.go index f3581877c..72183beb2 100644 --- a/sqle/api/controller/v1/rule.go +++ b/sqle/api/controller/v1/rule.go @@ -7,6 +7,9 @@ import ( "encoding/json" e "errors" "fmt" + "github.com/actiontech/sqle/sqle/driver/mysql/plocale" + "github.com/nicksnyder/go-i18n/v2/i18n" + "golang.org/x/text/language" "io" "mime" "net/http" @@ -264,6 +267,7 @@ func UpdateRuleTemplate(c echo.Context) error { type GetRuleTemplateReqV1 struct { FuzzyKeywordRule string `json:"fuzzy_keyword_rule" query:"fuzzy_keyword_rule"` + Tags string `json:"tags" query:"tags"` } type GetRuleTemplateResV1 struct { @@ -308,6 +312,7 @@ func convertRuleTemplateToRes(ctx context.Context, template *model.RuleTemplate) // @Param rule_template_name path string true "rule template name" // @Param fuzzy_keyword_rule query string false "fuzzy rule,keyword for desc and annotation" // @Success 200 {object} v1.GetRuleTemplateResV1 +// @Param tags query string false "tags for rule" // @router /v1/rule_templates/{rule_template_name}/ [get] func GetRuleTemplate(c echo.Context) error { s := model.GetStorage() @@ -317,7 +322,7 @@ func GetRuleTemplate(c echo.Context) error { if err := controller.BindAndValidateReq(c, req); err != nil { return err } - template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{model.ProjectIdForGlobalRuleTemplate}, templateName, req.FuzzyKeywordRule) + template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{model.ProjectIdForGlobalRuleTemplate}, templateName, req.FuzzyKeywordRule, req.Tags) if err != nil { return c.JSON(200, controller.NewBaseReq(err)) } @@ -462,6 +467,7 @@ type GetRulesReqV1 struct { FilterGlobalRuleTemplateName string `json:"filter_global_rule_template_name" query:"filter_global_rule_template_name"` FilterRuleNames string `json:"filter_rule_names" query:"filter_rule_names"` FuzzyKeywordRule string `json:"fuzzy_keyword_rule" query:"fuzzy_keyword_rule"` + Tags string `json:"tags" query:"tags"` } type GetRulesResV1 struct { @@ -470,16 +476,17 @@ type GetRulesResV1 struct { } type RuleResV1 struct { - Name string `json:"rule_name"` - Desc string `json:"desc"` - Annotation string `json:"annotation" example:"避免多次 table rebuild 带来的消耗、以及对线上业务的影响"` - Level string `json:"level" example:"error" enums:"normal,notice,warn,error"` - Typ string `json:"type" example:"全局配置" ` - DBType string `json:"db_type" example:"mysql"` - Params []RuleParamResV1 `json:"params,omitempty"` - IsCustomRule bool `json:"is_custom_rule"` - HasAuditPower bool `json:"has_audit_power"` - HasRewritePower bool `json:"has_rewrite_power"` + Name string `json:"rule_name"` + Desc string `json:"desc"` + Annotation string `json:"annotation" example:"避免多次 table rebuild 带来的消耗、以及对线上业务的影响"` + Level string `json:"level" example:"error" enums:"normal,notice,warn,error"` + Typ string `json:"type" example:"全局配置" ` + DBType string `json:"db_type" example:"mysql"` + Params []RuleParamResV1 `json:"params,omitempty"` + IsCustomRule bool `json:"is_custom_rule"` + HasAuditPower bool `json:"has_audit_power"` + HasRewritePower bool `json:"has_rewrite_power"` + Categories map[string][]string `json:"categories"` } type RuleParamResV1 struct { @@ -519,6 +526,7 @@ func convertRuleToRes(ctx context.Context, rule *model.Rule) RuleResV1 { } ruleRes.Params = paramsRes } + ruleRes.Categories = associateCategories(rule.Categories) return ruleRes } @@ -534,9 +542,30 @@ func convertCustomRuleToRuleResV1(rule *model.CustomRule) RuleResV1 { HasAuditPower: true, HasRewritePower: false, } + ruleRes.Categories = associateCategories(rule.Categories) return ruleRes } +func associateCategories(categories []*model.AuditRuleCategory) map[string][]string { + categoryRes := make(map[string][]string) + if categories != nil && len(categories) > 0 { + for _, entity := range categories { + categoryRes[entity.Category] = append(categoryRes[entity.Category], entity.Tag) + } + } + return categoryRes +} + +func associateBizCategories(lang language.Tag, categories []*model.AuditRuleCategory) map[string][]string { + categoryRes := make(map[string][]string) + if categories != nil && len(categories) > 0 { + for _, entity := range categories { + categoryRes[entity.Category] = append(categoryRes[entity.Category], plocale.Bundle.LocalizeMsgByLang(lang, ruleCategoryMapping[entity.Tag])) + } + } + return categoryRes +} + func convertRulesToRes(ctx context.Context, rules interface{}) []RuleResV1 { rulesRes := []RuleResV1{} switch ruleSlice := rules.(type) { @@ -561,6 +590,7 @@ func convertRulesToRes(ctx context.Context, rules interface{}) []RuleResV1 { // @Param fuzzy_keyword_rule query string false "fuzzy rule,keyword for desc and annotation" // @Param filter_global_rule_template_name query string false "filter global rule template name" // @Param filter_rule_names query string false "filter rule name list" +// @Param tags query string false "filter tags" // @Success 200 {object} v1.GetRulesResV1 // @router /v1/rules [get] func GetRules(c echo.Context) error { @@ -578,6 +608,7 @@ func GetRules(c echo.Context) error { "filter_db_type": req.FilterDBType, "filter_rule_names": req.FilterRuleNames, "fuzzy_keyword_rule": req.FuzzyKeywordRule, + "tags": req.Tags, }) if err != nil { return controller.JSONBaseErrorReq(c, err) @@ -587,6 +618,7 @@ func GetRules(c echo.Context) error { "filter_db_type": req.FilterDBType, "filter_rule_names": req.FilterRuleNames, "fuzzy_keyword_rule": req.FuzzyKeywordRule, + "tags": req.Tags, }) if err != nil { return controller.JSONBaseErrorReq(c, err) @@ -601,6 +633,51 @@ func GetRules(c echo.Context) error { }) } +// GetCategoryStatistics +// @Summary 获取规则分类统计信息 +// @Description get all rule category statistics +// @Id getCategoryStatistics +// @Tags rule_template +// @Security ApiKeyAuth +// @Success 200 {object} v1.GetRuleCategoryStatisticResV1 +// @router /v1/rules/categoryStatistics [get] +func GetCategoryStatistics(c echo.Context) error { + s := model.GetStorage() + auditRuleCategoryStatistics, err := s.GetAuditRuleCategoryStatistics() + if err != nil { + return controller.JSONBaseErrorReq(c, err) + } + customRuleCategoryStatistics, err := s.GetCustomRuleCategoryStatistics() + if err != nil { + return controller.JSONBaseErrorReq(c, err) + } + ruleCategoryStatistics := append(auditRuleCategoryStatistics, customRuleCategoryStatistics...) + categoryStatisticsResult := map[string][]*model.RuleCategoryStatistic{} + for _, statistic := range ruleCategoryStatistics { + statisticListInMap := categoryStatisticsResult[statistic.Category] + merged := false + for _, statisticInMap := range statisticListInMap { + // merge + if statistic.Category == statisticInMap.Category && statistic.Tag == statisticInMap.Tag { + statisticInMap.Count += statistic.Count + merged = true + } + } + if !merged { + categoryStatisticsResult[statistic.Category] = append(categoryStatisticsResult[statistic.Category], statistic) + } + } + return c.JSON(http.StatusOK, &GetRuleCategoryStatisticResV1{ + BaseRes: controller.NewBaseReq(nil), + Data: categoryStatisticsResult, + }) +} + +type GetRuleCategoryStatisticResV1 struct { + controller.BaseRes + Data map[string][]*model.RuleCategoryStatistic `json:"data"` +} + type RuleTemplateTipReqV1 struct { FilterDBType string `json:"filter_db_type" query:"filter_db_type"` } @@ -688,7 +765,7 @@ func CloneRuleTemplate(c echo.Context) error { } sourceTplName := c.Param("rule_template_name") - sourceTpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{model.ProjectIdForGlobalRuleTemplate}, sourceTplName, "") + sourceTpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{model.ProjectIdForGlobalRuleTemplate}, sourceTplName, "", "") if err != nil { return c.JSON(200, controller.NewBaseReq(err)) } @@ -921,6 +998,7 @@ type ProjectRuleTemplateInstance struct { // @Param project_name path string true "project name" // @Param rule_template_name path string true "rule template name" // @Param fuzzy_keyword_rule query string false "fuzzy rule,keyword for desc and annotation" +// @Param tags query string false "tags for rule" // @Success 200 {object} v1.GetProjectRuleTemplateResV1 // @router /v1/projects/{project_name}/rule_templates/{rule_template_name}/ [get] func GetProjectRuleTemplate(c echo.Context) error { @@ -935,7 +1013,7 @@ func GetProjectRuleTemplate(c echo.Context) error { if err := controller.BindAndValidateReq(c, req); err != nil { return err } - template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectUid}, templateName, req.FuzzyKeywordRule) + template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectUid}, templateName, req.FuzzyKeywordRule, req.Tags) if err != nil { return c.JSON(http.StatusOK, controller.NewBaseReq(err)) } @@ -1137,7 +1215,7 @@ func CloneProjectRuleTemplate(c echo.Context) error { } sourceTplName := c.Param("rule_template_name") - sourceTpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectUid}, sourceTplName, "") + sourceTpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectUid}, sourceTplName, "", "") if err != nil { return c.JSON(200, controller.NewBaseReq(err)) } @@ -1291,12 +1369,14 @@ func checkRuleList(file *ParseProjectRuleTemplateFileResDataV1) (*RuleTemplateEx Annotation: rule.Annotation, Level: rule.Level, Typ: rule.Typ, + Categories: rule.Categories, DBType: rule.DBType, }, } for _, param := range rule.Params { ruleTemplateExport.RuleList[i].Params = append(ruleTemplateExport.RuleList[i].Params, RuleParamRes{ + Key: param.Key, Value: param.Value, Desc: param.Desc, Type: param.Type, @@ -1334,7 +1414,6 @@ func parseRuleTemplate(c echo.Context, fileType ExportType) (*ParseProjectRuleTe if !exist { return nil, errors.New(errors.DataNotExist, fmt.Errorf("the file has not been uploaded or the key bound to the file is not 'rule_template_file'")) } - resp := &ParseProjectRuleTemplateFileResDataV1{} switch fileType { case CsvExportType: @@ -1380,12 +1459,12 @@ func parseRuleTemplate(c echo.Context, fileType ExportType) (*ParseProjectRuleTe Desc: rule[1], Annotation: rule[2], Level: rule[3], - Typ: rule[4], - DBType: rule[5], + Categories: parseRuleCategory(rule), + DBType: rule[8], } var params []RuleParamResV1 - err = json.Unmarshal([]byte(rule[6]), ¶ms) + err = json.Unmarshal([]byte(rule[9]), ¶ms) if err != nil { return nil, err } @@ -1424,17 +1503,87 @@ func parseRuleTemplate(c echo.Context, fileType ExportType) (*ParseProjectRuleTe return resp, nil case JsonExportType: - err = json.Unmarshal([]byte(file), &resp) + ruleTemplateExport := &RuleTemplateExport{} + err = json.Unmarshal([]byte(file), &ruleTemplateExport) if err != nil { return nil, fmt.Errorf("the file format is incorrect. Please check the uploaded file, error: %v", err) } - + resp.Name = ruleTemplateExport.Name + resp.Desc = ruleTemplateExport.Desc + resp.DBType = ruleTemplateExport.DBType + err = ruleTemplateExportToParseDataV1(ruleTemplateExport, resp) + if err != nil { + return nil, err + } return resp, nil default: return nil, errors.New(errors.DataInvalid, fmt.Errorf("file type is invalid")) } } +func parseRuleCategory(csvRule []string) map[string][]string { + categories := make(map[string][]string) + if csvRule[4] != "" { + operandIds := getAuditRuleCategoryIds(strings.Split(csvRule[4], " ")) + categories[plocale.RuleCategoryOperand.ID] = operandIds + } + if csvRule[5] != "" { + auditPurposeIds := getAuditRuleCategoryIds(strings.Split(csvRule[5], " ")) + categories[plocale.RuleCategoryAuditPurpose.ID] = auditPurposeIds + } + if csvRule[6] != "" { + sqlIds := getAuditRuleCategoryIds(strings.Split(csvRule[6], " ")) + categories[plocale.RuleCategorySQL.ID] = sqlIds + } + if csvRule[7] != "" { + auditAccuracyIds := getAuditRuleCategoryIds(strings.Split(csvRule[7], " ")) + categories[plocale.RuleCategoryAuditAccuracy.ID] = auditAccuracyIds + } + return categories +} + +func ruleTemplateExportToParseDataV1(ruleTemplateExport *RuleTemplateExport, parseResData *ParseProjectRuleTemplateFileResDataV1) error { + parseResData.Name = ruleTemplateExport.Name + parseResData.Desc = ruleTemplateExport.Desc + parseResData.DBType = ruleTemplateExport.DBType + for _, rule := range ruleTemplateExport.RuleList { + ruleRes := RuleResV1{} + ruleRes.Name = rule.Name + ruleRes.Desc = rule.Desc + ruleRes.Annotation = rule.Annotation + ruleRes.Level = rule.Level + ruleRes.DBType = rule.DBType + + categories := make(map[string][]string) + for category, tags := range rule.Categories { + for _, tag := range tags { + categories[category] = append(categories[category], ruleCategoryReversedMapping[tag]) + } + } + ruleRes.Categories = categories + params := make([]RuleParamResV1, 0) + for _, ruleParam := range rule.Params { + params = append(params, RuleParamResV1{ + Key: ruleParam.Key, + Value: ruleParam.Value, + Type: ruleParam.Type, + Desc: ruleParam.Desc, + }) + } + ruleRes.Params = params + parseResData.RuleList = append(parseResData.RuleList, ruleRes) + } + return nil +} + +func getAuditRuleCategoryIds(categories []string) []string { + categoryIds := make([]string, 0) + for _, category := range categories { + categoryIds = append(categoryIds, ruleCategoryReversedMapping[category]) + } + return categoryIds +} + type GetRuleTemplateFileReqV1 struct { InstanceType string `json:"instance_type" query:"instance_type" valid:"required"` FileType string `json:"file_type" query:"file_type" enums:"csv,json" valid:"required,oneof=csv json"` @@ -1511,12 +1660,16 @@ func exportTemplateFile(c echo.Context, exportType ExportType, templateFile inte var columnContentList [][]string ctx := c.Request().Context() + // CSV文件列名 defaultColumnNameList := []string{ locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleName), locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleDesc), locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleAnnotation), locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleLevel), - locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleCategory), + locale.Bundle.LocalizeMsgByCtx(ctx, plocale.RuleCategoryOperand), + locale.Bundle.LocalizeMsgByCtx(ctx, plocale.RuleCategoryAuditPurpose), + locale.Bundle.LocalizeMsgByCtx(ctx, plocale.RuleCategorySQL), + locale.Bundle.LocalizeMsgByCtx(ctx, plocale.RuleCategoryAuditAccuracy), locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateInstType), locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleParam), } @@ -1532,7 +1685,10 @@ func exportTemplateFile(c echo.Context, exportType ExportType, templateFile inte ruleTemplateInfo.Desc, ruleTemplateInfo.Annotation, ruleTemplateInfo.Level, - ruleTemplateInfo.Typ, + strings.Join(ruleTemplateInfo.Categories[plocale.RuleCategoryOperand.ID], " "), + strings.Join(ruleTemplateInfo.Categories[plocale.RuleCategoryAuditPurpose.ID], " "), + strings.Join(ruleTemplateInfo.Categories[plocale.RuleCategorySQL.ID], " "), + strings.Join(ruleTemplateInfo.Categories[plocale.RuleCategoryAuditAccuracy.ID], " "), ruleTemplateInfo.DBType, string(paramsBytes), }, nil @@ -1669,6 +1825,7 @@ type RuleTemplateRuleInfo struct { Annotation string Level string Typ string + Categories map[string][]string DBType string Params []RuleParamRes } @@ -1684,6 +1841,7 @@ type RuleTemplateResErr struct { } type RuleParamRes struct { + Key string `json:"key" form:"key"` Value string `json:"value" form:"value"` Desc string `json:"desc" form:"desc"` Type string `json:"type" form:"type" enums:"string,int,bool"` @@ -1692,7 +1850,7 @@ type RuleParamRes struct { func getRuleTemplateFile(ctx context.Context, projectID string, ruleTemplateName string) (*RuleTemplateExport, error) { // 获取规则模板详情 s := model.GetStorage() - template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectID}, ruleTemplateName, "") + template, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds([]string{projectID}, ruleTemplateName, "", "") if err != nil { return nil, err } @@ -1718,7 +1876,7 @@ func getRuleTemplateFile(ctx context.Context, projectID string, ruleTemplateName Desc: ruleInfo.Desc, Annotation: ruleInfo.Annotation, Level: rule.RuleLevel, - Typ: ruleInfo.Category, + Categories: associateBizCategories(lang, rule.Rule.Categories), DBType: rule.RuleDBType, Params: []RuleParamRes{}, }, @@ -1726,6 +1884,7 @@ func getRuleTemplateFile(ctx context.Context, projectID string, ruleTemplateName for _, param := range rule.RuleParams { r.Params = append(r.Params, RuleParamRes{ + Key: param.Key, Value: param.Value, Desc: param.GetDesc(lang), Type: string(param.Type), @@ -1738,14 +1897,79 @@ func getRuleTemplateFile(ctx context.Context, projectID string, ruleTemplateName return resp, nil } +var ruleCategoryMapping = map[string]*i18n.Message{ + plocale.RuleCategoryOperand.ID: plocale.RuleCategoryOperand, + plocale.RuleCategorySQL.ID: plocale.RuleCategorySQL, + plocale.RuleCategoryAuditPurpose.ID: plocale.RuleCategoryAuditPurpose, + plocale.RuleCategoryAuditAccuracy.ID: plocale.RuleCategoryAuditAccuracy, + plocale.RuleTagDatabase.ID: plocale.RuleTagDatabase, + plocale.RuleTagTablespace.ID: plocale.RuleTagTablespace, + plocale.RuleTagTable.ID: plocale.RuleTagTable, + plocale.RuleTagColumn.ID: plocale.RuleTagColumn, + plocale.RuleTagIndex.ID: plocale.RuleTagIndex, + plocale.RuleTagView.ID: plocale.RuleTagView, + plocale.RuleTagProcedure.ID: plocale.RuleTagProcedure, + plocale.RuleTagFunction.ID: plocale.RuleTagFunction, + plocale.RuleTagTrigger.ID: plocale.RuleTagTrigger, + plocale.RuleTagEvent.ID: plocale.RuleTagEvent, + plocale.RuleTagUser.ID: plocale.RuleTagUser, + plocale.RuleTagDML.ID: plocale.RuleTagDML, + plocale.RuleTagDDL.ID: plocale.RuleTagDDL, + plocale.RuleTagDCL.ID: plocale.RuleTagDCL, + plocale.RuleTagIntegrity.ID: plocale.RuleTagIntegrity, + plocale.RuleTagQuery.ID: plocale.RuleTagQuery, + plocale.RuleTagTransaction.ID: plocale.RuleTagTransaction, + plocale.RuleTagPrivilege.ID: plocale.RuleTagPrivilege, + plocale.RuleTagManagement.ID: plocale.RuleTagManagement, + plocale.RuleTagPerformance.ID: plocale.RuleTagPerformance, + plocale.RuleTagMaintenance.ID: plocale.RuleTagMaintenance, + plocale.RuleTagSecurity.ID: plocale.RuleTagSecurity, + plocale.RuleTagCorrection.ID: plocale.RuleTagCorrection, + plocale.RuleTagOnline.ID: plocale.RuleTagOnline, + plocale.RuleTagOffline.ID: plocale.RuleTagOffline, +} + +var ruleCategoryReversedMapping = map[string]string{ + plocale.RuleCategoryOperand.Other: plocale.RuleCategoryOperand.ID, + plocale.RuleCategorySQL.Other: plocale.RuleCategorySQL.ID, + plocale.RuleCategoryAuditPurpose.Other: plocale.RuleCategoryAuditPurpose.ID, + plocale.RuleCategoryAuditAccuracy.Other: plocale.RuleCategoryAuditAccuracy.ID, + plocale.RuleTagDatabase.Other: plocale.RuleTagDatabase.ID, + plocale.RuleTagTablespace.Other: plocale.RuleTagTablespace.ID, + plocale.RuleTagTable.Other: plocale.RuleTagTable.ID, + plocale.RuleTagColumn.Other: plocale.RuleTagColumn.ID, + plocale.RuleTagIndex.Other: plocale.RuleTagIndex.ID, + plocale.RuleTagView.Other: plocale.RuleTagView.ID, + plocale.RuleTagProcedure.Other: plocale.RuleTagProcedure.ID, + plocale.RuleTagFunction.Other: plocale.RuleTagFunction.ID, + plocale.RuleTagTrigger.Other: plocale.RuleTagTrigger.ID, + plocale.RuleTagEvent.Other: plocale.RuleTagEvent.ID, + plocale.RuleTagUser.Other: plocale.RuleTagUser.ID, + plocale.RuleTagDML.Other: plocale.RuleTagDML.ID, + plocale.RuleTagDDL.Other: plocale.RuleTagDDL.ID, + plocale.RuleTagDCL.Other: plocale.RuleTagDCL.ID, + plocale.RuleTagIntegrity.Other: plocale.RuleTagIntegrity.ID, + plocale.RuleTagQuery.Other: plocale.RuleTagQuery.ID, + plocale.RuleTagTransaction.Other: plocale.RuleTagTransaction.ID, + plocale.RuleTagPrivilege.Other: plocale.RuleTagPrivilege.ID, + plocale.RuleTagManagement.Other: plocale.RuleTagManagement.ID, + plocale.RuleTagPerformance.Other: plocale.RuleTagPerformance.ID, + plocale.RuleTagMaintenance.Other: plocale.RuleTagMaintenance.ID, + plocale.RuleTagSecurity.Other: plocale.RuleTagSecurity.ID, + plocale.RuleTagCorrection.Other: plocale.RuleTagCorrection.ID, + plocale.RuleTagOnline.Other: plocale.RuleTagOnline.ID, + plocale.RuleTagOffline.Other: plocale.RuleTagOffline.ID, +} + type CustomRuleResV1 struct { - RuleId string `json:"rule_id"` - Desc string `json:"desc" example:"this is test rule"` - Annotation string `json:"annotation" example:"this is test rule"` - DBType string `json:"db_type" example:"MySQL"` - Level string `json:"level" example:"notice" enums:"normal,notice,warn,error"` - Type string `json:"type" example:"DDL规则"` - RuleScript string `json:"rule_script,omitempty"` + RuleId string `json:"rule_id"` + Desc string `json:"desc" example:"this is test rule"` + Annotation string `json:"annotation" example:"this is test rule"` + DBType string `json:"db_type" example:"MySQL"` + Level string `json:"level" example:"notice" enums:"normal,notice,warn,error"` + Type string `json:"type" example:"DDL规则"` + RuleScript string `json:"rule_script,omitempty"` + Categories map[string][]string `json:"categories"` } type GetCustomRulesResV1 struct { @@ -1784,12 +2008,13 @@ func DeleteCustomRule(c echo.Context) error { } type CreateCustomRuleReqV1 struct { - DBType string `json:"db_type" form:"db_type" example:"MySQL" valid:"required"` - Desc string `json:"desc" form:"desc" example:"this is test rule" valid:"required"` - Annotation string `json:"annotation" form:"annotation" example:"this is test rule"` - Level string `json:"level" form:"level" example:"notice" valid:"required" enums:"normal,notice,warn,error"` - Type string `json:"type" form:"type" example:"DDL规则" valid:"required"` - RuleScript string `json:"rule_script" form:"rule_script" valid:"required"` + DBType string `json:"db_type" form:"db_type" example:"MySQL" valid:"required"` + Desc string `json:"desc" form:"desc" example:"this is test rule" valid:"required"` + Annotation string `json:"annotation" form:"annotation" example:"this is test rule"` + Level string `json:"level" form:"level" example:"notice" valid:"required" enums:"normal,notice,warn,error"` + Type string `json:"type" form:"type" example:"DDL规则"` + RuleScript string `json:"rule_script" form:"rule_script" valid:"required"` + Tags *[]string `json:"tags" form:"tags"` } // @Summary 添加自定义规则 @@ -1805,11 +2030,12 @@ func CreateCustomRule(c echo.Context) error { } type UpdateCustomRuleReqV1 struct { - Desc *string `json:"desc" form:"desc" example:"this is test rule"` - Annotation *string `json:"annotation" form:"annotation" example:"this is test rule"` - Level *string `json:"level" form:"level" example:"notice" enums:"normal,notice,warn,error"` - Type *string `json:"type" form:"type" example:"DDL规则"` - RuleScript *string `json:"rule_script" form:"rule_script"` + Desc *string `json:"desc" form:"desc" example:"this is test rule"` + Annotation *string `json:"annotation" form:"annotation" example:"this is test rule"` + Level *string `json:"level" form:"level" example:"notice" enums:"normal,notice,warn,error"` + Type *string `json:"type" form:"type" example:"DDL规则"` + RuleScript *string `json:"rule_script" form:"rule_script"` + Tags *[]string `json:"tags" form:"tags"` } // @Summary 更新自定义规则 diff --git a/sqle/docs/docs.go b/sqle/docs/docs.go index 1ae3d7e9e..86576c999 100644 --- a/sqle/docs/docs.go +++ b/sqle/docs/docs.go @@ -4356,6 +4356,12 @@ var doc = `{ "description": "fuzzy rule,keyword for desc and annotation", "name": "fuzzy_keyword_rule", "in": "query" + }, + { + "type": "string", + "description": "tags for rule", + "name": "tags", + "in": "query" } ], "responses": { @@ -8409,6 +8415,12 @@ var doc = `{ "description": "fuzzy rule,keyword for desc and annotation", "name": "fuzzy_keyword_rule", "in": "query" + }, + { + "type": "string", + "description": "tags for rule", + "name": "tags", + "in": "query" } ], "responses": { @@ -8614,6 +8626,12 @@ var doc = `{ "description": "filter rule name list", "name": "filter_rule_names", "in": "query" + }, + { + "type": "string", + "description": "filter tags", + "name": "tags", + "in": "query" } ], "responses": { @@ -8626,6 +8644,29 @@ var doc = `{ } } }, + "/v1/rules/categoryStatistics": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get all rule category statistics", + "tags": [ + "rule_template" + ], + "summary": "获取规则分类统计信息", + "operationId": "getCategoryStatistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.GetRuleCategoryStatisticResV1" + } + } + } + } + }, "/v1/sql_analysis": { "get": { "security": [ @@ -11303,6 +11344,26 @@ var doc = `{ "$ref": "#/definitions/model.AuditResultInfo" } }, + "model.RuleCategoryStatistic": { + "type": "object", + "properties": { + "category": { + "type": "string", + "enum": [ + "audit_accuracy", + "audit_purpose", + "operand", + "sql" + ] + }, + "count": { + "type": "integer" + }, + "tag": { + "type": "string" + } + } + }, "v1.AffectRows": { "type": "object", "properties": { @@ -12505,6 +12566,12 @@ var doc = `{ "rule_script": { "type": "string" }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, "type": { "type": "string", "example": "DDL规则" @@ -12771,6 +12838,15 @@ var doc = `{ "type": "string", "example": "this is test rule" }, + "categories": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "db_type": { "type": "string", "example": "MySQL" @@ -14540,6 +14616,28 @@ var doc = `{ } } }, + "v1.GetRuleCategoryStatisticResV1": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 0 + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/model.RuleCategoryStatistic" + } + } + }, + "message": { + "type": "string", + "example": "ok" + } + } + }, "v1.GetRuleKnowledgeResV1": { "type": "object", "properties": { @@ -16693,6 +16791,15 @@ var doc = `{ "type": "string", "example": "避免多次 table rebuild 带来的消耗、以及对线上业务的影响" }, + "categories": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "db_type": { "type": "string", "example": "mysql" @@ -17905,6 +18012,12 @@ var doc = `{ "rule_script": { "type": "string" }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, "type": { "type": "string", "example": "DDL规则" diff --git a/sqle/docs/swagger.json b/sqle/docs/swagger.json index 4ae53711f..663360d48 100644 --- a/sqle/docs/swagger.json +++ b/sqle/docs/swagger.json @@ -4340,6 +4340,12 @@ "description": "fuzzy rule,keyword for desc and annotation", "name": "fuzzy_keyword_rule", "in": "query" + }, + { + "type": "string", + "description": "tags for rule", + "name": "tags", + "in": "query" } ], "responses": { @@ -8393,6 +8399,12 @@ "description": "fuzzy rule,keyword for desc and annotation", "name": "fuzzy_keyword_rule", "in": "query" + }, + { + "type": "string", + "description": "tags for rule", + "name": "tags", + "in": "query" } ], "responses": { @@ -8598,6 +8610,12 @@ "description": "filter rule name list", "name": "filter_rule_names", "in": "query" + }, + { + "type": "string", + "description": "filter tags", + "name": "tags", + "in": "query" } ], "responses": { @@ -8610,6 +8628,29 @@ } } }, + "/v1/rules/categoryStatistics": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get all rule category statistics", + "tags": [ + "rule_template" + ], + "summary": "获取规则分类统计信息", + "operationId": "getCategoryStatistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.GetRuleCategoryStatisticResV1" + } + } + } + } + }, "/v1/sql_analysis": { "get": { "security": [ @@ -11287,6 +11328,26 @@ "$ref": "#/definitions/model.AuditResultInfo" } }, + "model.RuleCategoryStatistic": { + "type": "object", + "properties": { + "category": { + "type": "string", + "enum": [ + "audit_accuracy", + "audit_purpose", + "operand", + "sql" + ] + }, + "count": { + "type": "integer" + }, + "tag": { + "type": "string" + } + } + }, "v1.AffectRows": { "type": "object", "properties": { @@ -12489,6 +12550,12 @@ "rule_script": { "type": "string" }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, "type": { "type": "string", "example": "DDL规则" @@ -12755,6 +12822,15 @@ "type": "string", "example": "this is test rule" }, + "categories": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "db_type": { "type": "string", "example": "MySQL" @@ -14524,6 +14600,28 @@ } } }, + "v1.GetRuleCategoryStatisticResV1": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 0 + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/model.RuleCategoryStatistic" + } + } + }, + "message": { + "type": "string", + "example": "ok" + } + } + }, "v1.GetRuleKnowledgeResV1": { "type": "object", "properties": { @@ -16677,6 +16775,15 @@ "type": "string", "example": "避免多次 table rebuild 带来的消耗、以及对线上业务的影响" }, + "categories": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "db_type": { "type": "string", "example": "mysql" @@ -17889,6 +17996,12 @@ "rule_script": { "type": "string" }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, "type": { "type": "string", "example": "DDL规则" diff --git a/sqle/docs/swagger.yaml b/sqle/docs/swagger.yaml index 7c4e5b934..d01b64985 100644 --- a/sqle/docs/swagger.yaml +++ b/sqle/docs/swagger.yaml @@ -18,6 +18,20 @@ definitions: additionalProperties: $ref: '#/definitions/model.AuditResultInfo' type: object + model.RuleCategoryStatistic: + properties: + category: + enum: + - audit_accuracy + - audit_purpose + - operand + - sql + type: string + count: + type: integer + tag: + type: string + type: object v1.AffectRows: properties: count: @@ -843,6 +857,10 @@ definitions: type: string rule_script: type: string + tags: + items: + type: string + type: array type: example: DDL规则 type: string @@ -1022,6 +1040,12 @@ definitions: annotation: example: this is test rule type: string + categories: + additionalProperties: + items: + type: string + type: array + type: object db_type: example: MySQL type: string @@ -2239,6 +2263,21 @@ definitions: example: ok type: string type: object + v1.GetRuleCategoryStatisticResV1: + properties: + code: + example: 0 + type: integer + data: + additionalProperties: + items: + $ref: '#/definitions/model.RuleCategoryStatistic' + type: array + type: object + message: + example: ok + type: string + type: object v1.GetRuleKnowledgeResV1: properties: code: @@ -3720,6 +3759,12 @@ definitions: annotation: example: 避免多次 table rebuild 带来的消耗、以及对线上业务的影响 type: string + categories: + additionalProperties: + items: + type: string + type: array + type: object db_type: example: mysql type: string @@ -4541,6 +4586,10 @@ definitions: type: string rule_script: type: string + tags: + items: + type: string + type: array type: example: DDL规则 type: string @@ -9007,6 +9056,10 @@ paths: in: query name: fuzzy_keyword_rule type: string + - description: tags for rule + in: query + name: tags + type: string responses: "200": description: OK @@ -11637,6 +11690,10 @@ paths: in: query name: fuzzy_keyword_rule type: string + - description: tags for rule + in: query + name: tags + type: string responses: "200": description: OK @@ -11783,6 +11840,10 @@ paths: in: query name: filter_rule_names type: string + - description: filter tags + in: query + name: tags + type: string responses: "200": description: OK @@ -11793,6 +11854,20 @@ paths: summary: 规则列表 tags: - rule_template + /v1/rules/categoryStatistics: + get: + description: get all rule category statistics + operationId: getCategoryStatistics + responses: + "200": + description: OK + schema: + $ref: '#/definitions/v1.GetRuleCategoryStatisticResV1' + security: + - ApiKeyAuth: [] + summary: 获取规则分类统计信息 + tags: + - rule_template /v1/sql_analysis: get: description: Direct get sql analysis result diff --git a/sqle/driver/mysql/plocale/active.en.toml b/sqle/driver/mysql/plocale/active.en.toml index 6f1a8bb90..34ec0de87 100644 --- a/sqle/driver/mysql/plocale/active.en.toml +++ b/sqle/driver/mysql/plocale/active.en.toml @@ -678,6 +678,8 @@ PrimaryKeyExistMessage = "Primary key already exists, cannot add it again." PrimaryKeyNotExistMessage = "There is no primary key currently, cannot execute deletion." RuleTypeDDLConvention = "DDL convention" RuleTypeDMLConvention = "DML convention" +RuleTypeDistributedConvention = "Distributed convention" +RuleTypeExecutePlan = "Execute plan" RuleTypeGlobalConfig = "Global configuration" RuleTypeIndexInvalidation = "Index invalidation" RuleTypeIndexOptimization = "Index optimization" @@ -689,4 +691,33 @@ SchemaNotExistMessage = "Schema %s does not exist." TableExistMessage = "Table %s already exists." TableNotExistMessage = "Table %s does not exist." ThreeStarIndexAdviceFormat = "Index suggestion | According to the three-star index design specification, it is recommended to add %s index to table %s: [%s]" -UnsupportedSyntaxError = "Syntax error or parser does not support it. Please manually confirm the correctness of SQL." \ No newline at end of file +UnsupportedSyntaxError = "Syntax error or parser does not support it. Please manually confirm the correctness of SQL." +audit_accuracy = "audit_accuracy" +audit_purpose = "audit_purpose" +column = "column" +correction = "correction" +database = "database" +dcl = "dcl" +ddl = "ddl" +dml = "dml" +event = "event" +function = "function" +index = "index" +integrity = "integrity" +maintenance = "maintenance" +management = "management" +offline = "offline" +online = "online" +operand = "operand" +performance = "performance" +privilege = "privilege" +procedure = "procedure" +query = "query" +security = "security" +sql = "sql" +table = "table" +table_space = "table_space" +transaction = "transaction" +trigger = "trigger" +user = "user" +view = "view" diff --git a/sqle/driver/mysql/plocale/active.zh.toml b/sqle/driver/mysql/plocale/active.zh.toml index 24824f9a7..b924ba2fb 100644 --- a/sqle/driver/mysql/plocale/active.zh.toml +++ b/sqle/driver/mysql/plocale/active.zh.toml @@ -678,6 +678,8 @@ PrimaryKeyExistMessage = "已经存在主键,不能再添加" PrimaryKeyNotExistMessage = "当前没有主键,不能执行删除" RuleTypeDDLConvention = "DDL规范" RuleTypeDMLConvention = "DML规范" +RuleTypeDistributedConvention = "分布式规范" +RuleTypeExecutePlan = "执行计划" RuleTypeGlobalConfig = "全局配置" RuleTypeIndexInvalidation = "索引失效" RuleTypeIndexOptimization = "索引优化" @@ -690,3 +692,32 @@ TableExistMessage = "表 %s 已存在" TableNotExistMessage = "表 %s 不存在" ThreeStarIndexAdviceFormat = "索引建议 | 根据三星索引设计规范,建议对表%s添加%s索引:【%s】" UnsupportedSyntaxError = "语法错误或者解析器不支持,请人工确认SQL正确性" +audit_accuracy = "审核精度" +audit_purpose = "审核目的" +column = "字段" +correction = "正确性" +database = "数据库" +dcl = "DCL" +ddl = "DDL" +dml = "DML" +event = "事件" +function = "函数" +index = "索引" +integrity = "完整性约束" +maintenance = "可维护性" +management = "数据库管理" +offline = "离线" +online = "在线" +operand = "操作对象" +performance = "性能问题" +privilege = "数据权限" +procedure = "存储过程" +query = "查询" +security = "安全性" +sql = "SQL分类" +table = "表" +table_space = "表空间" +transaction = "事务控制" +trigger = "触发器" +user = "用户" +view = "视图" diff --git a/sqle/driver/mysql/plocale/message_zh.go b/sqle/driver/mysql/plocale/message_zh.go index 09e0c8da1..8cf8db1b9 100644 --- a/sqle/driver/mysql/plocale/message_zh.go +++ b/sqle/driver/mysql/plocale/message_zh.go @@ -106,14 +106,45 @@ var ( // rule Category var ( - RuleTypeGlobalConfig = &i18n.Message{ID: "RuleTypeGlobalConfig", Other: "全局配置"} - RuleTypeNamingConvention = &i18n.Message{ID: "RuleTypeNamingConvention", Other: "命名规范"} - RuleTypeIndexingConvention = &i18n.Message{ID: "RuleTypeIndexingConvention", Other: "索引规范"} - RuleTypeDDLConvention = &i18n.Message{ID: "RuleTypeDDLConvention", Other: "DDL规范"} - RuleTypeDMLConvention = &i18n.Message{ID: "RuleTypeDMLConvention", Other: "DML规范"} - RuleTypeUsageSuggestion = &i18n.Message{ID: "RuleTypeUsageSuggestion", Other: "使用建议"} - RuleTypeIndexOptimization = &i18n.Message{ID: "RuleTypeIndexOptimization", Other: "索引优化"} - RuleTypeIndexInvalidation = &i18n.Message{ID: "RuleTypeIndexInvalidation", Other: "索引失效"} + RuleTypeGlobalConfig = &i18n.Message{ID: "RuleTypeGlobalConfig", Other: "全局配置"} + RuleTypeNamingConvention = &i18n.Message{ID: "RuleTypeNamingConvention", Other: "命名规范"} + RuleTypeIndexingConvention = &i18n.Message{ID: "RuleTypeIndexingConvention", Other: "索引规范"} + RuleTypeDDLConvention = &i18n.Message{ID: "RuleTypeDDLConvention", Other: "DDL规范"} + RuleTypeDMLConvention = &i18n.Message{ID: "RuleTypeDMLConvention", Other: "DML规范"} + RuleTypeUsageSuggestion = &i18n.Message{ID: "RuleTypeUsageSuggestion", Other: "使用建议"} + RuleTypeIndexOptimization = &i18n.Message{ID: "RuleTypeIndexOptimization", Other: "索引优化"} + RuleTypeIndexInvalidation = &i18n.Message{ID: "RuleTypeIndexInvalidation", Other: "索引失效"} + RuleTypeExecutePlan = &i18n.Message{ID: "RuleTypeExecutePlan", Other: "执行计划"} + RuleTypeDistributedConvention = &i18n.Message{ID: "RuleTypeDistributedConvention", Other: "分布式规范"} + RuleCategoryOperand = &i18n.Message{ID: "operand", Other: "操作对象"} + RuleCategorySQL = &i18n.Message{ID: "sql", Other: "SQL分类"} + RuleCategoryAuditPurpose = &i18n.Message{ID: "audit_purpose", Other: "审核目的"} + RuleCategoryAuditAccuracy = &i18n.Message{ID: "audit_accuracy", Other: "审核精度"} + RuleTagDatabase = &i18n.Message{ID: "database", Other: "数据库"} + RuleTagTablespace = &i18n.Message{ID: "table_space", Other: "表空间"} + RuleTagTable = &i18n.Message{ID: "table", Other: "表"} + RuleTagColumn = &i18n.Message{ID: "column", Other: "字段"} + RuleTagIndex = &i18n.Message{ID: "index", Other: "索引"} + RuleTagView = &i18n.Message{ID: "view", Other: "视图"} + RuleTagProcedure = &i18n.Message{ID: "procedure", Other: "存储过程"} + RuleTagFunction = &i18n.Message{ID: "function", Other: "函数"} + RuleTagTrigger = &i18n.Message{ID: "trigger", Other: "触发器"} + RuleTagEvent = &i18n.Message{ID: "event", Other: "事件"} + RuleTagUser = &i18n.Message{ID: "user", Other: "用户"} + RuleTagDML = &i18n.Message{ID: "dml", Other: "DML"} + RuleTagDDL = &i18n.Message{ID: "ddl", Other: "DDL"} + RuleTagDCL = &i18n.Message{ID: "dcl", Other: "DCL"} + RuleTagIntegrity = &i18n.Message{ID: "integrity", Other: "完整性约束"} + RuleTagQuery = &i18n.Message{ID: "query", Other: "查询"} + RuleTagTransaction = &i18n.Message{ID: "transaction", Other: "事务控制"} + RuleTagPrivilege = &i18n.Message{ID: "privilege", Other: "数据权限"} + RuleTagManagement = &i18n.Message{ID: "management", Other: "数据库管理"} + RuleTagPerformance = &i18n.Message{ID: "performance", Other: "性能问题"} + RuleTagMaintenance = &i18n.Message{ID: "maintenance", Other: "可维护性"} + RuleTagSecurity = &i18n.Message{ID: "security", Other: "安全性"} + RuleTagCorrection = &i18n.Message{ID: "correction", Other: "正确性"} + RuleTagOnline = &i18n.Message{ID: "online", Other: "在线"} + RuleTagOffline = &i18n.Message{ID: "offline", Other: "离线"} ) // rule list diff --git a/sqle/driver/mysql/rule/rule.go b/sqle/driver/mysql/rule/rule.go index d894dfe9c..171d53a82 100644 --- a/sqle/driver/mysql/rule/rule.go +++ b/sqle/driver/mysql/rule/rule.go @@ -231,7 +231,6 @@ type RuleHandler struct { Rule driverV2.Rule Message *i18n.Message Func RuleHandlerFunc - AllowOffline bool NotAllowOfflineStmts []ast.Node // 开始事后审核时将会跳过这个值为ture的规则 OnlyAuditNotExecutedSQL bool @@ -271,7 +270,7 @@ func addResult(result *driverV2.AuditResults, currentRule driverV2.Rule, ruleNam } func (rh *RuleHandler) IsAllowOfflineRule(node ast.Node) bool { - if !rh.AllowOffline { + if !rh.Rule.AllowOffline { return false } for _, stmt := range rh.NotAllowOfflineStmts { diff --git a/sqle/driver/mysql/rule/rule_i18n_converter.go b/sqle/driver/mysql/rule/rule_i18n_converter.go index 04ee3de13..4ddf91a49 100644 --- a/sqle/driver/mysql/rule/rule_i18n_converter.go +++ b/sqle/driver/mysql/rule/rule_i18n_converter.go @@ -24,20 +24,20 @@ type SourceParam struct { } type SourceRule struct { - Name string - Desc *i18n.Message - Annotation *i18n.Message - Category *i18n.Message - Level driverV2.RuleLevel - Params []*SourceParam - Knowledge driverV2.RuleKnowledge + Name string + Desc *i18n.Message + Annotation *i18n.Message + Category *i18n.Message + Level driverV2.RuleLevel + Params []*SourceParam + Knowledge driverV2.RuleKnowledge + AllowOffline bool } type SourceHandler struct { Rule SourceRule Message *i18n.Message Func RuleHandlerFunc - AllowOffline bool NotAllowOfflineStmts []ast.Node // 开始事后审核时将会跳过这个值为ture的规则 OnlyAuditNotExecutedSQL bool @@ -53,7 +53,6 @@ func generateI18nRuleHandlersFromSource(shs []*SourceHandler) []RuleHandler { Rule: *ConvertSourceRule(&v.Rule), Message: v.Message, Func: v.Func, - AllowOffline: v.AllowOffline, NotAllowOfflineStmts: v.NotAllowOfflineStmts, OnlyAuditNotExecutedSQL: v.OnlyAuditNotExecutedSQL, NotSupportExecutedSQLAuditStmts: v.NotSupportExecutedSQLAuditStmts, @@ -66,8 +65,10 @@ func ConvertSourceRule(sr *SourceRule) *driverV2.Rule { r := &driverV2.Rule{ Name: sr.Name, Level: sr.Level, + Category: sr.Category.ID, Params: make(params.Params, 0, len(sr.Params)), I18nRuleInfo: genAllI18nRuleInfo(sr), + AllowOffline: sr.AllowOffline, } for _, v := range sr.Params { r.Params = append(r.Params, ¶ms.Param{ diff --git a/sqle/driver/mysql/rule/rule_list.go b/sqle/driver/mysql/rule/rule_list.go index eded5f96f..1ffcce90a 100644 --- a/sqle/driver/mysql/rule/rule_list.go +++ b/sqle/driver/mysql/rule/rule_list.go @@ -13,15 +13,15 @@ import ( var sourceRuleHandlers = []*SourceHandler{ { Rule: SourceRule{ - Name: DMLNotAllowInsertAutoincrement, - Desc: plocale.DMLNotAllowInsertAutoincrementDesc, - Annotation: plocale.DMLNotAllowInsertAutoincrementAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLNotAllowInsertAutoincrement, + Desc: plocale.DMLNotAllowInsertAutoincrementDesc, + Annotation: plocale.DMLNotAllowInsertAutoincrementAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - Message: plocale.DMLNotAllowInsertAutoincrementMessage, - AllowOffline: false, - Func: notAllowInsertAutoincrement, + Message: plocale.DMLNotAllowInsertAutoincrementMessage, + Func: notAllowInsertAutoincrement, }, { Rule: SourceRule{ @@ -94,14 +94,14 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DDLCheckRedundantIndex, - Desc: plocale.DDLCheckRedundantIndexDesc, - Annotation: plocale.DDLCheckRedundantIndexAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexOptimization, + Name: DDLCheckRedundantIndex, + Desc: plocale.DDLCheckRedundantIndexDesc, + Annotation: plocale.DDLCheckRedundantIndexAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexOptimization, + AllowOffline: true, }, Message: plocale.DDLCheckRedundantIndexMessage, - AllowOffline: true, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: checkIndex, }, @@ -181,23 +181,24 @@ var sourceRuleHandlers = []*SourceHandler{ // rule { Rule: SourceRule{ - Name: DDLCheckPKWithoutIfNotExists, - Desc: plocale.DDLCheckPKWithoutIfNotExistsDesc, - Annotation: plocale.DDLCheckPKWithoutIfNotExistsAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckPKWithoutIfNotExists, + Desc: plocale.DDLCheckPKWithoutIfNotExistsDesc, + Annotation: plocale.DDLCheckPKWithoutIfNotExistsAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckPKWithoutIfNotExistsMessage, - AllowOffline: true, - Func: checkIfNotExist, + Message: plocale.DDLCheckPKWithoutIfNotExistsMessage, + Func: checkIfNotExist, }, { Rule: SourceRule{ - Name: DDLCheckObjectNameLength, - Desc: plocale.DDLCheckObjectNameLengthDesc, - Annotation: plocale.DDLCheckObjectNameLengthAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckObjectNameLength, + Desc: plocale.DDLCheckObjectNameLengthDesc, + Annotation: plocale.DDLCheckObjectNameLengthAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, //Value: "64", Params: []*SourceParam{ { @@ -208,60 +209,59 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckObjectNameLengthMessage, - AllowOffline: true, - Func: checkNewObjectName, + Message: plocale.DDLCheckObjectNameLengthMessage, + Func: checkNewObjectName, }, { Rule: SourceRule{ - Name: DDLCheckObjectNameIsUpperAndLowerLetterMixed, - Desc: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedDesc, - Annotation: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedAnnotation, - Category: plocale.RuleTypeNamingConvention, - Level: driverV2.RuleLevelNotice, + Name: DDLCheckObjectNameIsUpperAndLowerLetterMixed, + Desc: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedDesc, + Annotation: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedAnnotation, + Category: plocale.RuleTypeNamingConvention, + Level: driverV2.RuleLevelNotice, + AllowOffline: true, }, - Message: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedMessage, - Func: checkIsObjectNameUpperAndLowerLetterMixed, - AllowOffline: true, + Message: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedMessage, + Func: checkIsObjectNameUpperAndLowerLetterMixed, }, { Rule: SourceRule{ - Name: DDLCheckPKNotExist, - Desc: plocale.DDLCheckPKNotExistDesc, - Annotation: plocale.DDLCheckPKNotExistAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKNotExist, + Desc: plocale.DDLCheckPKNotExistDesc, + Annotation: plocale.DDLCheckPKNotExistAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKNotExistMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, }, { Rule: SourceRule{ - Name: DDLCheckPKWithoutAutoIncrement, - Desc: plocale.DDLCheckPKWithoutAutoIncrementDesc, - Annotation: plocale.DDLCheckPKWithoutAutoIncrementAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKWithoutAutoIncrement, + Desc: plocale.DDLCheckPKWithoutAutoIncrementDesc, + Annotation: plocale.DDLCheckPKWithoutAutoIncrementAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKWithoutAutoIncrementMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, }, { Rule: SourceRule{ - Name: DDLCheckPKWithoutBigintUnsigned, - Desc: plocale.DDLCheckPKWithoutBigintUnsignedDesc, - Annotation: plocale.DDLCheckPKWithoutBigintUnsignedAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKWithoutBigintUnsigned, + Desc: plocale.DDLCheckPKWithoutBigintUnsignedDesc, + Annotation: plocale.DDLCheckPKWithoutBigintUnsignedAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKWithoutBigintUnsignedMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, @@ -274,77 +274,77 @@ var sourceRuleHandlers = []*SourceHandler{ Level: driverV2.RuleLevelWarn, Category: plocale.RuleTypeDMLConvention, }, - Message: plocale.DMLCheckJoinFieldTypeMessage, - AllowOffline: false, - Func: checkJoinFieldType, + Message: plocale.DMLCheckJoinFieldTypeMessage, + Func: checkJoinFieldType, }, { Rule: SourceRule{ - Name: DMLCheckHasJoinCondition, - Desc: plocale.DMLCheckHasJoinConditionDesc, - Annotation: plocale.DMLCheckHasJoinConditionAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckHasJoinCondition, + Desc: plocale.DMLCheckHasJoinConditionDesc, + Annotation: plocale.DMLCheckHasJoinConditionAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckHasJoinConditionMessage, - AllowOffline: true, - Func: checkHasJoinCondition, + Message: plocale.DMLCheckHasJoinConditionMessage, + Func: checkHasJoinCondition, }, { Rule: SourceRule{ - Name: DDLCheckColumnCharLength, - Desc: plocale.DDLCheckColumnCharLengthDesc, - Annotation: plocale.DDLCheckColumnCharLengthAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnCharLength, + Desc: plocale.DDLCheckColumnCharLengthDesc, + Annotation: plocale.DDLCheckColumnCharLengthAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnCharLengthMessage, - AllowOffline: true, - Func: checkStringType, + Message: plocale.DDLCheckColumnCharLengthMessage, + Func: checkStringType, }, { Rule: SourceRule{ - Name: DDLCheckFieldNotNUllMustContainDefaultValue, - Desc: plocale.DDLCheckFieldNotNUllMustContainDefaultValueDesc, - Annotation: plocale.DDLCheckFieldNotNUllMustContainDefaultValueAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckFieldNotNUllMustContainDefaultValue, + Desc: plocale.DDLCheckFieldNotNUllMustContainDefaultValueDesc, + Annotation: plocale.DDLCheckFieldNotNUllMustContainDefaultValueAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckFieldNotNUllMustContainDefaultValueMessage, - AllowOffline: true, - Func: checkFieldNotNUllMustContainDefaultValue, + Message: plocale.DDLCheckFieldNotNUllMustContainDefaultValueMessage, + Func: checkFieldNotNUllMustContainDefaultValue, }, { Rule: SourceRule{ - Name: DDLDisableFK, - Desc: plocale.DDLDisableFKDesc, - Annotation: plocale.DDLDisableFKAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLDisableFK, + Desc: plocale.DDLDisableFKDesc, + Annotation: plocale.DDLDisableFKAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, - Message: plocale.DDLDisableFKMessage, - AllowOffline: true, - Func: checkForeignKey, + Message: plocale.DDLDisableFKMessage, + Func: checkForeignKey, }, { Rule: SourceRule{ - Name: DDLDisableAlterFieldUseFirstAndAfter, - Desc: plocale.DDLDisableAlterFieldUseFirstAndAfterDesc, - Annotation: plocale.DDLDisableAlterFieldUseFirstAndAfterAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLDisableAlterFieldUseFirstAndAfter, + Desc: plocale.DDLDisableAlterFieldUseFirstAndAfterDesc, + Annotation: plocale.DDLDisableAlterFieldUseFirstAndAfterAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLDisableAlterFieldUseFirstAndAfterMessage, - AllowOffline: true, - Func: disableAlterUseFirstAndAfter, + Message: plocale.DDLDisableAlterFieldUseFirstAndAfterMessage, + Func: disableAlterUseFirstAndAfter, }, { Rule: SourceRule{ - Name: DDLCheckCreateTimeColumn, - Desc: plocale.DDLCheckCreateTimeColumnDesc, - Annotation: plocale.DDLCheckCreateTimeColumnAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckCreateTimeColumn, + Desc: plocale.DDLCheckCreateTimeColumnDesc, + Annotation: plocale.DDLCheckCreateTimeColumnAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -354,9 +354,8 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckCreateTimeColumnMessage, - AllowOffline: true, - Func: checkFieldCreateTime, + Message: plocale.DDLCheckCreateTimeColumnMessage, + Func: checkFieldCreateTime, }, { Rule: SourceRule{ @@ -365,7 +364,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DDLCheckIndexCountAnnotation, Level: driverV2.RuleLevelNotice, //Value: "5", - Category: plocale.RuleTypeIndexingConvention, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -376,18 +376,18 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, Message: plocale.DDLCheckIndexCountMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: checkIndex, }, { Rule: SourceRule{ - Name: DDLCheckUpdateTimeColumn, - Desc: plocale.DDLCheckUpdateTimeColumnDesc, - Annotation: plocale.DDLCheckUpdateTimeColumnAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckUpdateTimeColumn, + Desc: plocale.DDLCheckUpdateTimeColumnDesc, + Annotation: plocale.DDLCheckUpdateTimeColumnAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -397,9 +397,8 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckUpdateTimeColumnMessage, - AllowOffline: true, - Func: checkFieldUpdateTime, + Message: plocale.DDLCheckUpdateTimeColumnMessage, + Func: checkFieldUpdateTime, }, { Rule: SourceRule{ @@ -408,7 +407,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DDLCheckCompositeIndexMaxAnnotation, Level: driverV2.RuleLevelNotice, //Value: "3", - Category: plocale.RuleTypeIndexingConvention, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -419,55 +419,55 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, Message: plocale.DDLCheckCompositeIndexMaxMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: checkIndex, }, { Rule: SourceRule{ - Name: DDLCheckIndexNotNullConstraint, - Desc: plocale.DDLCheckIndexNotNullConstraintDesc, - Annotation: plocale.DDLCheckIndexNotNullConstraintAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckIndexNotNullConstraint, + Desc: plocale.DDLCheckIndexNotNullConstraintDesc, + Annotation: plocale.DDLCheckIndexNotNullConstraintAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckIndexNotNullConstraintMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: checkIndexNotNullConstraint, }, { Rule: SourceRule{ - Name: DDLCheckObjectNameUsingKeyword, - Desc: plocale.DDLCheckObjectNameUsingKeywordDesc, - Annotation: plocale.DDLCheckObjectNameUsingKeywordAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckObjectNameUsingKeyword, + Desc: plocale.DDLCheckObjectNameUsingKeywordDesc, + Annotation: plocale.DDLCheckObjectNameUsingKeywordAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckObjectNameUsingKeywordMessage, - AllowOffline: true, - Func: checkNewObjectName, + Message: plocale.DDLCheckObjectNameUsingKeywordMessage, + Func: checkNewObjectName, }, { Rule: SourceRule{ - Name: DDLCheckObjectNameUseCN, - Desc: plocale.DDLCheckObjectNameUseCNDesc, - Annotation: plocale.DDLCheckObjectNameUseCNAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckObjectNameUseCN, + Desc: plocale.DDLCheckObjectNameUseCNDesc, + Annotation: plocale.DDLCheckObjectNameUseCNAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckObjectNameUseCNMessage, - AllowOffline: true, - Func: checkNewObjectName, + Message: plocale.DDLCheckObjectNameUseCNMessage, + Func: checkNewObjectName, }, { Rule: SourceRule{ - Name: DDLCheckTableDBEngine, - Desc: plocale.DDLCheckTableDBEngineDesc, - Annotation: plocale.DDLCheckTableDBEngineAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckTableDBEngine, + Desc: plocale.DDLCheckTableDBEngineDesc, + Annotation: plocale.DDLCheckTableDBEngineAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: false, //Value: "Innodb", Params: []*SourceParam{ { @@ -478,17 +478,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckTableDBEngineMessage, - AllowOffline: false, - Func: checkEngine, + Message: plocale.DDLCheckTableDBEngineMessage, + Func: checkEngine, }, { Rule: SourceRule{ - Name: DDLCheckTableCharacterSet, - Desc: plocale.DDLCheckTableCharacterSetDesc, - Annotation: plocale.DDLCheckTableCharacterSetAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckTableCharacterSet, + Desc: plocale.DDLCheckTableCharacterSetDesc, + Annotation: plocale.DDLCheckTableCharacterSetAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: false, //Value: "utf8mb4", Params: []*SourceParam{ { @@ -499,104 +499,104 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckTableCharacterSetMessage, - AllowOffline: false, - Func: checkCharacterSet, + Message: plocale.DDLCheckTableCharacterSetMessage, + Func: checkCharacterSet, }, { Rule: SourceRule{ - Name: DDLCheckIndexedColumnWithBlob, - Desc: plocale.DDLCheckIndexedColumnWithBlobDesc, - Annotation: plocale.DDLCheckIndexedColumnWithBlobAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckIndexedColumnWithBlob, + Desc: plocale.DDLCheckIndexedColumnWithBlobDesc, + Annotation: plocale.DDLCheckIndexedColumnWithBlobAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckIndexedColumnWithBlobMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: disableAddIndexForColumnsTypeBlob, }, { Rule: SourceRule{ - Name: DMLCheckWhereIsInvalid, - Desc: plocale.DMLCheckWhereIsInvalidDesc, - Annotation: plocale.DMLCheckWhereIsInvalidAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWhereIsInvalid, + Desc: plocale.DMLCheckWhereIsInvalidDesc, + Annotation: plocale.DMLCheckWhereIsInvalidAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWhereIsInvalidMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckWhereIsInvalidMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ - Name: DDLCheckAlterTableNeedMerge, - Desc: plocale.DDLCheckAlterTableNeedMergeDesc, - Annotation: plocale.DDLCheckAlterTableNeedMergeAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckAlterTableNeedMerge, + Desc: plocale.DDLCheckAlterTableNeedMergeDesc, + Annotation: plocale.DDLCheckAlterTableNeedMergeAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: false, }, Message: plocale.DDLCheckAlterTableNeedMergeMessage, - AllowOffline: false, OnlyAuditNotExecutedSQL: true, Func: checkMergeAlterTable, }, { Rule: SourceRule{ - Name: DMLDisableSelectAllColumn, - Desc: plocale.DMLDisableSelectAllColumnDesc, - Annotation: plocale.DMLDisableSelectAllColumnAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLDisableSelectAllColumn, + Desc: plocale.DMLDisableSelectAllColumnDesc, + Annotation: plocale.DMLDisableSelectAllColumnAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLDisableSelectAllColumnMessage, - AllowOffline: true, - Func: checkSelectAll, + Message: plocale.DMLDisableSelectAllColumnMessage, + Func: checkSelectAll, }, { Rule: SourceRule{ - Name: DDLDisableDropStatement, - Desc: plocale.DDLDisableDropStatementDesc, - Annotation: plocale.DDLDisableDropStatementAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLDisableDropStatement, + Desc: plocale.DDLDisableDropStatementDesc, + Annotation: plocale.DDLDisableDropStatementAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLDisableDropStatementMessage, - AllowOffline: true, - Func: disableDropStmt, + Message: plocale.DDLDisableDropStatementMessage, + Func: disableDropStmt, }, { Rule: SourceRule{ - Name: DDLCheckTableWithoutComment, - Desc: plocale.DDLCheckTableWithoutCommentDesc, - Annotation: plocale.DDLCheckTableWithoutCommentAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckTableWithoutComment, + Desc: plocale.DDLCheckTableWithoutCommentDesc, + Annotation: plocale.DDLCheckTableWithoutCommentAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckTableWithoutCommentMessage, - AllowOffline: true, - Func: checkTableWithoutComment, + Message: plocale.DDLCheckTableWithoutCommentMessage, + Func: checkTableWithoutComment, }, { Rule: SourceRule{ - Name: DDLCheckColumnWithoutComment, - Desc: plocale.DDLCheckColumnWithoutCommentDesc, - Annotation: plocale.DDLCheckColumnWithoutCommentAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnWithoutComment, + Desc: plocale.DDLCheckColumnWithoutCommentDesc, + Annotation: plocale.DDLCheckColumnWithoutCommentAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnWithoutCommentMessage, - AllowOffline: true, - Func: checkColumnWithoutComment, + Message: plocale.DDLCheckColumnWithoutCommentMessage, + Func: checkColumnWithoutComment, }, { Rule: SourceRule{ - Name: DDLCheckIndexPrefix, - Desc: plocale.DDLCheckIndexPrefixDesc, - Annotation: plocale.DDLCheckIndexPrefixAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckIndexPrefix, + Desc: plocale.DDLCheckIndexPrefixDesc, + Annotation: plocale.DDLCheckIndexPrefixAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, //Value: "idx_", Params: []*SourceParam{ { @@ -607,17 +607,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckIndexPrefixMessage, - AllowOffline: true, - Func: checkIndexPrefix, + Message: plocale.DDLCheckIndexPrefixMessage, + Func: checkIndexPrefix, }, { Rule: SourceRule{ - Name: DDLCheckUniqueIndexPrefix, - Desc: plocale.DDLCheckUniqueIndexPrefixDesc, - Annotation: plocale.DDLCheckUniqueIndexPrefixAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckUniqueIndexPrefix, + Desc: plocale.DDLCheckUniqueIndexPrefixDesc, + Annotation: plocale.DDLCheckUniqueIndexPrefixAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, //Value: "uniq_", Params: []*SourceParam{ { @@ -628,113 +628,113 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckUniqueIndexPrefixMessage, - AllowOffline: true, - Func: checkUniqIndexPrefix, + Message: plocale.DDLCheckUniqueIndexPrefixMessage, + Func: checkUniqIndexPrefix, }, { Rule: SourceRule{ - Name: DDLCheckUniqueIndex, - Desc: plocale.DDLCheckUniqueIndexDesc, - Annotation: plocale.DDLCheckUniqueIndexAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckUniqueIndex, + Desc: plocale.DDLCheckUniqueIndexDesc, + Annotation: plocale.DDLCheckUniqueIndexAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckUniqueIndexMessage, - AllowOffline: true, - Func: checkUniqIndex, + Message: plocale.DDLCheckUniqueIndexMessage, + Func: checkUniqIndex, }, { Rule: SourceRule{ - Name: DDLCheckColumnWithoutDefault, - Desc: plocale.DDLCheckColumnWithoutDefaultDesc, - Annotation: plocale.DDLCheckColumnWithoutDefaultAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnWithoutDefault, + Desc: plocale.DDLCheckColumnWithoutDefaultDesc, + Annotation: plocale.DDLCheckColumnWithoutDefaultAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnWithoutDefaultMessage, - AllowOffline: true, - Func: checkColumnWithoutDefault, + Message: plocale.DDLCheckColumnWithoutDefaultMessage, + Func: checkColumnWithoutDefault, }, { Rule: SourceRule{ - Name: DDLCheckColumnTimestampWithoutDefault, - Desc: plocale.DDLCheckColumnTimestampWithoutDefaultDesc, - Annotation: plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnTimestampWithoutDefault, + Desc: plocale.DDLCheckColumnTimestampWithoutDefaultDesc, + Annotation: plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnTimestampWithoutDefaultMessage, - AllowOffline: true, - Func: checkColumnTimestampWithoutDefault, + Message: plocale.DDLCheckColumnTimestampWithoutDefaultMessage, + Func: checkColumnTimestampWithoutDefault, }, { Rule: SourceRule{ - Name: DDLCheckColumnBlobWithNotNull, - Desc: plocale.DDLCheckColumnBlobWithNotNullDesc, - Annotation: plocale.DDLCheckColumnBlobWithNotNullAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnBlobWithNotNull, + Desc: plocale.DDLCheckColumnBlobWithNotNullDesc, + Annotation: plocale.DDLCheckColumnBlobWithNotNullAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnBlobWithNotNullMessage, - AllowOffline: true, - Func: checkColumnBlobNotNull, + Message: plocale.DDLCheckColumnBlobWithNotNullMessage, + Func: checkColumnBlobNotNull, }, { Rule: SourceRule{ - Name: DDLCheckColumnBlobDefaultIsNotNull, - Desc: plocale.DDLCheckColumnBlobDefaultIsNotNullDesc, - Annotation: plocale.DDLCheckColumnBlobDefaultIsNotNullAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnBlobDefaultIsNotNull, + Desc: plocale.DDLCheckColumnBlobDefaultIsNotNullDesc, + Annotation: plocale.DDLCheckColumnBlobDefaultIsNotNullAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnBlobDefaultIsNotNullMessage, - AllowOffline: true, - Func: checkColumnBlobDefaultNull, + Message: plocale.DDLCheckColumnBlobDefaultIsNotNullMessage, + Func: checkColumnBlobDefaultNull, }, { Rule: SourceRule{ - Name: DDLCheckAutoIncrementFieldNum, - Desc: plocale.DDLCheckAutoIncrementFieldNumDesc, - Annotation: plocale.DDLCheckAutoIncrementFieldNumAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckAutoIncrementFieldNum, + Desc: plocale.DDLCheckAutoIncrementFieldNumDesc, + Annotation: plocale.DDLCheckAutoIncrementFieldNumAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLCheckAutoIncrementFieldNumMessage, - Func: checkAutoIncrementFieldNum, + Message: plocale.DDLCheckAutoIncrementFieldNumMessage, + Func: checkAutoIncrementFieldNum, }, { Rule: SourceRule{ - Name: DDLCheckAllIndexNotNullConstraint, - Desc: plocale.DDLCheckAllIndexNotNullConstraintDesc, - Annotation: plocale.DDLCheckAllIndexNotNullConstraintAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckAllIndexNotNullConstraint, + Desc: plocale.DDLCheckAllIndexNotNullConstraintDesc, + Annotation: plocale.DDLCheckAllIndexNotNullConstraintAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLCheckAllIndexNotNullConstraintMessage, - Func: checkAllIndexNotNullConstraint, + Message: plocale.DDLCheckAllIndexNotNullConstraintMessage, + Func: checkAllIndexNotNullConstraint, }, { Rule: SourceRule{ - Name: DMLCheckWithLimit, - Desc: plocale.DMLCheckWithLimitDesc, - Annotation: plocale.DMLCheckWithLimitAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWithLimit, + Desc: plocale.DMLCheckWithLimitDesc, + Annotation: plocale.DMLCheckWithLimitAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWithLimitMessage, - AllowOffline: true, - Func: checkDMLWithLimit, + Message: plocale.DMLCheckWithLimitMessage, + Func: checkDMLWithLimit, }, { Rule: SourceRule{ - Name: DMLCheckSelectLimit, - Desc: plocale.DMLCheckSelectLimitDesc, - Annotation: plocale.DMLCheckSelectLimitAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSelectLimit, + Desc: plocale.DMLCheckSelectLimitDesc, + Annotation: plocale.DMLCheckSelectLimitAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -744,46 +744,45 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckSelectLimitMessage, - AllowOffline: true, - Func: checkSelectLimit, + Message: plocale.DMLCheckSelectLimitMessage, + Func: checkSelectLimit, }, { Rule: SourceRule{ - Name: DMLCheckWithOrderBy, - Desc: plocale.DMLCheckWithOrderByDesc, - Annotation: plocale.DMLCheckWithOrderByAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWithOrderBy, + Desc: plocale.DMLCheckWithOrderByDesc, + Annotation: plocale.DMLCheckWithOrderByAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWithOrderByMessage, - AllowOffline: true, - Func: checkDMLWithOrderBy, + Message: plocale.DMLCheckWithOrderByMessage, + Func: checkDMLWithOrderBy, }, { Rule: SourceRule{ - Name: DMLCheckSelectWithOrderBy, - Desc: plocale.DMLCheckSelectWithOrderByDesc, - Annotation: plocale.DMLCheckSelectWithOrderByAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSelectWithOrderBy, + Desc: plocale.DMLCheckSelectWithOrderByDesc, + Annotation: plocale.DMLCheckSelectWithOrderByAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckSelectWithOrderByMessage, - AllowOffline: true, - Func: checkSelectWithOrderBy, + Message: plocale.DMLCheckSelectWithOrderByMessage, + Func: checkSelectWithOrderBy, }, { // TODO: 修改level以适配默认模板 Rule: SourceRule{ - Name: DMLCheckInsertColumnsExist, - Desc: plocale.DMLCheckInsertColumnsExistDesc, - Annotation: plocale.DMLCheckInsertColumnsExistAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckInsertColumnsExist, + Desc: plocale.DMLCheckInsertColumnsExistDesc, + Annotation: plocale.DMLCheckInsertColumnsExistAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckInsertColumnsExistMessage, - AllowOffline: true, - Func: checkDMLWithInsertColumnExist, + Message: plocale.DMLCheckInsertColumnsExistMessage, + Func: checkDMLWithInsertColumnExist, }, { Rule: SourceRule{ @@ -792,7 +791,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DMLCheckBatchInsertListsMaxAnnotation, Level: driverV2.RuleLevelNotice, //Value: "5000", - Category: plocale.RuleTypeDMLConvention, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -802,17 +802,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckBatchInsertListsMaxMessage, - AllowOffline: true, - Func: checkDMLWithBatchInsertMaxLimits, + Message: plocale.DMLCheckBatchInsertListsMaxMessage, + Func: checkDMLWithBatchInsertMaxLimits, }, { Rule: SourceRule{ - Name: DMLCheckInQueryNumber, - Desc: plocale.DMLCheckInQueryNumberDesc, - Annotation: plocale.DMLCheckInQueryNumberAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckInQueryNumber, + Desc: plocale.DMLCheckInQueryNumberDesc, + Annotation: plocale.DMLCheckInQueryNumberAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -822,59 +822,58 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckInQueryNumberMessage, - AllowOffline: true, - Func: checkInQueryLimit, + Message: plocale.DMLCheckInQueryNumberMessage, + Func: checkInQueryLimit, }, { Rule: SourceRule{ - Name: DDLCheckPKProhibitAutoIncrement, - Desc: plocale.DDLCheckPKProhibitAutoIncrementDesc, - Annotation: plocale.DDLCheckPKProhibitAutoIncrementAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKProhibitAutoIncrement, + Desc: plocale.DDLCheckPKProhibitAutoIncrementDesc, + Annotation: plocale.DDLCheckPKProhibitAutoIncrementAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKProhibitAutoIncrementMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, }, { Rule: SourceRule{ - Name: DMLCheckWhereExistFunc, - Desc: plocale.DMLCheckWhereExistFuncDesc, - Annotation: plocale.DMLCheckWhereExistFuncAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWhereExistFunc, + Desc: plocale.DMLCheckWhereExistFuncDesc, + Annotation: plocale.DMLCheckWhereExistFuncAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - Message: plocale.DMLCheckWhereExistFuncMessage, - AllowOffline: false, - Func: checkWhereExistFunc, + Message: plocale.DMLCheckWhereExistFuncMessage, + Func: checkWhereExistFunc, }, { Rule: SourceRule{ - Name: DMLCheckWhereExistNot, - Desc: plocale.DMLCheckWhereExistNotDesc, - Annotation: plocale.DMLCheckWhereExistNotAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWhereExistNot, + Desc: plocale.DMLCheckWhereExistNotDesc, + Annotation: plocale.DMLCheckWhereExistNotAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWhereExistNotMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckWhereExistNotMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ - Name: DMLWhereExistNull, - Desc: plocale.DMLWhereExistNullDesc, - Annotation: plocale.DMLWhereExistNullAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLWhereExistNull, + Desc: plocale.DMLWhereExistNullDesc, + Annotation: plocale.DMLWhereExistNullAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLWhereExistNullMessage, - Func: checkWhereExistNull, - AllowOffline: true, + Message: plocale.DMLWhereExistNullMessage, + Func: checkWhereExistNull, }, { Rule: SourceRule{ @@ -889,27 +888,27 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DMLCheckLimitMustExist, - Desc: plocale.DMLCheckLimitMustExistDesc, - Annotation: plocale.DMLCheckLimitMustExistAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckLimitMustExist, + Desc: plocale.DMLCheckLimitMustExistDesc, + Annotation: plocale.DMLCheckLimitMustExistAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckLimitMustExistMessage, - Func: checkDMLLimitExist, - AllowOffline: true, + Message: plocale.DMLCheckLimitMustExistMessage, + Func: checkDMLLimitExist, }, { Rule: SourceRule{ - Name: DMLCheckWhereExistScalarSubquery, - Desc: plocale.DMLCheckWhereExistScalarSubqueryDesc, - Annotation: plocale.DMLCheckWhereExistScalarSubqueryAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWhereExistScalarSubquery, + Desc: plocale.DMLCheckWhereExistScalarSubqueryDesc, + Annotation: plocale.DMLCheckWhereExistScalarSubqueryAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWhereExistScalarSubqueryMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckWhereExistScalarSubqueryMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ @@ -925,15 +924,15 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DMLCheckSelectForUpdate, - Desc: plocale.DMLCheckSelectForUpdateDesc, - Annotation: plocale.DMLCheckSelectForUpdateAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSelectForUpdate, + Desc: plocale.DMLCheckSelectForUpdateDesc, + Annotation: plocale.DMLCheckSelectForUpdateAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckSelectForUpdateMessage, - Func: checkDMLSelectForUpdate, - AllowOffline: true, + Message: plocale.DMLCheckSelectForUpdateMessage, + Func: checkDMLSelectForUpdate, }, { Rule: SourceRule{ @@ -957,35 +956,36 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DDLCheckDecimalTypeColumn, - Desc: plocale.DDLCheckDecimalTypeColumnDesc, - Annotation: plocale.DDLCheckDecimalTypeColumnAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckDecimalTypeColumn, + Desc: plocale.DDLCheckDecimalTypeColumnDesc, + Annotation: plocale.DDLCheckDecimalTypeColumnAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckDecimalTypeColumnMessage, - Func: checkDecimalTypeColumn, - AllowOffline: true, + Message: plocale.DDLCheckDecimalTypeColumnMessage, + Func: checkDecimalTypeColumn, }, { Rule: SourceRule{ - Name: DDLCheckBigintInsteadOfDecimal, - Desc: plocale.DDLCheckBigintInsteadOfDecimalDesc, - Annotation: plocale.DDLCheckBigintInsteadOfDecimalAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckBigintInsteadOfDecimal, + Desc: plocale.DDLCheckBigintInsteadOfDecimalDesc, + Annotation: plocale.DDLCheckBigintInsteadOfDecimalAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckBigintInsteadOfDecimalMessage, - Func: checkBigintInsteadOfDecimal, - AllowOffline: true, + Message: plocale.DDLCheckBigintInsteadOfDecimalMessage, + Func: checkBigintInsteadOfDecimal, }, { Rule: SourceRule{ - Name: DMLCheckSubQueryNestNum, - Desc: plocale.DMLCheckSubQueryNestNumDesc, - Annotation: plocale.DMLCheckSubQueryNestNumAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSubQueryNestNum, + Desc: plocale.DMLCheckSubQueryNestNumDesc, + Annotation: plocale.DMLCheckSubQueryNestNumAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -995,9 +995,8 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckSubQueryNestNumMessage, - Func: checkSubQueryNestNum, - AllowOffline: true, + Message: plocale.DMLCheckSubQueryNestNumMessage, + Func: checkSubQueryNestNum, }, { Rule: SourceRule{ @@ -1006,7 +1005,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DMLCheckNeedlessFuncAnnotation, Level: driverV2.RuleLevelNotice, //Value: "sha(),sqrt(),md5()", - Category: plocale.RuleTypeDMLConvention, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1016,17 +1016,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckNeedlessFuncMessage, - Func: checkNeedlessFunc, - AllowOffline: true, + Message: plocale.DMLCheckNeedlessFuncMessage, + Func: checkNeedlessFunc, }, { Rule: SourceRule{ - Name: DDLCheckDatabaseSuffix, - Desc: plocale.DDLCheckDatabaseSuffixDesc, - Annotation: plocale.DDLCheckDatabaseSuffixAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckDatabaseSuffix, + Desc: plocale.DDLCheckDatabaseSuffixDesc, + Annotation: plocale.DDLCheckDatabaseSuffixAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, //Value: "_DB", Params: []*SourceParam{ { @@ -1037,57 +1037,56 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckDatabaseSuffixMessage, - Func: checkDatabaseSuffix, - AllowOffline: true, + Message: plocale.DDLCheckDatabaseSuffixMessage, + Func: checkDatabaseSuffix, }, { Rule: SourceRule{ - Name: DDLCheckPKName, - Desc: plocale.DDLCheckPKNameDesc, - Annotation: plocale.DDLCheckPKNameAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckPKName, + Desc: plocale.DDLCheckPKNameDesc, + Annotation: plocale.DDLCheckPKNameAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckPKNameMessage, - Func: checkPKIndexName, - AllowOffline: true, + Message: plocale.DDLCheckPKNameMessage, + Func: checkPKIndexName, }, { Rule: SourceRule{ - Name: DDLCheckTransactionIsolationLevel, - Desc: plocale.DDLCheckTransactionIsolationLevelDesc, - Annotation: plocale.DDLCheckTransactionIsolationLevelAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckTransactionIsolationLevel, + Desc: plocale.DDLCheckTransactionIsolationLevelDesc, + Annotation: plocale.DDLCheckTransactionIsolationLevelAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckTransactionIsolationLevelMessage, - Func: checkTransactionIsolationLevel, - AllowOffline: true, + Message: plocale.DDLCheckTransactionIsolationLevelMessage, + Func: checkTransactionIsolationLevel, }, { Rule: SourceRule{ - Name: DMLCheckFuzzySearch, - Desc: plocale.DMLCheckFuzzySearchDesc, - Annotation: plocale.DMLCheckFuzzySearchAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckFuzzySearch, + Desc: plocale.DMLCheckFuzzySearchDesc, + Annotation: plocale.DMLCheckFuzzySearchAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckFuzzySearchMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckFuzzySearchMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ - Name: DDLCheckTablePartition, - Desc: plocale.DDLCheckTablePartitionDesc, - Annotation: plocale.DDLCheckTablePartitionAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckTablePartition, + Desc: plocale.DDLCheckTablePartitionDesc, + Annotation: plocale.DDLCheckTablePartitionAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckTablePartitionMessage, - AllowOffline: true, - Func: checkTablePartition, + Message: plocale.DDLCheckTablePartitionMessage, + Func: checkTablePartition, }, { Rule: SourceRule{ @@ -1096,7 +1095,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DMLCheckNumberOfJoinTablesAnnotation, Level: driverV2.RuleLevelNotice, //Value: "3", - Category: plocale.RuleTypeDMLConvention, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1106,33 +1106,32 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckNumberOfJoinTablesMessage, - AllowOffline: true, - Func: checkNumberOfJoinTables, + Message: plocale.DMLCheckNumberOfJoinTablesMessage, + Func: checkNumberOfJoinTables, }, { Rule: SourceRule{ - Name: DMLCheckIfAfterUnionDistinct, - Desc: plocale.DMLCheckIfAfterUnionDistinctDesc, - Annotation: plocale.DMLCheckIfAfterUnionDistinctAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckIfAfterUnionDistinct, + Desc: plocale.DMLCheckIfAfterUnionDistinctDesc, + Annotation: plocale.DMLCheckIfAfterUnionDistinctAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckIfAfterUnionDistinctMessage, - AllowOffline: true, - Func: checkIsAfterUnionDistinct, + Message: plocale.DMLCheckIfAfterUnionDistinctMessage, + Func: checkIsAfterUnionDistinct, }, { Rule: SourceRule{ - Name: DDLCheckIsExistLimitOffset, - Desc: plocale.DDLCheckIsExistLimitOffsetDesc, - Annotation: plocale.DDLCheckIsExistLimitOffsetAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDMLConvention, + Name: DDLCheckIsExistLimitOffset, + Desc: plocale.DDLCheckIsExistLimitOffsetDesc, + Annotation: plocale.DDLCheckIsExistLimitOffsetAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckIsExistLimitOffsetMessage, - AllowOffline: true, - Func: checkIsExistLimitOffset, + Message: plocale.DDLCheckIsExistLimitOffsetMessage, + Func: checkIsExistLimitOffset, }, { Rule: SourceRule{ @@ -1141,7 +1140,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DDLCheckIndexOptionAnnotation, Level: driverV2.RuleLevelNotice, //Value: "0.7", - Category: plocale.RuleTypeIndexOptimization, + Category: plocale.RuleTypeIndexOptimization, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1151,53 +1151,53 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckIndexOptionMessage, - AllowOffline: false, - Func: checkIndexOption, + Message: plocale.DDLCheckIndexOptionMessage, + Func: checkIndexOption, }, { Rule: SourceRule{ - Name: DDLCheckColumnEnumNotice, - Desc: plocale.DDLCheckColumnEnumNoticeDesc, - Annotation: plocale.DDLCheckColumnEnumNoticeAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnEnumNotice, + Desc: plocale.DDLCheckColumnEnumNoticeDesc, + Annotation: plocale.DDLCheckColumnEnumNoticeAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnEnumNoticeMessage, - AllowOffline: true, - Func: checkColumnEnumNotice, + Message: plocale.DDLCheckColumnEnumNoticeMessage, + Func: checkColumnEnumNotice, }, { Rule: SourceRule{ - Name: DDLCheckColumnSetNotice, - Desc: plocale.DDLCheckColumnSetNoticeDesc, - Annotation: plocale.DDLCheckColumnSetNoticeAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnSetNotice, + Desc: plocale.DDLCheckColumnSetNoticeDesc, + Annotation: plocale.DDLCheckColumnSetNoticeAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnSetNoticeMessage, - AllowOffline: true, - Func: checkColumnSetNotice, + Message: plocale.DDLCheckColumnSetNoticeMessage, + Func: checkColumnSetNotice, }, { Rule: SourceRule{ - Name: DDLCheckColumnBlobNotice, - Desc: plocale.DDLCheckColumnBlobNoticeDesc, - Annotation: plocale.DDLCheckColumnBlobNoticeAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnBlobNotice, + Desc: plocale.DDLCheckColumnBlobNoticeDesc, + Annotation: plocale.DDLCheckColumnBlobNoticeAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnBlobNoticeMessage, - AllowOffline: true, - Func: checkColumnBlobNotice, + Message: plocale.DDLCheckColumnBlobNoticeMessage, + Func: checkColumnBlobNotice, }, { Rule: SourceRule{ - Name: DMLCheckExplainAccessTypeAll, - Desc: plocale.DMLCheckExplainAccessTypeAllDesc, - Annotation: plocale.DMLCheckExplainAccessTypeAllAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainAccessTypeAll, + Desc: plocale.DMLCheckExplainAccessTypeAllDesc, + Annotation: plocale.DMLCheckExplainAccessTypeAllAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1207,93 +1207,92 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckExplainAccessTypeAllMessage, - AllowOffline: false, - Func: checkExplain, + Message: plocale.DMLCheckExplainAccessTypeAllMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DMLCheckExplainExtraUsingFilesort, - Desc: plocale.DMLCheckExplainExtraUsingFilesortDesc, - Annotation: plocale.DMLCheckExplainExtraUsingFilesortAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainExtraUsingFilesort, + Desc: plocale.DMLCheckExplainExtraUsingFilesortDesc, + Annotation: plocale.DMLCheckExplainExtraUsingFilesortAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - Message: plocale.DMLCheckExplainExtraUsingFilesortMessage, - AllowOffline: false, - Func: checkExplain, + Message: plocale.DMLCheckExplainExtraUsingFilesortMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DMLCheckExplainExtraUsingTemporary, - Desc: plocale.DMLCheckExplainExtraUsingTemporaryDesc, - Annotation: plocale.DMLCheckExplainExtraUsingTemporaryAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainExtraUsingTemporary, + Desc: plocale.DMLCheckExplainExtraUsingTemporaryDesc, + Annotation: plocale.DMLCheckExplainExtraUsingTemporaryAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - Message: plocale.DMLCheckExplainExtraUsingTemporaryMessage, - AllowOffline: false, - Func: checkExplain, + Message: plocale.DMLCheckExplainExtraUsingTemporaryMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DDLCheckCreateView, - Desc: plocale.DDLCheckCreateViewDesc, - Annotation: plocale.DDLCheckCreateViewAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckCreateView, + Desc: plocale.DDLCheckCreateViewDesc, + Annotation: plocale.DDLCheckCreateViewAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckCreateViewMessage, - AllowOffline: true, - Func: checkCreateView, + Message: plocale.DDLCheckCreateViewMessage, + Func: checkCreateView, }, { Rule: SourceRule{ - Name: DDLCheckCreateTrigger, - Desc: plocale.DDLCheckCreateTriggerDesc, - Annotation: plocale.DDLCheckCreateTriggerAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckCreateTrigger, + Desc: plocale.DDLCheckCreateTriggerDesc, + Annotation: plocale.DDLCheckCreateTriggerAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckCreateTriggerMessage, - AllowOffline: true, - Func: checkCreateTrigger, + Message: plocale.DDLCheckCreateTriggerMessage, + Func: checkCreateTrigger, }, { Rule: SourceRule{ - Name: DDLCheckCreateFunction, - Desc: plocale.DDLCheckCreateFunctionDesc, - Annotation: plocale.DDLCheckCreateFunctionAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckCreateFunction, + Desc: plocale.DDLCheckCreateFunctionDesc, + Annotation: plocale.DDLCheckCreateFunctionAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckCreateFunctionMessage, - AllowOffline: true, - Func: checkCreateFunction, + Message: plocale.DDLCheckCreateFunctionMessage, + Func: checkCreateFunction, }, { Rule: SourceRule{ - Name: DDLCheckCreateProcedure, - Desc: plocale.DDLCheckCreateProcedureDesc, - Annotation: plocale.DDLCheckCreateProcedureAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckCreateProcedure, + Desc: plocale.DDLCheckCreateProcedureDesc, + Annotation: plocale.DDLCheckCreateProcedureAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLCheckCreateProcedureMessage, - AllowOffline: true, - Func: checkCreateProcedure, + Message: plocale.DDLCheckCreateProcedureMessage, + Func: checkCreateProcedure, }, { Rule: SourceRule{ - Name: DDLDisableTypeTimestamp, - Desc: plocale.DDLDisableTypeTimestampDesc, - Annotation: plocale.DDLDisableTypeTimestampAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DDLDisableTypeTimestamp, + Desc: plocale.DDLDisableTypeTimestampDesc, + Annotation: plocale.DDLDisableTypeTimestampAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLDisableTypeTimestampMessage, - AllowOffline: true, - Func: disableUseTypeTimestampField, + Message: plocale.DDLDisableTypeTimestampMessage, + Func: disableUseTypeTimestampField, }, { Rule: SourceRule{ //select a as id, id , b as user from mysql.user; @@ -1514,11 +1513,12 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ //create table t(c1 int,c2 int,c3 int,c4 int,c5 int,c6 int); - Name: DDLCheckColumnQuantity, - Desc: plocale.DDLCheckColumnQuantityDesc, - Annotation: plocale.DDLCheckColumnQuantityAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnQuantity, + Desc: plocale.DDLCheckColumnQuantityDesc, + Annotation: plocale.DDLCheckColumnQuantityAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1528,9 +1528,8 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckColumnQuantityMessage, - Func: checkColumnQuantity, - AllowOffline: true, + Message: plocale.DDLCheckColumnQuantityMessage, + Func: checkColumnQuantity, }, { Rule: SourceRule{ //CREATE TABLE `tb2` ( `id` int(11) DEFAULT NULL, `col` char(10) CHARACTER SET utf8 DEFAULT NULL) @@ -1608,15 +1607,15 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DMLHintCountFuncWithCol, - Desc: plocale.DMLHintCountFuncWithColDesc, - Annotation: plocale.DMLHintCountFuncWithColAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLHintCountFuncWithCol, + Desc: plocale.DMLHintCountFuncWithColDesc, + Annotation: plocale.DMLHintCountFuncWithColAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLHintCountFuncWithColMessage, - Func: hintCountFuncWithCol, - AllowOffline: true, + Message: plocale.DMLHintCountFuncWithColMessage, + Func: hintCountFuncWithCol, }, { Rule: SourceRule{ @@ -1727,35 +1726,36 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ // rename table t1 to t2; - Name: DDLNotAllowRenaming, - Desc: plocale.DDLNotAllowRenamingDesc, - Annotation: plocale.DDLNotAllowRenamingAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLNotAllowRenaming, + Desc: plocale.DDLNotAllowRenamingDesc, + Annotation: plocale.DDLNotAllowRenamingAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLNotAllowRenamingMessage, - Func: ddlNotAllowRenaming, + Message: plocale.DDLNotAllowRenamingMessage, + Func: ddlNotAllowRenaming, }, { Rule: SourceRule{ - Name: DMLCheckExplainFullIndexScan, - Desc: plocale.DMLCheckExplainFullIndexScanDesc, - Annotation: plocale.DMLCheckExplainFullIndexScanAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainFullIndexScan, + Desc: plocale.DMLCheckExplainFullIndexScanDesc, + Annotation: plocale.DMLCheckExplainFullIndexScanAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckExplainFullIndexScanMessage, - Func: checkExplain, + Message: plocale.DMLCheckExplainFullIndexScanMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DMLCheckLimitOffsetNum, - Desc: plocale.DMLCheckLimitOffsetNumDesc, - Annotation: plocale.DMLCheckLimitOffsetNumAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckLimitOffsetNum, + Desc: plocale.DMLCheckLimitOffsetNumDesc, + Annotation: plocale.DMLCheckLimitOffsetNumAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1765,29 +1765,29 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DMLCheckLimitOffsetNumMessage, - AllowOffline: true, - Func: checkLimitOffsetNum, + Message: plocale.DMLCheckLimitOffsetNumMessage, + Func: checkLimitOffsetNum, }, { Rule: SourceRule{ - Name: DMLCheckUpdateOrDeleteHasWhere, - Desc: plocale.DMLCheckUpdateOrDeleteHasWhereDesc, - Annotation: plocale.DMLCheckUpdateOrDeleteHasWhereAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckUpdateOrDeleteHasWhere, + Desc: plocale.DMLCheckUpdateOrDeleteHasWhereDesc, + Annotation: plocale.DMLCheckUpdateOrDeleteHasWhereAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckUpdateOrDeleteHasWhereMessage, - AllowOffline: true, - Func: checkUpdateOrDeleteHasWhere, + Message: plocale.DMLCheckUpdateOrDeleteHasWhereMessage, + Func: checkUpdateOrDeleteHasWhere, }, { Rule: SourceRule{ - Name: DMLCheckSortColumnLength, - Desc: plocale.DMLCheckSortColumnLengthDesc, - Annotation: plocale.DMLCheckSortColumnLengthAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DMLCheckSortColumnLength, + Desc: plocale.DMLCheckSortColumnLengthDesc, + Annotation: plocale.DMLCheckSortColumnLengthAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1797,17 +1797,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckSortColumnLengthMessage, - Func: checkSortColumnLength, + Message: plocale.DMLCheckSortColumnLengthMessage, + Func: checkSortColumnLength, }, { Rule: SourceRule{ - Name: AllCheckPrepareStatementPlaceholders, - Desc: plocale.AllCheckPrepareStatementPlaceholdersDesc, - Annotation: plocale.AllCheckPrepareStatementPlaceholdersAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: AllCheckPrepareStatementPlaceholders, + Desc: plocale.AllCheckPrepareStatementPlaceholdersDesc, + Annotation: plocale.AllCheckPrepareStatementPlaceholdersAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1817,29 +1817,29 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: true, - Message: plocale.AllCheckPrepareStatementPlaceholdersMessage, - Func: checkPrepareStatementPlaceholders, + Message: plocale.AllCheckPrepareStatementPlaceholdersMessage, + Func: checkPrepareStatementPlaceholders, }, { Rule: SourceRule{ - Name: DMLCheckExplainExtraUsingIndexForSkipScan, - Desc: plocale.DMLCheckExplainExtraUsingIndexForSkipScanDesc, - Annotation: plocale.DMLCheckExplainExtraUsingIndexForSkipScanAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainExtraUsingIndexForSkipScan, + Desc: plocale.DMLCheckExplainExtraUsingIndexForSkipScanDesc, + Annotation: plocale.DMLCheckExplainExtraUsingIndexForSkipScanAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckExplainExtraUsingIndexForSkipScanMessage, - Func: checkExplain, + Message: plocale.DMLCheckExplainExtraUsingIndexForSkipScanMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DMLCheckAffectedRows, - Desc: plocale.DMLCheckAffectedRowsDesc, - Annotation: plocale.DMLCheckAffectedRowsAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckAffectedRows, + Desc: plocale.DMLCheckAffectedRowsDesc, + Annotation: plocale.DMLCheckAffectedRowsAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1849,77 +1849,77 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckAffectedRowsMessage, - Func: checkAffectedRows, + Message: plocale.DMLCheckAffectedRowsMessage, + Func: checkAffectedRows, }, { Rule: SourceRule{ - Name: DMLCheckSameTableJoinedMultipleTimes, - Desc: plocale.DMLCheckSameTableJoinedMultipleTimesDesc, - Annotation: plocale.DMLCheckSameTableJoinedMultipleTimesAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSameTableJoinedMultipleTimes, + Desc: plocale.DMLCheckSameTableJoinedMultipleTimesDesc, + Annotation: plocale.DMLCheckSameTableJoinedMultipleTimesAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckSameTableJoinedMultipleTimesMessage, - Func: checkSameTableJoinedMultipleTimes, + Message: plocale.DMLCheckSameTableJoinedMultipleTimesMessage, + Func: checkSameTableJoinedMultipleTimes, }, { Rule: SourceRule{ - Name: DMLCheckExplainUsingIndex, - Desc: plocale.DMLCheckExplainUsingIndexDesc, - Annotation: plocale.DMLCheckExplainUsingIndexAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckExplainUsingIndex, + Desc: plocale.DMLCheckExplainUsingIndexDesc, + Annotation: plocale.DMLCheckExplainUsingIndexAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckExplainUsingIndexMessage, - Func: checkExplain, + Message: plocale.DMLCheckExplainUsingIndexMessage, + Func: checkExplain, }, { Rule: SourceRule{ - Name: DMLCheckInsertSelect, - Desc: plocale.DMLCheckInsertSelectDesc, - Annotation: plocale.DMLCheckInsertSelectAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckInsertSelect, + Desc: plocale.DMLCheckInsertSelectDesc, + Annotation: plocale.DMLCheckInsertSelectAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DMLCheckInsertSelectMessage, - Func: checkInsertSelect, + Message: plocale.DMLCheckInsertSelectMessage, + Func: checkInsertSelect, }, { Rule: SourceRule{ - Name: DMLCheckAggregate, - Desc: plocale.DMLCheckAggregateDesc, - Annotation: plocale.DMLCheckAggregateAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckAggregate, + Desc: plocale.DMLCheckAggregateDesc, + Annotation: plocale.DMLCheckAggregateAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DMLCheckAggregateMessage, - Func: checkAggregateFunc, + Message: plocale.DMLCheckAggregateMessage, + Func: checkAggregateFunc, }, { Rule: SourceRule{ - Name: DDLCheckColumnNotNULL, - Desc: plocale.DDLCheckColumnNotNULLDesc, - Annotation: plocale.DDLCheckColumnNotNULLAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnNotNULL, + Desc: plocale.DDLCheckColumnNotNULLDesc, + Annotation: plocale.DDLCheckColumnNotNULLAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DDLCheckColumnNotNULLMessage, - Func: checkColumnNotNull, + Message: plocale.DDLCheckColumnNotNULLMessage, + Func: checkColumnNotNull, }, { Rule: SourceRule{ - Name: DMLCheckIndexSelectivity, - Desc: plocale.DMLCheckIndexSelectivityDesc, - Annotation: plocale.DMLCheckIndexSelectivityAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckIndexSelectivity, + Desc: plocale.DMLCheckIndexSelectivityDesc, + Annotation: plocale.DMLCheckIndexSelectivityAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1929,9 +1929,8 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckIndexSelectivityMessage, - Func: checkIndexSelectivity, + Message: plocale.DMLCheckIndexSelectivityMessage, + Func: checkIndexSelectivity, }, { // 该规则只适用于库表元数据扫描并且需要与停用上线审核模式规则一起使用 @@ -1955,35 +1954,36 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DDLCheckCompositeIndexDistinction, - Desc: plocale.DDLCheckCompositeIndexDistinctionDesc, - Annotation: plocale.DDLCheckCompositeIndexDistinctionAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckCompositeIndexDistinction, + Desc: plocale.DDLCheckCompositeIndexDistinctionDesc, + Annotation: plocale.DDLCheckCompositeIndexDistinctionAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DDLCheckCompositeIndexDistinctionMessage, - Func: checkCompositeIndexSelectivity, + Message: plocale.DDLCheckCompositeIndexDistinctionMessage, + Func: checkCompositeIndexSelectivity, }, { Rule: SourceRule{ - Name: DDLAvoidText, - Desc: plocale.DDLAvoidTextDesc, - Annotation: plocale.DDLAvoidTextAnnotation, - Level: driverV2.RuleLevelNotice, - Category: plocale.RuleTypeDDLConvention, + Name: DDLAvoidText, + Desc: plocale.DDLAvoidTextDesc, + Annotation: plocale.DDLAvoidTextAnnotation, + Level: driverV2.RuleLevelNotice, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLAvoidTextMessage, - Func: checkText, + Message: plocale.DDLAvoidTextMessage, + Func: checkText, }, { Rule: SourceRule{ - Name: DMLCheckSelectRows, - Desc: plocale.DMLCheckSelectRowsDesc, - Annotation: plocale.DMLCheckSelectRowsAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckSelectRows, + Desc: plocale.DMLCheckSelectRowsDesc, + Annotation: plocale.DMLCheckSelectRowsAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -1993,17 +1993,17 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckSelectRowsMessage, - Func: checkSelectRows, + Message: plocale.DMLCheckSelectRowsMessage, + Func: checkSelectRows, }, { Rule: SourceRule{ - Name: DMLCheckScanRows, - Desc: plocale.DMLCheckScanRowsDesc, - Annotation: plocale.DMLCheckScanRowsAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckScanRows, + Desc: plocale.DMLCheckScanRowsDesc, + Annotation: plocale.DMLCheckScanRowsAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -2013,77 +2013,77 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckScanRowsMessage, - Func: checkScanRows, + Message: plocale.DMLCheckScanRowsMessage, + Func: checkScanRows, }, { Rule: SourceRule{ - Name: DMLMustUseLeftMostPrefix, - Desc: plocale.DMLMustUseLeftMostPrefixDesc, - Annotation: plocale.DMLMustUseLeftMostPrefixAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLMustUseLeftMostPrefix, + Desc: plocale.DMLMustUseLeftMostPrefixDesc, + Annotation: plocale.DMLMustUseLeftMostPrefixAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLMustUseLeftMostPrefixMessage, - Func: mustMatchLeftMostPrefix, + Message: plocale.DMLMustUseLeftMostPrefixMessage, + Func: mustMatchLeftMostPrefix, }, { Rule: SourceRule{ - Name: DMLMustMatchLeftMostPrefix, - Desc: plocale.DMLMustMatchLeftMostPrefixDesc, - Annotation: plocale.DMLMustMatchLeftMostPrefixAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLMustMatchLeftMostPrefix, + Desc: plocale.DMLMustMatchLeftMostPrefixDesc, + Annotation: plocale.DMLMustMatchLeftMostPrefixAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLMustMatchLeftMostPrefixMessage, - Func: mustMatchLeftMostPrefix, + Message: plocale.DMLMustMatchLeftMostPrefixMessage, + Func: mustMatchLeftMostPrefix, }, { Rule: SourceRule{ - Name: DMLCheckJoinFieldUseIndex, - Desc: plocale.DMLCheckJoinFieldUseIndexDesc, - Annotation: plocale.DMLCheckJoinFieldUseIndexAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLCheckJoinFieldUseIndex, + Desc: plocale.DMLCheckJoinFieldUseIndexDesc, + Annotation: plocale.DMLCheckJoinFieldUseIndexAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckJoinFieldUseIndexMessage, - Func: checkJoinFieldUseIndex, + Message: plocale.DMLCheckJoinFieldUseIndexMessage, + Func: checkJoinFieldUseIndex, }, { Rule: SourceRule{ - Name: DMLCheckJoinFieldCharacterSetAndCollation, - Desc: plocale.DMLCheckJoinFieldCharacterSetAndCollationDesc, - Annotation: plocale.DMLCheckJoinFieldCharacterSetAndCollationAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLCheckJoinFieldCharacterSetAndCollation, + Desc: plocale.DMLCheckJoinFieldCharacterSetAndCollationDesc, + Annotation: plocale.DMLCheckJoinFieldCharacterSetAndCollationAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckJoinFieldCharacterSetAndCollationMessage, - Func: checkJoinFieldCharacterSetAndCollation, + Message: plocale.DMLCheckJoinFieldCharacterSetAndCollationMessage, + Func: checkJoinFieldCharacterSetAndCollation, }, { Rule: SourceRule{ - Name: DMLCheckMathComputationOrFuncOnIndex, - Desc: plocale.DMLCheckMathComputationOrFuncOnIndexDesc, - Annotation: plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLCheckMathComputationOrFuncOnIndex, + Desc: plocale.DMLCheckMathComputationOrFuncOnIndexDesc, + Annotation: plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckMathComputationOrFuncOnIndexMessage, - Func: checkMathComputationOrFuncOnIndex, + Message: plocale.DMLCheckMathComputationOrFuncOnIndexMessage, + Func: checkMathComputationOrFuncOnIndex, }, { Rule: SourceRule{ - Name: DMLSQLExplainLowestLevel, - Desc: plocale.DMLSQLExplainLowestLevelDesc, - Annotation: plocale.DMLSQLExplainLowestLevelAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDDLConvention, + Name: DMLSQLExplainLowestLevel, + Desc: plocale.DMLSQLExplainLowestLevelDesc, + Annotation: plocale.DMLSQLExplainLowestLevelAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -2093,65 +2093,65 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLSQLExplainLowestLevelMessage, - Func: checkSQLExplainLowestLevel, + Message: plocale.DMLSQLExplainLowestLevelMessage, + Func: checkSQLExplainLowestLevel, }, { Rule: SourceRule{ - Name: DDLAvoidFullText, - Desc: plocale.DDLAvoidFullTextDesc, - Annotation: plocale.DDLAvoidFullTextAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLAvoidFullText, + Desc: plocale.DDLAvoidFullTextDesc, + Annotation: plocale.DDLAvoidFullTextAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLAvoidFullTextMessage, - Func: avoidFullText, + Message: plocale.DDLAvoidFullTextMessage, + Func: avoidFullText, }, { Rule: SourceRule{ - Name: DDLAvoidGeometry, - Desc: plocale.DDLAvoidGeometryDesc, - Annotation: plocale.DDLAvoidGeometryAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLAvoidGeometry, + Desc: plocale.DDLAvoidGeometryDesc, + Annotation: plocale.DDLAvoidGeometryAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLAvoidGeometryMessage, - Func: avoidGeometry, + Message: plocale.DDLAvoidGeometryMessage, + Func: avoidGeometry, }, { Rule: SourceRule{ - Name: DMLAvoidWhereEqualNull, - Desc: plocale.DMLAvoidWhereEqualNullDesc, - Annotation: plocale.DMLAvoidWhereEqualNullAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLAvoidWhereEqualNull, + Desc: plocale.DMLAvoidWhereEqualNullDesc, + Annotation: plocale.DMLAvoidWhereEqualNullAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DMLAvoidWhereEqualNullMessage, - Func: avoidWhereEqualNull, + Message: plocale.DMLAvoidWhereEqualNullMessage, + Func: avoidWhereEqualNull, }, { Rule: SourceRule{ - Name: DDLAvoidEvent, - Desc: plocale.DDLAvoidEventDesc, - Annotation: plocale.DDLAvoidEventAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLAvoidEvent, + Desc: plocale.DDLAvoidEventDesc, + Annotation: plocale.DDLAvoidEventAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - AllowOffline: true, - Message: plocale.DDLAvoidEventMessage, - Func: avoidEvent, + Message: plocale.DDLAvoidEventMessage, + Func: avoidEvent, }, { Rule: SourceRule{ - Name: DDLCheckCharLength, - Desc: plocale.DDLCheckCharLengthDesc, - Annotation: plocale.DDLCheckCharLengthAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLCheckCharLength, + Desc: plocale.DDLCheckCharLengthDesc, + Annotation: plocale.DDLCheckCharLengthAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -2161,8 +2161,7 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DDLCheckCharLengthMessage, - Func: checkCharLength, + Message: plocale.DDLCheckCharLengthMessage, + Func: checkCharLength, }, } diff --git a/sqle/driver/mysql/rule/rule_list_trial.go b/sqle/driver/mysql/rule/rule_list_trial.go index e889e74b5..3ae2a4ce6 100644 --- a/sqle/driver/mysql/rule/rule_list_trial.go +++ b/sqle/driver/mysql/rule/rule_list_trial.go @@ -13,27 +13,27 @@ import ( var sourceRuleHandlers = []*SourceHandler{ { Rule: SourceRule{ - Name: DMLCheckFuzzySearch, - Desc: plocale.DMLCheckFuzzySearchDesc, - Annotation: plocale.DMLCheckFuzzySearchAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckFuzzySearch, + Desc: plocale.DMLCheckFuzzySearchDesc, + Annotation: plocale.DMLCheckFuzzySearchAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckFuzzySearchMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckFuzzySearchMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ - Name: DMLCheckJoinFieldType, - Desc: plocale.DMLCheckJoinFieldTypeDesc, - Annotation: plocale.DMLCheckJoinFieldTypeAnnotation, - Level: driverV2.RuleLevelWarn, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckJoinFieldType, + Desc: plocale.DMLCheckJoinFieldTypeDesc, + Annotation: plocale.DMLCheckJoinFieldTypeAnnotation, + Level: driverV2.RuleLevelWarn, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, }, - Message: plocale.DMLCheckJoinFieldTypeMessage, - AllowOffline: false, - Func: checkJoinFieldType, + Message: plocale.DMLCheckJoinFieldTypeMessage, + Func: checkJoinFieldType, }, { Rule: SourceRule{ @@ -48,23 +48,24 @@ var sourceRuleHandlers = []*SourceHandler{ }, { Rule: SourceRule{ - Name: DDLCheckColumnTimestampWithoutDefault, - Desc: plocale.DDLCheckColumnTimestampWithoutDefaultDesc, - Annotation: plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnTimestampWithoutDefault, + Desc: plocale.DDLCheckColumnTimestampWithoutDefaultDesc, + Annotation: plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnTimestampWithoutDefaultMessage, - AllowOffline: true, - Func: checkColumnTimestampWithoutDefault, + Message: plocale.DDLCheckColumnTimestampWithoutDefaultMessage, + Func: checkColumnTimestampWithoutDefault, }, { Rule: SourceRule{ - Name: DDLCheckIndexPrefix, - Desc: plocale.DDLCheckIndexPrefixDesc, - Annotation: plocale.DDLCheckIndexPrefixAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckIndexPrefix, + Desc: plocale.DDLCheckIndexPrefixDesc, + Annotation: plocale.DDLCheckIndexPrefixAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -74,20 +75,19 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - Message: plocale.DDLCheckIndexPrefixMessage, - AllowOffline: true, - Func: checkIndexPrefix, + Message: plocale.DDLCheckIndexPrefixMessage, + Func: checkIndexPrefix, }, { Rule: SourceRule{ - Name: DDLCheckPKNotExist, - Desc: plocale.DDLCheckPKNotExistDesc, - Annotation: plocale.DDLCheckPKNotExistAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKNotExist, + Desc: plocale.DDLCheckPKNotExistDesc, + Annotation: plocale.DDLCheckPKNotExistAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKNotExistMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, @@ -109,7 +109,8 @@ var sourceRuleHandlers = []*SourceHandler{ Annotation: plocale.DDLCheckIndexCountAnnotation, Level: driverV2.RuleLevelNotice, //Value: "5", - Category: plocale.RuleTypeIndexingConvention, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -120,68 +121,68 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, Message: plocale.DDLCheckIndexCountMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}}, Func: checkIndex, }, { Rule: SourceRule{ - Name: DDLCheckPKWithoutAutoIncrement, - Desc: plocale.DDLCheckPKWithoutAutoIncrementDesc, - Annotation: plocale.DDLCheckPKWithoutAutoIncrementAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexingConvention, + Name: DDLCheckPKWithoutAutoIncrement, + Desc: plocale.DDLCheckPKWithoutAutoIncrementDesc, + Annotation: plocale.DDLCheckPKWithoutAutoIncrementAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexingConvention, + AllowOffline: true, }, Message: plocale.DDLCheckPKWithoutAutoIncrementMessage, - AllowOffline: true, NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}}, NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}}, Func: checkPrimaryKey, }, { Rule: SourceRule{ - Name: DDLCheckObjectNameUsingKeyword, - Desc: plocale.DDLCheckObjectNameUsingKeywordDesc, - Annotation: plocale.DDLCheckObjectNameUsingKeywordAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeNamingConvention, + Name: DDLCheckObjectNameUsingKeyword, + Desc: plocale.DDLCheckObjectNameUsingKeywordDesc, + Annotation: plocale.DDLCheckObjectNameUsingKeywordAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeNamingConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckObjectNameUsingKeywordMessage, - AllowOffline: true, - Func: checkNewObjectName, + Message: plocale.DDLCheckObjectNameUsingKeywordMessage, + Func: checkNewObjectName, }, { Rule: SourceRule{ - Name: DMLCheckMathComputationOrFuncOnIndex, - Desc: plocale.DMLCheckMathComputationOrFuncOnIndexDesc, - Annotation: plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeIndexInvalidation, + Name: DMLCheckMathComputationOrFuncOnIndex, + Desc: plocale.DMLCheckMathComputationOrFuncOnIndexDesc, + Annotation: plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeIndexInvalidation, + AllowOffline: false, }, - AllowOffline: false, - Message: plocale.DMLCheckMathComputationOrFuncOnIndexMessage, - Func: checkMathComputationOrFuncOnIndex, + Message: plocale.DMLCheckMathComputationOrFuncOnIndexMessage, + Func: checkMathComputationOrFuncOnIndex, }, { Rule: SourceRule{ - Name: DDLDisableDropStatement, - Desc: plocale.DDLDisableDropStatementDesc, - Annotation: plocale.DDLDisableDropStatementAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeUsageSuggestion, + Name: DDLDisableDropStatement, + Desc: plocale.DDLDisableDropStatementDesc, + Annotation: plocale.DDLDisableDropStatementAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeUsageSuggestion, + AllowOffline: true, }, - Message: plocale.DDLDisableDropStatementMessage, - AllowOffline: true, - Func: disableDropStmt, + Message: plocale.DDLDisableDropStatementMessage, + Func: disableDropStmt, }, { Rule: SourceRule{ - Name: DMLCheckScanRows, - Desc: plocale.DMLCheckScanRowsDesc, - Annotation: plocale.DMLCheckScanRowsAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckScanRows, + Desc: plocale.DMLCheckScanRowsDesc, + Annotation: plocale.DMLCheckScanRowsAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: false, Params: []*SourceParam{ { Key: DefaultSingleParamKeyName, @@ -191,32 +192,31 @@ var sourceRuleHandlers = []*SourceHandler{ }, }, }, - AllowOffline: false, - Message: plocale.DMLCheckScanRowsMessage, - Func: checkScanRows, + Message: plocale.DMLCheckScanRowsMessage, + Func: checkScanRows, }, { Rule: SourceRule{ - Name: DMLCheckWhereIsInvalid, - Desc: plocale.DMLCheckWhereIsInvalidDesc, - Annotation: plocale.DMLCheckWhereIsInvalidAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDMLConvention, + Name: DMLCheckWhereIsInvalid, + Desc: plocale.DMLCheckWhereIsInvalidDesc, + Annotation: plocale.DMLCheckWhereIsInvalidAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDMLConvention, + AllowOffline: true, }, - Message: plocale.DMLCheckWhereIsInvalidMessage, - AllowOffline: true, - Func: checkSelectWhere, + Message: plocale.DMLCheckWhereIsInvalidMessage, + Func: checkSelectWhere, }, { Rule: SourceRule{ - Name: DDLCheckColumnWithoutDefault, - Desc: plocale.DDLCheckColumnWithoutDefaultDesc, - Annotation: plocale.DDLCheckColumnWithoutDefaultAnnotation, - Level: driverV2.RuleLevelError, - Category: plocale.RuleTypeDDLConvention, + Name: DDLCheckColumnWithoutDefault, + Desc: plocale.DDLCheckColumnWithoutDefaultDesc, + Annotation: plocale.DDLCheckColumnWithoutDefaultAnnotation, + Level: driverV2.RuleLevelError, + Category: plocale.RuleTypeDDLConvention, + AllowOffline: true, }, - Message: plocale.DDLCheckColumnWithoutDefaultMessage, - AllowOffline: true, - Func: checkColumnWithoutDefault, + Message: plocale.DDLCheckColumnWithoutDefaultMessage, + Func: checkColumnWithoutDefault, }, } diff --git a/sqle/driver/v2/driver_grpc_server.go b/sqle/driver/v2/driver_grpc_server.go index f2b4ff879..20523750a 100644 --- a/sqle/driver/v2/driver_grpc_server.go +++ b/sqle/driver/v2/driver_grpc_server.go @@ -36,8 +36,10 @@ type DSN struct { type Rule struct { Name string Level RuleLevel + Category string Params params.Params I18nRuleInfo I18nRuleInfo + AllowOffline bool } type I18nRuleInfo map[language.Tag]*RuleInfo diff --git a/sqle/locale/active.en.toml b/sqle/locale/active.en.toml index cfc70f667..3b559b8b0 100644 --- a/sqle/locale/active.en.toml +++ b/sqle/locale/active.en.toml @@ -72,21 +72,11 @@ ApSQLStatement = "SQL statement" ApSchema = "Schema" AuditRecordTagFull = "Full" AuditRecordTagIncrement = "Increment" -ConfigFeishuTestContent = "This is a test approval, used to test whether the SQLE Feishu approval function is normal." ConfigCodingTest = "This is a test message, used to test whether the function of SQLE push to Coding platform is normal." +ConfigFeishuTestContent = "This is a test approval, used to test whether the SQLE Feishu approval function is normal." ConfigTestAudit = "Test approval" DefaultRuleTemplatesDesc = "Default rule template" DefaultTemplatesDesc = "%s default template" -RuleTemplateName = "Rule template name" -RuleTemplateDesc = "Rule template description" -RuleTemplateInstType = "instance type" -RuleTemplateRuleName = "rule name" -RuleTemplateRuleDesc = "desc" -RuleTemplateRuleAnnotation = "annotation" -RuleTemplateRuleLevel = "level" -RuleTemplateRuleCategory = "category" -RuleTemplateRuleParam = "param" -RuleTemplateRuleErr = "error" EnumSlowLogFileSource = "Collected from slow.log file, need to adapt scanner" EnumSlowLogTableSource = "Collected from mysql.slow_log table" ExportCreateTime = "Created time" @@ -254,6 +244,16 @@ ParamSQLMinSecond = "SQL Minimum Execution Time (Second)" ParamSlowLogCollectInput = "Collect Source" ParamTopN = "Top N" PipelineCmdUsage = "#Usage#\n1. Ensure the user running this command has execution permission for scannerd.\n2. Execute the start command in the directory where the scannerd file is located.\n#Start Command#\n" +RuleTemplateDesc = "Rule template description" +RuleTemplateInstType = "instance type" +RuleTemplateName = "Rule template name" +RuleTemplateRuleAnnotation = "annotation" +RuleTemplateRuleCategory = "category" +RuleTemplateRuleDesc = "desc" +RuleTemplateRuleErr = "error" +RuleTemplateRuleLevel = "level" +RuleTemplateRuleName = "rule name" +RuleTemplateRuleParam = "param" SMExportAuditResult = "Audit Result" SMExportDataSource = "DB Instance" SMExportEndpoint = "Endpoint Info" @@ -282,9 +282,9 @@ SQLManageSourceAuditPlan = "Intelligent scan" SQLManageSourceSqlAuditRecord = "SQL audit" SQLManageStatusIgnored = "Ignored" SQLManageStatusManualAudited = "Manually audited" +SQLManageStatusSent = "Sent" SQLManageStatusSolved = "Solved" SQLManageStatusUnhandled = "Unhandled" -SQLManageStatusSent = "Sent" SqlVersionExecFailedReason = "workflow %s execution status is not finished and stop execution" SqlVersionInvalidStatusReason = "Execution failed: A workflow with status %v exists at the stage of the SQL version bound to this workflow, and its SQL version ID is %v" SqlVersionReleaseFailedReason = "workflow %s release fail and stop release" diff --git a/sqle/locale/active.zh.toml b/sqle/locale/active.zh.toml index 8416cc89d..c01fbd8c8 100644 --- a/sqle/locale/active.zh.toml +++ b/sqle/locale/active.zh.toml @@ -72,21 +72,11 @@ ApSQLStatement = "SQL语句" ApSchema = "schema" AuditRecordTagFull = "全量" AuditRecordTagIncrement = "增量" -ConfigFeishuTestContent = "这是一条测试审批,用来测试SQLE飞书审批功能是否正常" ConfigCodingTest = "这是一条测试信息,用来测试SQLE推送事项到Coding平台功能是否正常" +ConfigFeishuTestContent = "这是一条测试审批,用来测试SQLE飞书审批功能是否正常" ConfigTestAudit = "测试审批" DefaultRuleTemplatesDesc = "默认规则模板" DefaultTemplatesDesc = "%s 默认模板" -RuleTemplateName = "规则模板名" -RuleTemplateDesc = "规则模板描述" -RuleTemplateInstType = "数据源类型" -RuleTemplateRuleName = "规则名" -RuleTemplateRuleDesc = "规则描述" -RuleTemplateRuleAnnotation = "规则注解" -RuleTemplateRuleLevel = "规则等级" -RuleTemplateRuleCategory = "规则分类" -RuleTemplateRuleParam = "规则参数" -RuleTemplateRuleErr = "问题" EnumSlowLogFileSource = "从slow.log 文件采集,需要适配scanner" EnumSlowLogTableSource = "从mysql.slow_log 表采集" ExportCreateTime = "创建时间" @@ -254,6 +244,16 @@ ParamSQLMinSecond = "SQL 最小执行时间(秒)" ParamSlowLogCollectInput = "采集来源" ParamTopN = "Top N" PipelineCmdUsage = "#使用方法#\n1. 确保运行该命令的用户具有scannerd的执行权限。\n2. 在scannerd文件所在目录执行启动命令。\n#启动命令#\n" +RuleTemplateDesc = "规则模板描述" +RuleTemplateInstType = "数据源类型" +RuleTemplateName = "规则模板名" +RuleTemplateRuleAnnotation = "规则注解" +RuleTemplateRuleCategory = "规则分类" +RuleTemplateRuleDesc = "规则描述" +RuleTemplateRuleErr = "问题" +RuleTemplateRuleLevel = "规则等级" +RuleTemplateRuleName = "规则名" +RuleTemplateRuleParam = "规则参数" SMExportAuditResult = "审核结果" SMExportDataSource = "数据源" SMExportEndpoint = "端点信息" @@ -282,9 +282,9 @@ SQLManageSourceAuditPlan = "智能扫描" SQLManageSourceSqlAuditRecord = "SQL审核" SQLManageStatusIgnored = "已忽略" SQLManageStatusManualAudited = "已人工审核" +SQLManageStatusSent = "已推送到其他平台" SQLManageStatusSolved = "已解决" SQLManageStatusUnhandled = "未处理" -SQLManageStatusSent = "已推送到其他平台" SqlVersionExecFailedReason = "工单:%s 上线失败并停止继续上线" SqlVersionInvalidStatusReason = "执行失败:在该工单绑定的SQL版本的阶段上,存在状态为%v的工单,其SQL版本id为%v" SqlVersionReleaseFailedReason = "工单:%s 发布失败并停止继续发布" diff --git a/sqle/model/audit_rule_category.go b/sqle/model/audit_rule_category.go new file mode 100644 index 000000000..8bf323ccd --- /dev/null +++ b/sqle/model/audit_rule_category.go @@ -0,0 +1,101 @@ +package model + +import ( + "github.com/actiontech/sqle/sqle/errors" + "gorm.io/gorm" + "time" +) + +type AuditRuleCategory struct { + ID uint `json:"id" gorm:"primary_key" example:"1"` + CreatedAt time.Time `json:"created_at" gorm:"default:current_timestamp(3)" example:"2018-10-21T16:40:23+08:00"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:current_timestamp(3) on update current_timestamp(3)" example:"2018-10-21T16:40:23+08:00"` + Category string `json:"category" gorm:"not null;type:varchar(255)"` + Tag string `json:"tag" gorm:"not null;type:varchar(255)"` +} + +func (s *Storage) GetAllCategories() ([]*AuditRuleCategory, error) { + var auditRuleCategories []*AuditRuleCategory + err := s.db.Find(&auditRuleCategories).Error + if err != nil { + return nil, err + } + return auditRuleCategories, nil +} + +func (s *Storage) GetAuditRuleCategoryByCategory(category string) ([]*AuditRuleCategory, error) { + var auditRuleCategory []*AuditRuleCategory + err := s.db.Model(AuditRuleCategory{}).Where("category = ?", category).Find(&auditRuleCategory).Error + if err == gorm.ErrRecordNotFound { + return auditRuleCategory, err + } + return auditRuleCategory, errors.New(errors.ConnectStorageError, err) +} + +func (s *Storage) GetAuditRuleCategoryByTagIn(tag []string) ([]*AuditRuleCategory, error) { + var auditRuleCategory []*AuditRuleCategory + err := s.db.Model(AuditRuleCategory{}).Where("tag in (?)", tag).Find(&auditRuleCategory).Error + if err == gorm.ErrRecordNotFound { + return auditRuleCategory, err + } + return auditRuleCategory, errors.New(errors.ConnectStorageError, err) +} + +type RuleCategoryStatistic struct { + Category string `json:"category" enums:"audit_accuracy,audit_purpose,operand,sql"` + Tag string `json:"tag"` + Count int `json:"count"` +} + +func (s *Storage) GetAuditRuleCategoryStatistics() ([]*RuleCategoryStatistic, error) { + var auditRuleCategoryStatistics []*RuleCategoryStatistic + err := s.db.Model(AuditRuleCategory{}). + Joins("left join audit_rule_category_rels on audit_rule_categories.id = audit_rule_category_rels.category_id"). + Joins("left join rules on audit_rule_category_rels.rule_name = rules.name and audit_rule_category_rels.rule_db_type = rules.db_type"). + Select("audit_rule_categories.category, audit_rule_categories.tag, count(audit_rule_categories.tag) as count"). + Group("category, tag"). + Scan(&auditRuleCategoryStatistics).Error + return auditRuleCategoryStatistics, err +} + +func (s *Storage) GetCustomRuleCategoryStatistics() ([]*RuleCategoryStatistic, error) { + var auditRuleCategoryStatistics []*RuleCategoryStatistic + err := s.db.Model(AuditRuleCategory{}). + Joins("left join custom_rule_category_rels on audit_rule_categories.id = custom_rule_category_rels.category_id"). + Joins("left join custom_rules on custom_rule_category_rels.custom_rule_id = custom_rules.rule_id"). + Select("audit_rule_categories.category, audit_rule_categories.tag, count(audit_rule_categories.tag) as count"). + Group("category, tag"). + Scan(&auditRuleCategoryStatistics).Error + return auditRuleCategoryStatistics, err +} + +type AuditRuleCategoryRel struct { + CategoryId uint `json:"category_id" gorm:"not null;type:bigint unsigned;primary_key;autoIncrement:false"` + RuleName string `json:"rule_name" gorm:"not null;type:varchar(255);primary_key"` + RuleDBType string `json:"db_type" gorm:"not null;column:rule_db_type;type:varchar(255);primary_key"` + Rule *Rule `json:"-" gorm:"foreignkey:Name,DBType;references:RuleName,RuleDBType"` +} + +func (s *Storage) FirstAuditRuleCategoryRelByRule(ruleName string, ruleDbType string) (*AuditRuleCategoryRel, bool, error) { + categoryRel := &AuditRuleCategoryRel{} + err := s.db.Where("rule_name = ? AND rule_db_type = ?", ruleName, ruleDbType).First(categoryRel).Error + if err == gorm.ErrRecordNotFound { + return categoryRel, false, nil + } + return categoryRel, true, errors.New(errors.ConnectStorageError, err) +} + +type CustomRuleCategoryRel struct { + CategoryId uint `json:"category_id" gorm:"not null;type:bigint unsigned;primary_key"` + CustomRuleId string `json:"custom_rule_id" gorm:"not null;type:varchar(255);primary_key"` + CustomRule *CustomRule `json:"-" gorm:"foreignkey:RuleId;references:CustomRuleId"` +} + +func (s *Storage) FirstCustomRuleCategoryRelByCustomRuleId(customRuleId string) (*CustomRuleCategoryRel, bool, error) { + categoryRel := &CustomRuleCategoryRel{} + err := s.db.Where("custom_rule_id = ?", customRuleId).First(categoryRel).Error + if err == gorm.ErrRecordNotFound { + return categoryRel, false, nil + } + return categoryRel, true, errors.New(errors.ConnectStorageError, err) +} diff --git a/sqle/model/rule.go b/sqle/model/rule.go index d0c885f74..dc46f006b 100644 --- a/sqle/model/rule.go +++ b/sqle/model/rule.go @@ -36,6 +36,7 @@ func GenerateRuleByDriverRule(dr *driverV2.Rule, dbType string) *Rule { I18nContent: make(i18nPkg.I18nStr, len(dr.I18nRuleInfo)), }, I18nRuleInfo: make(driverV2.I18nRuleInfo, len(dr.I18nRuleInfo)), + AllowOffline: dr.AllowOffline, } for lang, v := range dr.I18nRuleInfo { r.Knowledge.I18nContent[lang] = v.Knowledge.Content @@ -92,6 +93,8 @@ type Rule struct { HasAuditPower bool `json:"has_audit_power" gorm:"type:bool" example:"true"` HasRewritePower bool `json:"has_rewrite_power" gorm:"type:bool" example:"true"` I18nRuleInfo driverV2.I18nRuleInfo `json:"i18n_rule_info" gorm:"type:json"` + Categories []*AuditRuleCategory `gorm:"many2many:audit_rule_category_rels;joinForeignKey:RuleName,RuleDBType;joinReferences:CategoryId"` + AllowOffline bool `json:"allow_offline" gorm:"-"` } func (r Rule) TableName() string { @@ -210,7 +213,7 @@ func (s *Storage) GetRuleTemplatesByInstanceNameAndProjectId(name string, projec } func (s *Storage) GetRulesFromRuleTemplateByName(projectIds []string, name string) ([]*Rule, []*CustomRule, error) { - tpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds(projectIds, name, "") + tpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds(projectIds, name, "", "") if !exist { return nil, nil, errors.New(errors.DataNotExist, err) } @@ -245,7 +248,7 @@ func (s *Storage) GetAllRulesByInstance(instance *Instance) ([]*Rule, []*CustomR } func (s *Storage) GetOptimizationRulesFromRuleTemplateByName(projectIds []string, name string) ([]*Rule, error) { - tpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds(projectIds, name, "") + tpl, exist, err := s.GetRuleTemplateDetailByNameAndProjectIds(projectIds, name, "", "") if !exist { return nil, errors.New(errors.DataNotExist, err) } @@ -302,7 +305,7 @@ func (s *Storage) IsRuleTemplateExistFromAnyProject(projectId ProjectUID, name s return count > 0, errors.ConnectStorageErrWrapper(err) } -func (s *Storage) GetRuleTemplateDetailByNameAndProjectIds(projectIds []string, name string, fuzzy_keyword_rule string) (*RuleTemplate, bool, error) { +func (s *Storage) GetRuleTemplateDetailByNameAndProjectIds(projectIds []string, name string, fuzzy_keyword_rule string, tags string) (*RuleTemplate, bool, error) { dbOrder := func(db *gorm.DB) *gorm.DB { return db.Order("rule_template_rule.rule_name ASC") } @@ -314,16 +317,60 @@ func (s *Storage) GetRuleTemplateDetailByNameAndProjectIds(projectIds []string, return db.Where("`i18n_rule_info` like ?", fmt.Sprintf("%%%s%%", fuzzy_keyword_rule)) } t := &RuleTemplate{Name: name} - err := s.db.Preload("RuleList", dbOrder).Preload("RuleList.Rule", fuzzy_condition).Preload("CustomRuleList.CustomRule", fuzzy_condition). + err := s.db.Preload("RuleList", dbOrder).Preload("RuleList.Rule", fuzzy_condition).Preload("RuleList.Rule.Categories"). + Preload("CustomRuleList.CustomRule", fuzzy_condition).Preload("CustomRuleList.CustomRule.Categories"). Where(t). Where("project_id IN (?)", projectIds). First(t).Error if err == gorm.ErrRecordNotFound { return t, false, nil } + t.RuleList = filterRulesByTag(t.RuleList, tags) + t.CustomRuleList = filterCustomRulesByTag(t.CustomRuleList, tags) return t, true, errors.New(errors.ConnectStorageError, err) } +func filterRulesByTag(ruleTemplateRules []RuleTemplateRule, tags string) []RuleTemplateRule { + if tags == "" { + return ruleTemplateRules + } + var filteredRuleResult []RuleTemplateRule + for _, ruleTemplateRule := range ruleTemplateRules { + if templateRuleByTagsCondition(ruleTemplateRule.Rule.Categories, tags) { + filteredRuleResult = append(filteredRuleResult, ruleTemplateRule) + } + } + return filteredRuleResult +} + +func filterCustomRulesByTag(ruleTemplateRules []RuleTemplateCustomRule, tags string) []RuleTemplateCustomRule { + if tags == "" { + return ruleTemplateRules + } + var filteredRuleResult []RuleTemplateCustomRule + for _, ruleTemplateRule := range ruleTemplateRules { + if templateRuleByTagsCondition(ruleTemplateRule.CustomRule.Categories, tags) { + filteredRuleResult = append(filteredRuleResult, ruleTemplateRule) + } + } + return filteredRuleResult +} + +func templateRuleByTagsCondition(ruleCategories []*AuditRuleCategory, tags string) bool { + tagSlice := strings.Split(tags, ",") + tagSliceLen := len(tagSlice) + tagMatchCount := 0 + for _, tag := range tagSlice { + for _, ruleCategory := range ruleCategories { + if ruleCategory.Tag == tag { + tagMatchCount++ + break + } + } + } + return tagSliceLen == tagMatchCount +} + func (s *Storage) UpdateRuleTemplateRules(tpl *RuleTemplate, rules ...RuleTemplateRule) error { if err := s.db.Where(&RuleTemplateRule{RuleTemplateId: tpl.ID}).Delete(&RuleTemplateRule{}).Error; err != nil { return errors.New(errors.ConnectStorageError, err) @@ -535,20 +582,21 @@ type CustomRule struct { Model RuleId string `json:"rule_id" gorm:"index:unique; not null; type:varchar(255)"` - Desc string `json:"desc" gorm:"not null; type:varchar(255)"` - Annotation string `json:"annotation" gorm:"type:varchar(1024)"` - DBType string `json:"db_type" gorm:"not null; default:\"mysql\"; type:varchar(255)"` - Level string `json:"level" example:"error" gorm:"type:varchar(255)"` // notice, warn, error - Typ string `json:"type" gorm:"column:type; not null; type:varchar(255)"` - RuleScript string `json:"rule_script" gorm:"type:text"` - ScriptType string `json:"script_type" gorm:"not null; default:\"regular\"; type:varchar(255)"` - KnowledgeId uint `json:"knowledge_id"` - Knowledge *RuleKnowledge `json:"knowledge" gorm:"foreignkey:KnowledgeId"` + Desc string `json:"desc" gorm:"not null; type:varchar(255)"` + Annotation string `json:"annotation" gorm:"type:varchar(1024)"` + DBType string `json:"db_type" gorm:"not null; default:\"mysql\"; type:varchar(255)"` + Level string `json:"level" example:"error" gorm:"type:varchar(255)"` // notice, warn, error + Typ string `json:"type" gorm:"column:type; not null; type:varchar(255)"` + RuleScript string `json:"rule_script" gorm:"type:text"` + ScriptType string `json:"script_type" gorm:"not null; default:\"regular\"; type:varchar(255)"` + KnowledgeId uint `json:"knowledge_id"` + Knowledge *RuleKnowledge `json:"knowledge" gorm:"foreignkey:KnowledgeId"` + Categories []*AuditRuleCategory `json:"categories" gorm:"many2many:custom_rule_category_rels;foreignKey:RuleId;joinForeignKey:CustomRuleId;joinReferences:CategoryId"` } func (s *Storage) GetCustomRuleByRuleId(ruleId string) (*CustomRule, bool, error) { rule := &CustomRule{} - err := s.db.Where("rule_id = ?", ruleId).First(rule).Error + err := s.db.Preload("Categories").Where("rule_id = ?", ruleId).First(rule).Error if err == gorm.ErrRecordNotFound { return rule, false, nil } @@ -571,7 +619,7 @@ func (s *Storage) GetCustomRulesByDBTypeAndFuzzyDesc(queryFields, filterDbType, func (s *Storage) GetCustomRules(queryFields string) ([]*CustomRule, error) { rules := []*CustomRule{} - err := s.db.Select(queryFields).Find(&rules).Error + err := s.db.Preload("Categories").Select(queryFields).Find(&rules).Error return rules, errors.New(errors.ConnectStorageError, err) } @@ -589,6 +637,25 @@ func (s *Storage) UpdateCustomRuleByRuleId(ruleId string, attrs interface{}) err return errors.New(errors.ConnectStorageError, err) } +func (s *Storage) UpdateCustomRuleCategoriesByRuleId(ruleId string, tags []string) error { + err := s.db.Where(&CustomRuleCategoryRel{CustomRuleId: ruleId}).Delete(&CustomRuleCategoryRel{}).Error + if err != nil { + return err + } + var auditRuleCategory []*AuditRuleCategory + err = s.db.Model(AuditRuleCategory{}).Where("tag in (?)", tags).Find(&auditRuleCategory).Error + if err != nil { + return err + } + for _, category := range auditRuleCategory { + err = s.db.Save(CustomRuleCategoryRel{CategoryId: category.ID, CustomRuleId: ruleId}).Error + } + if err != nil { + return err + } + return nil +} + func (s *Storage) GetCustomRuleByDBTypeAndScriptType(DBType, ScriptType string) ([]CustomRule, bool, error) { rules := []CustomRule{} result := s.db.Where("db_type = ? and script_type = ?", DBType, ScriptType).Find(&rules) diff --git a/sqle/model/rule_list.go b/sqle/model/rule_list.go index 01b01b232..0e4ab7e8c 100644 --- a/sqle/model/rule_list.go +++ b/sqle/model/rule_list.go @@ -48,7 +48,7 @@ func (s *Storage) GetRuleTemplatesByReq(data map[string]interface{}) ( func (s *Storage) GetRulesByReq(data map[string]interface{}) ( result []*Rule, err error) { - db := s.db + db := s.db.Preload("Categories") if data["filter_global_rule_template_name"] != "" { db = db.Joins("LEFT JOIN rule_template_rule ON rules.name = rule_template_rule.rule_name AND rules.db_type = rule_template_rule.db_type"). Joins("LEFT JOIN rule_templates ON rule_template_rule.rule_template_id = rule_templates.id"). @@ -67,13 +67,21 @@ func (s *Storage) GetRulesByReq(data map[string]interface{}) ( // todo i18n use json syntax to query? db = db.Where("rules.`i18n_rule_info` like ?", fmt.Sprintf("%%%s%%", data["fuzzy_keyword_rule"])) } + if data["tags"] != "" { + tags := strings.Split(data["tags"].(string), ",") + db = db.Joins("LEFT JOIN audit_rule_category_rels on rules.name = audit_rule_category_rels.rule_name AND audit_rule_category_rels.rule_db_type = rules.db_type"). + Joins("LEFT JOIN audit_rule_categories on audit_rule_category_rels.category_id = audit_rule_categories.id"). + Where("audit_rule_categories.tag in (?)", tags). + Group("rules.name, rules.db_type"). + Having("COUNT(DISTINCT audit_rule_categories.id) = ?", len(tags)) + } err = db.Find(&result).Error return result, err } func (s *Storage) GetCustomRulesByReq(data map[string]interface{}) ( result []*CustomRule, err error) { - db := s.db + db := s.db.Preload("Categories") if data["filter_global_rule_template_name"] != "" { db = db.Joins("LEFT JOIN rule_template_custom_rules ON custom_rules.rule_id = rule_template_custom_rules.rule_id"). Joins("LEFT JOIN rule_templates ON rule_template_custom_rules.rule_template_id = rule_templates.id"). @@ -92,6 +100,14 @@ func (s *Storage) GetCustomRulesByReq(data map[string]interface{}) ( if data["fuzzy_keyword_rule"] != "" { db = db.Where("custom_rules.`desc` like ? OR custom_rules.annotation like ?", fmt.Sprintf("%%%s%%", data["fuzzy_keyword_rule"]), fmt.Sprintf("%%%s%%", data["fuzzy_keyword_rule"])) } + if data["tags"] != "" { + tags := strings.Split(data["tags"].(string), ",") + db = db.Joins("LEFT JOIN custom_rule_category_rels on custom_rule_category_rels.custom_rule_id = custom_rules.rule_id"). + Joins("LEFT JOIN audit_rule_categories on custom_rule_category_rels.category_id = audit_rule_categories.id"). + Where("audit_rule_categories.tag in (?)", tags). + Group("custom_rules.id"). + Having("COUNT(DISTINCT audit_rule_categories.id) = ?", len(tags)) + } err = db.Find(&result).Error return result, err } diff --git a/sqle/model/utils.go b/sqle/model/utils.go index babfd4561..c28a19f81 100644 --- a/sqle/model/utils.go +++ b/sqle/model/utils.go @@ -6,6 +6,8 @@ import ( sqlDriver "database/sql/driver" "encoding/json" "fmt" + "github.com/actiontech/sqle/sqle/driver/mysql/plocale" + "golang.org/x/text/language" "reflect" "strconv" "strings" @@ -130,6 +132,9 @@ var autoMigrateList = []interface{}{ &RuleTemplateRule{}, &RuleTemplate{}, &Rule{}, + &AuditRuleCategory{}, + &AuditRuleCategoryRel{}, + &CustomRuleCategoryRel{}, &SqlWhitelist{}, &SystemVariable{}, &Task{}, @@ -177,7 +182,14 @@ func (s *Storage) AutoMigrate() error { if err != nil { return errors.New(errors.ConnectStorageError, err) } - + err = s.db.SetupJoinTable(&Rule{}, "Categories", &AuditRuleCategoryRel{}) + if err != nil { + return errors.New(errors.ConnectStorageError, err) + } + err = s.db.SetupJoinTable(&CustomRule{}, "Categories", &CustomRuleCategoryRel{}) + if err != nil { + return errors.New(errors.ConnectStorageError, err) + } if !s.db.Migrator().HasIndex(&SqlManage{}, "idx_project_id_status_deleted_at") { err = s.db.Exec("CREATE INDEX idx_project_id_status_deleted_at ON sql_manages (project_id, status, deleted_at)").Error if err != nil { @@ -187,6 +199,97 @@ func (s *Storage) AutoMigrate() error { return nil } +func (s *Storage) CreateRuleCategoriesRelated() error { + err := s.CreateRuleCategories() + if err != nil { + return err + } + // 创建自定义规则和分类的关系 + err = s.UpdateCustomRuleCategoryRels() + if err != nil { + return err + } + return nil +} + +func (s *Storage) UpdateCustomRuleCategoryRels() error { + customRules := []*CustomRule{} + s.db.Find(&customRules) + for _, customRule := range customRules { + if customRule.Typ == "" { + // 新的规则分类Typ字段为""说明已经有了新的分类关系,直接忽略 + continue + } + _, existed, err := s.FirstCustomRuleCategoryRelByCustomRuleId(customRule.RuleId) + if err != nil { + return err + } + // 已存在规则关系直接忽略 + if existed { + return nil + } + newCategoryMap := categoryMapping[customRule.Typ] + var tags []string + if newCategoryMap == nil { + // 自定义规则可以自己定义规则分类,对于这种分类的统一映射 + tags = []string{plocale.RuleTagDatabase.ID, plocale.RuleTagTablespace.ID, plocale.RuleTagTable.ID, plocale.RuleTagColumn.ID, plocale.RuleTagIndex.ID, plocale.RuleTagView.ID, plocale.RuleTagProcedure.ID, plocale.RuleTagFunction.ID, plocale.RuleTagTrigger.ID, plocale.RuleTagEvent.ID, plocale.RuleTagUser.ID} + } else { + // 这里的newCategoryMap只会有一次循环 + for _, newTags := range newCategoryMap { + tags = newTags + } + } + // 获取分类表中的分类信息 + auditRuleCategories, err := s.GetAuditRuleCategoryByTagIn(tags) + if err != nil { + return err + } + for _, newCategory := range auditRuleCategories { + customerCategoryRel := CustomRuleCategoryRel{CategoryId: newCategory.ID, CustomRuleId: customRule.RuleId} + err = s.db.Create(&customerCategoryRel).Error + if err != nil { + return err + } + } + } + return nil +} + +func (s *Storage) CreateRuleCategories() error { + isCategoryExistInDB := func(categories []*AuditRuleCategory, targetCategory *AuditRuleCategory) (*AuditRuleCategory, bool) { + for i := range categories { + if categories[i].Category != targetCategory.Category || categories[i].Tag != targetCategory.Tag { + continue + } + return categories[i], true + } + return nil, false + } + categories, err := s.GetAllCategories() + if err != nil { + return errors.New(errors.ConnectStorageError, err) + } + categoryTagMap := map[string][]string{ + plocale.RuleCategoryOperand.ID: {plocale.RuleTagDatabase.ID, plocale.RuleTagTablespace.ID, plocale.RuleTagTable.ID, plocale.RuleTagColumn.ID, plocale.RuleTagIndex.ID, plocale.RuleTagView.ID, plocale.RuleTagProcedure.ID, plocale.RuleTagFunction.ID, plocale.RuleTagTrigger.ID, plocale.RuleTagEvent.ID, plocale.RuleTagUser.ID}, + plocale.RuleCategorySQL.ID: {plocale.RuleTagDML.ID, plocale.RuleTagDDL.ID, plocale.RuleTagDCL.ID, plocale.RuleTagIntegrity.ID, plocale.RuleTagQuery.ID, plocale.RuleTagTransaction.ID, plocale.RuleTagPrivilege.ID, plocale.RuleTagManagement.ID}, + plocale.RuleCategoryAuditPurpose.ID: {plocale.RuleTagPerformance.ID, plocale.RuleTagMaintenance.ID, plocale.RuleTagSecurity.ID, plocale.RuleTagCorrection.ID}, + plocale.RuleCategoryAuditAccuracy.ID: {plocale.RuleTagOnline.ID, plocale.RuleTagOffline.ID}, + } + for category, tags := range categoryTagMap { + for _, tag := range tags { + auditRuleCategory := &AuditRuleCategory{Category: category, Tag: tag} + _, existed := isCategoryExistInDB(categories, auditRuleCategory) + if !existed { + err := s.Save(auditRuleCategory) + if err != nil { + return err + } + } + } + } + return nil +} + func (s *Storage) CreateRulesIfNotExist(rulesMap map[string][]*Rule) error { isRuleExistInDB := func(rulesInDB []*Rule, targetRule *Rule, dbType string) (*Rule, bool) { for i := range rulesInDB { @@ -205,6 +308,11 @@ func (s *Storage) CreateRulesIfNotExist(rulesMap map[string][]*Rule) error { } for dbType, rules := range rulesMap { for _, rule := range rules { + // 持久化规则分类信息 + categoryError := s.UpdateRuleCategoryRels(rule) + if categoryError != nil { + return categoryError + } existedRule, exist := isRuleExistInDB(rulesInDB, rule, dbType) // rule will be created or update if: // 1. rule not exist; @@ -458,6 +566,81 @@ func (s *Storage) CreateDefaultTemplateIfNotExist(projectId ProjectUID, rules ma return nil } +var categoryMapping = map[string]map[string][]string{ + plocale.RuleTypeGlobalConfig.Other: { + plocale.RuleCategoryAuditPurpose.ID: {plocale.RuleTagMaintenance.ID}, + }, + plocale.RuleTypeNamingConvention.Other: { + plocale.RuleCategoryOperand.ID: {plocale.RuleTagDatabase.ID, plocale.RuleTagTablespace.ID, plocale.RuleTagTable.ID, plocale.RuleTagColumn.ID, plocale.RuleTagIndex.ID, plocale.RuleTagView.ID, plocale.RuleTagProcedure.ID, plocale.RuleTagFunction.ID, plocale.RuleTagTrigger.ID, plocale.RuleTagEvent.ID, plocale.RuleTagUser.ID}, + }, + plocale.RuleTypeIndexingConvention.Other: { + plocale.RuleCategoryOperand.ID: {plocale.RuleTagIndex.ID}, + }, + plocale.RuleTypeIndexOptimization.Other: { + plocale.RuleCategoryOperand.ID: {plocale.RuleTagIndex.ID}, + }, + plocale.RuleTypeIndexInvalidation.Other: { + plocale.RuleCategoryOperand.ID: {plocale.RuleTagIndex.ID}, + }, + plocale.RuleTypeDDLConvention.Other: { + plocale.RuleCategorySQL.ID: {plocale.RuleTagDDL.ID}, + }, + plocale.RuleTypeDMLConvention.Other: { + plocale.RuleCategorySQL.ID: {plocale.RuleTagDML.ID}, + }, + plocale.RuleTypeUsageSuggestion.Other: { + plocale.RuleCategoryOperand.ID: {plocale.RuleTagDatabase.ID, plocale.RuleTagTablespace.ID, plocale.RuleTagTable.ID, plocale.RuleTagColumn.ID, plocale.RuleTagIndex.ID, plocale.RuleTagView.ID, plocale.RuleTagProcedure.ID, plocale.RuleTagFunction.ID, plocale.RuleTagTrigger.ID, plocale.RuleTagEvent.ID, plocale.RuleTagUser.ID}, + }, + plocale.RuleTypeExecutePlan.Other: { + plocale.RuleCategoryAuditPurpose.ID: {plocale.RuleTagPerformance.ID}, + }, + plocale.RuleTypeDistributedConvention.Other: { + plocale.RuleCategoryAuditPurpose.ID: {plocale.RuleTagMaintenance.ID}, + }, +} + +func (s *Storage) UpdateRuleCategoryRels(rule *Rule) error { + oldCategory := rule.I18nRuleInfo.GetRuleInfoByLangTag(language.Chinese).Category + _, existed, err := s.FirstAuditRuleCategoryRelByRule(rule.Name, rule.DBType) + if err != nil { + return err + } + // 某个规则存在分类不做处理 + if existed { + return nil + } + for _, tags := range categoryMapping[oldCategory] { + // 获取分类表中的分类信息 + auditRuleCategories, err := s.GetAuditRuleCategoryByTagIn(tags) + if err != nil { + return err + } + for _, newCategory := range auditRuleCategories { + auditRuleCategoryRel := AuditRuleCategoryRel{CategoryId: newCategory.ID, RuleName: rule.Name, RuleDBType: rule.DBType} + err = s.db.Create(&auditRuleCategoryRel).Error + if err != nil { + return err + } + } + } + auditAccuracyCategories, err := s.GetAuditRuleCategoryByCategory(plocale.RuleCategoryAuditAccuracy.ID) + if err != nil { + return err + } + // 根据离线/在线审核生成规则的分类关系 + for _, auditAccuracyCategory := range auditAccuracyCategories { + if !rule.AllowOffline && auditAccuracyCategory.Tag == plocale.RuleTagOffline.ID { + continue + } + auditRuleCategoryRel := AuditRuleCategoryRel{CategoryId: auditAccuracyCategory.ID, RuleName: rule.Name, RuleDBType: rule.DBType} + err = s.db.Create(&auditRuleCategoryRel).Error + if err != nil { + return err + } + } + return err +} + func (s *Storage) GetDefaultRuleTemplateName(dbType string) string { return fmt.Sprintf("default_%v", dbType) } diff --git a/sqle/sqled.go b/sqle/sqled.go index 465fbc5c5..2c1eb8c2c 100644 --- a/sqle/sqled.go +++ b/sqle/sqled.go @@ -103,6 +103,9 @@ func Run(options *config.SqleOptions) error { if err != nil { return fmt.Errorf("create workflow template failed: %v", err) } + if err := s.CreateRuleCategoriesRelated(); err != nil { + return fmt.Errorf("create rule categories related failed while auto migrating table: %v", err) + } rules := model.MergeOptimizationRules(driver.GetPluginManager().GetAllRules(), opt.OptimizationRuleMap) if err := s.CreateRulesIfNotExist(rules); err != nil { return fmt.Errorf("create rules failed while auto migrating table: %v", err)