mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-01-08 07:15:48 +08:00
feat: sql解析器替换、工单统一由‘我的流程’发起、流程定义支持自定义条件触发审批、资源隐藏编号、model支持物理删除等
This commit is contained in:
171
server/internal/db/dbm/sqlparser/sqlstmt/common.go
Normal file
171
server/internal/db/dbm/sqlparser/sqlstmt/common.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
IExpr interface {
|
||||
INode
|
||||
|
||||
isExpr()
|
||||
}
|
||||
|
||||
Expr struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
ExprLogical struct {
|
||||
Expr
|
||||
|
||||
Operator string
|
||||
Exprs []IExpr
|
||||
}
|
||||
|
||||
ExprPredicate struct {
|
||||
Expr
|
||||
|
||||
Predicate IPredicate
|
||||
}
|
||||
)
|
||||
|
||||
func (*Expr) isExpr() {}
|
||||
|
||||
type (
|
||||
IPredicate interface {
|
||||
INode
|
||||
|
||||
isPredicate()
|
||||
}
|
||||
|
||||
Predicate struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
PredicateBinaryComparison struct {
|
||||
Predicate
|
||||
|
||||
Left IPredicate
|
||||
Right IPredicate
|
||||
ComparisonOperator string
|
||||
}
|
||||
|
||||
PredicateIn struct {
|
||||
Predicate
|
||||
|
||||
InPredicate IPredicate
|
||||
Exprs []IExpr
|
||||
SelectStmt ISelectStmt
|
||||
}
|
||||
|
||||
PredicateExprAtom struct {
|
||||
Predicate
|
||||
|
||||
ExprAtom IExprAtom
|
||||
}
|
||||
)
|
||||
|
||||
func (*Predicate) isPredicate() {}
|
||||
|
||||
type (
|
||||
IExprAtom interface {
|
||||
INode
|
||||
|
||||
isExprAtom()
|
||||
}
|
||||
|
||||
ExprAtom struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
ExprAtomFunctionCall struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
ExprAtomConstant struct {
|
||||
ExprAtom
|
||||
|
||||
Constant *Constant
|
||||
}
|
||||
|
||||
ExprAtomColumnName struct {
|
||||
ExprAtom
|
||||
|
||||
ColumnName *ColumnName
|
||||
}
|
||||
)
|
||||
|
||||
func (*ExprAtom) isExprAtom() {}
|
||||
|
||||
type (
|
||||
ITableSource interface {
|
||||
INode
|
||||
|
||||
isTableSource()
|
||||
}
|
||||
|
||||
TableSource struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
TableSources struct {
|
||||
*Node
|
||||
|
||||
TableSources []ITableSource
|
||||
}
|
||||
|
||||
TableSourceBase struct {
|
||||
TableSource
|
||||
|
||||
TableSourceItem ITableSourceItem
|
||||
JoinParts []IJoinPart
|
||||
}
|
||||
|
||||
ITableSourceItem interface {
|
||||
INode
|
||||
}
|
||||
|
||||
TableSourceItem struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
AtomTableItem struct {
|
||||
TableSourceItem
|
||||
|
||||
TableName *TableName // 表名
|
||||
Alias string // 别名
|
||||
}
|
||||
)
|
||||
|
||||
func (*TableSource) isTableSource() {}
|
||||
|
||||
type (
|
||||
Constant struct {
|
||||
*Node
|
||||
|
||||
Value string
|
||||
}
|
||||
|
||||
FullId struct {
|
||||
*Node
|
||||
|
||||
Uids []string
|
||||
}
|
||||
)
|
||||
|
||||
type ColumnName struct {
|
||||
*Node
|
||||
|
||||
Owner string
|
||||
Identifier *IdentifierValue
|
||||
NestedObjectAttrs []string
|
||||
}
|
||||
|
||||
type TableName struct {
|
||||
*Node
|
||||
|
||||
Owner string
|
||||
Identifier *IdentifierValue
|
||||
}
|
||||
|
||||
type (
|
||||
FuncCall interface {
|
||||
INode
|
||||
}
|
||||
)
|
||||
53
server/internal/db/dbm/sqlparser/sqlstmt/ddl.go
Normal file
53
server/internal/db/dbm/sqlparser/sqlstmt/ddl.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
IDdlStmt interface {
|
||||
isDdl()
|
||||
}
|
||||
|
||||
DdlStmt struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
CreateDatabase struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
CreateTable struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
CreateIndex struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
AlterTable struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
AlterDatabase struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
DropDatabase struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
DropIndex struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
DropTable struct {
|
||||
DdlStmt
|
||||
}
|
||||
|
||||
DropView struct {
|
||||
DdlStmt
|
||||
}
|
||||
)
|
||||
|
||||
func (d *DdlStmt) isDdl() {}
|
||||
|
||||
func IsDDL(node INode) bool {
|
||||
return true
|
||||
}
|
||||
16
server/internal/db/dbm/sqlparser/sqlstmt/delete.go
Normal file
16
server/internal/db/dbm/sqlparser/sqlstmt/delete.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
IDeleteStmt interface {
|
||||
isDelete()
|
||||
}
|
||||
|
||||
DeleteStmt struct {
|
||||
*Node
|
||||
|
||||
TableSources *TableSources
|
||||
Where IExpr
|
||||
}
|
||||
)
|
||||
|
||||
func (*DeleteStmt) isDelete() {}
|
||||
15
server/internal/db/dbm/sqlparser/sqlstmt/insert.go
Normal file
15
server/internal/db/dbm/sqlparser/sqlstmt/insert.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
IInsertStmt interface {
|
||||
isInsert()
|
||||
}
|
||||
|
||||
InsertStmt struct {
|
||||
*Node
|
||||
|
||||
TableName *TableName
|
||||
}
|
||||
)
|
||||
|
||||
func (*InsertStmt) isInsert() {}
|
||||
76
server/internal/db/dbm/sqlparser/sqlstmt/quote_char.go
Normal file
76
server/internal/db/dbm/sqlparser/sqlstmt/quote_char.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package sqlstmt
|
||||
|
||||
import "strings"
|
||||
|
||||
type QuoteChar struct {
|
||||
StartDelimiter string
|
||||
EndDelimiter string
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap value with quote character.
|
||||
*
|
||||
* @param value value to be wrapped
|
||||
* @return wrapped value
|
||||
*/
|
||||
func (qc *QuoteChar) Wrap(value string) string {
|
||||
return qc.StartDelimiter + value + qc.EndDelimiter
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap value with quote character.
|
||||
*
|
||||
* @param value value to be unwrapped
|
||||
* @return unwrapped value
|
||||
*/
|
||||
func (qc *QuoteChar) Unwrap(value string) string {
|
||||
if qc.IsWrapped(value) {
|
||||
return value[len(qc.StartDelimiter) : len(value)-len(qc.EndDelimiter)]
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Is wrapped by quote character.
|
||||
*
|
||||
* @param value value to be judged
|
||||
* @return is wrapped or not
|
||||
*/
|
||||
func (qc *QuoteChar) IsWrapped(value string) bool {
|
||||
return strings.HasPrefix(value, qc.StartDelimiter) && strings.HasSuffix(value, qc.EndDelimiter)
|
||||
}
|
||||
|
||||
func NewQuoteChar(startDelimiter, endDelimiter string) *QuoteChar {
|
||||
return &QuoteChar{
|
||||
StartDelimiter: startDelimiter,
|
||||
EndDelimiter: endDelimiter,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
BACK_QUOTE = NewQuoteChar("`", "`")
|
||||
SINGLE_QUOTE = NewQuoteChar("'", "'")
|
||||
QUOTE = NewQuoteChar("\"", "\"")
|
||||
BRACKETS = NewQuoteChar("[", "]")
|
||||
PARENTHESES = NewQuoteChar("(", ")")
|
||||
NONE = NewQuoteChar("", "")
|
||||
|
||||
BY_FIRST_CHAR = map[string]*QuoteChar{
|
||||
BACK_QUOTE.StartDelimiter: BACK_QUOTE,
|
||||
SINGLE_QUOTE.StartDelimiter: SINGLE_QUOTE,
|
||||
QUOTE.StartDelimiter: QUOTE,
|
||||
BRACKETS.StartDelimiter: BRACKETS,
|
||||
PARENTHESES.StartDelimiter: PARENTHESES,
|
||||
}
|
||||
)
|
||||
|
||||
func GetQuoteChar(value string) *QuoteChar {
|
||||
if value == "" {
|
||||
return NONE
|
||||
}
|
||||
if qc := BY_FIRST_CHAR[value[0:1]]; qc != nil {
|
||||
return qc
|
||||
} else {
|
||||
return NONE
|
||||
}
|
||||
}
|
||||
15
server/internal/db/dbm/sqlparser/sqlstmt/quote_char_test.go
Normal file
15
server/internal/db/dbm/sqlparser/sqlstmt/quote_char_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package sqlstmt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestQuoteCharUnwrap(t *testing.T) {
|
||||
value := "`hehehe`"
|
||||
qc := GetQuoteChar(value)
|
||||
if qc != BACK_QUOTE {
|
||||
t.Fatal("quote char should be BACK_QUOTE")
|
||||
}
|
||||
oriValue := qc.Unwrap(value)
|
||||
t.Log(oriValue)
|
||||
}
|
||||
135
server/internal/db/dbm/sqlparser/sqlstmt/select.go
Normal file
135
server/internal/db/dbm/sqlparser/sqlstmt/select.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
ISelectStmt interface {
|
||||
INode
|
||||
|
||||
isSelect()
|
||||
}
|
||||
|
||||
SelectStmt struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
QuerySpecification struct {
|
||||
*Node
|
||||
|
||||
SelectElements *SelectElements
|
||||
From *TableSources
|
||||
Where IExpr
|
||||
Limit *Limit
|
||||
}
|
||||
|
||||
SimpleSelectStmt struct {
|
||||
SelectStmt
|
||||
|
||||
QuerySpecification *QuerySpecification
|
||||
}
|
||||
|
||||
UnionSelectStmt struct {
|
||||
SelectStmt
|
||||
|
||||
UnionType string
|
||||
QuerySpecification *QuerySpecification
|
||||
QueryExpr *QueryExpr
|
||||
UnionStmts []*UnionStmt
|
||||
Limit *Limit
|
||||
}
|
||||
|
||||
// 圆括号查询
|
||||
ParenthesisSelect struct {
|
||||
SelectStmt
|
||||
|
||||
QueryExpr *QueryExpr
|
||||
}
|
||||
|
||||
QueryExpr struct {
|
||||
*Node
|
||||
|
||||
QuerySpecification *QuerySpecification
|
||||
QueryExpr *QueryExpr
|
||||
}
|
||||
)
|
||||
|
||||
func (*SelectStmt) isSelect() {}
|
||||
|
||||
// var _ (ISelectStmt) = (*SimpleSelectStmt)(nil)
|
||||
// var _ (ISelectStmt) = (*SelectStmt)(nil)
|
||||
// var _ (ISelectStmt) = (*ParenthesisSelect)(nil)
|
||||
|
||||
type (
|
||||
SelectElements struct {
|
||||
*Node
|
||||
|
||||
Star string // 查询所有
|
||||
Elements []ISelectElement
|
||||
}
|
||||
|
||||
ISelectElement interface {
|
||||
INode
|
||||
}
|
||||
|
||||
SelectStarElement struct {
|
||||
*Node
|
||||
|
||||
FullId string
|
||||
}
|
||||
|
||||
SelectColumnElement struct {
|
||||
*Node
|
||||
|
||||
FullColumnName *ColumnName
|
||||
Alias string
|
||||
}
|
||||
|
||||
SelectFunctionElement struct {
|
||||
*Node
|
||||
|
||||
Alias string
|
||||
}
|
||||
)
|
||||
|
||||
type From struct {
|
||||
TableSource *ITableSource
|
||||
}
|
||||
|
||||
type Limit struct {
|
||||
*Node
|
||||
|
||||
RowCount int
|
||||
Offset int
|
||||
}
|
||||
|
||||
type (
|
||||
IJoinPart interface {
|
||||
INode
|
||||
}
|
||||
|
||||
JoinPart struct {
|
||||
*Node
|
||||
|
||||
TableSourceItem ITableSourceItem
|
||||
}
|
||||
|
||||
InnerJoin struct {
|
||||
JoinPart
|
||||
}
|
||||
|
||||
OuterJoin struct {
|
||||
JoinPart
|
||||
}
|
||||
|
||||
NaturalJoin struct {
|
||||
JoinPart
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
UnionStmt struct {
|
||||
*Node
|
||||
|
||||
UnionType string
|
||||
QuerySpecification *QuerySpecification
|
||||
QueryExpr *QueryExpr
|
||||
}
|
||||
)
|
||||
75
server/internal/db/dbm/sqlparser/sqlstmt/stmt.go
Normal file
75
server/internal/db/dbm/sqlparser/sqlstmt/stmt.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package sqlstmt
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
)
|
||||
|
||||
type INode interface {
|
||||
GetText() string
|
||||
|
||||
// GetStartIndex() int
|
||||
// GetStopIndex() int
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
// startIndex int
|
||||
// stopIndex int
|
||||
|
||||
parser antlr.Parser
|
||||
ruleContext antlr.RuleContext
|
||||
}
|
||||
|
||||
func (n *Node) GetText() string {
|
||||
if n == nil || n.ruleContext == nil || n.parser == nil {
|
||||
return ""
|
||||
}
|
||||
return n.parser.GetTokenStream().GetTextFromRuleContext(n.ruleContext)
|
||||
}
|
||||
|
||||
// func (n *Node) GetStartIndex() int {
|
||||
// return n.startIndex
|
||||
// }
|
||||
|
||||
// func (n *Node) GetStopIndex() int {
|
||||
// return n.stopIndex
|
||||
// }
|
||||
|
||||
func NewNode(parser antlr.Parser, ruleContext antlr.RuleContext) *Node {
|
||||
return &Node{
|
||||
parser: parser,
|
||||
ruleContext: ruleContext,
|
||||
}
|
||||
}
|
||||
|
||||
// func NewNode(startIndex, stopIndex int) *Node {
|
||||
// return &Node{
|
||||
// startIndex: startIndex,
|
||||
// stopIndex: stopIndex,
|
||||
// }
|
||||
// }
|
||||
|
||||
// func GetText(sqlstmts string, node INode) string {
|
||||
// return sqlstmts[node.GetStartIndex() : node.GetStopIndex()+1]
|
||||
// }
|
||||
|
||||
type Stmt interface {
|
||||
INode
|
||||
}
|
||||
|
||||
type SqlStmt struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
type DmlStmt struct {
|
||||
SqlStmt
|
||||
}
|
||||
|
||||
type OtherReadStmt struct {
|
||||
*Node
|
||||
}
|
||||
|
||||
func IsSelectStmt(stmt Stmt) bool {
|
||||
return reflect.TypeOf(stmt).AssignableTo(reflect.TypeOf(&SelectStmt{}))
|
||||
}
|
||||
26
server/internal/db/dbm/sqlparser/sqlstmt/update.go
Normal file
26
server/internal/db/dbm/sqlparser/sqlstmt/update.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package sqlstmt
|
||||
|
||||
type (
|
||||
IUpdateStmt interface {
|
||||
INode
|
||||
|
||||
isUpdate()
|
||||
}
|
||||
|
||||
UpdateStmt struct {
|
||||
*Node
|
||||
|
||||
TableSources *TableSources
|
||||
UpdatedElements []*UpdatedElement
|
||||
Where IExpr
|
||||
}
|
||||
)
|
||||
|
||||
func (*UpdateStmt) isUpdate() {}
|
||||
|
||||
type UpdatedElement struct {
|
||||
*Node
|
||||
|
||||
ColumnName *ColumnName
|
||||
Value IExpr
|
||||
}
|
||||
23
server/internal/db/dbm/sqlparser/sqlstmt/value.go
Normal file
23
server/internal/db/dbm/sqlparser/sqlstmt/value.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package sqlstmt
|
||||
|
||||
import "strings"
|
||||
|
||||
type IdentifierValue struct {
|
||||
Value string
|
||||
QuoteChar *QuoteChar
|
||||
}
|
||||
|
||||
func NewIdentifierValue(value string) *IdentifierValue {
|
||||
value = strings.TrimPrefix(value, ".")
|
||||
qc := GetQuoteChar(value)
|
||||
if qc == NONE {
|
||||
return &IdentifierValue{
|
||||
Value: value,
|
||||
QuoteChar: qc,
|
||||
}
|
||||
}
|
||||
return &IdentifierValue{
|
||||
Value: qc.Unwrap(value),
|
||||
QuoteChar: qc,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user