|
|
@@ -11,9 +11,23 @@ import (
|
|
|
"git.sxidc.com/go-tools/utils/strutils"
|
|
|
"github.com/pkg/errors"
|
|
|
"reflect"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ LogicalOperatorAnd = "and"
|
|
|
+ LogicalOperatorOr = "or"
|
|
|
+)
|
|
|
+
|
|
|
+func isSupportedLogicalOperator(logicalOperator string) bool {
|
|
|
+ return logicalOperator == LogicalOperatorAnd || logicalOperator == LogicalOperatorOr
|
|
|
+}
|
|
|
+
|
|
|
type Rule struct {
|
|
|
+ LogicalOperator string `json:"logical_operator"`
|
|
|
+ Left *Rule `json:"left"`
|
|
|
+ Right *Rule `json:"right"`
|
|
|
+
|
|
|
FieldName string `json:"fieldName"`
|
|
|
FieldType string `json:"fieldType"`
|
|
|
ColumnName string `json:"columnName"`
|
|
|
@@ -22,6 +36,54 @@ type Rule struct {
|
|
|
}
|
|
|
|
|
|
func (r Rule) Check() error {
|
|
|
+ if strutils.IsStringNotEmpty(r.LogicalOperator) {
|
|
|
+ return r.checkAsNode()
|
|
|
+ } else {
|
|
|
+ return r.checkAsLeaf()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (r Rule) checkAsNode() error {
|
|
|
+ if !isSupportedLogicalOperator(r.LogicalOperator) {
|
|
|
+ return errors.New("不支持的逻辑操作符")
|
|
|
+ }
|
|
|
+
|
|
|
+ if r.Left == nil {
|
|
|
+ return errors.New("左结点为空")
|
|
|
+ }
|
|
|
+
|
|
|
+ if r.Right == nil {
|
|
|
+ return errors.New("右结点为空")
|
|
|
+ }
|
|
|
+
|
|
|
+ if strutils.IsStringNotEmpty(r.Left.LogicalOperator) {
|
|
|
+ err := r.Left.checkAsNode()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ err := r.Left.checkAsLeaf()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if strutils.IsStringNotEmpty(r.Right.LogicalOperator) {
|
|
|
+ err := r.Right.checkAsNode()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ err := r.Right.checkAsLeaf()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (r Rule) checkAsLeaf() error {
|
|
|
if strutils.IsStringEmpty(r.FieldName) {
|
|
|
return errors.New("字段名为空")
|
|
|
}
|
|
|
@@ -46,20 +108,13 @@ func (r Rule) Check() error {
|
|
|
}
|
|
|
|
|
|
func Lint(ruleStr string) error {
|
|
|
- rules := make([]Rule, 0)
|
|
|
- err := json.Unmarshal([]byte(ruleStr), &rules)
|
|
|
+ r := new(Rule)
|
|
|
+ err := json.Unmarshal([]byte(ruleStr), r)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- for _, r := range rules {
|
|
|
- err := r.Check()
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
+ return r.Check()
|
|
|
}
|
|
|
|
|
|
func HasRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (bool, error) {
|
|
|
@@ -71,7 +126,21 @@ func HasRule(dbSchema string, scope string, domainName string, i *infrastructure
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func GetRules(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) ([]Rule, error) {
|
|
|
+func GetRulesAndFormConditionClause(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (string, error) {
|
|
|
+ r, err := getRule(dbSchema, scope, domainName, i)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ clause, err := formConditionClause(r)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return clause, nil
|
|
|
+}
|
|
|
+
|
|
|
+func getRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (Rule, error) {
|
|
|
dbExecutor := i.DBExecutor()
|
|
|
|
|
|
result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
|
|
|
@@ -79,25 +148,21 @@ func GetRules(dbSchema string, scope string, domainName string, i *infrastructur
|
|
|
Conditions: sql.NewConditions().Equal(ColumnScope, scope).Equal(ColumnDomainName, domainName),
|
|
|
})
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return Rule{}, err
|
|
|
}
|
|
|
|
|
|
- rules := make([]Rule, 0)
|
|
|
- err = json.Unmarshal([]byte(result.ColumnValueString(ColumnRule)), &rules)
|
|
|
+ r := new(Rule)
|
|
|
+ err = json.Unmarshal([]byte(result.ColumnValueString(ColumnRule)), r)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return Rule{}, err
|
|
|
}
|
|
|
|
|
|
- return rules, nil
|
|
|
+ return *r, nil
|
|
|
}
|
|
|
|
|
|
-func FormConditions(rules []Rule) (*sql.Conditions, error) {
|
|
|
- conditions := sql.NewConditions()
|
|
|
- for _, r := range rules {
|
|
|
- err := r.Check()
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
+func formConditionClause(r Rule) (string, error) {
|
|
|
+ if strutils.IsStringEmpty(r.LogicalOperator) {
|
|
|
+ conditions := sql.NewConditions()
|
|
|
|
|
|
switch r.Operator {
|
|
|
case opEqual:
|
|
|
@@ -114,55 +179,66 @@ func FormConditions(rules []Rule) (*sql.Conditions, error) {
|
|
|
conditions.GreaterThanAndEqual(r.ColumnName, r.Value)
|
|
|
case opIn:
|
|
|
if reflect.TypeOf(r.Value).Kind() != reflect.Slice {
|
|
|
- return nil, errors.New("使用\"包含在列表\"操作符必须使用列表")
|
|
|
+ return "", errors.New("使用\"包含在列表\"操作符必须使用列表")
|
|
|
}
|
|
|
|
|
|
conditions.In(r.FieldName, r.Value)
|
|
|
case opNotIn:
|
|
|
if reflect.TypeOf(r.Value).Kind() != reflect.Slice {
|
|
|
- return nil, errors.New("使用\"不包含在列表\"操作符必须使用列表")
|
|
|
+ return "", errors.New("使用\"不包含在列表\"操作符必须使用列表")
|
|
|
}
|
|
|
|
|
|
conditions.NotIn(r.FieldName, r.Value)
|
|
|
case opPrefix:
|
|
|
strValue, err := reflectutils.ToString(r.Value)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return "", err
|
|
|
}
|
|
|
|
|
|
conditions.Like(r.FieldName, strValue+"%")
|
|
|
case opSuffix:
|
|
|
strValue, err := reflectutils.ToString(r.Value)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return "", err
|
|
|
}
|
|
|
|
|
|
conditions.Like(r.FieldName, "%"+strValue)
|
|
|
case opContains:
|
|
|
strValue, err := reflectutils.ToString(r.Value)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return "", err
|
|
|
}
|
|
|
|
|
|
conditions.Like(r.FieldName, "%"+strValue+"%")
|
|
|
default:
|
|
|
- return nil, errors.Errorf("不支持的操作符%v", r.Operator)
|
|
|
+ return "", errors.Errorf("不支持的操作符%v", r.Operator)
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return conditions, nil
|
|
|
-}
|
|
|
+ return conditions.And(), nil
|
|
|
+ }
|
|
|
|
|
|
-func GetRulesAndFormConditions(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (*sql.Conditions, error) {
|
|
|
- rules, err := GetRules(dbSchema, scope, domainName, i)
|
|
|
+ leftClause, err := formConditionClause(*r.Left)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return "", err
|
|
|
}
|
|
|
|
|
|
- conditions, err := FormConditions(rules)
|
|
|
+ rightClause, err := formConditionClause(*r.Right)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return "", err
|
|
|
}
|
|
|
|
|
|
- return conditions, nil
|
|
|
+ clauseBuilder := strings.Builder{}
|
|
|
+
|
|
|
+ clauseBuilder.WriteString("(" + leftClause + ")")
|
|
|
+
|
|
|
+ switch r.LogicalOperator {
|
|
|
+ case LogicalOperatorAnd:
|
|
|
+ clauseBuilder.WriteString(" AND ")
|
|
|
+ case LogicalOperatorOr:
|
|
|
+ clauseBuilder.WriteString(" OR ")
|
|
|
+ }
|
|
|
+
|
|
|
+ clauseBuilder.WriteString("(" + rightClause + ")")
|
|
|
+
|
|
|
+ return clauseBuilder.String(), nil
|
|
|
}
|