feat(collections): add sequence (#14364)
Co-authored-by: testinginprod <testinginprod@somewhere.idk> Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
parent
22dfa112b9
commit
1d16adce8a
@ -32,4 +32,5 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
## [Unreleased]
|
||||
|
||||
* [#14134](https://github.com/cosmos/cosmos-sdk/pull/14134) Initialise core (Prefix, KeyEncoder, ValueEncoder, Map).
|
||||
* [#14351](https://github.com/cosmos/cosmos-sdk/pull/14351) Add keyset
|
||||
* [#14351](https://github.com/cosmos/cosmos-sdk/pull/14351) Add keyset
|
||||
* [#14364](https://github.com/cosmos/cosmos-sdk/pull/14364) Add sequence
|
||||
49
collections/sequence.go
Normal file
49
collections/sequence.go
Normal file
@ -0,0 +1,49 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// DefaultSequenceStart defines the default starting number of a sequence.
|
||||
const DefaultSequenceStart uint64 = 1
|
||||
|
||||
// Sequence builds on top of an Item, and represents a monotonically increasing number.
|
||||
type Sequence Item[uint64]
|
||||
|
||||
// NewSequence instantiates a new sequence given
|
||||
// a Schema, a Prefix and humanised name for the sequence.
|
||||
func NewSequence(schema Schema, prefix Prefix, name string) Sequence {
|
||||
return (Sequence)(NewItem(schema, prefix, name, Uint64Value))
|
||||
}
|
||||
|
||||
// Peek returns the current sequence value, if no number
|
||||
// is set then the DefaultSequenceStart is returned.
|
||||
// Errors on encoding issues.
|
||||
func (s Sequence) Peek(ctx context.Context) (uint64, error) {
|
||||
n, err := (Item[uint64])(s).Get(ctx)
|
||||
switch {
|
||||
case err == nil:
|
||||
return n, nil
|
||||
case errors.Is(err, ErrNotFound):
|
||||
return DefaultSequenceStart, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// Next returns the next sequence number, and sets the next expected sequence.
|
||||
// Errors on encoding issues.
|
||||
func (s Sequence) Next(ctx context.Context) (uint64, error) {
|
||||
seq, err := s.Peek(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return seq, s.Set(ctx, seq+1)
|
||||
}
|
||||
|
||||
// Set hard resets the sequence to the provided value.
|
||||
// Errors on encoding issues.
|
||||
func (s Sequence) Set(ctx context.Context, value uint64) error {
|
||||
return (Item[uint64])(s).Set(ctx, value)
|
||||
}
|
||||
32
collections/sequence_test.go
Normal file
32
collections/sequence_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSequence(t *testing.T) {
|
||||
sk, ctx := deps()
|
||||
schema := NewSchema(sk)
|
||||
seq := NewSequence(schema, NewPrefix(0), "sequence")
|
||||
// initially the first available number is DefaultSequenceStart
|
||||
n, err := seq.Peek(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, DefaultSequenceStart, n)
|
||||
|
||||
// when we call next when sequence is still unset the first expected value is DefaultSequenceStart
|
||||
n, err = seq.Next(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, DefaultSequenceStart, n)
|
||||
// when we call peek after the first number is set, then the next expected sequence is DefaultSequenceStart + 1
|
||||
n, err = seq.Peek(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, DefaultSequenceStart+1, n)
|
||||
|
||||
// set
|
||||
err = seq.Set(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
n, err = seq.Peek(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, n, uint64(10))
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user