-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(collections): add sequence (#14364)
Co-authored-by: testinginprod <[email protected]> Co-authored-by: Aleksandr Bezobchuk <[email protected]>
- Loading branch information
1 parent
22dfa11
commit 1d16adc
Showing
3 changed files
with
83 additions
and
1 deletion.
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
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,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) | ||
} |
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,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)) | ||
} |