Package-level declarations

Types

Link copied to clipboard

How a storage's presence operators see a stored null and an empty array.

Link copied to clipboard
data class AggregationSupport(val having: SupportMode = SupportMode.NATIVE, val topN: SupportMode = SupportMode.NATIVE, val denseFill: SupportMode = SupportMode.NATIVE, val percentile: SupportMode = SupportMode.NATIVE, val distinctCount: SupportMode = SupportMode.NATIVE, val firstLast: SupportMode = SupportMode.NATIVE)

How a storage aggregates. HAVING, top-N by a metric and dense date-histogram fill may be RESIDUAL; percentiles and distinct counts need the records themselves, so they are NATIVE or NONE.

Link copied to clipboard
class ClasspathQuerySchemaSource(classLoader: ClassLoader = Thread.currentThread().contextClassLoader ?: ClasspathQuerySchemaSource::class.java.classLoader) : QuerySchemaSource
Link copied to clipboard
sealed interface DeclarationValue<out T>
Link copied to clipboard
class DefaultQueryModelSchemaProvider(context: QuerySchemaContext, sources: List<QuerySchemaSource>, adapter: QueryStorageAdapter, sensitivity: QuerySensitivityPolicy = QuerySensitivityPolicy.DEFAULT) : QueryModelSchemaProvider

The Catalog's compilation of one aggregate model (design §5.2): merges the declarations of sources into the logical model under sensitivity, asks the storage adapter for its facts about it, and compiles them into the published QueryModelSchema. The first load is shared by concurrent callers; a refresh reloads the sources and the storage's native structures and replaces the published schema only when it compiles.

Link copied to clipboard

Aggregated domain event streams: one record per command, typed event payloads under body[].body.

Link copied to clipboard
class InferredQuerySchemaSource(modelSource: QueryModelSource, typeResolver: (QuerySchemaContext) -> Class<*> = ::payloadOwnerType) : QuerySchemaSource

Declares the fields a QueryModelSource infers from the domain types of a built-in model.

Link copied to clipboard
class LogicalQuerySchema(val root: QueryValueSchema, val sensitivity: QuerySensitivityPolicy = QuerySensitivityPolicy.DEFAULT)

A logical definition is shared unchanged with every native binding snapshot.

Link copied to clipboard
class MaskRule(val level: SensitivityLevel, val mask: Mask = Mask())

The compiled form of one Sensitive declaration: its level and the compiled strategy that masks result values. Two rules are equal when they declare the same level and mask, so the same declaration reached through different members is one rule.

Link copied to clipboard
data class PagingSupport(val keyset: SupportMode = SupportMode.NATIVE, val unboundedStream: SupportMode = SupportMode.NATIVE, val maxOffsetWindow: Int? = null)

How a storage pages. Neither mode has a residual implementation, so each is NATIVE or NONE.

Link copied to clipboard
class QueryFieldBinding(val physicalField: QueryField, storageTypes: Set<QueryStorageType>?, val physicalScope: QueryField? = null)

Where a logical field is stored for one capability. physicalScope is the physical container physicalField lies in whose elements storage indexes as separate documents, such as an Elasticsearch nested mapping, so a backend addresses the field through it; null when there is none.

Link copied to clipboard
class QueryFieldBindingTemplate(val physicalPath: QueryPathTemplate, storageTypes: Set<QueryStorageType>?, val physicalScope: QueryField? = null)

A native binding as a storage adapter reports it; physicalScope is QueryFieldBinding.physicalScope.

Link copied to clipboard

The effective capabilities of one field, compiled once from its value definition, the capabilities storage grants it, its sensitivity, its element scopes and the model's storage support (design §5.2, P2). Admission checks each reference against this record, the descriptor publishes it, and it lists each capability with the cost class its spec states, which an entry gate that refuses expensive operations also reads. The value rules of the operator, group and metric specs are decided here, once, so admission and the descriptor cannot disagree about them.

Link copied to clipboard
data class QueryFieldDeclaration(val title: DeclarationValue<String?> = DeclarationValue.Unset, val description: DeclarationValue<String?> = DeclarationValue.Unset, val enumValues: DeclarationValue<List<JsonNode>?> = DeclarationValue.Unset, val enumDescriptions: DeclarationValue<Map<JsonNode, String>> = DeclarationValue.Unset, val valueTypes: DeclarationValue<Set<QueryValueType>> = DeclarationValue.Unset, val nullable: DeclarationValue<Boolean> = DeclarationValue.Unset, val required: DeclarationValue<Boolean> = DeclarationValue.Unset, val kind: DeclarationValue<QueryValueKind> = DeclarationValue.Unset, val properties: DeclarationValue<Map<String, QueryFieldDeclaration>> = DeclarationValue.Unset, val items: DeclarationValue<QueryFieldDeclaration?> = DeclarationValue.Unset, val additionalProperties: DeclarationValue<QueryFieldDeclaration?> = DeclarationValue.Unset, val alternatives: DeclarationValue<List<QueryFieldDeclaration>> = DeclarationValue.Unset, val semanticType: DeclarationValue<QuerySemanticType?> = DeclarationValue.Unset, val maskRule: DeclarationValue<MaskRule> = DeclarationValue.Unset, val variant: DeclarationValue<String?> = DeclarationValue.Unset, val aliases: DeclarationValue<Set<QueryField>> = DeclarationValue.Unset, val deprecated: DeclarationValue<QueryDeprecation?> = DeclarationValue.Unset)
Link copied to clipboard

One field or nested value: its shape (kind, types, nullability, structure) and semantics (enum, time, text).

Link copied to clipboard

One resolved field of a QueryModelSchema with its capability facts. Facts that depend only on the field and its schema are computed once per instance; static fields are resolved once per schema.

Link copied to clipboard
class QueryMemberFact(val name: String, val type: Class<*>, annotations: List<Annotation>, val valueType: Class<*> = type)

A serialized member: its JVM type and its effective annotations, those declared on the field, getter or inherited property it serializes from. Meta-annotations are not expanded.

Link copied to clipboard
fun interface QueryModelCompiler

How the Catalog compiles one aggregate model: from its context and its storage's facts to a schema provider.

Link copied to clipboard
sealed class QueryModelProfile

Record layout and invariants of one built-in QueryModel.

Link copied to clipboard
class QueryModelSchema(val model: QueryModel, capabilities: Set<QueryCapability>, val definition: LogicalQuerySchema, bindings: Map<QueryPathTemplate, QueryValueBindings>, val fullProjectionAvailable: Boolean = true, approximateMetrics: Set<String> = emptySet(), val storage: StorageSupport = StorageSupport.NATIVE)

Published facts only: model values and operation-specific native locations.

Link copied to clipboard
Link copied to clipboard
fun interface QueryModelSource

Type inference for the query Catalog: reports how a JVM type serializes, as raw facts.

Link copied to clipboard
sealed interface QueryPathSegment

Schema path parts; keys are captured by logical lookup, items describe array traversal.

Link copied to clipboard
Link copied to clipboard
class QuerySchemaCatalog(snapshots: SnapshotQueryBackendFactory? = null, eventStreams: EventStreamQueryBackendFactory? = null, compiler: QueryModelCompiler = QueryModelCompiler.of(), aggregates: Collection<NamedAggregate> = emptyList(), meterRegistry: MeterRegistry? = null)

The Catalog (design §4, §5.2): compiles the query schema of every aggregate model this instance serves, one provider per aggregate and model, with its compiler (by default the model sources merged under the sensitivity policy, see QueryModelCompiler.of). Each storage only reports its native facts, through the storage adapter its backend factory supplies. Gateways, point reads and the capability descriptor all read their schema here.

Link copied to clipboard
Link copied to clipboard
data class QuerySchemaContext(val namedAggregate: NamedAggregate, val model: QueryModel)
Link copied to clipboard
Link copied to clipboard

Declares, in code, what inference cannot know about a model's fields; the same vocabulary as a declaration file (see QuerySchemaDeclarationProperties).

Link copied to clipboard

The keys of a declaration file (META-INF/wow/query-schema/{context}.{aggregate}.{model}.json or config/wow/query-schema/…). A file only supplements what inference cannot know, in the capability descriptor's vocabulary:

Link copied to clipboard
Link copied to clipboard
data class QuerySchemaRegistration(val context: QuerySchemaContext, val declaration: QuerySchemaDeclaration)
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
class QuerySchemaValidationException(message: String, cause: Throwable? = null, val violation: QueryViolation? = null) : QuerySchemaException
Link copied to clipboard
data class QuerySensitivityPolicy(val displayComparable: Boolean = true)

How the query subsystem treats sensitive fields beyond their declared level.

Link copied to clipboard
fun interface QueryStorageAdapter

A storage's port into the Catalog (design §5.2, §5.5): it reports what its native structures (indexes, mappings, validators) prove about a logical model, and nothing else. The Catalog merges the model's sources and compiles the reported facts into a QueryModelSchema, applying every rule that does not depend on the storage.

Link copied to clipboard
class QueryStorageFacts(val bindings: Map<QueryPathTemplate, QueryValueBindings>, val capabilities: Set<QueryCapability> = emptySet(), val fullProjectionAvailable: Boolean = true, val approximateMetrics: Set<String> = emptySet(), val storage: StorageSupport = StorageSupport.NATIVE)

What a storage proves about one read model, in the storage-neutral vocabulary of capabilities: for each logical path, the capabilities its native structures can execute and the physical location each binds to, with the projection and response locations; and the storage's model-wide support. Which native types, index kinds or mapping options prove a capability is the storage's knowledge; what a logical value must be for a capability to apply at all is the Catalog's (compile).

Link copied to clipboard

A storage-neutral family of native types a logical value may be stored as. A storage adapter maps each family to its own native types (BSON types, Elasticsearch field kinds); which families a logical value needs for a capability is the Catalog's decision (storageFamilies).

Link copied to clipboard
data class QueryStorageFamilyRules(val dateOperands: Boolean = true, val strictValueTypes: Boolean = true)

Where a storage still departs from the strict table of storageFamilies. Each rule is a known divergence between storages, kept so that every adapter reproduces today's capabilities exactly; the defaults are the strict table.

Link copied to clipboard
data class QueryStorageType(val value: String)
Link copied to clipboard
class QueryTypeFact(val kind: QueryValueKind, valueTypes: Set<QueryValueType> = emptySet(), val nullable: Boolean? = null, val required: Boolean? = null, enumValues: List<JsonNode>? = null, val title: String? = null, val description: String? = null, formats: Set<String> = emptySet(), properties: Map<String, QueryTypeFact> = emptyMap(), val items: QueryTypeFact? = null, val additionalProperties: QueryTypeFact? = null, alternatives: List<QueryTypeFact> = emptyList(), val member: QueryMemberFact? = null, omitted: List<QueryMemberFact> = emptyList())

One value of a serialized type.

Link copied to clipboard
class QueryValueBindings(bindings: Map<QueryCapability, QueryFieldBindingTemplate> = emptyMap(), val projectionPath: QueryPathTemplate? = null, val responsePath: QueryPathTemplate? = null)
Link copied to clipboard
class QueryValueSchema(val kind: QueryValueKind, val title: String? = null, val description: String? = null, enumValues: List<JsonNode>? = null, enumDescriptions: Map<JsonNode, String> = emptyMap(), valueTypes: Set<QueryValueType> = if (kind == QueryValueKind.OBJECT) setOf(QueryValueType.OBJECT) else emptySet(), properties: Map<String, QueryValueSchema> = emptyMap(), val items: QueryValueSchema? = null, val additionalProperties: QueryValueSchema? = null, alternatives: List<QueryValueSchema> = emptyList(), val nullable: Boolean = kind != QueryValueKind.UNION || alternatives.any { it.nullable }, val required: Boolean = false, val semanticType: QuerySemanticType? = null, val maskRule: MaskRule? = null, val variant: String? = null, aliases: Set<QueryField> = emptySet(), val deprecated: QueryDeprecation? = null)

One immutable logical value shape, shared by backend schema snapshots. Collection inputs are snapshotted; mutable enum JSON is detached on read.

Link copied to clipboard
sealed interface QueryViolation

The error catalog (design §5.9): every rule a query can break, as structured facts. Each violation names its stable code, renders its message from its facts, and belongs to a Kind that decides the error it becomes (rejection): the one place a rejection is rendered. Codes are a contract (added, never renamed); texts are not.

Link copied to clipboard

Materialized aggregate snapshots: one record per aggregate, payload under state.

Link copied to clipboard
data class StorageSupport(val paging: PagingSupport = PagingSupport(), val aggregation: AggregationSupport = AggregationSupport(), val parallelArraySort: SupportMode = SupportMode.NATIVE, val absentValues: AbsentValues = AbsentValues.DISTINCT, val arrayEquality: SupportMode = SupportMode.NATIVE)

What a storage declares beyond each field's native capabilities; bound into the schema by its adapter.

Link copied to clipboard

How storage supports a query feature (design §5.5).

Link copied to clipboard

The schema provider of an aggregate model that has no query backend: every load fails with message. QuerySchemaCatalog skips it, since there is nothing to load or revalidate.

Link copied to clipboard

The storage adapter of an aggregate model that has no query backend: every load fails with message. QuerySchemaCatalog skips it, since there is nothing to load or revalidate.

Link copied to clipboard
class WorkingDirectoryQuerySchemaSource(basePath: Path = Path.of("config"), readText: (Path) -> String = Files::readString) : QuerySchemaSource

Properties

Link copied to clipboard

The profile of this schema's model, or null for a custom model.

Functions

Link copied to clipboard
Link copied to clipboard

Flattens nested unions into their non-union alternatives; any other value is its own single alternative.

Link copied to clipboard
fun QueryModelSchema.describe(budget: QueryBudget?, defaultListSize: Int?, timeZone: ZoneId = ZoneId.systemDefault()): QueryModelDescriptor

Describes how this model can be queried on one entry, derived from the same capability table and operator specs that admission reads, so the description and admission cannot disagree.

Link copied to clipboard

The ordering field of a FIRST / LAST metric: its own orderBy, or the model's event time when the metric sits at the record level (scope is null). Inside an element, and on a custom model, orderBy must be named.

Link copied to clipboard

Whether any alternative of this value is an array, so storage may flatten it into multiple values.

Link copied to clipboard

Whether this value can be an element scope: every non-null alternative is an array whose non-null items are all objects, so a predicate can match one element as a whole.

Link copied to clipboard

Operations on primitive arrays use one member layer, without flattening the definition.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Returns the record identity of this schema's model, rejecting custom models that define none.

Link copied to clipboard
fun QueryValueSchema.storageFamilies(capability: QueryCapability, rules: QueryStorageFamilyRules = QueryStorageFamilyRules.STRICT): List<Set<QueryStorageFamily>>

The native type families this scalar value needs for capability: one set per declared alternative, and storage proves the capability when its native types cover every set and fall in some set. An empty list, or a list with an empty set, means no storage can prove the capability for this value.

Link copied to clipboard

The logical field a system-field filter targets on this schema's model (QueryModelProfile.systemField). A custom model shares the record metadata fields but defines no identity, so an identity filter on it is rejected.

Link copied to clipboard

The query meaning of a QueryTypeFact at field: its structure as a declaration, with properties that are not valid query path segments left out, standard date formats as Temporal.Date, and member annotations applied.