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