added Model::operator==() 😮

This commit is contained in:
silverqx
2022-08-20 16:20:52 +02:00
parent a55e4c2595
commit 13bba6f2fc
4 changed files with 108 additions and 1 deletions
@@ -29,6 +29,9 @@ namespace Orm::Tiny::Concerns
using StringUtils = Orm::Tiny::Utils::String;
public:
/*! Comparison operator for the HasAttributes concern. */
inline bool operator==(const HasAttributes &) const = default;
/*! Set a given attribute on the model. */
Derived &setAttribute(const QString &key, QVariant value);
/*! Set a vector of model attributes. No checking is done. */
@@ -155,6 +155,10 @@ namespace Concerns
/*! Determine if the model touches a given relation. */
inline bool touches(const QString &relation) const;
/* Others */
/*! Comparison operator for the HasRelationships concern. */
bool operator==(const HasRelationships &right) const;
protected:
/*! Relation visitor lambda type. */
using RelationVisitor = std::function<void(
@@ -226,6 +230,12 @@ namespace Concerns
template<typename Related>
QString pivotTableName() const;
/* Others */
/*! Compare the u_relations hash (size and keys only). */
static bool compareURelations(
const QHash<QString, RelationVisitor> &left,
const QHash<QString, RelationVisitor> &right) noexcept;
/* Data members */
/*! Map of relation names to methods. */
QHash<QString, RelationVisitor> u_relations;
@@ -678,6 +688,24 @@ namespace Concerns
return getTouchedRelations().contains(relation);
}
/* Others */
template<typename Derived, AllRelationsConcept ...AllRelations>
bool HasRelationships<Derived, AllRelations...>::operator==(
const HasRelationships &right) const
{
// u_relations == right.u_relations
/* It compares only the size and keys and doesn't compare hash values because
the std::function doesn't have a full/complete operator==() (it only compares
for the nullptr). */
if (!compareURelations(u_relations, right.u_relations))
return false;
return m_relations == right.m_relations &&
u_touches == right.u_touches &&
m_pivots == right.m_pivots;
}
/* protected */
template<typename Derived, AllRelationsConcept ...AllRelations>
@@ -858,6 +886,23 @@ namespace Concerns
return segments.join(UNDERSCORE).toLower();
}
/* Others */
template<typename Derived, AllRelationsConcept ...AllRelations>
bool HasRelationships<Derived, AllRelations...>::compareURelations(
const QHash<QString, RelationVisitor> &left,
const QHash<QString, RelationVisitor> &right) noexcept
{
if (left.size() != right.size())
return false;
for (auto it = right.keyBegin(); it != right.keyEnd(); ++it)
if (left.find(*it) == left.constEnd())
return false;
return true;
}
/* private */
template<typename Derived, AllRelationsConcept ...AllRelations>
@@ -27,6 +27,9 @@ namespace Concerns
class HasTimestamps
{
public:
/*! Comparison operator for the HasTimestamps concern. */
inline bool operator==(const HasTimestamps &) const noexcept = default;
/*! Update the model's update timestamp. */
bool touch();
/*! Update the model's update timestamp. */
+57 -1
View File
@@ -31,7 +31,6 @@ namespace Orm::Tiny
using GuardedModel = Concerns::GuardedModel;
// TODO model missing methods Soft Deleting, Model::trashed()/restore()/withTrashed()/forceDelete()/onlyTrashed(), check this methods also on EloquentBuilder and SoftDeletes trait silverqx
// TODO model comparing operator==() silverqx
// TODO model missing methods Model::loadMissing() silverqx
// TODO model missing methods EloquentCollection::toQuery() silverqx
// TODO model missing saveOrFail(), updateOrFail(), deleteOrFail(), I will need to implement ManagesTransaction::transaction(callback) method silverqx
@@ -161,6 +160,9 @@ namespace Orm::Tiny
template<ModelConcept ModelToCompare>
bool isNot(const std::optional<ModelToCompare> &model) const;
/*! Comparison operator for the Model. */
bool operator==(const Model &right) const;
/*! Fill the model with a vector of attributes. */
Derived &fill(const QVector<AttributeItem> &attributes);
/*! Fill the model with a vector of attributes. */
@@ -698,6 +700,60 @@ namespace Orm::Tiny
return !is(model);
}
template<typename Derived, AllRelationsConcept ...AllRelations>
bool Model<Derived, AllRelations...>::operator==(const Model &right) const
{
/* Comparing the HasConnectionResolver, GuardsAttributes, ModelProxies, and
IsModel is not needed as they don't contain any data members or they
contain ony a static data members. */
// Compare the HasAttributes concern
using HasAttributes = Concerns::HasAttributes<Derived, AllRelations...>;
if (static_cast<const HasAttributes &>(*this) !=
static_cast<const HasAttributes &>(right)
)
return false;
// Compare the HasRelationships concern
using HasRelationships = Concerns::HasRelationships<Derived, AllRelations...>;
if (static_cast<const HasRelationships &>(*this) !=
static_cast<const HasRelationships &>(right)
)
return false;
// Compare the HasTimestamps concern
using HasTimestamps = Concerns::HasTimestamps<Derived, AllRelations...>;
if (static_cast<const HasTimestamps &>(*this) !=
static_cast<const HasTimestamps &>(right)
)
return false;
// Compare the Base Model
if (true != (exists == right.exists &&
u_table == right.u_table &&
u_connection == right.u_connection &&
u_incrementing == right.u_incrementing &&
u_primaryKey == right.u_primaryKey &&
u_with == right.u_with)
// u_withCount == right.u_withCount
)
return false;
// Compare the Derived Model 😮🤯😎
const auto &derivedRight = static_cast<const Derived &>(right);
// model().u_relations == derivedRight.u_relations
/* It compares only the size and keys and doesn't compare hash values because
the std::function doesn't have a full/complete operator==() (it only compares
for the nullptr). */
if (!HasRelationships::compareURelations(model().u_relations,
derivedRight.u_relations))
return false;
return model().u_touches == derivedRight.u_touches &&
model().u_timestamps == derivedRight.u_timestamps;
}
template<typename Derived, AllRelationsConcept ...AllRelations>
Derived &
Model<Derived, AllRelations...>::fill(const QVector<AttributeItem> &attributes)