...

Source file src/github.com/doug-martin/goqu/v9/exp/bool.go

Documentation: github.com/doug-martin/goqu/v9/exp

     1  package exp
     2  
     3  import (
     4  	"reflect"
     5  	"regexp"
     6  )
     7  
     8  type boolean struct {
     9  	lhs Expression
    10  	rhs interface{}
    11  	op  BooleanOperation
    12  }
    13  
    14  func NewBooleanExpression(op BooleanOperation, lhs Expression, rhs interface{}) BooleanExpression {
    15  	return boolean{op: op, lhs: lhs, rhs: rhs}
    16  }
    17  
    18  func (b boolean) Clone() Expression {
    19  	return NewBooleanExpression(b.op, b.lhs.Clone(), b.rhs)
    20  }
    21  
    22  func (b boolean) Expression() Expression {
    23  	return b
    24  }
    25  
    26  func (b boolean) RHS() interface{} {
    27  	return b.rhs
    28  }
    29  
    30  func (b boolean) LHS() Expression {
    31  	return b.lhs
    32  }
    33  
    34  func (b boolean) Op() BooleanOperation {
    35  	return b.op
    36  }
    37  
    38  func (b boolean) As(val interface{}) AliasedExpression {
    39  	return NewAliasExpression(b, val)
    40  }
    41  
    42  // used internally to create an equality BooleanExpression
    43  func eq(lhs Expression, rhs interface{}) BooleanExpression {
    44  	return checkBoolExpType(EqOp, lhs, rhs, false)
    45  }
    46  
    47  // used internally to create an in-equality BooleanExpression
    48  func neq(lhs Expression, rhs interface{}) BooleanExpression {
    49  	return checkBoolExpType(EqOp, lhs, rhs, true)
    50  }
    51  
    52  // used internally to create an gt comparison BooleanExpression
    53  func gt(lhs Expression, rhs interface{}) BooleanExpression {
    54  	return NewBooleanExpression(GtOp, lhs, rhs)
    55  }
    56  
    57  // used internally to create an gte comparison BooleanExpression
    58  func gte(lhs Expression, rhs interface{}) BooleanExpression {
    59  	return NewBooleanExpression(GteOp, lhs, rhs)
    60  }
    61  
    62  // used internally to create an lt comparison BooleanExpression
    63  func lt(lhs Expression, rhs interface{}) BooleanExpression {
    64  	return NewBooleanExpression(LtOp, lhs, rhs)
    65  }
    66  
    67  // used internally to create an lte comparison BooleanExpression
    68  func lte(lhs Expression, rhs interface{}) BooleanExpression {
    69  	return NewBooleanExpression(LteOp, lhs, rhs)
    70  }
    71  
    72  // used internally to create an IN BooleanExpression
    73  func in(lhs Expression, vals ...interface{}) BooleanExpression {
    74  	if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
    75  		return NewBooleanExpression(InOp, lhs, vals[0])
    76  	}
    77  	return NewBooleanExpression(InOp, lhs, vals)
    78  }
    79  
    80  // used internally to create a NOT IN BooleanExpression
    81  func notIn(lhs Expression, vals ...interface{}) BooleanExpression {
    82  	if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
    83  		return NewBooleanExpression(NotInOp, lhs, vals[0])
    84  	}
    85  	return NewBooleanExpression(NotInOp, lhs, vals)
    86  }
    87  
    88  // used internally to create an IS BooleanExpression
    89  func is(lhs Expression, val interface{}) BooleanExpression {
    90  	return checkBoolExpType(IsOp, lhs, val, false)
    91  }
    92  
    93  // used internally to create an IS NOT BooleanExpression
    94  func isNot(lhs Expression, val interface{}) BooleanExpression {
    95  	return checkBoolExpType(IsOp, lhs, val, true)
    96  }
    97  
    98  // used internally to create a LIKE BooleanExpression
    99  func like(lhs Expression, val interface{}) BooleanExpression {
   100  	return checkLikeExp(LikeOp, lhs, val, false)
   101  }
   102  
   103  // used internally to create an ILIKE BooleanExpression
   104  func iLike(lhs Expression, val interface{}) BooleanExpression {
   105  	return checkLikeExp(ILikeOp, lhs, val, false)
   106  }
   107  
   108  // used internally to create a NOT LIKE BooleanExpression
   109  func notLike(lhs Expression, val interface{}) BooleanExpression {
   110  	return checkLikeExp(LikeOp, lhs, val, true)
   111  }
   112  
   113  // used internally to create a NOT ILIKE BooleanExpression
   114  func notILike(lhs Expression, val interface{}) BooleanExpression {
   115  	return checkLikeExp(ILikeOp, lhs, val, true)
   116  }
   117  
   118  // used internally to create a LIKE BooleanExpression
   119  func regexpLike(lhs Expression, val interface{}) BooleanExpression {
   120  	return checkLikeExp(RegexpLikeOp, lhs, val, false)
   121  }
   122  
   123  // used internally to create an ILIKE BooleanExpression
   124  func regexpILike(lhs Expression, val interface{}) BooleanExpression {
   125  	return checkLikeExp(RegexpILikeOp, lhs, val, false)
   126  }
   127  
   128  // used internally to create a NOT LIKE BooleanExpression
   129  func regexpNotLike(lhs Expression, val interface{}) BooleanExpression {
   130  	return checkLikeExp(RegexpLikeOp, lhs, val, true)
   131  }
   132  
   133  // used internally to create a NOT ILIKE BooleanExpression
   134  func regexpNotILike(lhs Expression, val interface{}) BooleanExpression {
   135  	return checkLikeExp(RegexpILikeOp, lhs, val, true)
   136  }
   137  
   138  // checks an like rhs to create the proper like expression for strings or regexps
   139  func checkLikeExp(op BooleanOperation, lhs Expression, val interface{}, invert bool) BooleanExpression {
   140  	rhs := val
   141  
   142  	if t, ok := val.(*regexp.Regexp); ok {
   143  		if op == LikeOp {
   144  			op = RegexpLikeOp
   145  		} else if op == ILikeOp {
   146  			op = RegexpILikeOp
   147  		}
   148  		rhs = t.String()
   149  	}
   150  	if invert {
   151  		op = operatorInversions[op]
   152  	}
   153  	return NewBooleanExpression(op, lhs, rhs)
   154  }
   155  
   156  // checks a boolean operation normalizing the operation based on the RHS (e.g. "a" = true vs "a" IS TRUE
   157  func checkBoolExpType(op BooleanOperation, lhs Expression, rhs interface{}, invert bool) BooleanExpression {
   158  	if rhs == nil {
   159  		op = IsOp
   160  	} else {
   161  		switch reflect.Indirect(reflect.ValueOf(rhs)).Kind() {
   162  		case reflect.Bool:
   163  			op = IsOp
   164  		case reflect.Slice:
   165  			// if its a slice of bytes dont treat as an IN
   166  			if _, ok := rhs.([]byte); !ok {
   167  				op = InOp
   168  			}
   169  		case reflect.Struct:
   170  			switch rhs.(type) {
   171  			case SQLExpression:
   172  				op = InOp
   173  			case AppendableExpression:
   174  				op = InOp
   175  			case *regexp.Regexp:
   176  				return checkLikeExp(LikeOp, lhs, rhs, invert)
   177  			}
   178  		default:
   179  		}
   180  	}
   181  	if invert {
   182  		op = operatorInversions[op]
   183  	}
   184  	return NewBooleanExpression(op, lhs, rhs)
   185  }
   186  

View as plain text