|
@ -1,6 +1,7 @@ |
|
|
package kv |
|
|
package kv |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"context" |
|
|
"fmt" |
|
|
"fmt" |
|
|
"io/ioutil" |
|
|
"io/ioutil" |
|
|
"os" |
|
|
"os" |
|
@ -118,10 +119,12 @@ func TestTxSearch(t *testing.T) { |
|
|
{"account.number CONTAINS 'Iv'", 0}, |
|
|
{"account.number CONTAINS 'Iv'", 0}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
for _, tc := range testCases { |
|
|
tc := tc |
|
|
tc := tc |
|
|
t.Run(tc.q, func(t *testing.T) { |
|
|
t.Run(tc.q, func(t *testing.T) { |
|
|
results, err := indexer.Search(query.MustParse(tc.q)) |
|
|
|
|
|
|
|
|
results, err := indexer.Search(ctx, query.MustParse(tc.q)) |
|
|
assert.NoError(t, err) |
|
|
assert.NoError(t, err) |
|
|
|
|
|
|
|
|
assert.Len(t, results, tc.resultsLength) |
|
|
assert.Len(t, results, tc.resultsLength) |
|
@ -132,6 +135,73 @@ func TestTxSearch(t *testing.T) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestTxSearchWithCancelation(t *testing.T) { |
|
|
|
|
|
allowedKeys := []string{"account.number", "account.owner", "account.date"} |
|
|
|
|
|
indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) |
|
|
|
|
|
|
|
|
|
|
|
txResult := txResultWithEvents([]abci.Event{ |
|
|
|
|
|
{Type: "account", Attributes: []kv.Pair{{Key: []byte("number"), Value: []byte("1")}}}, |
|
|
|
|
|
{Type: "account", Attributes: []kv.Pair{{Key: []byte("owner"), Value: []byte("Ivan")}}}, |
|
|
|
|
|
{Type: "", Attributes: []kv.Pair{{Key: []byte("not_allowed"), Value: []byte("Vlad")}}}, |
|
|
|
|
|
}) |
|
|
|
|
|
hash := txResult.Tx.Hash() |
|
|
|
|
|
|
|
|
|
|
|
err := indexer.Index(txResult) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
testCases := []struct { |
|
|
|
|
|
q string |
|
|
|
|
|
resultsLength int |
|
|
|
|
|
}{ |
|
|
|
|
|
// search by hash
|
|
|
|
|
|
{fmt.Sprintf("tx.hash = '%X'", hash), 0}, |
|
|
|
|
|
// search by exact match (one key)
|
|
|
|
|
|
{"account.number = 1", 0}, |
|
|
|
|
|
// search by exact match (two keys)
|
|
|
|
|
|
{"account.number = 1 AND account.owner = 'Ivan'", 0}, |
|
|
|
|
|
// search by exact match (two keys)
|
|
|
|
|
|
{"account.number = 1 AND account.owner = 'Vlad'", 0}, |
|
|
|
|
|
{"account.owner = 'Vlad' AND account.number = 1", 0}, |
|
|
|
|
|
{"account.number >= 1 AND account.owner = 'Vlad'", 0}, |
|
|
|
|
|
{"account.owner = 'Vlad' AND account.number >= 1", 0}, |
|
|
|
|
|
{"account.number <= 0", 0}, |
|
|
|
|
|
{"account.number <= 0 AND account.owner = 'Ivan'", 0}, |
|
|
|
|
|
// search using a prefix of the stored value
|
|
|
|
|
|
{"account.owner = 'Iv'", 0}, |
|
|
|
|
|
// search by range
|
|
|
|
|
|
{"account.number >= 1 AND account.number <= 5", 0}, |
|
|
|
|
|
// search by range (lower bound)
|
|
|
|
|
|
{"account.number >= 1", 0}, |
|
|
|
|
|
// search by range (upper bound)
|
|
|
|
|
|
{"account.number <= 5", 0}, |
|
|
|
|
|
// search using not allowed key
|
|
|
|
|
|
{"not_allowed = 'boom'", 0}, |
|
|
|
|
|
// search for not existing tx result
|
|
|
|
|
|
{"account.number >= 2 AND account.number <= 5", 0}, |
|
|
|
|
|
// search using not existing key
|
|
|
|
|
|
{"account.date >= TIME 2013-05-03T14:45:00Z", 0}, |
|
|
|
|
|
// search using CONTAINS
|
|
|
|
|
|
{"account.owner CONTAINS 'an'", 0}, |
|
|
|
|
|
// search for non existing value using CONTAINS
|
|
|
|
|
|
{"account.owner CONTAINS 'Vlad'", 0}, |
|
|
|
|
|
// search using the wrong key (of numeric type) using CONTAINS
|
|
|
|
|
|
{"account.number CONTAINS 'Iv'", 0}, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
|
|
|
|
|
|
|
|
|
|
cancel() |
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
|
|
|
tc := tc |
|
|
|
|
|
t.Run(tc.q, func(t *testing.T) { |
|
|
|
|
|
results, err := indexer.Search(ctx, query.MustParse(tc.q)) |
|
|
|
|
|
assert.NoError(t, err) |
|
|
|
|
|
assert.Len(t, results, tc.resultsLength) |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func TestTxSearchDeprecatedIndexing(t *testing.T) { |
|
|
func TestTxSearchDeprecatedIndexing(t *testing.T) { |
|
|
allowedKeys := []string{"account.number", "sender"} |
|
|
allowedKeys := []string{"account.number", "sender"} |
|
|
indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) |
|
|
indexer := NewTxIndex(db.NewMemDB(), IndexEvents(allowedKeys)) |
|
@ -192,10 +262,12 @@ func TestTxSearchDeprecatedIndexing(t *testing.T) { |
|
|
{"sender = 'addr1'", []*types.TxResult{txResult2}}, |
|
|
{"sender = 'addr1'", []*types.TxResult{txResult2}}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
for _, tc := range testCases { |
|
|
tc := tc |
|
|
tc := tc |
|
|
t.Run(tc.q, func(t *testing.T) { |
|
|
t.Run(tc.q, func(t *testing.T) { |
|
|
results, err := indexer.Search(query.MustParse(tc.q)) |
|
|
|
|
|
|
|
|
results, err := indexer.Search(ctx, query.MustParse(tc.q)) |
|
|
require.NoError(t, err) |
|
|
require.NoError(t, err) |
|
|
require.Equal(t, results, tc.results) |
|
|
require.Equal(t, results, tc.results) |
|
|
}) |
|
|
}) |
|
@ -214,7 +286,9 @@ func TestTxSearchOneTxWithMultipleSameTagsButDifferentValues(t *testing.T) { |
|
|
err := indexer.Index(txResult) |
|
|
err := indexer.Index(txResult) |
|
|
require.NoError(t, err) |
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
results, err := indexer.Search(query.MustParse("account.number >= 1")) |
|
|
|
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
|
|
|
|
|
|
|
results, err := indexer.Search(ctx, query.MustParse("account.number >= 1")) |
|
|
assert.NoError(t, err) |
|
|
assert.NoError(t, err) |
|
|
|
|
|
|
|
|
assert.Len(t, results, 1) |
|
|
assert.Len(t, results, 1) |
|
@ -268,7 +342,9 @@ func TestTxSearchMultipleTxs(t *testing.T) { |
|
|
err = indexer.Index(txResult4) |
|
|
err = indexer.Index(txResult4) |
|
|
require.NoError(t, err) |
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
results, err := indexer.Search(query.MustParse("account.number >= 1")) |
|
|
|
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
|
|
|
|
|
|
|
results, err := indexer.Search(ctx, query.MustParse("account.number >= 1")) |
|
|
assert.NoError(t, err) |
|
|
assert.NoError(t, err) |
|
|
|
|
|
|
|
|
require.Len(t, results, 3) |
|
|
require.Len(t, results, 3) |
|
|