101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package adapter
|
|
|
|
import "git.hexq.cn/tiglog/mydb/internal/immutable"
|
|
|
|
// LogicalExpr represents a group formed by one or more sentences joined by
|
|
// an Operator like "AND" or "OR".
|
|
type LogicalExpr interface {
|
|
// Expressions returns child sentences.
|
|
Expressions() []LogicalExpr
|
|
|
|
// Operator returns the Operator that joins all the sentences in the group.
|
|
Operator() LogicalOperator
|
|
|
|
// Empty returns true if the compound has zero children, false otherwise.
|
|
Empty() bool
|
|
}
|
|
|
|
// LogicalOperator represents the operation on a compound statement.
|
|
type LogicalOperator uint
|
|
|
|
// LogicalExpr Operators.
|
|
const (
|
|
LogicalOperatorNone LogicalOperator = iota
|
|
LogicalOperatorAnd
|
|
LogicalOperatorOr
|
|
)
|
|
|
|
const DefaultLogicalOperator = LogicalOperatorAnd
|
|
|
|
type LogicalExprGroup struct {
|
|
op LogicalOperator
|
|
|
|
prev *LogicalExprGroup
|
|
fn func(*[]LogicalExpr) error
|
|
}
|
|
|
|
func NewLogicalExprGroup(op LogicalOperator, conds ...LogicalExpr) *LogicalExprGroup {
|
|
group := &LogicalExprGroup{op: op}
|
|
if len(conds) == 0 {
|
|
return group
|
|
}
|
|
return group.Frame(func(in *[]LogicalExpr) error {
|
|
*in = append(*in, conds...)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// Expressions returns each one of the conditions as a compound.
|
|
func (g *LogicalExprGroup) Expressions() []LogicalExpr {
|
|
conds, err := immutable.FastForward(g)
|
|
if err == nil {
|
|
return *(conds.(*[]LogicalExpr))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Operator is undefined for a logical group.
|
|
func (g *LogicalExprGroup) Operator() LogicalOperator {
|
|
if g.op == LogicalOperatorNone {
|
|
panic("operator is not defined")
|
|
}
|
|
return g.op
|
|
}
|
|
|
|
// Empty returns true if this condition has no elements. False otherwise.
|
|
func (g *LogicalExprGroup) Empty() bool {
|
|
if g.fn != nil {
|
|
return false
|
|
}
|
|
if g.prev != nil {
|
|
return g.prev.Empty()
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (g *LogicalExprGroup) Frame(fn func(*[]LogicalExpr) error) *LogicalExprGroup {
|
|
return &LogicalExprGroup{prev: g, op: g.op, fn: fn}
|
|
}
|
|
|
|
func (g *LogicalExprGroup) Prev() immutable.Immutable {
|
|
if g == nil {
|
|
return nil
|
|
}
|
|
return g.prev
|
|
}
|
|
|
|
func (g *LogicalExprGroup) Fn(in interface{}) error {
|
|
if g.fn == nil {
|
|
return nil
|
|
}
|
|
return g.fn(in.(*[]LogicalExpr))
|
|
}
|
|
|
|
func (g *LogicalExprGroup) Base() interface{} {
|
|
return &[]LogicalExpr{}
|
|
}
|
|
|
|
var (
|
|
_ = immutable.Immutable(&LogicalExprGroup{})
|
|
)
|