-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add QueryKey helper functions (#613)
* add QueryKey helper functions
- Loading branch information
1 parent
97ceadb
commit 59c388b
Showing
2 changed files
with
364 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package query | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" | ||
) | ||
|
||
// IndexedSequencesKeyFilter creates a KeyFilter that filters logs for the provided sequence property values at the | ||
// specified property name. Sequence value filters are 'OR'ed together. A sequence read name is the value that | ||
// identifies the sequence type. The signature value name is the sequence property to apply the filter to and the | ||
// sequence values are the individual values to search for in the provided property. | ||
func IndexedSequencesKeyFilter( | ||
readName string, | ||
comparatorName string, | ||
values []string, | ||
confidence primitives.ConfidenceLevel, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
filtersForValues(comparatorName, values), | ||
Confidence(confidence), | ||
}, | ||
} | ||
} | ||
|
||
// IndexedSequencesByBlockRangeKeyFilter creates a KeyFilter that filters sequences for the provided property values at | ||
// the specified property name. Value filters are 'OR'ed together and results are limited by provided cursor range. A | ||
// read name is the value that identifies the sequence type. The signature property name is the sequence property to | ||
// apply the filter to and the sequence values are the individual values to search for in the provided property. | ||
func IndexedSequencesByBlockRangeKeyFilter( | ||
readName string, | ||
start, end string, | ||
comparatorName string, | ||
values []string, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
filtersForValues(comparatorName, values), | ||
Block(start, primitives.Gte), | ||
Block(end, primitives.Lte), | ||
}, | ||
} | ||
} | ||
|
||
// IndexedSequencesValueGreaterThanKeyFilter creates a KeyFilter that filters sequences for the provided property value | ||
// and name at or above the specified confidence level. A sequence read name is the value that identifies the sequence | ||
// type. The property name is the sequence property to apply the filter to and the value is the individual value to | ||
// search for in the provided property. | ||
func IndexedSequencesValueGreaterThanKeyFilter( | ||
readName string, | ||
comparatorName, value string, | ||
confidence primitives.ConfidenceLevel, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
valueComparator(comparatorName, value, primitives.Gte), | ||
Confidence(confidence), | ||
}, | ||
} | ||
} | ||
|
||
// IndexedSequencesValueRangeKeyFilter creates a KeyFilter that filters logs on the provided sequence property between | ||
// the provided min and max, endpoints inclusive. A sequence read name is the value that identifies the sequence type. | ||
func IndexedSequencesValueRangeKeyFilter( | ||
readName string, | ||
comparatorName string, | ||
min, max string, | ||
confidence primitives.ConfidenceLevel, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
valueComparator(comparatorName, min, primitives.Gte), | ||
valueComparator(comparatorName, max, primitives.Lte), | ||
Confidence(confidence), | ||
}, | ||
} | ||
} | ||
|
||
// IndexedSequencesByTxHashKeyFilter creates a KeyFilter that filters logs for the provided transaction hash. A sequence | ||
// read name is the value that identifies the sequence type. | ||
func IndexedSequencesByTxHashKeyFilter( | ||
readName, txHash string, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
TxHash(txHash), | ||
}, | ||
} | ||
} | ||
|
||
// SequencesByBlockRangeKeyFilter creates a KeyFilter that filters sequences for the provided block range, endpoints inclusive. | ||
func SequencesByBlockRangeKeyFilter( | ||
readName string, | ||
start, end string, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
Block(start, primitives.Gte), | ||
Block(end, primitives.Lte), | ||
}, | ||
} | ||
} | ||
|
||
// SequencesCreatedAfterKeyFilter creates a KeyFilter that filters sequences for after but not equal to the provided time value. | ||
func SequencesCreatedAfterKeyFilter( | ||
readName string, | ||
timestamp time.Time, | ||
confidence primitives.ConfidenceLevel, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
Timestamp(uint64(timestamp.Unix()), primitives.Gt), | ||
Confidence(confidence), | ||
}, | ||
} | ||
} | ||
|
||
// IndexedSequencesCreatedAfterKeyFilter creates a KeyFilter that filters sequences for the provided property and values | ||
// created after the provided time value. Sequence property values filters are 'OR'ed. A sequence read name is the value | ||
// that identifies the sequence type. | ||
func IndexedSequencesCreatedAfterKeyFilter( | ||
readName string, | ||
comparatorName string, | ||
values []string, | ||
timestamp time.Time, | ||
confidence primitives.ConfidenceLevel, | ||
) KeyFilter { | ||
return KeyFilter{ | ||
Key: readName, | ||
Expressions: []Expression{ | ||
filtersForValues(comparatorName, values), | ||
Timestamp(uint64(timestamp.Unix()), primitives.Gt), | ||
Confidence(confidence), | ||
}, | ||
} | ||
} | ||
|
||
func valueComparator(comparatorName, value string, op primitives.ComparisonOperator) Expression { | ||
return Comparator(comparatorName, primitives.ValueComparator{ | ||
Value: value, | ||
Operator: op, | ||
}) | ||
} | ||
|
||
func filtersForValues(comparatorName string, values []string) Expression { | ||
valueFilters := BoolExpression{ | ||
Expressions: make([]Expression, len(values)), | ||
BoolOperator: OR, | ||
} | ||
|
||
for idx, value := range values { | ||
valueFilters.Expressions[idx] = valueComparator(comparatorName, value, primitives.Eq) | ||
} | ||
|
||
return Expression{BoolExpression: valueFilters} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
package query_test | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/types/query" | ||
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" | ||
) | ||
|
||
func TestIndexedSequencesKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.IndexedSequencesKeyFilter("readName", "property", []string{"value1", "value2"}, primitives.Finalized) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{BoolExpression: query.BoolExpression{ | ||
Expressions: []query.Expression{ | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value1", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value2", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
}, | ||
BoolOperator: query.OR, | ||
}}, | ||
{Primitive: &primitives.Confidence{ConfidenceLevel: primitives.Finalized}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestIndexedSequencesByBlockRangeKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.IndexedSequencesByBlockRangeKeyFilter("readName", "start", "end", "property", []string{"value1", "value2"}) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{BoolExpression: query.BoolExpression{ | ||
Expressions: []query.Expression{ | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value1", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value2", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
}, | ||
BoolOperator: query.OR, | ||
}}, | ||
{Primitive: &primitives.Block{Block: "start", Operator: primitives.Gte}}, | ||
{Primitive: &primitives.Block{Block: "end", Operator: primitives.Lte}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestIndexedSequencesValueGreaterThanKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.IndexedSequencesValueGreaterThanKeyFilter("readName", "property", "value1", primitives.Finalized) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value1", Operator: primitives.Gte}}, | ||
}, | ||
}, | ||
{Primitive: &primitives.Confidence{ConfidenceLevel: primitives.Finalized}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestIndexedSequencesValueRangeKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.IndexedSequencesValueRangeKeyFilter("readName", "property", "min", "max", primitives.Finalized) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "min", Operator: primitives.Gte}}, | ||
}, | ||
}, | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "max", Operator: primitives.Lte}}, | ||
}, | ||
}, | ||
{Primitive: &primitives.Confidence{ConfidenceLevel: primitives.Finalized}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestIndexedSequencesByTxHashKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.IndexedSequencesByTxHashKeyFilter("readName", "hash") | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{Primitive: &primitives.TxHash{TxHash: "hash"}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestSequencesByBlockRangeKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
filter := query.SequencesByBlockRangeKeyFilter("readName", "start", "end") | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{Primitive: &primitives.Block{Block: "start", Operator: primitives.Gte}}, | ||
{Primitive: &primitives.Block{Block: "end", Operator: primitives.Lte}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestSequencesCreatedAfterKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
now := time.Now() | ||
|
||
filter := query.SequencesCreatedAfterKeyFilter("readName", now, primitives.Finalized) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{Primitive: &primitives.Timestamp{Timestamp: uint64(now.Unix()), Operator: primitives.Gt}}, | ||
{Primitive: &primitives.Confidence{ConfidenceLevel: primitives.Finalized}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} | ||
|
||
func TestIndexedSequencesCreatedAfterKeyFilter(t *testing.T) { | ||
t.Parallel() | ||
|
||
now := time.Now() | ||
|
||
filter := query.IndexedSequencesCreatedAfterKeyFilter("readName", "property", []string{"value1", "value2"}, now, primitives.Finalized) | ||
expected := query.KeyFilter{ | ||
Key: "readName", | ||
Expressions: []query.Expression{ | ||
{BoolExpression: query.BoolExpression{ | ||
Expressions: []query.Expression{ | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value1", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
{ | ||
Primitive: &primitives.Comparator{ | ||
Name: "property", | ||
ValueComparators: []primitives.ValueComparator{{Value: "value2", Operator: primitives.Eq}}, | ||
}, | ||
}, | ||
}, | ||
BoolOperator: query.OR, | ||
}}, | ||
{Primitive: &primitives.Timestamp{Timestamp: uint64(now.Unix()), Operator: primitives.Gt}}, | ||
{Primitive: &primitives.Confidence{ConfidenceLevel: primitives.Finalized}}, | ||
}, | ||
} | ||
|
||
require.Equal(t, expected, filter) | ||
} |