1#ifndef QELOQUENT_RELATION_H
2#define QELOQUENT_RELATION_H
4#include <QEloquent/global.h>
5#include <QEloquent/entity.h>
6#include <QEloquent/serializable.h>
7#include <QEloquent/metaobject.h>
8#include <QEloquent/itemproxy.h>
9#include <QEloquent/listproxy.h>
10#include <QEloquent/datamap.h>
14#include <source_location>
21class QELOQUENT_EXPORT RelationData :
public QSharedData,
27 RelationData(
const RelationData &other);
28 virtual ~RelationData();
30 virtual void init(NamingConvention *convention) = 0;
31 virtual bool multiple()
const = 0;
34 bool save()
override {
return false; }
35 bool insert() override final {
return save(); }
36 bool update() override final {
return save(); };
37 bool deleteData()
override {
return false; }
39 template<
typename Model> QList<Model> &relatedModels()
const
40 {
return *
static_cast<QList<Model>*
>(relatedList()); }
41 virtual void *relatedList()
const = 0;
43 QString serializationContext() const override final;
44 bool isListSerializable() const override final {
return multiple(); }
46 virtual RelationData *clone()
const = 0;
49 QMap<int, DataMap> pivotData;
50 MetaObject primaryObject;
51 MetaObject relatedObject;
52 Model *parent =
nullptr;
54 bool isLoaded =
false;
56 static QExplicitlySharedDataPointer<RelationData> create(
const QString &name,
const Model *parent,
const std::function<RelationData *()> &creationCallback);
57 static QExplicitlySharedDataPointer<RelationData> create(
const std::source_location &location,
const Model *parent,
const std::function<RelationData *()> &creationCallback);
60 QVariant parentPrimary()
const;
61 void setParentPrimary(
const QVariant &value);
63 QVariant parentField(
const QString &name)
const;
64 void setParentField(
const QString &name,
const QVariant &value);
66 void conserve(
const Query &query);
67 void conserve(
const Query &query,
const Error &error);
83template<
typename Model>
85 public AbstractItemProxy<Model>,
86 public AbstractListProxy<Model>,
96 Relation(
const QString &name,
ParentModel *parent,
const std::function<RelationData *()> &creationCallback)
97 : data(RelationData::create(name, parent, creationCallback)) { ensureLoaded(); }
99 Relation(
const std::source_location &location,
const ParentModel *parent,
const std::function<RelationData *()> &creationCallback)
100 : data(RelationData::create(location, parent, creationCallback)) { ensureLoaded(); }
112 {
return data->pivotData.value(index).contains(name); }
115 QVariant
pivotData(
int index,
const QString &name)
const
116 {
return data->pivotData.value(index).value(name); }
119 void setPivotData(
int index,
const QString &name,
const QVariant &value)
120 { data->pivotData[index].insert(name, value); }
123 bool exists()
override { ensureLoaded();
return data->exists(); }
125 bool get()
override { ensureLoaded();
return data->get(); }
127 bool save()
override {
return data->save(); }
129 bool insert()
override {
return data->insert(); }
131 bool update()
override {
return data->update(); }
138 QString serializationContext() const override final {
return data->serializationContext(); }
139 bool isListSerializable() const override final {
return data->multiple(); }
140 QList<DataMap> serialize() const override final {
return data->serialize(); }
144 void ensureLoaded()
const {
145 if (!data->isLoaded) {
147 data->isLoaded =
true;
151 const RelatedModel *constItem()
const override {
153 const QList<RelatedModel> *list = this->constList();
154 return (list->isEmpty() ? this->defaultItem() : &list->first());
157 RelatedModel *mutableItem()
override {
159 QList<RelatedModel> *list = this->mutableList();
160 return (list->isEmpty() ? this->defaultItem() : &list->first());
163 RelatedModel *defaultItem()
const {
164 static RelatedModel m;
169 const QList<RelatedModel> *constList()
const override {
171 return &data->relatedModels<RelatedModel>();
174 QList<RelatedModel> *mutableList()
override {
176 return &data->relatedModels<RelatedModel>();
179 QExplicitlySharedDataPointer<RelationData> data;
The Model class is the base class for all ORM models.
Definition model.h:31
User-facing class for managing model relationships.
Definition relation.h:88
Relation()
Default constructor (uninitialized)
Definition relation.h:94
bool insert() override
Unsupported for relations directly.
Definition relation.h:129
void setPivotData(int index, const QString &name, const QVariant &value)
Set associated metadata.
Definition relation.h:119
QVariant pivotData(int index, const QString &name) const
Retrieve associated metadata.
Definition relation.h:115
Relation(const Relation &other)=default
Copy constructor.
bool deleteData() override
Unsupported for relations directly.
Definition relation.h:133
Relation(const std::source_location &location, const ParentModel *parent, const std::function< RelationData *()> &creationCallback)
Constructor.
Definition relation.h:99
Relation< Model > & operator=(const Relation &other)=default
Copy assignment operator.
QList< RelatedModel > related() const
Explicitly returns the list of related models.
Definition relation.h:136
bool save() override
Unsupported for relations directly.
Definition relation.h:127
bool update() override
Unsupported for relations directly.
Definition relation.h:131
bool get() override
Manually fetches related models from the database.
Definition relation.h:125
Relation(Relation &&other)=default
Move constructor.
bool exists() override
Returns true if related models exist in the database (triggers load)
Definition relation.h:123
bool hasPivotData(int index, const QString &name) const
Check if associated metadata exists at a given index.
Definition relation.h:111
Relation(const QString &name, ParentModel *parent, const std::function< RelationData *()> &creationCallback)
Internal constructor used by Model factory methods.
Definition relation.h:96
Relation< Model > & operator=(Relation &&other)=default
Move assignment operator.