feat(orm): add sequence getter for auto increment tables (#15320)
Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
parent
112d071598
commit
ddd18ff2eb
@ -36,10 +36,14 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Feature
|
||||
|
||||
* [#15320](https://github.com/cosmos/cosmos-sdk/pull/15320) Add current sequence getter (`LastInsertedSequence`) for auto increment tables.
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
- [14822](https://github.com/cosmos/cosmos-sdk/pull/14822) Migrate to cosmossdk.io/core genesis API
|
||||
* [#14822](https://github.com/cosmos/cosmos-sdk/pull/14822) Migrate to cosmossdk.io/core genesis API
|
||||
|
||||
### State-machine Breaking Changes
|
||||
|
||||
- [12273](https://github.com/cosmos/cosmos-sdk/pull/12273) The timestamp key encoding was reworked to properly handle nil values. Existing users will need to manually migrate their data to the new encoding before upgrading.
|
||||
* [#12273](https://github.com/cosmos/cosmos-sdk/pull/12273) The timestamp key encoding was reworked to properly handle nil values. Existing users will need to manually migrate their data to the new encoding before upgrading.
|
||||
|
||||
@ -62,6 +62,7 @@ func (t tableGen) getTableInterface() {
|
||||
t.P("Insert(ctx ", contextPkg.Ident("Context"), ", ", t.param(t.msg.GoIdent.GoName), " *", t.QualifiedGoIdent(t.msg.GoIdent), ") error")
|
||||
if t.table.PrimaryKey.AutoIncrement {
|
||||
t.P("InsertReturning", fieldsToCamelCase(t.table.PrimaryKey.Fields), "(ctx ", contextPkg.Ident("Context"), ", ", t.param(t.msg.GoIdent.GoName), " *", t.QualifiedGoIdent(t.msg.GoIdent), ") (uint64, error)")
|
||||
t.P("LastInsertedSequence(ctx ", contextPkg.Ident("Context"), ") (uint64, error)")
|
||||
}
|
||||
t.P("Update(ctx ", contextPkg.Ident("Context"), ", ", t.param(t.msg.GoIdent.GoName), " *", t.QualifiedGoIdent(t.msg.GoIdent), ") error")
|
||||
t.P("Save(ctx ", contextPkg.Ident("Context"), ", ", t.param(t.msg.GoIdent.GoName), " *", t.QualifiedGoIdent(t.msg.GoIdent), ") error")
|
||||
@ -184,6 +185,11 @@ func (t tableGen) genTableImpl() {
|
||||
t.P("return ", receiverVar, ".table.InsertReturningPKey(ctx, ", varName, ")")
|
||||
t.P("}")
|
||||
t.P()
|
||||
|
||||
t.P(receiver, "LastInsertedSequence(ctx ", contextPkg.Ident("Context"), ") (uint64, error) {")
|
||||
t.P("return ", receiverVar, ".table.LastInsertedSequence(ctx)")
|
||||
t.P("}")
|
||||
t.P()
|
||||
}
|
||||
|
||||
// Has
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: testpb/bank.proto
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: testpb/bank_query.proto
|
||||
|
||||
@ -139,6 +139,7 @@ type ListBalanceRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListBalanceRequest_PrefixQuery
|
||||
// *ListBalanceRequest_RangeQuery_
|
||||
Query isListBalanceRequest_Query `protobuf_oneof:"query"`
|
||||
@ -389,6 +390,7 @@ type ListSupplyRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListSupplyRequest_PrefixQuery
|
||||
// *ListSupplyRequest_RangeQuery_
|
||||
Query isListSupplyRequest_Query `protobuf_oneof:"query"`
|
||||
@ -541,6 +543,7 @@ type ListBalanceRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListBalanceRequest_IndexKey_AddressDenom_
|
||||
// *ListBalanceRequest_IndexKey_Denom_
|
||||
Key isListBalanceRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
@ -795,6 +798,7 @@ type ListSupplyRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListSupplyRequest_IndexKey_Denom_
|
||||
Key isListSupplyRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
}
|
||||
|
||||
@ -216,6 +216,7 @@ func NewExampleTableTable(db ormtable.Schema) (ExampleTableTable, error) {
|
||||
type ExampleAutoIncrementTableTable interface {
|
||||
Insert(ctx context.Context, exampleAutoIncrementTable *ExampleAutoIncrementTable) error
|
||||
InsertReturningId(ctx context.Context, exampleAutoIncrementTable *ExampleAutoIncrementTable) (uint64, error)
|
||||
LastInsertedSequence(ctx context.Context) (uint64, error)
|
||||
Update(ctx context.Context, exampleAutoIncrementTable *ExampleAutoIncrementTable) error
|
||||
Save(ctx context.Context, exampleAutoIncrementTable *ExampleAutoIncrementTable) error
|
||||
Delete(ctx context.Context, exampleAutoIncrementTable *ExampleAutoIncrementTable) error
|
||||
@ -302,6 +303,10 @@ func (this exampleAutoIncrementTableTable) InsertReturningId(ctx context.Context
|
||||
return this.table.InsertReturningPKey(ctx, exampleAutoIncrementTable)
|
||||
}
|
||||
|
||||
func (this exampleAutoIncrementTableTable) LastInsertedSequence(ctx context.Context) (uint64, error) {
|
||||
return this.table.LastInsertedSequence(ctx)
|
||||
}
|
||||
|
||||
func (this exampleAutoIncrementTableTable) Has(ctx context.Context, id uint64) (found bool, err error) {
|
||||
return this.table.PrimaryKey().Has(ctx, id)
|
||||
}
|
||||
@ -401,6 +406,7 @@ func NewExampleSingletonTable(db ormtable.Schema) (ExampleSingletonTable, error)
|
||||
type ExampleTimestampTable interface {
|
||||
Insert(ctx context.Context, exampleTimestamp *ExampleTimestamp) error
|
||||
InsertReturningId(ctx context.Context, exampleTimestamp *ExampleTimestamp) (uint64, error)
|
||||
LastInsertedSequence(ctx context.Context) (uint64, error)
|
||||
Update(ctx context.Context, exampleTimestamp *ExampleTimestamp) error
|
||||
Save(ctx context.Context, exampleTimestamp *ExampleTimestamp) error
|
||||
Delete(ctx context.Context, exampleTimestamp *ExampleTimestamp) error
|
||||
@ -484,6 +490,10 @@ func (this exampleTimestampTable) InsertReturningId(ctx context.Context, example
|
||||
return this.table.InsertReturningPKey(ctx, exampleTimestamp)
|
||||
}
|
||||
|
||||
func (this exampleTimestampTable) LastInsertedSequence(ctx context.Context) (uint64, error) {
|
||||
return this.table.LastInsertedSequence(ctx)
|
||||
}
|
||||
|
||||
func (this exampleTimestampTable) Has(ctx context.Context, id uint64) (found bool, err error) {
|
||||
return this.table.PrimaryKey().Has(ctx, id)
|
||||
}
|
||||
@ -683,6 +693,7 @@ func NewSimpleExampleTable(db ormtable.Schema) (SimpleExampleTable, error) {
|
||||
type ExampleAutoIncFieldNameTable interface {
|
||||
Insert(ctx context.Context, exampleAutoIncFieldName *ExampleAutoIncFieldName) error
|
||||
InsertReturningFoo(ctx context.Context, exampleAutoIncFieldName *ExampleAutoIncFieldName) (uint64, error)
|
||||
LastInsertedSequence(ctx context.Context) (uint64, error)
|
||||
Update(ctx context.Context, exampleAutoIncFieldName *ExampleAutoIncFieldName) error
|
||||
Save(ctx context.Context, exampleAutoIncFieldName *ExampleAutoIncFieldName) error
|
||||
Delete(ctx context.Context, exampleAutoIncFieldName *ExampleAutoIncFieldName) error
|
||||
@ -753,6 +764,10 @@ func (this exampleAutoIncFieldNameTable) InsertReturningFoo(ctx context.Context,
|
||||
return this.table.InsertReturningPKey(ctx, exampleAutoIncFieldName)
|
||||
}
|
||||
|
||||
func (this exampleAutoIncFieldNameTable) LastInsertedSequence(ctx context.Context) (uint64, error) {
|
||||
return this.table.LastInsertedSequence(ctx)
|
||||
}
|
||||
|
||||
func (this exampleAutoIncFieldNameTable) Has(ctx context.Context, foo uint64) (found bool, err error) {
|
||||
return this.table.PrimaryKey().Has(ctx, foo)
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: testpb/test_schema.proto
|
||||
|
||||
@ -105,6 +105,7 @@ type ExampleTable struct {
|
||||
Map map[string]uint32 `protobuf:"bytes,18,rep,name=map,proto3" json:"map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
|
||||
Msg *ExampleTable_ExampleMessage `protobuf:"bytes,19,opt,name=msg,proto3" json:"msg,omitempty"`
|
||||
// Types that are assignable to Sum:
|
||||
//
|
||||
// *ExampleTable_Oneof
|
||||
Sum isExampleTable_Sum `protobuf_oneof:"sum"`
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: testpb/test_schema_query.proto
|
||||
|
||||
@ -253,6 +253,7 @@ type ListExampleTableRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListExampleTableRequest_PrefixQuery
|
||||
// *ListExampleTableRequest_RangeQuery_
|
||||
Query isListExampleTableRequest_Query `protobuf_oneof:"query"`
|
||||
@ -599,6 +600,7 @@ type ListExampleAutoIncrementTableRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListExampleAutoIncrementTableRequest_PrefixQuery
|
||||
// *ListExampleAutoIncrementTableRequest_RangeQuery_
|
||||
Query isListExampleAutoIncrementTableRequest_Query `protobuf_oneof:"query"`
|
||||
@ -938,6 +940,7 @@ type ListExampleTimestampRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListExampleTimestampRequest_PrefixQuery
|
||||
// *ListExampleTimestampRequest_RangeQuery_
|
||||
Query isListExampleTimestampRequest_Query `protobuf_oneof:"query"`
|
||||
@ -1284,6 +1287,7 @@ type ListSimpleExampleRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListSimpleExampleRequest_PrefixQuery
|
||||
// *ListSimpleExampleRequest_RangeQuery_
|
||||
Query isListSimpleExampleRequest_Query `protobuf_oneof:"query"`
|
||||
@ -1534,6 +1538,7 @@ type ListExampleAutoIncFieldNameRequest struct {
|
||||
// query specifies the type of query - either a prefix or range query.
|
||||
//
|
||||
// Types that are assignable to Query:
|
||||
//
|
||||
// *ListExampleAutoIncFieldNameRequest_PrefixQuery
|
||||
// *ListExampleAutoIncFieldNameRequest_RangeQuery_
|
||||
Query isListExampleAutoIncFieldNameRequest_Query `protobuf_oneof:"query"`
|
||||
@ -1686,6 +1691,7 @@ type ListExampleTableRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListExampleTableRequest_IndexKey_U_32I_64Str
|
||||
// *ListExampleTableRequest_IndexKey_U_64Str
|
||||
// *ListExampleTableRequest_IndexKey_StrU_32
|
||||
@ -2108,6 +2114,7 @@ type ListExampleAutoIncrementTableRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListExampleAutoIncrementTableRequest_IndexKey_Id_
|
||||
// *ListExampleAutoIncrementTableRequest_IndexKey_X_
|
||||
Key isListExampleAutoIncrementTableRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
@ -2354,6 +2361,7 @@ type ListExampleTimestampRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListExampleTimestampRequest_IndexKey_Id_
|
||||
// *ListExampleTimestampRequest_IndexKey_Ts_
|
||||
Key isListExampleTimestampRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
@ -2598,6 +2606,7 @@ type ListSimpleExampleRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListSimpleExampleRequest_IndexKey_Name_
|
||||
// *ListSimpleExampleRequest_IndexKey_Unique_
|
||||
Key isListSimpleExampleRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
@ -2842,6 +2851,7 @@ type ListExampleAutoIncFieldNameRequest_IndexKey struct {
|
||||
// key specifies the index key value.
|
||||
//
|
||||
// Types that are assignable to Key:
|
||||
//
|
||||
// *ListExampleAutoIncFieldNameRequest_IndexKey_Foo_
|
||||
Key isListExampleAutoIncFieldNameRequest_IndexKey_Key `protobuf_oneof:"key"`
|
||||
}
|
||||
|
||||
@ -61,6 +61,15 @@ func (t autoIncrementTable) Update(ctx context.Context, message proto.Message) e
|
||||
return err
|
||||
}
|
||||
|
||||
func (t autoIncrementTable) LastInsertedSequence(ctx context.Context) (uint64, error) {
|
||||
backend, err := t.getBackend(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return t.curSeqValue(backend.IndexStoreReader())
|
||||
}
|
||||
|
||||
func (t *autoIncrementTable) save(ctx context.Context, backend Backend, message proto.Message, mode saveMode) (newPK uint64, err error) {
|
||||
messageRef := message.ProtoReflect()
|
||||
val := messageRef.Get(t.autoIncField).Uint()
|
||||
|
||||
@ -52,12 +52,18 @@ func runAutoIncrementScenario(t *testing.T, table ormtable.AutoIncrementTable, c
|
||||
ex1 := &testpb.ExampleAutoIncrementTable{X: "foo", Y: 5}
|
||||
assert.NilError(t, store.Save(ctx, ex1))
|
||||
assert.Equal(t, uint64(1), ex1.Id)
|
||||
curSeq, err := table.LastInsertedSequence(ctx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, curSeq, uint64(1))
|
||||
|
||||
ex2 := &testpb.ExampleAutoIncrementTable{X: "bar", Y: 10}
|
||||
newId, err := table.InsertReturningPKey(ctx, ex2)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, uint64(2), ex2.Id)
|
||||
assert.Equal(t, newId, ex2.Id)
|
||||
curSeq, err = table.LastInsertedSequence(ctx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, curSeq, uint64(2))
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
assert.NilError(t, table.ExportJSON(ctx, buf))
|
||||
@ -78,6 +84,9 @@ func runAutoIncrementScenario(t *testing.T, table ormtable.AutoIncrementTable, c
|
||||
ex1.Id = 0
|
||||
assert.NilError(t, table.Insert(store3, ex1))
|
||||
assert.Equal(t, uint64(3), ex1.Id) // should equal 3 because the sequence number 2 should have been imported from JSON
|
||||
curSeq, err = table.LastInsertedSequence(store3)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, curSeq, uint64(3))
|
||||
}
|
||||
|
||||
func TestBadJSON(t *testing.T) {
|
||||
|
||||
@ -3,18 +3,15 @@ package ormtable
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/orm/internal/fieldnames"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/orm/encoding/encodeutil"
|
||||
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
ormv1 "cosmossdk.io/api/cosmos/orm/v1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/orm/encoding/encodeutil"
|
||||
"github.com/cosmos/cosmos-sdk/orm/encoding/ormkv"
|
||||
"github.com/cosmos/cosmos-sdk/orm/internal/fieldnames"
|
||||
"github.com/cosmos/cosmos-sdk/orm/types/ormerrors"
|
||||
)
|
||||
|
||||
|
||||
@ -143,6 +143,7 @@ type Table interface {
|
||||
|
||||
// Schema is an interface for things that contain tables and can encode and
|
||||
// decode kv-store pairs.
|
||||
|
||||
type Schema interface {
|
||||
ormkv.EntryCodec
|
||||
|
||||
@ -156,4 +157,8 @@ type AutoIncrementTable interface {
|
||||
// InsertReturningPKey inserts the provided entry in the store and returns the newly
|
||||
// generated primary key for the message or an error.
|
||||
InsertReturningPKey(ctx context.Context, message proto.Message) (newPK uint64, err error)
|
||||
|
||||
// LastInsertedSequence retrieves the sequence number of the last entry inserted into the table.
|
||||
// The LastInsertedSequence is 0 if no entries have been inserted into the table.
|
||||
LastInsertedSequence(ctx context.Context) (uint64, error)
|
||||
}
|
||||
|
||||
@ -14,6 +14,8 @@ SET 03808002 01
|
||||
SET 0301666f6f 0001
|
||||
UNIQ testpb.ExampleAutoIncrementTable x : foo -> 1
|
||||
ORM AFTER INSERT testpb.ExampleAutoIncrementTable {"id":1,"x":"foo","y":5}
|
||||
GET 03808002 01
|
||||
SEQ testpb.ExampleAutoIncrementTable 1
|
||||
GET 03808002 01
|
||||
SEQ testpb.ExampleAutoIncrementTable 1
|
||||
GET 03000002
|
||||
@ -28,6 +30,8 @@ SET 03808002 02
|
||||
SET 0301626172 0002
|
||||
UNIQ testpb.ExampleAutoIncrementTable x : bar -> 2
|
||||
ORM AFTER INSERT testpb.ExampleAutoIncrementTable {"id":2,"x":"bar","y":10}
|
||||
GET 03808002 02
|
||||
SEQ testpb.ExampleAutoIncrementTable 2
|
||||
GET 03808002 02
|
||||
SEQ testpb.ExampleAutoIncrementTable 2
|
||||
ITERATOR 0300 -> 0301
|
||||
|
||||
Loading…
Reference in New Issue
Block a user