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