File indexing completed on 2025-01-05 04:46:58
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2006 Andreas Gungl <a.gungl@gmx.de> * 0003 * * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later * 0005 ***************************************************************************/ 0006 0007 #pragma once 0008 0009 #include <QString> 0010 #include <QStringList> 0011 0012 class QVariant; 0013 0014 namespace Akonadi 0015 { 0016 namespace Server 0017 { 0018 class DataStore; 0019 /** 0020 Base class for classes representing database records. It also contains 0021 low-level data access and manipulation template methods. 0022 */ 0023 class Entity 0024 { 0025 public: 0026 using Id = qint64; 0027 0028 protected: 0029 qint64 id() const; 0030 void setId(qint64 id); 0031 0032 bool isValid() const; 0033 0034 public: 0035 template<typename T> 0036 static QString joinByName(const QList<T> &list, const QString &sep) 0037 { 0038 QStringList tmp; 0039 tmp.reserve(list.count()); 0040 for (const T &t : list) { 0041 tmp << t.name(); 0042 } 0043 return tmp.join(sep); 0044 } 0045 0046 /** 0047 Returns the number of records having @p value in @p column. 0048 @param column The name of the key column. 0049 @param value The value used to identify the record. 0050 */ 0051 template<typename T> 0052 inline static int count(const QString &column, const QVariant &value) 0053 { 0054 return count<T>(dataStore(), column, value); 0055 } 0056 0057 template<typename T> 0058 inline static int count(DataStore *store, const QString &column, const QVariant &value) 0059 { 0060 return Entity::countImpl(store, T::tableName(), column, value); 0061 } 0062 0063 /** 0064 Deletes all records having @p value in @p column. 0065 */ 0066 template<typename T> 0067 inline static bool remove(const QString &column, const QVariant &value) 0068 { 0069 return remove<T>(dataStore(), column, value); 0070 } 0071 0072 template<typename T> 0073 inline static bool remove(DataStore *store, const QString &column, const QVariant &value) 0074 { 0075 return Entity::removeImpl(store, T::tableName(), column, value); 0076 } 0077 0078 /** 0079 Checks whether an entry in a n:m relation table exists. 0080 @param leftId Identifier of the left part of the relation. 0081 @param rightId Identifier of the right part of the relation. 0082 */ 0083 template<typename T> 0084 inline static bool relatesTo(qint64 leftId, qint64 rightId) 0085 { 0086 return relatesTo<T>(dataStore(), leftId, rightId); 0087 } 0088 0089 template<typename T> 0090 inline static bool relatesTo(DataStore *store, qint64 leftId, qint64 rightId) 0091 { 0092 return Entity::relatesToImpl(store, T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); 0093 } 0094 0095 /** 0096 Adds an entry to a n:m relation table (specified by the template parameter). 0097 @param leftId Identifier of the left part of the relation. 0098 @param rightId Identifier of the right part of the relation. 0099 */ 0100 template<typename T> 0101 inline static bool addToRelation(qint64 leftId, qint64 rightId) 0102 { 0103 return addToRelation<T>(dataStore(), leftId, rightId); 0104 } 0105 0106 template<typename T> 0107 inline static bool addToRelation(DataStore *store, qint64 leftId, qint64 rightId) 0108 { 0109 return Entity::addToRelationImpl(store, T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); 0110 } 0111 0112 /** 0113 Removes an entry from a n:m relation table (specified by the template parameter). 0114 @param leftId Identifier of the left part of the relation. 0115 @param rightId Identifier of the right part of the relation. 0116 */ 0117 template<typename T> 0118 inline static bool removeFromRelation(qint64 leftId, qint64 rightId) 0119 { 0120 return removeFromRelation<T>(dataStore(), leftId, rightId); 0121 } 0122 0123 template<typename T> 0124 inline static bool removeFromRelation(DataStore *store, qint64 leftId, qint64 rightId) 0125 { 0126 return Entity::removeFromRelationImpl(store, T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); 0127 } 0128 0129 enum RelationSide { 0130 Left, 0131 Right, 0132 }; 0133 0134 /** 0135 Clears all entries from a n:m relation table (specified by the given template parameter). 0136 @param id Identifier on the relation side. 0137 @param side The side of the relation. 0138 */ 0139 template<typename T> 0140 inline static bool clearRelation(qint64 id, RelationSide side = Left) 0141 { 0142 return clearRelation<T>(dataStore(), id, side); 0143 } 0144 template<typename T> 0145 inline static bool clearRelation(DataStore *store, qint64 id, RelationSide side = Left) 0146 { 0147 return Entity::clearRelationImpl(store, T::tableName(), T::leftColumn(), T::rightColumn(), id, side); 0148 } 0149 0150 protected: 0151 Entity(); 0152 explicit Entity(qint64 id); 0153 ~Entity(); 0154 0155 private: 0156 static DataStore *dataStore(); 0157 0158 static int countImpl(DataStore *store, const QString &tableName, const QString &column, const QVariant &value); 0159 static bool removeImpl(DataStore *store, const QString &tableName, const QString &column, const QVariant &value); 0160 static bool relatesToImpl(DataStore *store, const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); 0161 static bool 0162 addToRelationImpl(DataStore *store, const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); 0163 static bool 0164 removeFromRelationImpl(DataStore *store, const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); 0165 static bool 0166 clearRelationImpl(DataStore *store, const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 id, RelationSide side); 0167 0168 private: 0169 qint64 m_id; 0170 }; 0171 0172 namespace _detail 0173 { 0174 /*! 0175 Binary predicate to sort collections of Entity subclasses by 0176 their id. 0177 0178 Example for sorting: 0179 \code 0180 std::sort( coll.begin(), coll.end(), _detail::ById<std::less>() ); 0181 \endcode 0182 0183 Example for finding by id: 0184 \code 0185 // linear: 0186 std::find_if( coll.begin(), coll.end(), bind( _detail::ById<std::equal_to>(), _1, myId ) ); 0187 // binary: 0188 std::lower_bound( coll.begin(), coll.end(), myId, _detail::ById<std::less>() ); 0189 \endcode 0190 */ 0191 template<template<typename U> class Op> 0192 struct ById { 0193 using result_type = bool; 0194 bool operator()(Entity::Id lhs, Entity::Id rhs) const 0195 { 0196 return Op<Entity::Id>()(lhs, rhs); 0197 } 0198 template<typename E> 0199 bool operator()(const E &lhs, const E &rhs) const 0200 { 0201 return this->operator()(lhs.id(), rhs.id()); 0202 } 0203 template<typename E> 0204 bool operator()(const E &lhs, Entity::Id rhs) const 0205 { 0206 return this->operator()(lhs.id(), rhs); 0207 } 0208 template<typename E> 0209 bool operator()(Entity::Id lhs, const E &rhs) const 0210 { 0211 return this->operator()(lhs, rhs.id()); 0212 } 0213 }; 0214 } 0215 0216 } // namespace Server 0217 } // namespace Akonadi