PostgresQueryBackend

A query backend of one aggregate type on PostgreSQL: the four primitives over one of the aggregate type's own tables, read as layout says, compiled to parameterized SQL (PostgresSnapshotSqlCompiler, PostgresAggregationCompiler): its snapshot table (on the bindings of PostgresSnapshotStorageAdapter; records of the shape of SnapshotRecord.toQueryRecord(), a row without any kept state field not reading the state at all) or its log table (on the bindings of PostgresEventStorageAdapter; one record per stream, as stored). A projection is applied to each record as it is read.

Every statement runs in its own read transaction under SET LOCAL statement_timeout of the admitted timeout; PostgreSQL cancelling it there is a StorageTimeoutException. JDBC calls run on dispatcher, virtual threads by default. A table not created yet (no snapshot of the aggregate type was saved, no stream appended) holds no records: every primitive answers as over an empty table, as the provisional facts of PostgresQuerySchemaAdapter describe it.

Properties

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

Functions

Link copied to clipboard
open override fun aggregate(query: AdmittedQuery<AggregationQuery>, window: GroupWindow): Flow<ObjectNode>
Link copied to clipboard
open suspend override fun count(query: AdmittedQuery<CountQuery>): Long
Link copied to clipboard
open suspend override fun page(query: AdmittedQuery<Queryable<*>>, window: PageWindow): BackendPage
Link copied to clipboard
open override fun stream(query: AdmittedQuery<ListQuery>): Flow<ObjectNode>

The records of query, read in full in their transaction, which then ends and gives its connection back, and only then emitted: a consumer as slow as an SSE client's never holds a connection of the pool the log appends through. The admission bounds the list (maxListSize); a budget without that bound (maxListSize = 0) holds a whole unbounded list in memory.