Lightweight 0.20260625.0
Loading...
Searching...
No Matches
Lightweight::CompositeForeignKey< Connections > Class Template Reference

Represents a foreign key spanning several columns. More...

#include <CompositeForeignKey.hpp>

Classes

struct  Loader
 Carries the deferred load, installed by the DataMapper. More...
 

Public Types

using Child = std::tuple_element_t< 0, std::tuple< typename Connections::FromRecord... > >
 The record holding the foreign key, i.e. the one declaring this member.
 
using ReferencedRecord = std::tuple_element_t< 0, std::tuple< typename Connections::IntoRecord... > >
 The referenced record.
 
using ValueType = std::tuple< typename Connections::FromField::ValueType... >
 The tuple of foreign key values, in the order the connections are declared.
 
using OrderedValueType = decltype([]< std::size_t... Slot >(std::index_sequence< Slot... >) { return std::tuple< typename ConnectionAtSlot< Slot >::FromField::ValueType... > {}
 

Public Member Functions

LIGHTWEIGHT_FORCE_INLINE ReferencedRecord const & Record () const
 
LIGHTWEIGHT_FORCE_INLINE constexpr bool IsLoaded () const noexcept
 
LIGHTWEIGHT_FORCE_INLINE void Unload () noexcept
 Discards the loaded record, so the next access loads it again.
 
LIGHTWEIGHT_FORCE_INLINE constexpr void EmplaceRecord (std::shared_ptr< ReferencedRecord > record) noexcept
 
LIGHTWEIGHT_FORCE_INLINE constexpr ReferencedRecord const * operator-> () const
 
void SetAutoLoader (Loader loader)
 
std::weak_ordering operator<=> (CompositeForeignKey const &other) const noexcept=default
 
bool operator== (CompositeForeignKey const &other) const noexcept=default
 Equality comparison operator.
 

Static Public Member Functions

static ValueType ValuesOf (Child const &record)
 
static constexpr void AssertCoversReferencedKey () noexcept
 
static OrderedValueType OrderedValuesOf (Child const &record)
 

Static Public Attributes

static constexpr std::size_t Count = sizeof...(Connections)
 Number of columns this foreign key spans.
 

Detailed Description

template<ConnectionType... Connections>
class Lightweight::CompositeForeignKey< Connections >

Represents a foreign key spanning several columns.

Declared as a list of Connection, each pairing one of this record's columns with the column it references. The referenced and referencing records are derived from those pointers rather than named again, so they cannot disagree with the connections.

This member holds no column of its own. Every foreign key column is an ordinary Field on the record - one data member per database column - and this relation only ties them together and navigates. It therefore contributes nothing to RecordColumnCount and is skipped by every projection, exactly as HasMany and HasOneThrough are.

Connections may be listed in any order. Values are permuted into the referenced record's member order before binding, because that is the order a primary key lookup emits its predicates in - see OrderedValuesOf and src/tests/CompositeKeyOrderingTests.cpp.

Template Parameters
ConnectionsOne Connection per column of the foreign key.
struct Parent
{
// Composite key members must not be PrimaryKey::AutoAssign: auto-assignment yields one value
// that would be written into every key member. See GenerateAutoAssignPrimaryKey.
Field<int32_t, PrimaryKey::ServerSideAutoIncrement, SqlRealName { "part_a" }> partA;
Field<int32_t, PrimaryKey::ServerSideAutoIncrement, SqlRealName { "part_b" }> partB;
};
struct Child
{
Field<int32_t, PrimaryKey::AutoAssign> id;
Field<int32_t, SqlRealName { "ref_a" }> refA;
Field<int32_t, SqlRealName { "ref_b" }> refB;
CompositeForeignKey<Connection<&Child::refA, &Parent::partA>,
Connection<&Child::refB, &Parent::partB>> parent;
};
std::tuple_element_t< 0, std::tuple< typename Connections::FromRecord... > > Child
The record holding the foreign key, i.e. the one declaring this member.
Represents a single column in a table.
Definition Field.hpp:84
Helper class, used to represent a real SQL column names as template arguments.

Definition at line 186 of file CompositeForeignKey.hpp.

Member Typedef Documentation

◆ Child

template<ConnectionType... Connections>
using Lightweight::CompositeForeignKey< Connections >::Child = std::tuple_element_t<0, std::tuple<typename Connections::FromRecord...> >

The record holding the foreign key, i.e. the one declaring this member.

Definition at line 195 of file CompositeForeignKey.hpp.

◆ ReferencedRecord

template<ConnectionType... Connections>
using Lightweight::CompositeForeignKey< Connections >::ReferencedRecord = std::tuple_element_t<0, std::tuple<typename Connections::IntoRecord...> >

The referenced record.

Definition at line 198 of file CompositeForeignKey.hpp.

◆ ValueType

template<ConnectionType... Connections>
using Lightweight::CompositeForeignKey< Connections >::ValueType = std::tuple<typename Connections::FromField::ValueType...>

The tuple of foreign key values, in the order the connections are declared.

Definition at line 249 of file CompositeForeignKey.hpp.

◆ OrderedValueType

template<ConnectionType... Connections>
using Lightweight::CompositeForeignKey< Connections >::OrderedValueType = decltype([]<std::size_t... Slot>(std::index_sequence<Slot...>) { return std::tuple<typename ConnectionAtSlot<Slot>::FromField::ValueType...> {}

The tuple of foreign key values, ordered to match the referenced record's key members.

Differs from ValueType whenever the connections are not written in the referenced record's member order, and differs in type too when the key columns are heterogeneous.

Definition at line 289 of file CompositeForeignKey.hpp.

Member Function Documentation

◆ ValuesOf()

template<ConnectionType... Connections>
static ValueType Lightweight::CompositeForeignKey< Connections >::ValuesOf ( Child const &  record)
inlinestatic

Reads this record's foreign key values, in the order the connections are declared.

The values are not stored on the relation: there is exactly one copy of each, in the Field that owns the column, so nothing can fall out of sync.

Parameters
recordThe record holding the foreign key.
Returns
The values, in declaration order of the connections.

Definition at line 300 of file CompositeForeignKey.hpp.

References Lightweight::CompositeForeignKey< Connections >::AssertCoversReferencedKey().

◆ AssertCoversReferencedKey()

template<ConnectionType... Connections>
static constexpr void Lightweight::CompositeForeignKey< Connections >::AssertCoversReferencedKey ( )
inlinestaticconstexprnoexcept

Checks that the connections cover the referenced record's whole primary key.

Deferred to first use rather than asserted in the class body: at class-instantiation time the referenced record can still be incomplete, so reflecting over its members is not yet possible. A partial key would otherwise surface only as an argument-count mismatch thrown from the first navigation, far from the declaration that caused it.

Definition at line 312 of file CompositeForeignKey.hpp.

References Lightweight::CompositeForeignKey< Connections >::Count.

Referenced by Lightweight::CompositeForeignKey< Connections >::OrderedValuesOf(), and Lightweight::CompositeForeignKey< Connections >::ValuesOf().

◆ OrderedValuesOf()

template<ConnectionType... Connections>
static OrderedValueType Lightweight::CompositeForeignKey< Connections >::OrderedValuesOf ( Child const &  record)
inlinestatic

Reads this record's foreign key values, permuted into the referenced record's member order.

This is the order they must be bound in. A primary key lookup emits one WHERE predicate per primary key member, in that record's member declaration order, and binds its arguments positionally - so passing values in connection order would bind them to the wrong predicates whenever the two orders differ. With same-typed key columns that yields a wrong row rather than an error, which is why the permutation is done here rather than left to the caller.

Parameters
recordThe record holding the foreign key.
Returns
The values, ordered to match the referenced record's primary key members.

Definition at line 338 of file CompositeForeignKey.hpp.

References Lightweight::CompositeForeignKey< Connections >::AssertCoversReferencedKey().

◆ Record()

template<ConnectionType... Connections>
LIGHTWEIGHT_FORCE_INLINE ReferencedRecord const & Lightweight::CompositeForeignKey< Connections >::Record ( ) const
inline
Returns
The referenced record, loading it on first access.

Definition at line 352 of file CompositeForeignKey.hpp.

◆ IsLoaded()

template<ConnectionType... Connections>
LIGHTWEIGHT_FORCE_INLINE constexpr bool Lightweight::CompositeForeignKey< Connections >::IsLoaded ( ) const
inlineconstexprnoexcept
Returns
true if the referenced record has been loaded.

Definition at line 359 of file CompositeForeignKey.hpp.

◆ Unload()

template<ConnectionType... Connections>
LIGHTWEIGHT_FORCE_INLINE void Lightweight::CompositeForeignKey< Connections >::Unload ( )
inlinenoexcept

Discards the loaded record, so the next access loads it again.

Definition at line 365 of file CompositeForeignKey.hpp.

◆ EmplaceRecord()

template<ConnectionType... Connections>
LIGHTWEIGHT_FORCE_INLINE constexpr void Lightweight::CompositeForeignKey< Connections >::EmplaceRecord ( std::shared_ptr< ReferencedRecord record)
inlineconstexprnoexcept

Adopts an already-fetched referenced record, marking the relation loaded.

Parameters
recordThe fetched record.

Definition at line 373 of file CompositeForeignKey.hpp.

◆ operator->()

template<ConnectionType... Connections>
LIGHTWEIGHT_FORCE_INLINE constexpr ReferencedRecord const * Lightweight::CompositeForeignKey< Connections >::operator-> ( ) const
inlineconstexpr
Returns
A pointer to the referenced record, loading it on first access.

Definition at line 379 of file CompositeForeignKey.hpp.

◆ SetAutoLoader()

template<ConnectionType... Connections>
void Lightweight::CompositeForeignKey< Connections >::SetAutoLoader ( Loader  loader)
inline

Used internally to configure on-demand loading of the referenced record.

Parameters
loaderThe loader to install.

Definition at line 412 of file CompositeForeignKey.hpp.

◆ operator<=>()

template<ConnectionType... Connections>
std::weak_ordering Lightweight::CompositeForeignKey< Connections >::operator<=> ( CompositeForeignKey< Connections > const &  other) const
defaultnoexcept

Three-way comparison operator.

Without this, the relation is neither std::equality_comparable nor (owing to its private members) an aggregate, and Reflection::CollectDifferences - which falls back to recursing into non-comparable members as aggregates - hard-errors on any record holding one. HasMany, HasOneThrough and HasManyThrough all define one for the same reason.

Member Data Documentation

◆ Count

template<ConnectionType... Connections>
constexpr std::size_t Lightweight::CompositeForeignKey< Connections >::Count = sizeof...(Connections)
staticconstexpr

Number of columns this foreign key spans.

Definition at line 192 of file CompositeForeignKey.hpp.

Referenced by Lightweight::CompositeForeignKey< Connections >::AssertCoversReferencedKey().


The documentation for this class was generated from the following file: