github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/databases/orm/orm_conds.go (about)

     1  // The original package is migrated from beego and modified, you can find orignal from following link:
     2  //    "github.com/beego/beego/"
     3  //
     4  // Copyright 2023 IAC. All Rights Reserved.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //      http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package orm
    19  
    20  import (
    21  	"fmt"
    22  	"strings"
    23  
    24  	"github.com/mdaxf/iac/databases/orm/clauses"
    25  )
    26  
    27  // ExprSep define the expression separation
    28  const (
    29  	ExprSep = clauses.ExprSep
    30  )
    31  
    32  type condValue struct {
    33  	exprs  []string
    34  	args   []interface{}
    35  	cond   *Condition
    36  	isOr   bool
    37  	isNot  bool
    38  	isCond bool
    39  	isRaw  bool
    40  	sql    string
    41  }
    42  
    43  // Condition struct.
    44  // work for WHERE conditions.
    45  type Condition struct {
    46  	params []condValue
    47  }
    48  
    49  // NewCondition return new condition struct
    50  func NewCondition() *Condition {
    51  	c := &Condition{}
    52  	return c
    53  }
    54  
    55  // Raw add raw sql to condition
    56  func (c Condition) Raw(expr string, sql string) *Condition {
    57  	if len(sql) == 0 {
    58  		panic(fmt.Errorf("<Condition.Raw> sql cannot empty"))
    59  	}
    60  	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), sql: sql, isRaw: true})
    61  	return &c
    62  }
    63  
    64  // And add expression to condition
    65  func (c Condition) And(expr string, args ...interface{}) *Condition {
    66  	if expr == "" || len(args) == 0 {
    67  		panic(fmt.Errorf("<Condition.And> args cannot empty"))
    68  	}
    69  	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args})
    70  	return &c
    71  }
    72  
    73  // AndNot add NOT expression to condition
    74  func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
    75  	if expr == "" || len(args) == 0 {
    76  		panic(fmt.Errorf("<Condition.AndNot> args cannot empty"))
    77  	}
    78  	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true})
    79  	return &c
    80  }
    81  
    82  // AndCond combine a condition to current condition
    83  func (c *Condition) AndCond(cond *Condition) *Condition {
    84  	if c == cond {
    85  		panic(fmt.Errorf("<Condition.AndCond> cannot use self as sub cond"))
    86  	}
    87  
    88  	c = c.clone()
    89  
    90  	if cond != nil {
    91  		c.params = append(c.params, condValue{cond: cond, isCond: true})
    92  	}
    93  	return c
    94  }
    95  
    96  // AndNotCond combine an AND NOT condition to current condition
    97  func (c *Condition) AndNotCond(cond *Condition) *Condition {
    98  	c = c.clone()
    99  	if c == cond {
   100  		panic(fmt.Errorf("<Condition.AndNotCond> cannot use self as sub cond"))
   101  	}
   102  
   103  	if cond != nil {
   104  		c.params = append(c.params, condValue{cond: cond, isCond: true, isNot: true})
   105  	}
   106  	return c
   107  }
   108  
   109  // Or add OR expression to condition
   110  func (c Condition) Or(expr string, args ...interface{}) *Condition {
   111  	if expr == "" || len(args) == 0 {
   112  		panic(fmt.Errorf("<Condition.Or> args cannot empty"))
   113  	}
   114  	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isOr: true})
   115  	return &c
   116  }
   117  
   118  // OrNot add OR NOT expression to condition
   119  func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
   120  	if expr == "" || len(args) == 0 {
   121  		panic(fmt.Errorf("<Condition.OrNot> args cannot empty"))
   122  	}
   123  	c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true, isOr: true})
   124  	return &c
   125  }
   126  
   127  // OrCond combine an OR condition to current condition
   128  func (c *Condition) OrCond(cond *Condition) *Condition {
   129  	c = c.clone()
   130  	if c == cond {
   131  		panic(fmt.Errorf("<Condition.OrCond> cannot use self as sub cond"))
   132  	}
   133  	if cond != nil {
   134  		c.params = append(c.params, condValue{cond: cond, isCond: true, isOr: true})
   135  	}
   136  	return c
   137  }
   138  
   139  // OrNotCond combine an OR NOT condition to current condition
   140  func (c *Condition) OrNotCond(cond *Condition) *Condition {
   141  	c = c.clone()
   142  	if c == cond {
   143  		panic(fmt.Errorf("<Condition.OrNotCond> cannot use self as sub cond"))
   144  	}
   145  
   146  	if cond != nil {
   147  		c.params = append(c.params, condValue{cond: cond, isCond: true, isNot: true, isOr: true})
   148  	}
   149  	return c
   150  }
   151  
   152  // IsEmpty check the condition arguments are empty or not.
   153  func (c *Condition) IsEmpty() bool {
   154  	return len(c.params) == 0
   155  }
   156  
   157  // clone clone a condition
   158  func (c Condition) clone() *Condition {
   159  	params := make([]condValue, len(c.params))
   160  	copy(params, c.params)
   161  	c.params = params
   162  	return &c
   163  }