github.com/okex/exchain@v1.8.0/libs/tendermint/state/indexer/query_range.go (about)

     1  package indexer
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/okex/exchain/libs/tendermint/libs/pubsub/query"
     7  )
     8  
     9  type QueryRanges map[string]QueryRange
    10  
    11  // QueryRange defines a range within a query condition.
    12  type QueryRange struct {
    13  	LowerBound        interface{} // int || time.Time
    14  	UpperBound        interface{} // int || time.Time
    15  	Key               string
    16  	IncludeLowerBound bool
    17  	IncludeUpperBound bool
    18  }
    19  
    20  func LookForRanges(conditions []query.Condition) (ranges QueryRanges, indexes []int) {
    21  	ranges = make(QueryRanges)
    22  	for i, c := range conditions {
    23  		if IsRangeOperation(c.Op) {
    24  			r, ok := ranges[c.CompositeKey]
    25  			if !ok {
    26  				r = QueryRange{Key: c.CompositeKey}
    27  			}
    28  
    29  			switch c.Op {
    30  			case query.OpGreater:
    31  				r.LowerBound = c.Operand
    32  
    33  			case query.OpGreaterEqual:
    34  				r.IncludeLowerBound = true
    35  				r.LowerBound = c.Operand
    36  
    37  			case query.OpLess:
    38  				r.UpperBound = c.Operand
    39  
    40  			case query.OpLessEqual:
    41  				r.IncludeUpperBound = true
    42  				r.UpperBound = c.Operand
    43  			}
    44  
    45  			ranges[c.CompositeKey] = r
    46  			indexes = append(indexes, i)
    47  		}
    48  	}
    49  
    50  	return ranges, indexes
    51  }
    52  
    53  // IsRangeOperation returns a boolean signifying if a query Operator is a range
    54  // operation or not.
    55  func IsRangeOperation(op query.Operator) bool {
    56  	switch op {
    57  	case query.OpGreater, query.OpGreaterEqual, query.OpLess, query.OpLessEqual:
    58  		return true
    59  
    60  	default:
    61  		return false
    62  	}
    63  }
    64  
    65  // LowerBoundValue returns the value for the lower bound. If the lower bound is
    66  // nil, nil will be returned.
    67  func (qr QueryRange) LowerBoundValue() interface{} {
    68  	if qr.LowerBound == nil {
    69  		return nil
    70  	}
    71  
    72  	if qr.IncludeLowerBound {
    73  		return qr.LowerBound
    74  	}
    75  
    76  	switch t := qr.LowerBound.(type) {
    77  	case int64:
    78  		return t + 1
    79  
    80  	case time.Time:
    81  		return t.Unix() + 1
    82  
    83  	default:
    84  		panic("not implemented")
    85  	}
    86  }
    87  
    88  // UpperBoundValue returns the value for the upper bound. If the upper bound is
    89  // nil, nil will be returned.
    90  func (qr QueryRange) UpperBoundValue() interface{} {
    91  	if qr.UpperBound == nil {
    92  		return nil
    93  	}
    94  
    95  	if qr.IncludeUpperBound {
    96  		return qr.UpperBound
    97  	}
    98  
    99  	switch t := qr.UpperBound.(type) {
   100  	case int64:
   101  		return t - 1
   102  
   103  	case time.Time:
   104  		return t.Unix() - 1
   105  
   106  	default:
   107  		panic("not implemented")
   108  	}
   109  }
   110  
   111  // AnyBound returns either the lower bound if non-nil, otherwise the upper bound.
   112  func (qr QueryRange) AnyBound() interface{} {
   113  	if qr.LowerBound != nil {
   114  		return qr.LowerBound
   115  	}
   116  
   117  	return qr.UpperBound
   118  }