Documentation ¶
Index ¶
- Variables
- type AndFilter
- type BoolField
- type Bytes32Field
- type Callbacks
- type Capabilities
- type CollectionName
- type FFNameArrayField
- type Field
- type FieldSerialization
- type Filter
- type FilterBuilder
- type FilterInfo
- type FilterOp
- type FilterResult
- type HashCollectionNS
- type Int64Field
- type JSONField
- type MultiConditionFilter
- type NullBehavior
- type OrFilter
- type OrderedCollection
- type OrderedUUIDCollectionNS
- type OtherCollection
- type PeristenceInterface
- type Plugin
- type QueryFactory
- type SetOperation
- type SortField
- type StringField
- type TimeField
- type UUIDCollection
- type UUIDCollectionNS
- type UUIDField
- type Update
- type UpdateBuilder
- type UpdateFactory
- type UpdateInfo
- type UpsertOptimization
Constants ¶
This section is empty.
Variables ¶
var ( // HashMismatch sentinel error HashMismatch = i18n.NewError(context.Background(), i18n.MsgHashMismatch) // IDMismatch sentinel error IDMismatch = i18n.NewError(context.Background(), i18n.MsgIDMismatch) // DeleteRecordNotFound sentinel error DeleteRecordNotFound = i18n.NewError(context.Background(), i18n.Msg404NotFound) )
var BatchQueryFactory = &queryFields{ "id": &UUIDField{}, "namespace": &StringField{}, "type": &StringField{}, "author": &StringField{}, "key": &StringField{}, "group": &Bytes32Field{}, "hash": &Bytes32Field{}, "payloadref": &StringField{}, "created": &TimeField{}, "confirmed": &TimeField{}, "tx.type": &StringField{}, "tx.id": &UUIDField{}, "node": &UUIDField{}, }
BatchQueryFactory filter fields for batches
var BlobQueryFactory = &queryFields{ "hash": &Bytes32Field{}, "payloadref": &StringField{}, "created": &TimeField{}, }
BlobQueryFactory filter fields for config records
var ConfigRecordQueryFactory = &queryFields{ "key": &StringField{}, "value": &StringField{}, }
ConfigRecordQueryFactory filter fields for config records
var DataQueryFactory = &queryFields{ "id": &UUIDField{}, "namespace": &StringField{}, "validator": &StringField{}, "datatype.name": &StringField{}, "datatype.version": &StringField{}, "hash": &Bytes32Field{}, "blob.hash": &Bytes32Field{}, "blob.public": &StringField{}, "created": &TimeField{}, }
DataQueryFactory filter fields for data
var DatatypeQueryFactory = &queryFields{ "id": &UUIDField{}, "message": &UUIDField{}, "namespace": &StringField{}, "validator": &StringField{}, "name": &StringField{}, "version": &StringField{}, "created": &TimeField{}, }
DatatypeQueryFactory filter fields for data definitions
var EventQueryFactory = &queryFields{ "id": &UUIDField{}, "type": &StringField{}, "namespace": &StringField{}, "reference": &UUIDField{}, "group": &Bytes32Field{}, "sequence": &Int64Field{}, "created": &TimeField{}, }
EventQueryFactory filter fields for data events
var GroupQueryFactory = &queryFields{ "hash": &Bytes32Field{}, "message": &UUIDField{}, "namespace": &StringField{}, "description": &StringField{}, "ledger": &UUIDField{}, "created": &TimeField{}, }
GroupQueryFactory filter fields for nodes
var MessageQueryFactory = &queryFields{ "id": &UUIDField{}, "cid": &UUIDField{}, "namespace": &StringField{}, "type": &StringField{}, "author": &StringField{}, "key": &StringField{}, "topics": &FFNameArrayField{}, "tag": &StringField{}, "group": &Bytes32Field{}, "created": &TimeField{}, "hash": &Bytes32Field{}, "pins": &FFNameArrayField{}, "state": &StringField{}, "confirmed": &TimeField{}, "sequence": &Int64Field{}, "txtype": &StringField{}, "batch": &UUIDField{}, }
MessageQueryFactory filter fields for messages
var NamespaceQueryFactory = &queryFields{ "id": &UUIDField{}, "message": &UUIDField{}, "type": &StringField{}, "name": &StringField{}, "description": &StringField{}, "created": &TimeField{}, "confirmed": &TimeField{}, }
NamespaceQueryFactory filter fields for namespaces
var NextPinQueryFactory = &queryFields{ "context": &Bytes32Field{}, "identity": &StringField{}, "hash": &Bytes32Field{}, "nonce": &Int64Field{}, }
NextPinQueryFactory filter fields for nodes
var NodeQueryFactory = &queryFields{ "id": &UUIDField{}, "message": &UUIDField{}, "owner": &StringField{}, "name": &StringField{}, "description": &StringField{}, "dx.peer": &StringField{}, "dx.endpoint": &JSONField{}, "created": &TimeField{}, }
NodeQueryFactory filter fields for nodes
var NonceQueryFactory = &queryFields{ "context": &StringField{}, "nonce": &Int64Field{}, "group": &Bytes32Field{}, "topic": &StringField{}, }
NonceQueryFactory filter fields for nodes
var OffsetQueryFactory = &queryFields{ "name": &StringField{}, "type": &StringField{}, "current": &Int64Field{}, }
OffsetQueryFactory filter fields for data offsets
var OperationQueryFactory = &queryFields{ "id": &UUIDField{}, "tx": &UUIDField{}, "type": &StringField{}, "namespace": &StringField{}, "status": &StringField{}, "error": &StringField{}, "plugin": &StringField{}, "input": &JSONField{}, "output": &JSONField{}, "backendid": &StringField{}, "created": &TimeField{}, "updated": &TimeField{}, }
OperationQueryFactory filter fields for data operations
var OrganizationQueryFactory = &queryFields{ "id": &UUIDField{}, "message": &UUIDField{}, "parent": &StringField{}, "identity": &StringField{}, "description": &StringField{}, "profile": &JSONField{}, "created": &TimeField{}, }
OrganizationQueryFactory filter fields for organizations
var PinQueryFactory = &queryFields{ "sequence": &Int64Field{}, "masked": &BoolField{}, "hash": &Bytes32Field{}, "batch": &UUIDField{}, "index": &Int64Field{}, "dispatched": &BoolField{}, "created": &TimeField{}, }
PinQueryFactory filter fields for parked contexts
var SubscriptionQueryFactory = &queryFields{ "id": &UUIDField{}, "namespace": &StringField{}, "name": &StringField{}, "transport": &StringField{}, "events": &StringField{}, "filter.topics": &StringField{}, "filter.tag": &StringField{}, "filter.group": &StringField{}, "options": &StringField{}, "created": &TimeField{}, }
SubscriptionQueryFactory filter fields for data subscriptions
var TokenBalanceQueryFactory = &queryFields{ "pool": &UUIDField{}, "tokenindex": &StringField{}, "uri": &StringField{}, "connector": &StringField{}, "namespace": &StringField{}, "key": &StringField{}, "balance": &Int64Field{}, "updated": &TimeField{}, }
TokenBalanceQueryFactory filter fields for token accounts
var TokenPoolQueryFactory = &queryFields{ "id": &UUIDField{}, "type": &StringField{}, "namespace": &StringField{}, "name": &StringField{}, "standard": &StringField{}, "protocolid": &StringField{}, "key": &StringField{}, "symbol": &StringField{}, "message": &UUIDField{}, "state": &StringField{}, "created": &TimeField{}, "connector": &StringField{}, }
TokenPoolQueryFactory filter fields for token pools
var TokenTransferQueryFactory = &queryFields{ "localid": &StringField{}, "pool": &UUIDField{}, "tokenindex": &StringField{}, "uri": &StringField{}, "connector": &StringField{}, "namespace": &StringField{}, "key": &StringField{}, "from": &StringField{}, "to": &StringField{}, "amount": &Int64Field{}, "protocolid": &StringField{}, "message": &UUIDField{}, "messagehash": &Bytes32Field{}, "created": &TimeField{}, }
TokenTransferQueryFactory filter fields for token transfers
var TransactionQueryFactory = &queryFields{ "id": &UUIDField{}, "type": &StringField{}, "signer": &StringField{}, "status": &StringField{}, "reference": &UUIDField{}, "protocolid": &StringField{}, "created": &TimeField{}, "sequence": &Int64Field{}, "info": &JSONField{}, "namespace": &StringField{}, }
TransactionQueryFactory filter fields for transactions
Functions ¶
This section is empty.
Types ¶
type AndFilter ¶
type AndFilter interface{ MultiConditionFilter }
type Bytes32Field ¶
type Bytes32Field struct{}
type Callbacks ¶
type Callbacks interface { // OrderedUUIDCollectionNSEvent emits the sequence on insert, but it will be -1 on update OrderedUUIDCollectionNSEvent(resType OrderedUUIDCollectionNS, eventType fftypes.ChangeEventType, ns string, id *fftypes.UUID, sequence int64) OrderedCollectionEvent(resType OrderedCollection, eventType fftypes.ChangeEventType, sequence int64) UUIDCollectionNSEvent(resType UUIDCollectionNS, eventType fftypes.ChangeEventType, ns string, id *fftypes.UUID) UUIDCollectionEvent(resType UUIDCollection, eventType fftypes.ChangeEventType, id *fftypes.UUID) HashCollectionNSEvent(resType HashCollectionNS, eventType fftypes.ChangeEventType, ns string, hash *fftypes.Bytes32) }
Callbacks are the methods for passing data from plugin to core
If Capabilities returns ClusterEvents=true then these should be broadcast to every instance within a cluster that is connected to the database.
If Capabilities returns ClusterEvents=false then these events can be simply coupled in-process to update activities.
The system does not rely on these events exclusively for data/transaction integrity, but if an event is missed/delayed it might result in slower processing. For example, the batch interface will initiate a batch as soon as an event is triggered, but it will use a subsequent database query as the source of truth of the latest set/order of data, and it will periodically check for new messages even if it does not receive any events.
Events are emitted locally to the individual FireFly core process. However, a WebSocket interface is available for remote listening to these events. That allows the UI to listen to the events, as well as providing a building block for a cluster of FireFly servers to directly propgate events to each other.
type Capabilities ¶
type Capabilities struct {
ClusterEvents bool
}
Capabilities defines the capabilities a plugin can report as implementing or not
type FFNameArrayField ¶
type FFNameArrayField struct{}
type FieldSerialization ¶
type FieldSerialization interface { driver.Valuer sql.Scanner // Implementations can assume the value is ALWAYS a string }
FieldSerialization - we stand on the shoulders of the well adopted SQL serialization interface here to help us define what string<->value looks like, even though this plugin interface is not tightly coupled to SQL.
type Filter ¶
type Filter interface { // Sort adds a set of sort conditions (all in a single sort order) Sort(...string) Filter // Ascending sort order Ascending() Filter // Descending sort order Descending() Filter // Skip for pagination Skip(uint64) Filter // Limit for pagination Limit(uint64) Filter // Request a count to be returned on the total number that match the query Count(c bool) Filter // Finalize completes the filter, and for the plugin to validated output structure to convert Finalize() (*FilterInfo, error) // Builder returns the builder that made it Builder() FilterBuilder }
Filter is the output of the builder
type FilterBuilder ¶
type FilterBuilder interface { // Fields is the list of available fields Fields() []string // And requires all sub-filters to match And(and ...Filter) AndFilter // Or requires any of the sub-filters to match Or(and ...Filter) OrFilter // Eq equal Eq(name string, value driver.Value) Filter // Neq not equal Neq(name string, value driver.Value) Filter // In one of an array of values In(name string, value []driver.Value) Filter // NotIn not one of an array of values NotIn(name string, value []driver.Value) Filter // Lt less than Lt(name string, value driver.Value) Filter // Gt greater than Gt(name string, value driver.Value) Filter // Gte greater than or equal Gte(name string, value driver.Value) Filter // Lte less than or equal Lte(name string, value driver.Value) Filter // Contains allows the string anywhere - case sensitive Contains(name string, value driver.Value) Filter // NotContains disallows the string anywhere - case sensitive NotContains(name string, value driver.Value) Filter // IContains allows the string anywhere - case sensitive IContains(name string, value driver.Value) Filter // INotContains disallows the string anywhere - case sensitive NotIContains(name string, value driver.Value) Filter }
FilterBuilder is the syntax used to build the filter, where And() and Or() can be nested
type FilterInfo ¶
type FilterInfo struct { Sort []*SortField Skip uint64 Limit uint64 Count bool CountExpr string Field string Op FilterOp Values []FieldSerialization Value FieldSerialization Children []*FilterInfo }
FilterInfo is the structure returned by Finalize to the plugin, to serialize this filter into the underlying database mechanism's filter language
func (*FilterInfo) String ¶
func (f *FilterInfo) String() string
type FilterOp ¶
type FilterOp string
FilterOp enum of filter operations that must be implemented by plugins - the string value is used in the core string formatting method (for logging etc.)
const ( // FilterOpAnd and FilterOpAnd FilterOp = "&&" // FilterOpOr or FilterOpOr FilterOp = "||" // FilterOpEq equal FilterOpEq FilterOp = "==" // FilterOpNe not equal FilterOpNe FilterOp = "!=" // FilterOpIn in list of values FilterOpIn FilterOp = "IN" // FilterOpNotIn not in list of values FilterOpNotIn FilterOp = "NI" // FilterOpGt greater than FilterOpGt FilterOp = ">" // FilterOpLt less than FilterOpLt FilterOp = "<" // FilterOpGte greater than or equal FilterOpGte FilterOp = ">=" // FilterOpLte less than or equal FilterOpLte FilterOp = "<=" // FilterOpCont contains the specified text, case sensitive FilterOpCont FilterOp = "%=" // FilterOpNotCont does not contain the specified text, case sensitive FilterOpNotCont FilterOp = "%!" // FilterOpICont contains the specified text, case insensitive FilterOpICont FilterOp = "^=" // FilterOpNotICont does not contain the specified text, case insensitive FilterOpNotICont FilterOp = "^!" )
type FilterResult ¶
type FilterResult struct {
TotalCount *int64
}
FilterResult is has additional info if requested on the query - currently only the total count
type HashCollectionNS ¶
type HashCollectionNS CollectionName
HashCollectionNS is a collection where the primary key is a hash, such that it can by identifed by any member of the network at any time, without it first having been broadcast.
const (
CollectionGroups HashCollectionNS = "groups"
)
type Int64Field ¶
type Int64Field struct{}
type MultiConditionFilter ¶
type MultiConditionFilter interface { Filter // Add adds filters to the condition Condition(...Filter) MultiConditionFilter }
MultiConditionFilter gives convenience methods to add conditions
type NullBehavior ¶ added in v0.11.0
type NullBehavior int
NullBehavior specifies whether to sort nulls first or last in a query
const ( NullsDefault NullBehavior = iota NullsFirst NullsLast )
type OrFilter ¶
type OrFilter interface{ MultiConditionFilter }
type OrderedCollection ¶
type OrderedCollection CollectionName
OrderedCollection is a collection that is ordered, and that sequence is the only key
const (
CollectionPins OrderedCollection = "pins"
)
type OrderedUUIDCollectionNS ¶
type OrderedUUIDCollectionNS CollectionName
OrderedUUIDCollectionNS collections have a strong order that includes a sequence integer that uniquely identifies the entry in a sequence. The sequence is LOCAL to this FireFly node. We try to minimize adding new collections of this type, as they have implementation complexity in some databases (such as NoSQL databases)
const ( CollectionMessages OrderedUUIDCollectionNS = "messages" CollectionEvents OrderedUUIDCollectionNS = "events" )
type OtherCollection ¶
type OtherCollection CollectionName
OtherCollection are odd balls, that don't fit any of the categories above. These collections do not support change events, and generally their creation is coordinated with creation of another object that does support change events. Mainly they are entries that require lookup by compound IDs.
const ( CollectionConfigrecords OtherCollection = "configrecords" CollectionBlobs OtherCollection = "blobs" CollectionNextpins OtherCollection = "nextpins" CollectionNonces OtherCollection = "nonces" CollectionOffsets OtherCollection = "offsets" CollectionTokenBalances OtherCollection = "tokenbalances" )
type PeristenceInterface ¶
type PeristenceInterface interface { fftypes.Named // RunAsGroup instructs the database plugin that all database operations performed within the context // function can be grouped into a single transaction (if supported). // Requirements: // - Firefly must not depend on this to guarantee ACID properties (it is only a suggestion/optimization) // - The database implementation must support nested RunAsGroup calls (ie by reusing a transaction if one exists) // - The caller is responsible for passing the supplied context to all database operations within the callback function RunAsGroup(ctx context.Context, fn func(ctx context.Context) error) error // contains filtered or unexported methods }
PeristenceInterface are the operations that must be implemented by a database interfavce plugin. The database mechanism of Firefly is designed to provide the balance between being able to query the data a member of the network has transferred/received via Firefly efficiently, while not trying to become the core database of the application (where full deeply nested rich query is needed).
This means that we treat business data as opaque within the stroage, only verifying it against a data definition within the Firefly core runtime itself. The data types, indexes and relationships are designed to be simple, and map closely to the REST semantics of the Firefly API itself.
As a result, the database interface could be implemented efficiently by most database technologies. Including both Relational/SQL and Document/NoSQL database technologies.
As such we suggest the factors in choosing your database should be non-functional, such as: - Which provides you with the HA/DR capabilities you require - Which is most familiar within your existing devops pipeline for the application - Whether you can consolidate the HA/DR and server infrastructure for your app DB with the Firefly DB
Each database does need an update to the core codebase, to provide a plugin that implements this interface. For SQL databases the process of adding a new database is simplified via the common SQL layer. For NoSQL databases, the code should be straight forward to map the collections, indexes, and operations.
type Plugin ¶
type Plugin interface { PeristenceInterface // Split out to aid pluggability the next level down (SQL provider etc.) // InitPrefix initializes the set of configuration options that are valid, with defaults. Called on all plugins. InitPrefix(prefix config.Prefix) // Init initializes the plugin, with configuration // Returns the supported featureset of the interface Init(ctx context.Context, prefix config.Prefix, callbacks Callbacks) error // Capabilities returns capabilities - not called until after Init Capabilities() *Capabilities }
Plugin is the interface implemented by each plugin
type QueryFactory ¶
type QueryFactory interface { NewFilter(ctx context.Context) FilterBuilder NewFilterLimit(ctx context.Context, defLimit uint64) FilterBuilder NewUpdate(ctx context.Context) UpdateBuilder }
QueryFactory creates a filter builder in the given context, and contains the rules on which fields can be used by the builder (and how they are serialized)
type SetOperation ¶
type SetOperation struct { Field string Value FieldSerialization }
SetOperation is an individual update action to perform
type SortField ¶
type SortField struct { Field string Descending bool Nulls NullBehavior }
SortField is field+direction for sorting
type StringField ¶
type StringField struct{}
type UUIDCollection ¶
type UUIDCollection CollectionName
UUIDCollection is like UUIDCollectionNS, but for objects that do not reside within a namespace
const ( CollectionNamespaces UUIDCollection = "namespaces" CollectionNodes UUIDCollection = "nodes" CollectionOrganizations UUIDCollection = "organizations" CollectionTokenTransfers UUIDCollection = "tokentransfers" )
type UUIDCollectionNS ¶
type UUIDCollectionNS CollectionName
UUIDCollectionNS is the most common type of collection - each entry has a UUID that is globally unique, and used externally by apps to address entries in the collection. Objects in these collections are all namespaced,.
const ( CollectionBatches UUIDCollectionNS = "batches" CollectionData UUIDCollectionNS = "data" CollectionDataTypes UUIDCollectionNS = "datatypes" CollectionOperations UUIDCollectionNS = "operations" CollectionSubscriptions UUIDCollectionNS = "subscriptions" CollectionTransactions UUIDCollectionNS = "transactions" CollectionTokenPools UUIDCollectionNS = "tokenpools" )
type Update ¶
type Update interface { // Set adds a set condition to the update Set(field string, value interface{}) Update // IsEmpty IsEmpty() bool // Finalize completes the update, and for the plugin to validated output structure to convert Finalize() (*UpdateInfo, error) }
type UpdateBuilder ¶
type UpdateBuilder interface { // Set starts creation of a set operation Set(field string, value interface{}) Update // S starts an update that doesn't have any fields S() Update // Fields returns the available fields on the update Fields() []string }
UpdateBuilder is the output of the builder
type UpdateFactory ¶
type UpdateFactory interface {
New(ctx context.Context) UpdateBuilder
}
UpdateFactory creates a update builder in the given context, and contains the rules on which fields can be used by the builder (and how they are serialized)
type UpdateInfo ¶
type UpdateInfo struct {
SetOperations []*SetOperation
}
UpdateInfo is the structure returned by Finalize to the plugin, to serialize this uilter into the underlying database mechanism's uilter language
func (*UpdateInfo) String ¶
func (u *UpdateInfo) String() string
type UpsertOptimization ¶ added in v0.11.0
type UpsertOptimization int
const ( UpsertOptimizationSkip UpsertOptimization = iota UpsertOptimizationNew UpsertOptimizationExisting )