[feat] 重新梳理导出

This commit is contained in:
what 2024-05-09 09:26:57 +08:00
parent 50a0a1a85c
commit e54629237c
8 changed files with 74 additions and 151 deletions

View File

@ -4,31 +4,32 @@ import (
"fmt" "fmt"
"strings" "strings"
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/contracts/support" "git.fsdpf.net/go/contracts/support"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"github.com/samber/lo" "github.com/samber/lo"
) )
type ConditionType string
const ( const (
OR contracts.ConditionType = "OR" OR ConditionType = "OR"
AND = "AND" AND ConditionType = "AND"
) )
type Condition struct { type Condition struct {
parent contracts.Condition parent *Condition
typ contracts.ConditionType // 分组类型 typ ConditionType // 分组类型
describe string // 描述 describe string // 描述
exprs []contracts.ConditionExpr // 分组表达式成员 exprs []*ConditionExpr // 分组表达式成员
childrens []contracts.Condition // 分组子集 childrens []*Condition // 分组子集
} }
func (this *Condition) AppendTo(c contracts.Condition) { func (this *Condition) AppendTo(c *Condition) {
this.parent = c this.parent = c
} }
// 条件类型 // 条件类型
func (this Condition) Type() contracts.ConditionType { func (this Condition) Type() ConditionType {
return this.typ return this.typ
} }
@ -92,7 +93,7 @@ func (this Condition) IsAlwaysRight() bool {
} }
// 生成 SQL 语句 // 生成 SQL 语句
func (this Condition) ToSql(m contracts.ConditionTokenValue) db.Expression { func (this Condition) ToSql(m ConditionTokenValue) db.Expression {
conditions := []string{} conditions := []string{}
// 表达式 // 表达式
for _, item := range this.exprs { for _, item := range this.exprs {
@ -132,21 +133,21 @@ func (this Condition) ToSql(m contracts.ConditionTokenValue) db.Expression {
} }
// 设置条件表达式 // 设置条件表达式
func (this *Condition) SetExpr(expr contracts.ConditionExpr) contracts.Condition { func (this *Condition) SetExpr(expr *ConditionExpr) *Condition {
expr.AppendTo(this) expr.AppendTo(this)
this.exprs = append(this.exprs, expr) this.exprs = append(this.exprs, expr)
return this return this
} }
// 设置条件子集 // 设置条件子集
func (this *Condition) SetCondition(c contracts.Condition) contracts.Condition { func (this *Condition) SetCondition(c *Condition) *Condition {
c.AppendTo(this) c.AppendTo(this)
this.childrens = append(this.childrens, c) this.childrens = append(this.childrens, c)
return this return this
} }
// 设置 Token 匹配前缀 // 设置 Token 匹配前缀
func (this *Condition) SetMatchPrefix(prefix string) contracts.Condition { func (this *Condition) SetMatchPrefix(prefix string) *Condition {
for _, expr := range this.exprs { for _, expr := range this.exprs {
expr.SetMatchPrefix(prefix) expr.SetMatchPrefix(prefix)
} }
@ -156,7 +157,7 @@ func (this *Condition) SetMatchPrefix(prefix string) contracts.Condition {
return this return this
} }
func (this Condition) GetFieldsValue(m contracts.ConditionTokenValue, isWithResource bool) (result map[string]any) { func (this Condition) GetFieldsValue(m ConditionTokenValue, isWithResource bool) (result map[string]any) {
if this.IsEmpty() { if this.IsEmpty() {
return return
} }
@ -188,7 +189,7 @@ func (this Condition) GetFieldsValue(m contracts.ConditionTokenValue, isWithReso
* @param contracts.ConditionTokenType types * @param contracts.ConditionTokenType types
* @return map[string][string] // 如: {"TestA.field_a": "param"} * @return map[string][string] // 如: {"TestA.field_a": "param"}
*/ */
func (this Condition) GetFields(operator contracts.ConditionOperator, types ...contracts.ConditionTokenType) map[string]string { func (this Condition) GetFields(operator ConditionOperator, types ...ConditionTokenType) map[string]string {
result := make(map[string]string) result := make(map[string]string)
if this.IsEmpty() { if this.IsEmpty() {
@ -212,6 +213,6 @@ func (this Condition) GetFields(operator contracts.ConditionOperator, types ...c
return result return result
} }
func New(typ contracts.ConditionType, describe string) contracts.Condition { func New(typ ConditionType, describe string) *Condition {
return &Condition{typ: typ, describe: describe} return &Condition{typ: typ, describe: describe}
} }

View File

@ -6,21 +6,24 @@ import (
"reflect" "reflect"
"strings" "strings"
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
"github.com/samber/lo" "github.com/samber/lo"
"github.com/spf13/cast" "github.com/spf13/cast"
) )
type ConditionOperator string
type ConditionTokenType string
const ( const (
SQL contracts.ConditionTokenType = "sql" SQL ConditionTokenType = "sql"
FUNC = "func" FUNC = "func"
PARAM = "param" PARAM = "param"
STRING = "string" STRING = "string"
) )
const ( const (
IS_NULL contracts.ConditionOperator = "IS NULL" IS_NULL ConditionOperator = "IS NULL"
IS_NOT_NULL = "IS NOT NULL" IS_NOT_NULL = "IS NOT NULL"
EQ = "=" EQ = "="
NE = "!=" NE = "!="
@ -36,24 +39,29 @@ const (
NOT_REGEXP = "NOT REGEXP" NOT_REGEXP = "NOT REGEXP"
) )
type ConditionTokenValue interface {
GetParam(k string) req.GlobalParams
GetGlobalParamsUser() req.User
}
type ConditionExpr struct { type ConditionExpr struct {
parent contracts.Condition parent *Condition
operator contracts.ConditionOperator operator ConditionOperator
field string field string
fieldResource string fieldResource string
fieldSqlFunc string fieldSqlFunc string
fieldSqlFuncParam string fieldSqlFuncParam string
ignoreEmptyParma bool ignoreEmptyParma bool
tokenType contracts.ConditionTokenType tokenType ConditionTokenType
token string token string
matchPrefix string // 匹配前缀 matchPrefix string // 匹配前缀
} }
func (this ConditionExpr) GetOperator() contracts.ConditionOperator { func (this ConditionExpr) GetOperator() ConditionOperator {
return this.operator return this.operator
} }
func (this *ConditionExpr) SetMatchPrefix(s string) contracts.ConditionExpr { func (this *ConditionExpr) SetMatchPrefix(s string) *ConditionExpr {
this.matchPrefix = s this.matchPrefix = s
return this return this
} }
@ -66,11 +74,11 @@ func (this ConditionExpr) GetFieldResource() string {
return this.fieldResource return this.fieldResource
} }
func (this *ConditionExpr) AppendTo(c contracts.Condition) { func (this *ConditionExpr) AppendTo(c *Condition) {
this.parent = c this.parent = c
} }
func (this ConditionExpr) ToSql(m contracts.ConditionTokenValue) db.Expression { func (this ConditionExpr) ToSql(m ConditionTokenValue) db.Expression {
first := "`" + this.fieldResource + "`.`" + this.field + "`" first := "`" + this.fieldResource + "`.`" + this.field + "`"
if strings.Contains(this.field, "->") { if strings.Contains(this.field, "->") {
@ -79,7 +87,7 @@ func (this ConditionExpr) ToSql(m contracts.ConditionTokenValue) db.Expression {
value := this.GetTokenSqlValue(m) value := this.GetTokenSqlValue(m)
operator := contracts.ConditionOperator(strings.ToUpper(string(this.GetOperator()))) operator := ConditionOperator(strings.ToUpper(string(this.GetOperator())))
if value == "" { if value == "" {
// @todo return true // @todo return true
@ -137,11 +145,11 @@ func (this ConditionExpr) GetTokenName() string {
return this.token return this.token
} }
func (this ConditionExpr) GetTokenType() contracts.ConditionTokenType { func (this ConditionExpr) GetTokenType() ConditionTokenType {
return this.tokenType return this.tokenType
} }
func (this *ConditionExpr) GetTokenSqlValue(m contracts.ConditionTokenValue) string { func (this *ConditionExpr) GetTokenSqlValue(m ConditionTokenValue) string {
if this.GetTokenType() == SQL { if this.GetTokenType() == SQL {
return this.token return this.token
} }
@ -178,7 +186,7 @@ func (this *ConditionExpr) GetTokenSqlValue(m contracts.ConditionTokenValue) str
} }
} }
func (this ConditionExpr) GetTokenValue(m contracts.ConditionTokenValue) any { func (this ConditionExpr) GetTokenValue(m ConditionTokenValue) any {
switch this.GetTokenType() { switch this.GetTokenType() {
case PARAM: case PARAM:
if this.matchPrefix != "" { if this.matchPrefix != "" {
@ -206,7 +214,7 @@ func (this ConditionExpr) GetTokenValue(m contracts.ConditionTokenValue) any {
return nil return nil
} }
func (this ConditionExpr) IsIgnoreEmptyParma(m contracts.ConditionTokenValue) bool { func (this ConditionExpr) IsIgnoreEmptyParma(m ConditionTokenValue) bool {
if !this.ignoreEmptyParma { if !this.ignoreEmptyParma {
return false return false
} }
@ -224,7 +232,7 @@ func (this ConditionExpr) IsIgnoreEmptyParma(m contracts.ConditionTokenValue) bo
return false return false
} }
func NewExpr(rResource, rField, token string, operator contracts.ConditionOperator, tType contracts.ConditionTokenType, ignoreEmptyParma bool, fn, fnParam string) contracts.ConditionExpr { func NewExpr(rResource, rField, token string, operator ConditionOperator, tType ConditionTokenType, ignoreEmptyParma bool, fn, fnParam string) *ConditionExpr {
return &ConditionExpr{ return &ConditionExpr{
operator: operator, operator: operator,
field: rField, field: rField,

View File

@ -1,45 +1,36 @@
package contracts package contracts
import ( import (
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
) )
type ConditionType string
type ConditionOperator string
type ConditionTokenType string
type Condition interface { type Condition interface {
Type() ConditionType Type() condition.ConditionType
IsEmpty() bool IsEmpty() bool
IsNotEmpty() bool IsNotEmpty() bool
IsAlwaysRight() bool IsAlwaysRight() bool
ToSql(ConditionTokenValue) db.Expression ToSql(condition.ConditionTokenValue) db.Expression
AppendTo(Condition) AppendTo(Condition)
SetExpr(ConditionExpr) Condition SetExpr(ConditionExpr) Condition
SetCondition(Condition) Condition SetCondition(Condition) Condition
SetMatchPrefix(string) Condition SetMatchPrefix(string) Condition
GetFields(operator ConditionOperator, types ...ConditionTokenType) map[string]string GetFields(operator condition.ConditionOperator, types ...condition.ConditionTokenType) map[string]string
GetFieldsValue(m ConditionTokenValue, isWithResource bool) map[string]any GetFieldsValue(m condition.ConditionTokenValue, isWithResource bool) map[string]any
} }
type ConditionExpr interface { type ConditionExpr interface {
GetField() string GetField() string
GetFieldResource() string GetFieldResource() string
GetOperator() ConditionOperator GetOperator() condition.ConditionOperator
SetMatchPrefix(string) ConditionExpr SetMatchPrefix(string) ConditionExpr
AppendTo(Condition) AppendTo(Condition)
ToSql(m ConditionTokenValue) db.Expression ToSql(m condition.ConditionTokenValue) db.Expression
GetTokenName() string GetTokenName() string
GetTokenType() ConditionTokenType GetTokenType() condition.ConditionTokenType
GetTokenValue(ConditionTokenValue) any GetTokenValue(condition.ConditionTokenValue) any
GetTokenSqlValue(ConditionTokenValue) string GetTokenSqlValue(condition.ConditionTokenValue) string
IsIgnoreEmptyParma(ConditionTokenValue) bool IsIgnoreEmptyParma(condition.ConditionTokenValue) bool
}
type ConditionTokenValue interface {
GetParam(k string) req.GlobalParams
GetGlobalParamsUser() req.User
} }

View File

@ -6,7 +6,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"git.fsdpf.net/go/condition/contracts" "git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req" "git.fsdpf.net/go/req"
"github.com/samber/lo" "github.com/samber/lo"
@ -48,7 +48,7 @@ func (this *Engine[T]) SetGlobalParams(g req.GlobalParams) *Engine[T] {
return this return this
} }
func (this *Engine[T]) Case(cond contracts.Condition, cb func(data T, g req.GlobalParams) error) *Engine[T] { func (this *Engine[T]) Case(cond *condition.Condition, cb func(data T, g req.GlobalParams) error) *Engine[T] {
this.predicates = append(this.predicates, &EngineCase[T]{cond, cb}) this.predicates = append(this.predicates, &EngineCase[T]{cond, cb})
return this return this
} }

View File

@ -1,17 +1,17 @@
package engine package engine
import ( import (
"git.fsdpf.net/go/condition/contracts" "git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req" "git.fsdpf.net/go/req"
) )
type EngineCase[T any] struct { type EngineCase[T any] struct {
predicate contracts.Condition predicate *condition.Condition
cb func(data T, g req.GlobalParams) error cb func(data T, g req.GlobalParams) error
} }
func (this EngineCase[T]) ToSql(param contracts.ConditionTokenValue) db.Expression { func (this EngineCase[T]) ToSql(param condition.ConditionTokenValue) db.Expression {
if this.predicate == nil || this.predicate.IsEmpty() { if this.predicate == nil || this.predicate.IsEmpty() {
return db.Raw("NULL") return db.Raw("NULL")
} }

1
go.mod
View File

@ -20,7 +20,6 @@ require (
github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.9.7 // indirect github.com/goccy/go-json v0.9.7 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jhump/protoreflect v1.15.1 // indirect github.com/jhump/protoreflect v1.15.1 // indirect

2
go.sum
View File

@ -136,8 +136,6 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=

View File

@ -1,74 +0,0 @@
package condition
import (
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/contracts/base"
)
// Create Condition By Resource
func NewConditionByRes(items []base.ResCondition, describe string) (root contracts.Condition) {
conditions := map[int]any{}
for _, item := range items {
switch item.Type {
case "and":
conditions[item.Id] = &Condition{typ: AND}
case "or":
conditions[item.Id] = &Condition{typ: OR}
case "expr":
conditions[item.Id] = &ConditionExpr{
field: item.Column,
fieldResource: item.ColumnResource,
operator: contracts.ConditionOperator(item.Operator),
fieldSqlFunc: item.ColumnSqlFunc,
fieldSqlFuncParam: item.ColumnSqlFuncParam,
ignoreEmptyParma: item.IgnoreEmptyParma,
tokenType: contracts.ConditionTokenType(item.ValueType),
token: item.Value,
}
}
if item.Pid == 0 && (item.Type == "and" || item.Type == "or") {
root = conditions[item.Id].(*Condition)
}
}
for _, item := range items {
parent := root
if item.Pid == 0 {
continue
} else {
parent = conditions[item.Pid].(*Condition)
}
switch item.Type {
case "and", "or":
child := conditions[item.Id].(contracts.Condition)
if len(parent.(*Condition).childrens) == 0 {
parent.(*Condition).childrens = []contracts.Condition{child}
} else {
parent.(*Condition).childrens = append(parent.(*Condition).childrens, child)
}
child.AppendTo(parent)
case "expr":
expr := conditions[item.Id].(contracts.ConditionExpr)
if len(parent.(*Condition).exprs) == 0 {
parent.(*Condition).exprs = []contracts.ConditionExpr{expr}
} else {
parent.(*Condition).exprs = append(parent.(*Condition).exprs, expr)
}
expr.AppendTo(parent)
}
}
if root == nil {
root = &Condition{}
}
if describe != "" {
root.(*Condition).describe = describe
}
return root
}