5#include "../DataBinder/Core.hpp"
6#include "../DataBinder/SqlNullValue.hpp"
7#include "../SqlStatement.hpp"
8#include "BelongsTo.hpp"
12#include <reflection-cpp/reflection.hpp>
32template <
typename OtherRecord>
46 using iterator = ReferencedRecordList::iterator;
61 template <typename Callable>
62 void Each(Callable const& callable);
68 [[nodiscard]] std::
size_t Count() const noexcept;
71 [[nodiscard]]
bool IsEmpty() const noexcept;
78 [[nodiscard]] OtherRecord const&
At(std::
size_t index) const;
85 [[nodiscard]] OtherRecord&
At(std::
size_t index);
92 [[nodiscard]] OtherRecord const& operator[](std::
size_t index) const;
99 [[nodiscard]] OtherRecord& operator[](std::
size_t index);
111 constexpr std::weak_ordering operator<=>(
HasMany const& other) const noexcept = default;
113 constexpr
bool operator==(
HasMany const& other) const noexcept = default;
115 constexpr
bool operator!=(
HasMany const& other) const noexcept = default;
119 std::function<size_t()> count {};
123 std::weak_ordering
operator<=>(Loader
const& )
const noexcept
125 return std::weak_ordering::equivalent;
133 void RequireLoaded();
136 std::optional<ReferencedRecordList> _records;
137 std::optional<size_t> _count;
141constexpr bool IsHasMany = IsSpecializationOf<HasMany, T>;
143template <
typename OtherRecord>
146 _loader = std::move(loader);
149template <
typename OtherRecord>
153 _records = _loader.all();
156template <
typename OtherRecord>
160 _records = { std::move(records) };
164template <
typename OtherRecord>
171template <
typename OtherRecord>
172template <
typename Callable>
175 if (!_records && _loader.each)
177 _loader.each(callable);
181 for (
auto const& record: All())
185template <
typename OtherRecord>
192template <
typename OtherRecord>
196 return _records->size();
198 if (!_count && _loader.count)
201 return _count.value_or(0);
204template <
typename OtherRecord>
210template <
typename OtherRecord>
214 return *_records->at(index);
217template <
typename OtherRecord>
221 return *_records->at(index);
224template <
typename OtherRecord>
228 return *(*_records)[index];
231template <
typename OtherRecord>
235 return *(*_records)[index];
238template <
typename OtherRecord>
243 return _records->begin();
248template <
typename OtherRecord>
253 return _records->end();
258template <
typename OtherRecord>
263 return _records->begin();
268template <
typename OtherRecord>
273 return _records->end();
This HasMany<OtherRecord> represents a simple one-to-many relationship between two records.
OtherRecord value_type
Record type of the "many" side of the relationship.
iterator begin() noexcept
Returns an iterator to the beginning of the record list.
ReferencedRecordList::iterator iterator
Iterator type for the list of records.
void Each(Callable const &callable)
Iterates over the list of records and calls the given callable for each record.
std::size_t Count() const noexcept
Retrieves the number of records in this 1-to-many relationship.
std::vector< std::shared_ptr< OtherRecord > > ReferencedRecordList
The list of records on the "many" side of the relationship.
iterator end() noexcept
Returns an iterator to the end of the record list.
bool IsEmpty() const noexcept
Checks if this 1-to-many relationship is empty.
ReferencedRecordList & Emplace(ReferencedRecordList &&records) noexcept
Emplaces the given list of records.
constexpr std::weak_ordering operator<=>(HasMany const &other) const noexcept=default
Three-way comparison operator.
ReferencedRecordList::const_iterator const_iterator
Const iterator type for the list of records.
OtherRecord ReferencedRecord
The record type of the "many" side of the relationship.
void SetAutoLoader(Loader loader) noexcept
Used internally to configure on-demand loading of the records.
ReferencedRecordList const & All() const noexcept
Retrieves the list of loaded records.
OtherRecord const & operator[](std::size_t index) const
Retrieves the record at the given index.
OtherRecord const & At(std::size_t index) const
Retrieves the record at the given index.