stash/vendor/github.com/doug-martin/goqu/v9/exp/bool.go

186 lines
5.2 KiB
Go
Raw Normal View History

File storage rewrite (#2676) * Restructure data layer part 2 (#2599) * Refactor and separate image model * Refactor image query builder * Handle relationships in image query builder * Remove relationship management methods * Refactor gallery model/query builder * Add scenes to gallery model * Convert scene model * Refactor scene models * Remove unused methods * Add unit tests for gallery * Add image tests * Add scene tests * Convert unnecessary scene value pointers to values * Convert unnecessary pointer values to values * Refactor scene partial * Add scene partial tests * Refactor ImagePartial * Add image partial tests * Refactor gallery partial update * Add partial gallery update tests * Use zero/null package for null values * Add files and scan system * Add sqlite implementation for files/folders * Add unit tests for files/folders * Image refactors * Update image data layer * Refactor gallery model and creation * Refactor scene model * Refactor scenes * Don't set title from filename * Allow galleries to freely add/remove images * Add multiple scene file support to graphql and UI * Add multiple file support for images in graphql/UI * Add multiple file for galleries in graphql/UI * Remove use of some deprecated fields * Remove scene path usage * Remove gallery path usage * Remove path from image * Move funscript to video file * Refactor caption detection * Migrate existing data * Add post commit/rollback hook system * Lint. Comment out import/export tests * Add WithDatabase read only wrapper * Prepend tasks to list * Add 32 pre-migration * Add warnings in release and migration notes
2022-07-13 06:30:54 +00:00
package exp
import (
"reflect"
"regexp"
)
type boolean struct {
lhs Expression
rhs interface{}
op BooleanOperation
}
func NewBooleanExpression(op BooleanOperation, lhs Expression, rhs interface{}) BooleanExpression {
return boolean{op: op, lhs: lhs, rhs: rhs}
}
func (b boolean) Clone() Expression {
return NewBooleanExpression(b.op, b.lhs.Clone(), b.rhs)
}
func (b boolean) Expression() Expression {
return b
}
func (b boolean) RHS() interface{} {
return b.rhs
}
func (b boolean) LHS() Expression {
return b.lhs
}
func (b boolean) Op() BooleanOperation {
return b.op
}
func (b boolean) As(val interface{}) AliasedExpression {
return NewAliasExpression(b, val)
}
// used internally to create an equality BooleanExpression
func eq(lhs Expression, rhs interface{}) BooleanExpression {
return checkBoolExpType(EqOp, lhs, rhs, false)
}
// used internally to create an in-equality BooleanExpression
func neq(lhs Expression, rhs interface{}) BooleanExpression {
return checkBoolExpType(EqOp, lhs, rhs, true)
}
// used internally to create an gt comparison BooleanExpression
func gt(lhs Expression, rhs interface{}) BooleanExpression {
return NewBooleanExpression(GtOp, lhs, rhs)
}
// used internally to create an gte comparison BooleanExpression
func gte(lhs Expression, rhs interface{}) BooleanExpression {
return NewBooleanExpression(GteOp, lhs, rhs)
}
// used internally to create an lt comparison BooleanExpression
func lt(lhs Expression, rhs interface{}) BooleanExpression {
return NewBooleanExpression(LtOp, lhs, rhs)
}
// used internally to create an lte comparison BooleanExpression
func lte(lhs Expression, rhs interface{}) BooleanExpression {
return NewBooleanExpression(LteOp, lhs, rhs)
}
// used internally to create an IN BooleanExpression
func in(lhs Expression, vals ...interface{}) BooleanExpression {
if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
return NewBooleanExpression(InOp, lhs, vals[0])
}
return NewBooleanExpression(InOp, lhs, vals)
}
// used internally to create a NOT IN BooleanExpression
func notIn(lhs Expression, vals ...interface{}) BooleanExpression {
if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
return NewBooleanExpression(NotInOp, lhs, vals[0])
}
return NewBooleanExpression(NotInOp, lhs, vals)
}
// used internally to create an IS BooleanExpression
func is(lhs Expression, val interface{}) BooleanExpression {
return checkBoolExpType(IsOp, lhs, val, false)
}
// used internally to create an IS NOT BooleanExpression
func isNot(lhs Expression, val interface{}) BooleanExpression {
return checkBoolExpType(IsOp, lhs, val, true)
}
// used internally to create a LIKE BooleanExpression
func like(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(LikeOp, lhs, val, false)
}
// used internally to create an ILIKE BooleanExpression
func iLike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(ILikeOp, lhs, val, false)
}
// used internally to create a NOT LIKE BooleanExpression
func notLike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(LikeOp, lhs, val, true)
}
// used internally to create a NOT ILIKE BooleanExpression
func notILike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(ILikeOp, lhs, val, true)
}
// used internally to create a LIKE BooleanExpression
func regexpLike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(RegexpLikeOp, lhs, val, false)
}
// used internally to create an ILIKE BooleanExpression
func regexpILike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(RegexpILikeOp, lhs, val, false)
}
// used internally to create a NOT LIKE BooleanExpression
func regexpNotLike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(RegexpLikeOp, lhs, val, true)
}
// used internally to create a NOT ILIKE BooleanExpression
func regexpNotILike(lhs Expression, val interface{}) BooleanExpression {
return checkLikeExp(RegexpILikeOp, lhs, val, true)
}
// checks an like rhs to create the proper like expression for strings or regexps
func checkLikeExp(op BooleanOperation, lhs Expression, val interface{}, invert bool) BooleanExpression {
rhs := val
if t, ok := val.(*regexp.Regexp); ok {
if op == LikeOp {
op = RegexpLikeOp
} else if op == ILikeOp {
op = RegexpILikeOp
}
rhs = t.String()
}
if invert {
op = operatorInversions[op]
}
return NewBooleanExpression(op, lhs, rhs)
}
// checks a boolean operation normalizing the operation based on the RHS (e.g. "a" = true vs "a" IS TRUE
func checkBoolExpType(op BooleanOperation, lhs Expression, rhs interface{}, invert bool) BooleanExpression {
if rhs == nil {
op = IsOp
} else {
switch reflect.Indirect(reflect.ValueOf(rhs)).Kind() {
case reflect.Bool:
op = IsOp
case reflect.Slice:
// if its a slice of bytes dont treat as an IN
if _, ok := rhs.([]byte); !ok {
op = InOp
}
case reflect.Struct:
switch rhs.(type) {
case SQLExpression:
op = InOp
case AppendableExpression:
op = InOp
case *regexp.Regexp:
return checkLikeExp(LikeOp, lhs, rhs, invert)
}
default:
}
}
if invert {
op = operatorInversions[op]
}
return NewBooleanExpression(op, lhs, rhs)
}