// Copyright 2014 beego Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package orm import ( "fmt" "strings" ) // ExprSep define the expression separation const ( ExprSep = "__" ) type condValue struct { exprs []string args []interface{} cond *Condition isOr bool isNot bool isCond bool isRaw bool sql string } // Condition struct. // work for WHERE conditions. type Condition struct { params []condValue } // NewCondition return new condition struct func NewCondition() *Condition { c := &Condition{} return c } // Raw add raw sql to condition func (c Condition) Raw(expr string, sql string) *Condition { if len(sql) == 0 { panic(fmt.Errorf(" sql cannot empty")) } c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), sql: sql, isRaw: true}) return &c } // And add expression to condition func (c Condition) And(expr string, args ...interface{}) *Condition { if expr == "" || len(args) == 0 { panic(fmt.Errorf(" args cannot empty")) } c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args}) return &c } // AndNot add NOT expression to condition func (c Condition) AndNot(expr string, args ...interface{}) *Condition { if expr == "" || len(args) == 0 { panic(fmt.Errorf(" args cannot empty")) } c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true}) return &c } // AndCond combine a condition to current condition func (c *Condition) AndCond(cond *Condition) *Condition { if c == cond { panic(fmt.Errorf(" cannot use self as sub cond")) } c = c.clone() if cond != nil { c.params = append(c.params, condValue{cond: cond, isCond: true}) } return c } // AndNotCond combine a AND NOT condition to current condition func (c *Condition) AndNotCond(cond *Condition) *Condition { c = c.clone() if c == cond { panic(fmt.Errorf(" cannot use self as sub cond")) } if cond != nil { c.params = append(c.params, condValue{cond: cond, isCond: true, isNot: true}) } return c } // Or add OR expression to condition func (c Condition) Or(expr string, args ...interface{}) *Condition { if expr == "" || len(args) == 0 { panic(fmt.Errorf(" args cannot empty")) } c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isOr: true}) return &c } // OrNot add OR NOT expression to condition func (c Condition) OrNot(expr string, args ...interface{}) *Condition { if expr == "" || len(args) == 0 { panic(fmt.Errorf(" args cannot empty")) } c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true, isOr: true}) return &c } // OrCond combine a OR condition to current condition func (c *Condition) OrCond(cond *Condition) *Condition { c = c.clone() if c == cond { panic(fmt.Errorf(" cannot use self as sub cond")) } if cond != nil { c.params = append(c.params, condValue{cond: cond, isCond: true, isOr: true}) } return c } // OrNotCond combine a OR NOT condition to current condition func (c *Condition) OrNotCond(cond *Condition) *Condition { c = c.clone() if c == cond { panic(fmt.Errorf(" cannot use self as sub cond")) } if cond != nil { c.params = append(c.params, condValue{cond: cond, isCond: true, isNot: true, isOr: true}) } return c } // IsEmpty check the condition arguments are empty or not. func (c *Condition) IsEmpty() bool { return len(c.params) == 0 } // clone clone a condition func (c Condition) clone() *Condition { params := make([]condValue, len(c.params)) copy(params, c.params) c.params = params return &c }