1 | /*************************************************************************** |
2 | * Copyright (C) 2006 by Andreas Gungl <a.gungl@gmx.de> * |
3 | * * |
4 | * This program is free software; you can redistribute it and/or modify * |
5 | * it under the terms of the GNU Library General Public License as * |
6 | * published by the Free Software Foundation; either version 2 of the * |
7 | * License, or (at your option) any later version. * |
8 | * * |
9 | * This program is distributed in the hope that it will be useful, * |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
12 | * GNU General Public License for more details. * |
13 | * * |
14 | * You should have received a copy of the GNU Library General Public * |
15 | * License along with this program; if not, write to the * |
16 | * Free Software Foundation, Inc., * |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
18 | ***************************************************************************/ |
19 | |
20 | #ifndef ENTITY_H |
21 | #define ENTITY_H |
22 | |
23 | #include <QtCore/Qt> |
24 | #include <QtCore/QDateTime> |
25 | #include <QtCore/QDebug> |
26 | #include <QtCore/QString> |
27 | #include <QtCore/QStringList> |
28 | |
29 | class QVariant; |
30 | class QSqlDatabase; |
31 | |
32 | namespace Akonadi { |
33 | namespace Server { |
34 | |
35 | enum Tristate { |
36 | False = 0, |
37 | True = 1, |
38 | Undefined = 2 |
39 | }; |
40 | |
41 | /** |
42 | Base class for classes representing database records. It also contains |
43 | low-level data access and manipulation template methods. |
44 | */ |
45 | class Entity |
46 | { |
47 | public: |
48 | typedef qint64 Id; |
49 | |
50 | protected: |
51 | qint64 id() const; |
52 | void setId(qint64 id); |
53 | |
54 | bool isValid() const; |
55 | |
56 | public: |
57 | template <typename T> static QString joinByName(const QVector<T> &list, const QString &sep) |
58 | { |
59 | QStringList tmp; |
60 | Q_FOREACH (const T &t, list) { |
61 | tmp << t.name(); |
62 | } |
63 | return tmp.join(sep); |
64 | } |
65 | |
66 | /** |
67 | Returns the number of records having @p value in @p column. |
68 | @param column The name of the key column. |
69 | @param value The value used to identify the record. |
70 | */ |
71 | template <typename T> inline static int count(const QString &column, const QVariant &value) |
72 | { |
73 | return Entity::countImpl(T::tableName(), column, value); |
74 | } |
75 | |
76 | /** |
77 | Deletes all records having @p value in @p column. |
78 | */ |
79 | template <typename T> inline static bool remove(const QString &column, const QVariant &value) |
80 | { |
81 | return Entity::removeImpl(T::tableName(), column, value); |
82 | } |
83 | |
84 | /** |
85 | Checks whether an entry in a n:m relation table exists. |
86 | @param leftId Identifier of the left part of the relation. |
87 | @param rightId Identifier of the right part of the relation. |
88 | */ |
89 | template <typename T> inline static bool relatesTo(qint64 leftId, qint64 rightId) |
90 | { |
91 | return Entity::relatesToImpl(T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); |
92 | } |
93 | |
94 | /** |
95 | Adds an entry to a n:m relation table (specified by the template parameter). |
96 | @param leftId Identifier of the left part of the relation. |
97 | @param rightId Identifier of the right part of the relation. |
98 | */ |
99 | template <typename T> inline static bool addToRelation(qint64 leftId, qint64 rightId) |
100 | { |
101 | return Entity::addToRelationImpl(T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); |
102 | } |
103 | |
104 | /** |
105 | Removes an entry from a n:m relation table (specified by the template parameter). |
106 | @param leftId Identifier of the left part of the relation. |
107 | @param rightId Identifier of the right part of the relation. |
108 | */ |
109 | template <typename T> inline static bool removeFromRelation(qint64 leftId, qint64 rightId) |
110 | { |
111 | return Entity::removeFromRelationImpl(T::tableName(), T::leftColumn(), T::rightColumn(), leftId, rightId); |
112 | } |
113 | |
114 | enum RelationSide { |
115 | Left, |
116 | Right |
117 | }; |
118 | |
119 | /** |
120 | Clears all entries from a n:m relation table (specified by the given template parameter). |
121 | @param id Identifier on the relation side. |
122 | @param side The side of the relation. |
123 | */ |
124 | template <typename T> inline static bool clearRelation(qint64 id, RelationSide side = Left) |
125 | { |
126 | return Entity::clearRelationImpl(T::tableName(), T::leftColumn(), T::rightColumn(), id, side); |
127 | } |
128 | |
129 | protected: |
130 | Entity(); |
131 | explicit Entity(qint64 id); |
132 | ~Entity(); |
133 | |
134 | private: |
135 | static int countImpl(const QString &tableName, const QString &column, const QVariant &value); |
136 | static bool removeImpl(const QString &tableName, const QString &column, const QVariant &value); |
137 | static bool relatesToImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); |
138 | static bool addToRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); |
139 | static bool removeFromRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId); |
140 | static bool clearRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 id, RelationSide side); |
141 | |
142 | private: |
143 | static QSqlDatabase database(); |
144 | qint64 m_id; |
145 | }; |
146 | |
147 | namespace _detail { |
148 | |
149 | /*! |
150 | Binary predicate to sort collections of Entity subclasses by |
151 | their id. |
152 | |
153 | Example for sorting: |
154 | \code |
155 | std::sort( coll.begin(), coll.end(), _detail::ById<std::less>() ); |
156 | \endcode |
157 | |
158 | Example for finding by id: |
159 | \code |
160 | // linear: |
161 | std::find_if( coll.begin(), coll.end(), bind( _detail::ById<std::equal_to>(), _1, myId ) ); |
162 | // binary: |
163 | std::lower_bound( coll.begin(), coll.end(), myId, _detail::ById<std::less>() ); |
164 | \end |
165 | */ |
166 | template <template <typename U> class Op> |
167 | struct ById { |
168 | typedef bool result_type; |
169 | bool operator()(Entity::Id lhs, Entity::Id rhs) const |
170 | { |
171 | return Op<Entity::Id>()(lhs, rhs); |
172 | } |
173 | template <typename E> |
174 | bool operator()(const E &lhs, const E &rhs) const |
175 | { |
176 | return this->operator()(lhs.id() , rhs.id()); |
177 | } |
178 | template <typename E> |
179 | bool operator()(const E &lhs, Entity::Id rhs) const |
180 | { |
181 | return this->operator()(lhs.id(), rhs); |
182 | } |
183 | template <typename E> |
184 | bool operator()(Entity::Id lhs, const E &rhs) const |
185 | { |
186 | return this->operator()(lhs, rhs.id()); |
187 | } |
188 | }; |
189 | } |
190 | |
191 | } // namespace Server |
192 | } // namespace Akonadi |
193 | |
194 | Q_DECLARE_METATYPE(Akonadi::Server::Tristate) |
195 | |
196 | #endif |
197 | |