|
ORM C++
|
Partial-result queries select a subset of model fields into a flat user-defined DTO. Use them when you do not need to hydrate a full model object.
Full-model selects keep the existing API and result type:
Partial-result selects use a separate query type:
Source is the mapped ORM model. Result is a user-defined DTO with the exact fields returned by the projection. ProjectionQuery<Source, Result> is the only public entry point for partial-result queries; orm::Query<Model> remains reserved for full-model results.
The public projection helper lives in orm::query:
Projection aliases are explicit. The alias passed to as names a field on the DTO result type, while col references a field path on the source model.
ProjectionQuery supports the same filtering, ordering, paging, distinct, and join controls as Query:
The supported builder methods are:
Projection field paths use the same one-level relation rules as the existing query DSL. Relation fields are flattened into DTO fields through aliases:
Nullable result fields are represented with std::optional<T>:
Use ProjectionQuery<Source, Result> when aggregated values must be returned. They are projected into DTO fields through the same explicit as("dtoField", ...) aliases:
Supported v1 aggregate helpers are count(col(...)), countAll(), sum(col(...)), avg(col(...)), min(col(...)), and max(col(...)). countAll() renders COUNT(*); the other helpers validate and render a source column path.
HAVING uses aggregate predicates instead of regular column predicates:
Comparison values are bound as SQL parameters, the same way WHERE predicate values are bound.
The same aggregate helpers, groupBy, having, andHaving, and orHaving are available on full-model Query<Model>. That query still returns std::vector<Model> and uses aggregates only for HAVING; it does not require a DTO unless aggregate values are selected as result fields.
Common DTO field choices are:
Projection DTOs are flat result objects. Supported DTO field types are the scalar types already supported by model binding plus std::optional<T> for SQL NULL values.
Alias validation is part of the public contract:
Alias validation failures throw std::invalid_argument before executing SQL.
Projection DTOs are flat. Relation fields must be flattened through aliases, for example as("city", col("profile.city")).
ProjectionQuery does not expose include; collection wrappers are model state and are never hydrated into a flat DTO. A projection WHERE predicate may still use the dedicated any, exists, and none helpers to filter by a mapped source-model collection, but the collection itself cannot be projected.
Aggregate ORDER BY, COUNT(DISTINCT ...), raw aggregate expressions, and general subqueries are not part of this version. Correlated EXISTS is available only through the collection predicate helpers.