113 lines
3.5 KiB
Go
113 lines
3.5 KiB
Go
package indexes
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"cosmossdk.io/collections"
|
|
)
|
|
|
|
func TestMultiIndex(t *testing.T) {
|
|
sk, ctx := deps()
|
|
schema := collections.NewSchemaBuilder(sk)
|
|
|
|
mi := NewMulti(schema, collections.NewPrefix(1), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
|
|
return value.City, nil
|
|
})
|
|
|
|
// we create two reference keys for primary key 1 and 2 associated with "milan"
|
|
require.NoError(t, mi.Reference(ctx, 1, company{City: "milan"}, func() (company, error) { return company{}, collections.ErrNotFound }))
|
|
require.NoError(t, mi.Reference(ctx, 2, company{City: "milan"}, func() (company, error) { return company{}, collections.ErrNotFound }))
|
|
|
|
iter, err := mi.MatchExact(ctx, "milan")
|
|
require.NoError(t, err)
|
|
pks, err := iter.PrimaryKeys()
|
|
require.NoError(t, err)
|
|
require.Equal(t, []uint64{1, 2}, pks)
|
|
|
|
// replace
|
|
require.NoError(t, mi.Reference(ctx, 1, company{City: "new york"}, func() (company, error) { return company{City: "milan"}, nil }))
|
|
|
|
// assert after replace only company with id 2 is referenced by milan
|
|
iter, err = mi.MatchExact(ctx, "milan")
|
|
require.NoError(t, err)
|
|
pks, err = iter.PrimaryKeys()
|
|
require.NoError(t, err)
|
|
require.Equal(t, []uint64{2}, pks)
|
|
|
|
// assert after replace company with id 1 is referenced by new york
|
|
iter, err = mi.MatchExact(ctx, "new york")
|
|
require.NoError(t, err)
|
|
pks, err = iter.PrimaryKeys()
|
|
require.NoError(t, err)
|
|
require.Equal(t, []uint64{1}, pks)
|
|
|
|
// test iter methods
|
|
iter, err = mi.Iterate(ctx, nil)
|
|
require.NoError(t, err)
|
|
|
|
fullKey, err := iter.FullKey()
|
|
require.NoError(t, err)
|
|
require.Equal(t, collections.Join("milan", uint64(2)), fullKey)
|
|
|
|
pk, err := iter.PrimaryKey()
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(2), pk)
|
|
|
|
iter.Next()
|
|
require.True(t, iter.Valid())
|
|
iter.Next()
|
|
require.False(t, iter.Valid())
|
|
require.NoError(t, iter.Close())
|
|
}
|
|
|
|
func TestMultiUnchecked(t *testing.T) {
|
|
sk, ctx := deps()
|
|
schema := collections.NewSchemaBuilder(sk)
|
|
|
|
uncheckedMi := NewMulti(schema, collections.NewPrefix("prefix"), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
|
|
return value.City, nil
|
|
}, WithMultiUncheckedValue())
|
|
|
|
mi := NewMulti(schema, collections.NewPrefix("prefix"), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
|
|
return value.City, nil
|
|
})
|
|
|
|
rawKey, err := collections.EncodeKeyWithPrefix(
|
|
collections.NewPrefix("prefix"),
|
|
uncheckedMi.KeyCodec(),
|
|
collections.Join("milan", uint64(2)))
|
|
require.NoError(t, err)
|
|
|
|
// set value to be something different from []byte{}
|
|
require.NoError(t, sk.OpenKVStore(ctx).Set(rawKey, []byte("something")))
|
|
|
|
// normal multi index will fail.
|
|
err = mi.Walk(ctx, nil, func(indexingKey string, indexedKey uint64) (stop bool, err error) {
|
|
return true, err
|
|
})
|
|
require.ErrorIs(t, err, collections.ErrEncoding)
|
|
|
|
// unchecked multi index will not fail.
|
|
err = uncheckedMi.Walk(ctx, nil, func(indexingKey string, indexedKey uint64) (stop bool, err error) {
|
|
require.Equal(t, "milan", indexingKey)
|
|
require.Equal(t, uint64(2), indexedKey)
|
|
return true, err
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// unchecked multi will also reset the value
|
|
err = mi.Reference(ctx, 2, company{City: "milan"}, func() (company, error) {
|
|
return company{
|
|
City: "milan",
|
|
}, nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// value reset to []byte{}
|
|
rawValue, err := sk.OpenKVStore(ctx).Get(rawKey)
|
|
require.NoError(t, err)
|
|
require.Equal(t, []byte{}, rawValue)
|
|
}
|