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