Skip to content

Commit

Permalink
feat(collections): add sequence (#14364)
Browse files Browse the repository at this point in the history
Co-authored-by: testinginprod <[email protected]>
Co-authored-by: Aleksandr Bezobchuk <[email protected]>
  • Loading branch information
3 people authored Dec 21, 2022
1 parent 22dfa11 commit 1d16adc
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
3 changes: 2 additions & 1 deletion collections/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 49 additions & 0 deletions collections/sequence.go
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions collections/sequence_test.go
Original file line number Diff line number Diff line change
@@ -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))
}

0 comments on commit 1d16adc

Please sign in to comment.