DefaultQueryGateway

class DefaultQueryGateway(val aggregateType: AggregateType, backend: QueryBackend, schemaProvider: QueryModelSchemaProvider, filters: List<QueryFilter> = emptyList(), policies: List<QueryPolicy> = emptyList(), observer: QueryObserver = QueryObserver.NONE, val entryPolicy: QueryEntryPolicy = QueryEntryPolicy.DEFAULT, counts: QueryCountCache? = null, records: QueryRecordReader? = null, constraints: List<ConstraintDescriptor> = emptyList(), model: QueryModel = QueryModel.SNAPSHOT, authorizer: ReadAuthorizer = ReadAuthorizer.ALLOW_ALL) : QueryGateway

The QueryGateway over one backend: schemaProvider supplies the schema every query is admitted against, filters and policies run at admission steps 1 and 2, and observer sees every outcome. One instance serves every caller.

With counts, the counts and paged totals are cached (QueryCountCache): admitted as ever, then served from the cache while the type's snapshot write checkpoint holds; a query served so ends its observation with the outcome ObservedOutcome.CACHED. A cache is keyed by aggregate type, not by model: give each model's gateways a cache of their own.

Each record a backend returns is masked by the schema's response masks; with records, it is read by records instead (the events model reads each event as its aggregate reads it now and masks it by its own schema). constraints are rules its policies add to the schema's, which describe lists after the schema's own (the events model's AGGREGATE_REQUIRED). model is the model it serves, which its observer is told of each query.

Constructors

Link copied to clipboard
constructor(aggregateType: AggregateType, backend: QueryBackend, schemaProvider: QueryModelSchemaProvider, filters: List<QueryFilter> = emptyList(), policies: List<QueryPolicy> = emptyList(), observer: QueryObserver = QueryObserver.NONE, entryPolicy: QueryEntryPolicy = QueryEntryPolicy.DEFAULT, counts: QueryCountCache? = null, records: QueryRecordReader? = null, constraints: List<ConstraintDescriptor> = emptyList(), model: QueryModel = QueryModel.SNAPSHOT, authorizer: ReadAuthorizer = ReadAuthorizer.ALLOW_ALL)

Properties

Link copied to clipboard
open override val aggregateType: AggregateType
Link copied to clipboard
open override val entryPolicy: QueryEntryPolicy

The entry policy this gateway admits every query under: the one source of each entry's budget.

Functions

Link copied to clipboard
open suspend override fun admitRecord(selection: FilterExpression, record: ObjectNode, caller: QueryCaller): ObjectNode?

The single-aggregate visibility check of the policy chain: record, the snapshot-shaped record of one aggregate a point read chose by selection (a state read by id, its version or its trace, or the aggregate of an events query), as caller may read it: admitted by the same caller scope and QueryPolicy restrictions and the model's default scope as a query, evaluated in memory, and masked; null when the caller may not read it, so a row a query hides is hidden from a read by id too. A gateway without policies admits every record.

Link copied to clipboard
open override fun aggregate(query: AggregationQuery, caller: QueryCaller): Flow<ObjectNode>

The groups of query, streamed.

Link copied to clipboard
open suspend override fun count(query: CountQuery, caller: QueryCaller): CountResult

How many records query matches, bounded by its limit or its budget's.

Link copied to clipboard
open suspend override fun cursor(query: CursorQuery, caller: QueryCaller): CursorPage<ObjectNode>

One keyset page of the records query matches, with the cursor of the next one.

Link copied to clipboard
open suspend override fun describe(entry: QueryEntry, defaultListSize: Int? = null): QueryModelDescriptor

How this model can be queried on entry (the GET of the query route): the capability descriptor of the schema this gateway admits against, under the budget entryPolicy gives entry. defaultListSize is the list size the entry's adapter applies when a list query sends none, or null. Its version is the route's ETag.

Link copied to clipboard
open override fun list(query: ListQuery, caller: QueryCaller): Flow<ObjectNode>

The records query matches, streamed.

Link copied to clipboard
open suspend override fun maskRecord(record: ObjectNode): ObjectNode

record, the snapshot-shaped record of one aggregate, masked as this model's records are and admitted by no policy: a state of the history of an aggregate admitRecord admitted, read as the aggregate is now.

Link copied to clipboard
open suspend override fun paged(query: PagedQuery, caller: QueryCaller): PagedList<ObjectNode>

One page of the records query matches, with its total as PagedQuery.total asks.

Link copied to clipboard
open suspend override fun resumes(query: ListQuery): Boolean

Whether query streams as a resumable stream (stream): its model's storage pages by keyset and its sort, with the model's unique key appended, orders a cursor. A list that does not is streamed by list.

Link copied to clipboard
open suspend override fun single(query: SingleQuery, caller: QueryCaller): ObjectNode?

The first record query matches, or null when none does.

Link copied to clipboard
open override fun stream(query: ListQuery, caller: QueryCaller, after: String? = null, chunkSize: Int = DEFAULT_STREAM_CHUNK_SIZE): Flow<PositionedRecord>

The records query matches as a resumable stream: keyset chunks of chunkSize records read one after the other, each record with the cursor token of its position, from strictly after the position after names when given. after is a token of this model and effective sort (a stream's or a cursor query's); any other is wow.query.invalid. The query is admitted like a cursor query, so a stream resumed with the same query from another node or after a restart reads on from the same place, under its caller's scope again; at most query's limit records are read (0: all of them), and its budget bounds neither the limit nor the chunks. Each chunk runs within the query's timeout and under one bulkhead permit, given back before its records are emitted. Chunks are not one snapshot: see chunks. Only for a query resumes.