mydb/internal/adapter/logical_expr.go
2023-09-18 15:15:42 +08:00

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{})
)