5#include "../SqlConnection.hpp"
6#include "../SqlQueryFormatter.hpp"
7#include "../SqlStatement.hpp"
9#include "BelongsTo.hpp"
57enum class SqlQueryExecutionMode : std::uint8_t
68template <
typename Record,
typename Derived, DataMapperOptions QueryOptions = {}>
76 std::vector<SqlVariant> _boundInputs;
84 using RelationPreloader = void (*)(
DataMapper&, std::span<Record* const>);
85 std::vector<RelationPreloader> _relationPreloaders;
89 LIGHTWEIGHT_FORCE_INLINE SqlSearchCondition& SearchCondition()
noexcept
91 return this->_query.searchCondition;
94 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
SqlQueryFormatter const& Formatter()
const noexcept
128 return RunFinisher([
this] {
return ExistImpl(); });
140 return RunFinisher([
this] {
return CountImpl(); });
146 return RunFinisher([
this] {
return AllImpl(); });
188 template <
auto... RelationPath>
190 [[nodiscard]] Derived& With();
195 return RunFinisher([
this] {
return DeleteImpl(); });
210 template <auto Field>
211#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
212 requires(is_aggregate_type(parent_of(
Field)))
214 requires std::is_member_object_pointer_v<
decltype(
Field)>
218 return RunFinisher([
this] {
return this->
template AllImpl<Field>(); });
234 template <
auto... ReferencedFields>
235 requires(
sizeof...(ReferencedFields) >= 2)
238 return RunFinisher([
this] {
return this->
template AllImpl<ReferencedFields...>(); });
244 return RunFinisher([
this] {
return FirstImpl(); });
252 template <auto Field>
253#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
254 requires(is_aggregate_type(parent_of(
Field)))
256 requires std::is_member_object_pointer_v<
decltype(
Field)>
260 return RunFinisher([
this] {
return this->
template FirstImpl<Field>(); });
268 template <
auto... ReferencedFields>
269 requires(
sizeof...(ReferencedFields) >= 2)
272 return RunFinisher([
this] {
return this->
template FirstImpl<ReferencedFields...>(); });
278 return RunFinisher([
this, n] {
return FirstImpl(n); });
282 template <
auto... ReferencedFields>
285 return RunFinisher([
this, n] {
return this->
template FirstImpl<ReferencedFields...>(n); });
289 [[nodiscard]]
auto Range(
size_t offset,
size_t limit)
291 return RunFinisher([
this, offset, limit] {
return RangeImpl(offset, limit); });
295 template <
auto... ReferencedFields>
296 [[nodiscard]]
auto Range(
size_t offset,
size_t limit)
298 return RunFinisher([
this, offset, limit] {
return this->
template RangeImpl<ReferencedFields...>(offset, limit); });
313 template <
typename Finisher>
314 auto RunFinisher(Finisher finisher);
322 void RunRelationPreloaders(std::span<Record> records);
324 [[nodiscard]]
bool ExistImpl();
325 [[nodiscard]]
size_t CountImpl();
326 [[nodiscard]] std::vector<Record> AllImpl();
329 template <auto Field>
330#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
331 requires(is_aggregate_type(parent_of(
Field)))
333 requires std::is_member_object_pointer_v<
decltype(
Field)>
335 [[nodiscard]]
auto AllImpl() -> std::vector<ReferencedFieldTypeOf<Field>>;
337 template <
auto... ReferencedFields>
338 requires(
sizeof...(ReferencedFields) >= 2)
339 [[nodiscard]]
auto AllImpl() -> std::vector<Record>;
341 [[nodiscard]] std::optional<Record> FirstImpl();
343 template <auto Field>
344#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
345 requires(is_aggregate_type(parent_of(
Field)))
347 requires std::is_member_object_pointer_v<
decltype(
Field)>
349 [[nodiscard]]
auto FirstImpl() -> std::optional<ReferencedFieldTypeOf<Field>>;
351 template <
auto... ReferencedFields>
352 requires(
sizeof...(ReferencedFields) >= 2)
353 [[nodiscard]]
auto FirstImpl() -> std::optional<Record>;
355 [[nodiscard]] std::vector<Record> FirstImpl(
size_t n);
357 template <
auto... ReferencedFields>
358 [[nodiscard]] std::vector<Record> FirstImpl(
size_t n);
360 [[nodiscard]] std::vector<Record> RangeImpl(
size_t offset,
size_t limit);
362 template <
auto... ReferencedFields>
363 [[nodiscard]] std::vector<Record> RangeImpl(
size_t offset,
size_t limit);
373template <
typename Record,
374 DataMapperOptions QueryOptions,
375 SqlQueryExecutionMode Execution = SqlQueryExecutionMode::Synchronous>
386 static constexpr SqlQueryExecutionMode QueryExecution = Execution;
390 dm, std::move(fields)
395 static void ReadResults(SqlServerType sqlServerType,
SqlResultCursor reader, std::vector<Record>* records);
396 static void ReadResult(SqlServerType sqlServerType,
SqlResultCursor reader, std::optional<Record>* optionalRecord);
404template <
typename FirstRecord,
typename SecondRecord, DataMapperOptions QueryOptions, SqlQueryExecutionMode Execution>
407 std::tuple<FirstRecord, SecondRecord>,
408 SqlAllFieldsQueryBuilder<std::tuple<FirstRecord, SecondRecord>, QueryOptions, Execution>,
412 using RecordType = std::tuple<FirstRecord, SecondRecord>;
419 static constexpr SqlQueryExecutionMode QueryExecution = Execution;
424 QueryOptions> { dm, std::move(fields) }
428 static void ReadResults(SqlServerType sqlServerType, SqlResultCursor reader, std::vector<RecordType>* records);
Main API for mapping records to and from the database using high level C++ syntax.
Represents a query builder that retrieves all fields of a record.
auto All()
Executes a SELECT query and returns all records found for the specified field, only having the specif...
auto All()
Executes a SELECT query and returns all records found for the specified field.
auto Delete()
Executes a DELETE query.
auto Range(size_t offset, size_t limit)
Executes a SELECT query for a range of records and returns them.
auto Range(size_t offset, size_t limit)
Executes a SELECT query for a range of records with only the specified fields populated.
auto First()
Executes the query to get a single scalar value from the first record found.
auto First(size_t n)
Executes a SELECT query for the first n records with only the specified fields populated.
auto First()
Executes a SELECT query for the first record found and returns it.
auto All()
Executes a SELECT query and returns all records found.
auto First(size_t n)
Executes a SELECT query for the first n records found and returns them.
auto First()
Executes a SELECT query for the first record found and returns it with only the specified fields popu...
Represents a record type that can be used with the DataMapper.
size_t eagerLoadDepth
How many levels of relations to eagerly batch-load after a query materializes.
bool loadRelations
Whether to automatically load relations when querying records.
Represents a single column in a table.