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

View File

@ -6,54 +6,62 @@ import (
"reflect"
"strings"
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
"github.com/samber/lo"
"github.com/spf13/cast"
)
type ConditionOperator string
type ConditionTokenType string
const (
SQL contracts.ConditionTokenType = "sql"
FUNC = "func"
PARAM = "param"
STRING = "string"
SQL ConditionTokenType = "sql"
FUNC = "func"
PARAM = "param"
STRING = "string"
)
const (
IS_NULL contracts.ConditionOperator = "IS NULL"
IS_NOT_NULL = "IS NOT NULL"
EQ = "="
NE = "!="
GT = ">"
GE = ">="
LT = "<"
LE = "<="
LIKE = "LIKE"
NOT_LIKE = "NOT LIKE"
IN = "IN"
NOT_IN = "NOT IN"
REGEXP = "REGEXP"
NOT_REGEXP = "NOT REGEXP"
IS_NULL ConditionOperator = "IS NULL"
IS_NOT_NULL = "IS NOT NULL"
EQ = "="
NE = "!="
GT = ">"
GE = ">="
LT = "<"
LE = "<="
LIKE = "LIKE"
NOT_LIKE = "NOT LIKE"
IN = "IN"
NOT_IN = "NOT IN"
REGEXP = "REGEXP"
NOT_REGEXP = "NOT REGEXP"
)
type ConditionTokenValue interface {
GetParam(k string) req.GlobalParams
GetGlobalParamsUser() req.User
}
type ConditionExpr struct {
parent contracts.Condition
operator contracts.ConditionOperator
parent *Condition
operator ConditionOperator
field string
fieldResource string
fieldSqlFunc string
fieldSqlFuncParam string
ignoreEmptyParma bool
tokenType contracts.ConditionTokenType
tokenType ConditionTokenType
token string
matchPrefix string // 匹配前缀
}
func (this ConditionExpr) GetOperator() contracts.ConditionOperator {
func (this ConditionExpr) GetOperator() ConditionOperator {
return this.operator
}
func (this *ConditionExpr) SetMatchPrefix(s string) contracts.ConditionExpr {
func (this *ConditionExpr) SetMatchPrefix(s string) *ConditionExpr {
this.matchPrefix = s
return this
}
@ -66,11 +74,11 @@ func (this ConditionExpr) GetFieldResource() string {
return this.fieldResource
}
func (this *ConditionExpr) AppendTo(c contracts.Condition) {
func (this *ConditionExpr) AppendTo(c *Condition) {
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 + "`"
if strings.Contains(this.field, "->") {
@ -79,7 +87,7 @@ func (this ConditionExpr) ToSql(m contracts.ConditionTokenValue) db.Expression {
value := this.GetTokenSqlValue(m)
operator := contracts.ConditionOperator(strings.ToUpper(string(this.GetOperator())))
operator := ConditionOperator(strings.ToUpper(string(this.GetOperator())))
if value == "" {
// @todo return true
@ -137,11 +145,11 @@ func (this ConditionExpr) GetTokenName() string {
return this.token
}
func (this ConditionExpr) GetTokenType() contracts.ConditionTokenType {
func (this ConditionExpr) GetTokenType() ConditionTokenType {
return this.tokenType
}
func (this *ConditionExpr) GetTokenSqlValue(m contracts.ConditionTokenValue) string {
func (this *ConditionExpr) GetTokenSqlValue(m ConditionTokenValue) string {
if this.GetTokenType() == SQL {
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() {
case PARAM:
if this.matchPrefix != "" {
@ -206,7 +214,7 @@ func (this ConditionExpr) GetTokenValue(m contracts.ConditionTokenValue) any {
return nil
}
func (this ConditionExpr) IsIgnoreEmptyParma(m contracts.ConditionTokenValue) bool {
func (this ConditionExpr) IsIgnoreEmptyParma(m ConditionTokenValue) bool {
if !this.ignoreEmptyParma {
return false
}
@ -224,7 +232,7 @@ func (this ConditionExpr) IsIgnoreEmptyParma(m contracts.ConditionTokenValue) bo
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{
operator: operator,
field: rField,

View File

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

View File

@ -6,7 +6,7 @@ import (
"reflect"
"strings"
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
"github.com/samber/lo"
@ -48,7 +48,7 @@ func (this *Engine[T]) SetGlobalParams(g req.GlobalParams) *Engine[T] {
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})
return this
}

View File

@ -1,17 +1,17 @@
package engine
import (
"git.fsdpf.net/go/condition/contracts"
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
)
type EngineCase[T any] struct {
predicate contracts.Condition
predicate *condition.Condition
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() {
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/goccy/go-json v0.9.7 // 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/hashicorp/hcl v1.0.0 // 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/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.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.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
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
}