package clause type ConditionJoin struct { left Clause right Clause } func NewConditionJoin(left Clause, right Clause) *ConditionJoin { return &ConditionJoin{ left: left, right: right, } } func (clause *ConditionJoin) And() *AndJoin { return &AndJoin{ conditionJoin: clause, } } func (clause *ConditionJoin) Or() *OrJoin { return &OrJoin{ conditionJoin: clause, } } func (clause *ConditionJoin) formClause(conditionOperator string) (string, error) { if clause.left == nil || clause.right == nil { if clause.left != nil { return clause.left.Clause() } if clause.right != nil { return clause.right.Clause() } return "", nil } leftClause, err := clause.left.Clause() if err != nil { return "", err } rightClause, err := clause.right.Clause() if err != nil { return "", err } return "(" + leftClause + ") " + conditionOperator + " (" + rightClause + ")", nil } func (clause *ConditionJoin) formArgs() []any { args := make([]any, 0) if clause.left != nil { args = append(args, clause.left.Args()...) } if clause.right != nil { args = append(args, clause.right.Args()...) } return args } type AndJoin struct { conditionJoin *ConditionJoin } func (clause *AndJoin) Clause() (string, error) { return clause.conditionJoin.formClause("AND") } func (clause *AndJoin) Args() []any { return clause.conditionJoin.formArgs() } type OrJoin struct { conditionJoin *ConditionJoin } func (clause *OrJoin) Clause() (string, error) { return clause.conditionJoin.formClause("OR") } func (clause *OrJoin) Args() []any { return clause.conditionJoin.formArgs() }