![]() |
QxOrm
1.3.2
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://www.qxorm.com/ 00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com) 00005 ** 00006 ** This file is part of the QxOrm library 00007 ** 00008 ** This software is provided 'as-is', without any express or implied 00009 ** warranty. In no event will the authors be held liable for any 00010 ** damages arising from the use of this software 00011 ** 00012 ** Commercial Usage 00013 ** Licensees holding valid commercial QxOrm licenses may use this file in 00014 ** accordance with the commercial license agreement provided with the 00015 ** Software or, alternatively, in accordance with the terms contained in 00016 ** a written agreement between you and Lionel Marty 00017 ** 00018 ** GNU General Public License Usage 00019 ** Alternatively, this file may be used under the terms of the GNU 00020 ** General Public License version 3.0 as published by the Free Software 00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the 00022 ** packaging of this file. Please review the following information to 00023 ** ensure the GNU General Public License version 3.0 requirements will be 00024 ** met : http://www.gnu.org/copyleft/gpl.html 00025 ** 00026 ** If you are unsure which license is appropriate for your use, or 00027 ** if you have questions regarding the use of this file, please contact : 00028 ** contact@qxorm.com 00029 ** 00030 ****************************************************************************/ 00031 00032 #ifndef _QX_REPOSITORY_H_ 00033 #define _QX_REPOSITORY_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #include <boost/type_traits/is_base_of.hpp> 00047 00048 #include <QxDao/QxRepository/IxRepository.h> 00049 #include <QxDao/QxRepository/QxRepositoryX.h> 00050 00051 #include <QxDao/QxDao.h> 00052 #include <QxDao/QxSession.h> 00053 #include <QxDao/QxSqlError.h> 00054 00055 #include <QxRegister/QxClass.h> 00056 00057 #include <QxCollection/QxCollection.h> 00058 00059 #include <QxTraits/get_primary_key.h> 00060 00061 #define QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid collection pointer, dynamic_cast failed'", "", QSqlError::UnknownError) 00062 #define QX_REPOSITORY_POINTER_DYNAMIC_CAST_ERROR QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid pointer, dynamic_cast failed'", "", QSqlError::UnknownError) 00063 #define QX_REPOSITORY_QOBJECT_BASE_CLASS_ERROR QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid pointer, need to inherit from QObject class to use qx::IxRepository interface'", "", QSqlError::UnknownError) 00064 00065 namespace qx { 00066 00067 template <class T> 00068 inline void register_repository(const QString & sKey); 00069 00074 template <class T> 00075 class QxRepository : public IxRepository 00076 { 00077 00078 template <class U> 00079 friend inline void register_repository(const QString & sKey); 00080 00081 private: 00082 00083 QxRepository(const QString & sKey) : IxRepository(true, sKey) { ; } 00084 00085 public: 00086 00087 QxRepository() : IxRepository(false, QString("")) { ; } 00088 QxRepository(const QSqlDatabase & database) : IxRepository(false, QString(""), database) { ; } 00089 QxRepository(QxSession * pSession) : IxRepository(false, QString(""), pSession) { ; } 00090 virtual ~QxRepository() { ; } 00091 00092 long count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00093 { return qx::dao::count<T>(query, this->database()); } 00094 00095 T * fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00096 { 00097 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00098 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00099 if (! pDataMemberId) { qAssert(false); return NULL; } 00100 T * t = new T(); QSqlError err; 00101 pDataMemberId->fromVariant(t, id); 00102 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), this->database(), columns); } 00103 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), this->database()); } 00104 if (err.isValid() && m_pSession) { delete t; t = NULL; (* m_pSession) += err; } 00105 else if (err.isValid()) { delete t; t = NULL; } 00106 return t; 00107 } 00108 00109 template <class U> 00110 QSqlError fetchById(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00111 { 00112 QSqlError err; 00113 if (relation.count() == 0) { err = qx::dao::fetch_by_id(u, this->database(), columns); } 00114 else { err = qx::dao::fetch_by_id_with_relation(relation, u, this->database()); } 00115 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00116 return err; 00117 } 00118 00119 template <class U> 00120 QSqlError fetchAll(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00121 { 00122 QSqlError err; 00123 if (relation.count() == 0) { err = qx::dao::fetch_all(u, this->database(), columns); } 00124 else { err = qx::dao::fetch_all_with_relation(relation, u, this->database()); } 00125 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00126 return err; 00127 } 00128 00129 template <class U> 00130 QSqlError fetchByQuery(const qx::QxSqlQuery & query, U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00131 { 00132 QSqlError err; 00133 if (relation.count() == 0) { err = qx::dao::fetch_by_query(query, u, this->database(), columns); } 00134 else { err = qx::dao::fetch_by_query_with_relation(relation, query, u, this->database()); } 00135 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00136 return err; 00137 } 00138 00139 template <class U> 00140 QSqlError insert(U & u, const QStringList & relation = QStringList()) 00141 { 00142 QSqlError err; 00143 if (relation.count() == 0) { err = qx::dao::insert(u, this->database()); } 00144 else { err = qx::dao::insert_with_relation(relation, u, this->database()); } 00145 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00146 return err; 00147 } 00148 00149 template <class U> 00150 QSqlError update(U & u, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00151 { 00152 QSqlError err; 00153 if (relation.count() == 0) { err = qx::dao::update_by_query(query, u, this->database(), columns); } 00154 else { err = qx::dao::update_by_query_with_relation(relation, query, u, this->database()); } 00155 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00156 return err; 00157 } 00158 00159 template <class U> 00160 QSqlError save(U & u, const QStringList & relation = QStringList()) 00161 { 00162 QSqlError err; 00163 if (relation.count() == 0) { err = qx::dao::save(u, this->database()); } 00164 else { err = qx::dao::save_with_relation(relation, u, this->database()); } 00165 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00166 return err; 00167 } 00168 00169 QSqlError deleteById(const QVariant & id) 00170 { 00171 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00172 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00173 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00174 boost::shared_ptr<T> t; t.reset(new T()); 00175 pDataMemberId->fromVariant(t.get(), id); 00176 QSqlError err = qx::dao::delete_by_id((* t), this->database()); 00177 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00178 return err; 00179 } 00180 00181 template <class U> 00182 QSqlError deleteById(U & u) 00183 { 00184 QSqlError err = qx::dao::delete_by_id(u, this->database()); 00185 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00186 return err; 00187 } 00188 00189 QSqlError deleteAll() 00190 { 00191 QSqlError err = qx::dao::delete_all<T>(this->database()); 00192 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00193 return err; 00194 } 00195 00196 QSqlError deleteByQuery(const qx::QxSqlQuery & query) 00197 { 00198 QSqlError err = qx::dao::delete_by_query<T>(query, this->database()); 00199 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00200 return err; 00201 } 00202 00203 QSqlError destroyById(const QVariant & id) 00204 { 00205 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00206 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00207 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00208 boost::shared_ptr<T> t; t.reset(new T()); 00209 pDataMemberId->fromVariant(t.get(), id); 00210 QSqlError err = qx::dao::destroy_by_id((* t), this->database()); 00211 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00212 return err; 00213 } 00214 00215 template <class U> 00216 QSqlError destroyById(U & u) 00217 { 00218 QSqlError err = qx::dao::destroy_by_id(u, this->database()); 00219 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00220 return err; 00221 } 00222 00223 QSqlError destroyAll() 00224 { 00225 QSqlError err = qx::dao::destroy_all<T>(this->database()); 00226 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00227 return err; 00228 } 00229 00230 QSqlError destroyByQuery(const qx::QxSqlQuery & query) 00231 { 00232 QSqlError err = qx::dao::destroy_by_query<T>(query, this->database()); 00233 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00234 return err; 00235 } 00236 00237 template <class U> 00238 qx_bool exist(U & u) 00239 { return qx::dao::exist(u, this->database()); } 00240 00241 private: 00242 00243 typedef typename qx::trait::get_primary_key<T>::type type_primary_key; 00244 typedef qx::QxCollection< type_primary_key, QSharedPointer<T> > type_collection_qt; 00245 typedef qx::QxCollection< type_primary_key, boost::shared_ptr<T> > type_collection_boost; 00246 00247 template <bool bIsQObject /* = false */, int dummy> 00248 struct qxVerifyPointer 00249 { static inline T * get(QObject * p) { Q_UNUSED(p); throw qx::dao::sql_error(QX_REPOSITORY_QOBJECT_BASE_CLASS_ERROR); return NULL; } }; 00250 00251 template <int dummy> 00252 struct qxVerifyPointer<true, dummy> 00253 { static inline T * get(QObject * p) { T * t = dynamic_cast<T *>(p); if (! t) { throw qx::dao::sql_error(QX_REPOSITORY_POINTER_DYNAMIC_CAST_ERROR); }; return t; } }; 00254 00255 public: 00256 00257 virtual long _count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00258 { return this->count(query); } 00259 00260 virtual void * _fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00261 { return static_cast<void *>(this->fetchById(id, columns, relation)); } 00262 00263 virtual QSqlError _fetchById(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00264 { 00265 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00266 return this->fetchById((* t), columns, relation); 00267 } 00268 00269 virtual QSqlError _fetchById(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00270 { 00271 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00272 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00273 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00274 return (x ? this->fetchById((* x), columns, relation) : this->fetchById((* y), columns, relation)); 00275 } 00276 00277 virtual QSqlError _fetchAll(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00278 { 00279 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00280 return this->fetchAll((* t), columns, relation); 00281 } 00282 00283 virtual QSqlError _fetchAll(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00284 { 00285 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00286 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00287 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00288 return (x ? this->fetchAll((* x), columns, relation) : this->fetchAll((* y), columns, relation)); 00289 } 00290 00291 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00292 { 00293 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00294 return this->fetchByQuery(query, (* t), columns, relation); 00295 } 00296 00297 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00298 { 00299 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00300 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00301 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00302 return (x ? this->fetchByQuery(query, (* x), columns, relation) : this->fetchByQuery(query, (* y), columns, relation)); 00303 } 00304 00305 virtual QSqlError _insert(QObject * p, const QStringList & relation = QStringList()) 00306 { 00307 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00308 return this->insert((* t), relation); 00309 } 00310 00311 virtual QSqlError _insert(qx::IxCollection * p, const QStringList & relation = QStringList()) 00312 { 00313 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00314 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00315 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00316 return (x ? this->insert((* x), relation) : this->insert((* y), relation)); 00317 } 00318 00319 virtual QSqlError _update(QObject * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00320 { 00321 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00322 return this->update((* t), query, columns, relation); 00323 } 00324 00325 virtual QSqlError _update(qx::IxCollection * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00326 { 00327 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00328 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00329 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00330 return (x ? this->update((* x), query, columns, relation) : this->update((* y), query, columns, relation)); 00331 } 00332 00333 virtual QSqlError _save(QObject * p, const QStringList & relation = QStringList()) 00334 { 00335 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00336 return this->save((* t), relation); 00337 } 00338 00339 virtual QSqlError _save(qx::IxCollection * p, const QStringList & relation = QStringList()) 00340 { 00341 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00342 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00343 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00344 return (x ? this->save((* x), relation) : this->save((* y), relation)); 00345 } 00346 00347 virtual QSqlError _deleteById(const QVariant & id) 00348 { return this->deleteById(id); } 00349 00350 virtual QSqlError _deleteById(QObject * p) 00351 { 00352 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00353 return this->deleteById(* t); 00354 } 00355 00356 virtual QSqlError _deleteById(qx::IxCollection * p) 00357 { 00358 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00359 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00360 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00361 return (x ? this->deleteById(* x) : this->deleteById(* y)); 00362 } 00363 00364 virtual QSqlError _deleteAll() 00365 { return this->deleteAll(); } 00366 00367 virtual QSqlError _deleteByQuery(const qx::QxSqlQuery & query) 00368 { return this->deleteByQuery(query); } 00369 00370 virtual QSqlError _destroyById(const QVariant & id) 00371 { return this->destroyById(id); } 00372 00373 virtual QSqlError _destroyById(QObject * p) 00374 { 00375 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00376 return this->destroyById(* t); 00377 } 00378 00379 virtual QSqlError _destroyById(qx::IxCollection * p) 00380 { 00381 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00382 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00383 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00384 return (x ? this->destroyById(* x) : this->destroyById(* y)); 00385 } 00386 00387 virtual QSqlError _destroyAll() 00388 { return this->destroyAll(); } 00389 00390 virtual QSqlError _destroyByQuery(const qx::QxSqlQuery & query) 00391 { return this->destroyByQuery(query); } 00392 00393 virtual qx_bool _exist(QObject * p) 00394 { 00395 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00396 return this->exist(* t); 00397 } 00398 00399 virtual qx_bool _exist(qx::IxCollection * p) 00400 { 00401 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); 00402 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); 00403 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00404 return (x ? this->exist(* x) : this->exist(* y)); 00405 } 00406 00407 virtual qx::IxCollection_ptr _newCollection() const 00408 { 00409 qx::IxCollection_ptr lst; 00410 lst.reset(new type_collection_boost()); 00411 return lst; 00412 } 00413 00414 virtual qx::IxClass * _getClass() const 00415 { return qx::QxClass<T>::getSingleton(); } 00416 00417 public: 00418 00419 static T * getById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00420 { 00421 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00422 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00423 if (! pDataMemberId) { qAssert(false); return NULL; } 00424 T * t = new T(); QSqlError err; 00425 pDataMemberId->fromVariant(t, id); 00426 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), NULL, columns); } 00427 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), NULL); } 00428 if (err.isValid()) { delete t; t = NULL; } 00429 return t; 00430 } 00431 00432 }; 00433 00434 template <class T> 00435 inline void register_repository(const QString & sKey) 00436 { 00437 // 'pNewRepository' instance will be destroyed by 'qx::QxRepositoryX::unregisterRepository()' method 00438 qx::QxRepository<T> * pNewRepository = new qx::QxRepository<T>(sKey); 00439 Q_UNUSED(pNewRepository); 00440 } 00441 00442 } // namespace qx 00443 00444 #endif // _QX_REPOSITORY_H_