cosmos-sdk/orm/model/ormtable/table.go
Aaron Craelius 4e8172d1a1
feat(orm): return newly generated ID with auto-increment tables (#11040)
## Description

Adds a new interface `AutoIncrementTable` which extends `Table` and has a method `InsertWithID` which returns the newly generated ID. The new ID is also set on the message itself, but it feels like a nice improvement to have this method in real usage.



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
2022-02-01 17:14:46 +00:00

151 lines
5.5 KiB
Go

package ormtable
import (
"context"
"encoding/json"
"io"
"google.golang.org/protobuf/proto"
"github.com/cosmos/cosmos-sdk/orm/encoding/ormkv"
)
// View defines a read-only table.
//
// It exists as a separate interacted to support future scenarios where
// tables may be "supported" virtually to provide compatibility between
// systems, for instance to enable backwards compatibility when a major
// migration needs to be performed.
type View interface {
Index
// Has returns true if there is an entity in the table with the same
// primary key as message. Other fields besides the primary key fields will not
// be used for retrieval.
Has(ctx context.Context, message proto.Message) (found bool, err error)
// Get retrieves the message if one exists for the primary key fields
// set on the message. Other fields besides the primary key fields will not
// be used for retrieval.
Get(ctx context.Context, message proto.Message) (found bool, err error)
// GetIndex returns the index referenced by the provided fields if
// one exists or nil. Note that some concrete indexes can be retrieved by
// multiple lists of fields.
GetIndex(fields string) Index
// GetUniqueIndex returns the unique index referenced by the provided fields if
// one exists or nil. Note that some concrete indexes can be retrieved by
// multiple lists of fields.
GetUniqueIndex(fields string) UniqueIndex
// Indexes returns all the concrete indexes for the table.
Indexes() []Index
// GetIndexByID returns the index with the provided ID or nil.
GetIndexByID(id uint32) Index
// PrimaryKey returns the primary key unique index.
PrimaryKey() UniqueIndex
}
// Table is an abstract interface around a concrete table. Table instances
// are stateless, with all state existing only in the store passed
// to table and index methods.
type Table interface {
View
ormkv.EntryCodec
// Save saves the provided entry in the store either inserting it or
// updating it if needed.
//
// If store implement the Hooks interface, the appropriate OnInsert or
// OnUpdate hook method will be called.
//
// Save attempts to be atomic with respect to the underlying store,
// meaning that either the full save operation is written or the store is
// left unchanged, unless there is an error with the underlying store.
Save(context context.Context, message proto.Message) error
// Insert inserts the provided entry in the store and fails if there is
// an unique key violation. See Save for more details on behavior.
Insert(ctx context.Context, message proto.Message) error
// Update updates the provided entry in the store and fails if an entry
// with a matching primary key does not exist. See Save for more details
// on behavior.
Update(ctx context.Context, message proto.Message) error
// Delete deletes the entry with the with primary key fields set on message
// if one exists. Other fields besides the primary key fields will not
// be used for retrieval.
//
// If store implement the Hooks interface, the OnDelete hook method will
// be called.
//
// Delete attempts to be atomic with respect to the underlying store,
// meaning that either the full save operation is written or the store is
// left unchanged, unless there is an error with the underlying store.
Delete(ctx context.Context, message proto.Message) error
// DefaultJSON returns default JSON that can be used as a template for
// genesis files.
//
// For regular tables this an empty JSON array, but for singletons an
// empty instance of the singleton is marshaled.
DefaultJSON() json.RawMessage
// ValidateJSON validates JSON streamed from the reader.
ValidateJSON(io.Reader) error
// ImportJSON imports JSON into the store, streaming one entry at a time.
// Each table should be import from a separate JSON file to enable proper
// streaming.
//
// Regular tables should be stored as an array of objects with each object
// corresponding to a single record in the table.
//
// Auto-incrementing tables
// can optionally have the last sequence value as the first element in the
// array. If the last sequence value is provided, then each value of the
// primary key in the file must be <= this last sequence value or omitted
// entirely. If no last sequence value is provided, no entries should
// contain the primary key as this will be auto-assigned.
//
// Singletons should define a single object and not an array.
//
// ImportJSON is not atomic with respect to the underlying store, meaning
// that in the case of an error, some records may already have been
// imported. It is assumed that ImportJSON is called in the context of some
// larger transaction isolation.
ImportJSON(context.Context, io.Reader) error
// ExportJSON exports JSON in the format accepted by ImportJSON.
// Auto-incrementing tables will export the last sequence number as the
// first element in the JSON array.
ExportJSON(context.Context, io.Writer) error
// ID is the ID of this table within the schema of its FileDescriptor.
ID() uint32
Schema
}
// Schema is an interface for things that contain tables and can encode and
// decode kv-store pairs.
type Schema interface {
ormkv.EntryCodec
// GetTable returns the table for the provided message type or nil.
GetTable(message proto.Message) Table
}
type AutoIncrementTable interface {
Table
// InsertReturningID inserts the provided entry in the store and returns the newly
// generated ID for the message or an error.
InsertReturningID(ctx context.Context, message proto.Message) (newId uint64, err error)
}