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
114 return RunFinisher([
this] {
return ExistImpl(); });
126 return RunFinisher([
this] {
return CountImpl(); });
132 return RunFinisher([
this] {
return AllImpl(); });
175 template <
auto... RelationPath>
177 [[nodiscard]] Derived& With();
182 return RunFinisher([
this] {
return DeleteImpl(); });
197 template <auto Field>
198#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
199 requires(is_aggregate_type(parent_of(
Field)))
201 requires std::is_member_object_pointer_v<
decltype(
Field)>
205 return RunFinisher([
this] {
return this->
template AllImpl<Field>(); });
221 template <
auto... ReferencedFields>
222 requires(
sizeof...(ReferencedFields) >= 2)
225 return RunFinisher([
this] {
return this->
template AllImpl<ReferencedFields...>(); });
231 return RunFinisher([
this] {
return FirstImpl(); });
239 template <auto Field>
240#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
241 requires(is_aggregate_type(parent_of(
Field)))
243 requires std::is_member_object_pointer_v<
decltype(
Field)>
247 return RunFinisher([
this] {
return this->
template FirstImpl<Field>(); });
255 template <
auto... ReferencedFields>
256 requires(
sizeof...(ReferencedFields) >= 2)
259 return RunFinisher([
this] {
return this->
template FirstImpl<ReferencedFields...>(); });
265 return RunFinisher([
this, n] {
return FirstImpl(n); });
269 template <
auto... ReferencedFields>
272 return RunFinisher([
this, n] {
return this->
template FirstImpl<ReferencedFields...>(n); });
276 [[nodiscard]]
auto Range(
size_t offset,
size_t limit)
278 return RunFinisher([
this, offset, limit] {
return RangeImpl(offset, limit); });
282 template <
auto... ReferencedFields>
283 [[nodiscard]]
auto Range(
size_t offset,
size_t limit)
285 return RunFinisher([
this, offset, limit] {
return this->
template RangeImpl<ReferencedFields...>(offset, limit); });
300 template <
typename Finisher>
301 auto RunFinisher(Finisher finisher);
309 void RunRelationPreloaders(std::span<Record> records);
311 [[nodiscard]]
bool ExistImpl();
312 [[nodiscard]]
size_t CountImpl();
313 [[nodiscard]] std::vector<Record> AllImpl();
316 template <auto Field>
317#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
318 requires(is_aggregate_type(parent_of(
Field)))
320 requires std::is_member_object_pointer_v<
decltype(
Field)>
322 [[nodiscard]]
auto AllImpl() -> std::vector<ReferencedFieldTypeOf<Field>>;
324 template <
auto... ReferencedFields>
325 requires(
sizeof...(ReferencedFields) >= 2)
326 [[nodiscard]]
auto AllImpl() -> std::vector<Record>;
328 [[nodiscard]] std::optional<Record> FirstImpl();
330 template <auto Field>
331#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
332 requires(is_aggregate_type(parent_of(
Field)))
334 requires std::is_member_object_pointer_v<
decltype(
Field)>
336 [[nodiscard]]
auto FirstImpl() -> std::optional<ReferencedFieldTypeOf<Field>>;
338 template <
auto... ReferencedFields>
339 requires(
sizeof...(ReferencedFields) >= 2)
340 [[nodiscard]]
auto FirstImpl() -> std::optional<Record>;
342 [[nodiscard]] std::vector<Record> FirstImpl(
size_t n);
344 template <
auto... ReferencedFields>
345 [[nodiscard]] std::vector<Record> FirstImpl(
size_t n);
347 [[nodiscard]] std::vector<Record> RangeImpl(
size_t offset,
size_t limit);
349 template <
auto... ReferencedFields>
350 [[nodiscard]] std::vector<Record> RangeImpl(
size_t offset,
size_t limit);
360template <
typename Record,
361 DataMapperOptions QueryOptions,
362 SqlQueryExecutionMode Execution = SqlQueryExecutionMode::Synchronous>
373 static constexpr SqlQueryExecutionMode QueryExecution = Execution;
377 dm, std::move(fields)
382 static void ReadResults(SqlServerType sqlServerType,
SqlResultCursor reader, std::vector<Record>* records);
383 static void ReadResult(SqlServerType sqlServerType,
SqlResultCursor reader, std::optional<Record>* optionalRecord);
391template <
typename FirstRecord,
typename SecondRecord, DataMapperOptions QueryOptions, SqlQueryExecutionMode Execution>
394 std::tuple<FirstRecord, SecondRecord>,
395 SqlAllFieldsQueryBuilder<std::tuple<FirstRecord, SecondRecord>, QueryOptions, Execution>,
399 using RecordType = std::tuple<FirstRecord, SecondRecord>;
406 static constexpr SqlQueryExecutionMode QueryExecution = Execution;
411 QueryOptions> { dm, std::move(fields) }
415 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.