![]() |
QxOrm
1.4.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 #ifndef _QX_NO_RTTI 00066 #define QX_REPOSITORY_CAST_COLLECTION \ 00067 type_collection_qt * x = dynamic_cast<type_collection_qt *>(p); \ 00068 type_collection_boost * y = (x ? NULL : dynamic_cast<type_collection_boost *>(p)); \ 00069 if (! x && ! y) { throw qx::dao::sql_error(QX_REPOSITORY_COLLECTION_DYNAMIC_CAST_ERROR); } 00070 #else // _QX_NO_RTTI 00071 #define QX_REPOSITORY_CAST_COLLECTION \ 00072 type_collection_qt * x = NULL; \ 00073 type_collection_boost * y = static_cast<type_collection_boost *>(p); 00074 #endif // _QX_NO_RTTI 00075 00076 namespace qx { 00077 00078 template <class T> 00079 inline void register_repository(const QString & sKey); 00080 00085 template <class T> 00086 class QxRepository : public IxRepository 00087 { 00088 00089 template <class U> 00090 friend inline void register_repository(const QString & sKey); 00091 00092 private: 00093 00094 QxRepository(const QString & sKey) : IxRepository(true, sKey) { ; } 00095 00096 public: 00097 00098 QxRepository() : IxRepository(false, QString("")) { ; } 00099 QxRepository(const QSqlDatabase & database) : IxRepository(false, QString(""), database) { ; } 00100 QxRepository(QxSession * pSession) : IxRepository(false, QString(""), pSession) { ; } 00101 virtual ~QxRepository() { ; } 00102 00103 long count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00104 { return qx::dao::count<T>(query, this->database()); } 00105 00106 T * fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00107 { 00108 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00109 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00110 if (! pDataMemberId) { qAssert(false); return NULL; } 00111 T * t = new T(); QSqlError err; 00112 pDataMemberId->fromVariant(t, id); 00113 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), this->database(), columns); } 00114 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), this->database()); } 00115 if (err.isValid() && m_pSession) { delete t; t = NULL; (* m_pSession) += err; } 00116 else if (err.isValid()) { delete t; t = NULL; } 00117 return t; 00118 } 00119 00120 template <class U> 00121 QSqlError fetchById(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00122 { 00123 QSqlError err; 00124 if (relation.count() == 0) { err = qx::dao::fetch_by_id(u, this->database(), columns); } 00125 else { err = qx::dao::fetch_by_id_with_relation(relation, u, this->database()); } 00126 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00127 return err; 00128 } 00129 00130 template <class U> 00131 QSqlError fetchAll(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00132 { 00133 QSqlError err; 00134 if (relation.count() == 0) { err = qx::dao::fetch_all(u, this->database(), columns); } 00135 else { err = qx::dao::fetch_all_with_relation(relation, u, this->database()); } 00136 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00137 return err; 00138 } 00139 00140 template <class U> 00141 QSqlError fetchByQuery(const qx::QxSqlQuery & query, U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00142 { 00143 QSqlError err; 00144 if (relation.count() == 0) { err = qx::dao::fetch_by_query(query, u, this->database(), columns); } 00145 else { err = qx::dao::fetch_by_query_with_relation(relation, query, u, this->database()); } 00146 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00147 return err; 00148 } 00149 00150 template <class U> 00151 QSqlError insert(U & u, const QStringList & relation = QStringList()) 00152 { 00153 QSqlError err; 00154 if (relation.count() == 0) { err = qx::dao::insert(u, this->database()); } 00155 else { err = qx::dao::insert_with_relation(relation, u, this->database()); } 00156 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00157 return err; 00158 } 00159 00160 template <class U> 00161 QSqlError update(U & u, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00162 { 00163 QSqlError err; 00164 if (relation.count() == 0) { err = qx::dao::update_by_query(query, u, this->database(), columns); } 00165 else { err = qx::dao::update_by_query_with_relation(relation, query, u, this->database()); } 00166 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00167 return err; 00168 } 00169 00170 template <class U> 00171 QSqlError save(U & u, const QStringList & relation = QStringList()) 00172 { 00173 QSqlError err; 00174 if (relation.count() == 0) { err = qx::dao::save(u, this->database()); } 00175 else { err = qx::dao::save_with_relation(relation, u, this->database()); } 00176 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00177 return err; 00178 } 00179 00180 QSqlError deleteById(const QVariant & id) 00181 { 00182 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00183 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00184 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00185 qx_shared_ptr<T> t; t.reset(new T()); 00186 pDataMemberId->fromVariant(t.get(), id); 00187 QSqlError err = qx::dao::delete_by_id((* t), this->database()); 00188 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00189 return err; 00190 } 00191 00192 template <class U> 00193 QSqlError deleteById(U & u) 00194 { 00195 QSqlError err = qx::dao::delete_by_id(u, this->database()); 00196 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00197 return err; 00198 } 00199 00200 QSqlError deleteAll() 00201 { 00202 QSqlError err = qx::dao::delete_all<T>(this->database()); 00203 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00204 return err; 00205 } 00206 00207 QSqlError deleteByQuery(const qx::QxSqlQuery & query) 00208 { 00209 QSqlError err = qx::dao::delete_by_query<T>(query, this->database()); 00210 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00211 return err; 00212 } 00213 00214 QSqlError destroyById(const QVariant & id) 00215 { 00216 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00217 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00218 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00219 qx_shared_ptr<T> t; t.reset(new T()); 00220 pDataMemberId->fromVariant(t.get(), id); 00221 QSqlError err = qx::dao::destroy_by_id((* t), this->database()); 00222 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00223 return err; 00224 } 00225 00226 template <class U> 00227 QSqlError destroyById(U & u) 00228 { 00229 QSqlError err = qx::dao::destroy_by_id(u, this->database()); 00230 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00231 return err; 00232 } 00233 00234 QSqlError destroyAll() 00235 { 00236 QSqlError err = qx::dao::destroy_all<T>(this->database()); 00237 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00238 return err; 00239 } 00240 00241 QSqlError destroyByQuery(const qx::QxSqlQuery & query) 00242 { 00243 QSqlError err = qx::dao::destroy_by_query<T>(query, this->database()); 00244 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00245 return err; 00246 } 00247 00248 template <class U> 00249 qx_bool exist(U & u) 00250 { return qx::dao::exist(u, this->database()); } 00251 00252 private: 00253 00254 typedef typename qx::trait::get_primary_key<T>::type type_primary_key; 00255 typedef qx::QxCollection< type_primary_key, QSharedPointer<T> > type_collection_qt; 00256 typedef qx::QxCollection< type_primary_key, qx_shared_ptr<T> > type_collection_boost; 00257 00258 template <bool bIsQObject /* = false */, int dummy> 00259 struct qxVerifyPointer 00260 { static inline T * get(QObject * p) { Q_UNUSED(p); throw qx::dao::sql_error(QX_REPOSITORY_QOBJECT_BASE_CLASS_ERROR); return NULL; } }; 00261 00262 template <int dummy> 00263 struct qxVerifyPointer<true, dummy> 00264 #ifdef _QX_NO_RTTI 00265 { static inline T * get(QObject * p) { T * t = qobject_cast<T *>(p); if (! t) { throw qx::dao::sql_error(QX_REPOSITORY_POINTER_DYNAMIC_CAST_ERROR); }; return t; } }; 00266 #else // _QX_NO_RTTI 00267 { 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; } }; 00268 #endif // _QX_NO_RTTI 00269 00270 public: 00271 00272 virtual long _count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00273 { return this->count(query); } 00274 00275 virtual void * _fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00276 { return static_cast<void *>(this->fetchById(id, columns, relation)); } 00277 00278 virtual QSqlError _fetchById(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00279 { 00280 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00281 return this->fetchById((* t), columns, relation); 00282 } 00283 00284 virtual QSqlError _fetchById(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00285 { 00286 QX_REPOSITORY_CAST_COLLECTION 00287 return (x ? this->fetchById((* x), columns, relation) : this->fetchById((* y), columns, relation)); 00288 } 00289 00290 virtual QSqlError _fetchAll(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00291 { 00292 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00293 return this->fetchAll((* t), columns, relation); 00294 } 00295 00296 virtual QSqlError _fetchAll(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00297 { 00298 QX_REPOSITORY_CAST_COLLECTION 00299 return (x ? this->fetchAll((* x), columns, relation) : this->fetchAll((* y), columns, relation)); 00300 } 00301 00302 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00303 { 00304 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00305 return this->fetchByQuery(query, (* t), columns, relation); 00306 } 00307 00308 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00309 { 00310 QX_REPOSITORY_CAST_COLLECTION 00311 return (x ? this->fetchByQuery(query, (* x), columns, relation) : this->fetchByQuery(query, (* y), columns, relation)); 00312 } 00313 00314 virtual QSqlError _insert(QObject * p, const QStringList & relation = QStringList()) 00315 { 00316 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00317 return this->insert((* t), relation); 00318 } 00319 00320 virtual QSqlError _insert(qx::IxCollection * p, const QStringList & relation = QStringList()) 00321 { 00322 QX_REPOSITORY_CAST_COLLECTION 00323 return (x ? this->insert((* x), relation) : this->insert((* y), relation)); 00324 } 00325 00326 virtual QSqlError _update(QObject * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00327 { 00328 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00329 return this->update((* t), query, columns, relation); 00330 } 00331 00332 virtual QSqlError _update(qx::IxCollection * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00333 { 00334 QX_REPOSITORY_CAST_COLLECTION 00335 return (x ? this->update((* x), query, columns, relation) : this->update((* y), query, columns, relation)); 00336 } 00337 00338 virtual QSqlError _save(QObject * p, const QStringList & relation = QStringList()) 00339 { 00340 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00341 return this->save((* t), relation); 00342 } 00343 00344 virtual QSqlError _save(qx::IxCollection * p, const QStringList & relation = QStringList()) 00345 { 00346 QX_REPOSITORY_CAST_COLLECTION 00347 return (x ? this->save((* x), relation) : this->save((* y), relation)); 00348 } 00349 00350 virtual QSqlError _deleteById(const QVariant & id) 00351 { return this->deleteById(id); } 00352 00353 virtual QSqlError _deleteById(QObject * p) 00354 { 00355 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00356 return this->deleteById(* t); 00357 } 00358 00359 virtual QSqlError _deleteById(qx::IxCollection * p) 00360 { 00361 QX_REPOSITORY_CAST_COLLECTION 00362 return (x ? this->deleteById(* x) : this->deleteById(* y)); 00363 } 00364 00365 virtual QSqlError _deleteAll() 00366 { return this->deleteAll(); } 00367 00368 virtual QSqlError _deleteByQuery(const qx::QxSqlQuery & query) 00369 { return this->deleteByQuery(query); } 00370 00371 virtual QSqlError _destroyById(const QVariant & id) 00372 { return this->destroyById(id); } 00373 00374 virtual QSqlError _destroyById(QObject * p) 00375 { 00376 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00377 return this->destroyById(* t); 00378 } 00379 00380 virtual QSqlError _destroyById(qx::IxCollection * p) 00381 { 00382 QX_REPOSITORY_CAST_COLLECTION 00383 return (x ? this->destroyById(* x) : this->destroyById(* y)); 00384 } 00385 00386 virtual QSqlError _destroyAll() 00387 { return this->destroyAll(); } 00388 00389 virtual QSqlError _destroyByQuery(const qx::QxSqlQuery & query) 00390 { return this->destroyByQuery(query); } 00391 00392 virtual qx_bool _exist(QObject * p) 00393 { 00394 T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); 00395 return this->exist(* t); 00396 } 00397 00398 virtual qx_bool _exist(qx::IxCollection * p) 00399 { 00400 QX_REPOSITORY_CAST_COLLECTION 00401 return (x ? this->exist(* x) : this->exist(* y)); 00402 } 00403 00404 virtual qx::IxCollection_ptr _newCollection() const 00405 { 00406 qx::IxCollection_ptr lst; 00407 lst.reset(new type_collection_boost()); 00408 return lst; 00409 } 00410 00411 virtual qx::IxClass * _getClass() const 00412 { return qx::QxClass<T>::getSingleton(); } 00413 00414 public: 00415 00416 static T * getById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00417 { 00418 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00419 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00420 if (! pDataMemberId) { qAssert(false); return NULL; } 00421 T * t = new T(); QSqlError err; 00422 pDataMemberId->fromVariant(t, id); 00423 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), NULL, columns); } 00424 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), NULL); } 00425 if (err.isValid()) { delete t; t = NULL; } 00426 return t; 00427 } 00428 00429 }; 00430 00431 template <class T> 00432 inline void register_repository(const QString & sKey) 00433 { 00434 // 'pNewRepository' instance will be destroyed by 'qx::QxRepositoryX::unregisterRepository()' method 00435 qx::QxRepository<T> * pNewRepository = new qx::QxRepository<T>(sKey); 00436 Q_UNUSED(pNewRepository); 00437 } 00438 00439 } // namespace qx 00440 00441 #endif // _QX_REPOSITORY_H_