QEloquent 1.1.0
Qt most flexible ORM.
Loading...
Searching...
No Matches
relation.h
1#ifndef QELOQUENT_RELATION_H
2#define QELOQUENT_RELATION_H
3
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>
11
12#include <QList>
13
14#include <source_location>
15
16namespace QEloquent {
17
18class Query;
19class Error;
20
21class QELOQUENT_EXPORT RelationData : public QSharedData,
22 public Entity,
23 public Serializable
24{
25public:
26 RelationData();
27 RelationData(const RelationData &other);
28 virtual ~RelationData();
29
30 virtual void init(NamingConvention *convention) = 0;
31 virtual bool multiple() const = 0;
32
33 // No need for full CRUD for now, insert/update not handled separately
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; }
38
39 template<typename Model> QList<Model> &relatedModels() const
40 { return *static_cast<QList<Model>*>(relatedList()); }
41 virtual void *relatedList() const = 0;
42
43 QString serializationContext() const override final;
44 bool isListSerializable() const override final { return multiple(); }
45
46 virtual RelationData *clone() const = 0;
47
48 QString name;
49 QMap<int, DataMap> pivotData;
50 MetaObject primaryObject;
51 MetaObject relatedObject;
52 Model *parent = nullptr;
53
54 bool isLoaded = false;
55
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);
58
59protected:
60 QVariant parentPrimary() const;
61 void setParentPrimary(const QVariant &value);
62
63 QVariant parentField(const QString &name) const;
64 void setParentField(const QString &name, const QVariant &value);
65
66 void conserve(const Query &query);
67 void conserve(const Query &query, const Error &error);
68};
69
83template<typename Model>
84class Relation : public Entity,
85 public AbstractItemProxy<Model>,
86 public AbstractListProxy<Model>,
87 public Serializable
88{
90 using RelatedModel = Model;
91
92public:
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(); }
102 Relation(const Relation &other) = default;
104 Relation(Relation &&other) = default;
106 Relation<Model> &operator=(const Relation &other) = default;
108 Relation<Model> &operator=(Relation &&other) = default;
109
111 bool hasPivotData(int index, const QString &name) const
112 { return data->pivotData.value(index).contains(name); }
113
115 QVariant pivotData(int index, const QString &name) const
116 { return data->pivotData.value(index).value(name); }
117
119 void setPivotData(int index, const QString &name, const QVariant &value)
120 { data->pivotData[index].insert(name, value); }
121
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(); }
133 bool deleteData() override { return data->deleteData(); }
134
136 QList<RelatedModel> related() const { ensureLoaded(); return data->relatedModels<RelatedModel>(); }
137
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(); }
141
142private:
144 void ensureLoaded() const {
145 if (!data->isLoaded) {
146 data->get();
147 data->isLoaded = true;
148 }
149 }
150
151 const RelatedModel *constItem() const override {
152 ensureLoaded();
153 const QList<RelatedModel> *list = this->constList();
154 return (list->isEmpty() ? this->defaultItem() : &list->first());
155 }
156
157 RelatedModel *mutableItem() override {
158 ensureLoaded();
159 QList<RelatedModel> *list = this->mutableList();
160 return (list->isEmpty() ? this->defaultItem() : &list->first());
161 }
162
163 RelatedModel *defaultItem() const {
164 static RelatedModel m;
165 m = RelatedModel(); // We clear each time
166 return &m;
167 }
168
169 const QList<RelatedModel> *constList() const override {
170 ensureLoaded();
171 return &data->relatedModels<RelatedModel>();
172 }
173
174 QList<RelatedModel> *mutableList() override {
175 ensureLoaded();
176 return &data->relatedModels<RelatedModel>();
177 }
178
179 QExplicitlySharedDataPointer<RelationData> data;
180};
181
182} // namespace QEloquent
183
184Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(QEloquent::Relation)
185
186#endif // QELOQUENT_RELATION_H
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.