...

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

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

     1  package exp
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  
     7  	"github.com/doug-martin/goqu/v9/internal/errors"
     8  )
     9  
    10  type (
    11  	// A map of expressions to be ANDed together where the keys are string that will be used as Identifiers and values
    12  	// will be used in a boolean operation.
    13  	// The Ex map can be used in tandem with Op map to create more complex expression such as LIKE, GT, LT...
    14  	// See examples.
    15  	Ex map[string]interface{}
    16  	// A map of expressions to be ORed together where the keys are string that will be used as Identifiers and values
    17  	// will be used in a boolean operation.
    18  	// The Ex map can be used in tandem with Op map to create more complex expression such as LIKE, GT, LT...
    19  	// See examples.
    20  	ExOr map[string]interface{}
    21  	// Used in tandem with the Ex map to create complex comparisons such as LIKE, GT, LT... See examples
    22  	Op map[string]interface{}
    23  )
    24  
    25  func (e Ex) Expression() Expression {
    26  	return e
    27  }
    28  
    29  func (e Ex) Clone() Expression {
    30  	ret := Ex{}
    31  	for key, val := range e {
    32  		ret[key] = val
    33  	}
    34  	return ret
    35  }
    36  
    37  func (e Ex) IsEmpty() bool {
    38  	return len(e) == 0
    39  }
    40  
    41  func (e Ex) ToExpressions() (ExpressionList, error) {
    42  	return mapToExpressionList(e, AndType)
    43  }
    44  
    45  func (eo ExOr) Expression() Expression {
    46  	return eo
    47  }
    48  
    49  func (eo ExOr) Clone() Expression {
    50  	ret := ExOr{}
    51  	for key, val := range eo {
    52  		ret[key] = val
    53  	}
    54  	return ret
    55  }
    56  
    57  func (eo ExOr) IsEmpty() bool {
    58  	return len(eo) == 0
    59  }
    60  
    61  func (eo ExOr) ToExpressions() (ExpressionList, error) {
    62  	return mapToExpressionList(eo, OrType)
    63  }
    64  
    65  func getExMapKeys(ex map[string]interface{}) []string {
    66  	keys := make([]string, 0, len(ex))
    67  	for key := range ex {
    68  		keys = append(keys, key)
    69  	}
    70  	sort.Strings(keys)
    71  	return keys
    72  }
    73  
    74  func mapToExpressionList(ex map[string]interface{}, eType ExpressionListType) (ExpressionList, error) {
    75  	keys := getExMapKeys(ex)
    76  	ret := make([]Expression, 0, len(keys))
    77  	for _, key := range keys {
    78  		lhs := ParseIdentifier(key)
    79  		rhs := ex[key]
    80  		var exp Expression
    81  		if op, ok := rhs.(Op); ok {
    82  			ors, err := createOredExpressionFromMap(lhs, op)
    83  			if err != nil {
    84  				return nil, err
    85  			}
    86  			exp = NewExpressionList(OrType, ors...)
    87  		} else {
    88  			exp = lhs.Eq(rhs)
    89  		}
    90  		ret = append(ret, exp)
    91  	}
    92  	if eType == OrType {
    93  		return NewExpressionList(OrType, ret...), nil
    94  	}
    95  	return NewExpressionList(AndType, ret...), nil
    96  }
    97  
    98  func createOredExpressionFromMap(lhs IdentifierExpression, op Op) ([]Expression, error) {
    99  	opKeys := getExMapKeys(op)
   100  	ors := make([]Expression, 0, len(opKeys))
   101  	for _, opKey := range opKeys {
   102  		if exp, err := createExpressionFromOp(lhs, opKey, op); err != nil {
   103  			return nil, err
   104  		} else if exp != nil {
   105  			ors = append(ors, exp)
   106  		}
   107  	}
   108  	return ors, nil
   109  }
   110  
   111  // nolint:gocyclo // not complex just long
   112  func createExpressionFromOp(lhs IdentifierExpression, opKey string, op Op) (exp Expression, err error) {
   113  	switch strings.ToLower(opKey) {
   114  	case EqOp.String():
   115  		exp = lhs.Eq(op[opKey])
   116  	case NeqOp.String():
   117  		exp = lhs.Neq(op[opKey])
   118  	case IsOp.String():
   119  		exp = lhs.Is(op[opKey])
   120  	case IsNotOp.String():
   121  		exp = lhs.IsNot(op[opKey])
   122  	case GtOp.String():
   123  		exp = lhs.Gt(op[opKey])
   124  	case GteOp.String():
   125  		exp = lhs.Gte(op[opKey])
   126  	case LtOp.String():
   127  		exp = lhs.Lt(op[opKey])
   128  	case LteOp.String():
   129  		exp = lhs.Lte(op[opKey])
   130  	case InOp.String():
   131  		exp = lhs.In(op[opKey])
   132  	case NotInOp.String():
   133  		exp = lhs.NotIn(op[opKey])
   134  	case LikeOp.String():
   135  		exp = lhs.Like(op[opKey])
   136  	case NotLikeOp.String():
   137  		exp = lhs.NotLike(op[opKey])
   138  	case ILikeOp.String():
   139  		exp = lhs.ILike(op[opKey])
   140  	case NotILikeOp.String():
   141  		exp = lhs.NotILike(op[opKey])
   142  	case RegexpLikeOp.String():
   143  		exp = lhs.RegexpLike(op[opKey])
   144  	case RegexpNotLikeOp.String():
   145  		exp = lhs.RegexpNotLike(op[opKey])
   146  	case RegexpILikeOp.String():
   147  		exp = lhs.RegexpILike(op[opKey])
   148  	case RegexpNotILikeOp.String():
   149  		exp = lhs.RegexpNotILike(op[opKey])
   150  	case betweenStr:
   151  		rangeVal, ok := op[opKey].(RangeVal)
   152  		if ok {
   153  			exp = lhs.Between(rangeVal)
   154  		}
   155  	case "notbetween":
   156  		rangeVal, ok := op[opKey].(RangeVal)
   157  		if ok {
   158  			exp = lhs.NotBetween(rangeVal)
   159  		}
   160  	default:
   161  		err = errors.New("unsupported expression type %s", opKey)
   162  	}
   163  	return exp, err
   164  }
   165  

View as plain text