![]() |
QxOrm
1.2.2
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 namespace qx { 00056 00057 template <class T> 00058 inline void register_repository(const QString & sKey); 00059 00064 template <class T> 00065 class QxRepository : public IxRepository 00066 { 00067 00068 template <class U> 00069 friend inline void register_repository(const QString & sKey); 00070 00071 private: 00072 00073 QxRepository(const QString & sKey) : IxRepository(true, sKey) { ; } 00074 00075 public: 00076 00077 QxRepository() : IxRepository(false, QString("")) { ; } 00078 QxRepository(const QSqlDatabase & database) : IxRepository(false, QString(""), database) { ; } 00079 QxRepository(QxSession * pSession) : IxRepository(false, QString(""), pSession) { ; } 00080 virtual ~QxRepository() { ; } 00081 00082 long count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00083 { return qx::dao::count<T>(query, this->database()); } 00084 00085 T * fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00086 { 00087 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00088 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00089 if (! pDataMemberId) { qAssert(false); return NULL; } 00090 T * t = new T(); QSqlError err; 00091 pDataMemberId->fromVariant(t, id); 00092 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), this->database(), columns); } 00093 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), this->database()); } 00094 if (err.isValid() && m_pSession) { delete t; t = NULL; (* m_pSession) += err; } 00095 else if (err.isValid()) { delete t; t = NULL; } 00096 return t; 00097 } 00098 00099 template <class U> 00100 QSqlError fetchById(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00101 { 00102 QSqlError err; 00103 if (relation.count() == 0) { err = qx::dao::fetch_by_id(u, this->database(), columns); } 00104 else { err = qx::dao::fetch_by_id_with_relation(relation, u, this->database()); } 00105 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00106 return err; 00107 } 00108 00109 template <class U> 00110 QSqlError fetchAll(U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00111 { 00112 QSqlError err; 00113 if (relation.count() == 0) { err = qx::dao::fetch_all(u, this->database(), columns); } 00114 else { err = qx::dao::fetch_all_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 fetchByQuery(const qx::QxSqlQuery & query, U & u, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00121 { 00122 QSqlError err; 00123 if (relation.count() == 0) { err = qx::dao::fetch_by_query(query, u, this->database(), columns); } 00124 else { err = qx::dao::fetch_by_query_with_relation(relation, query, u, this->database()); } 00125 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00126 return err; 00127 } 00128 00129 template <class U> 00130 QSqlError insert(U & u, const QStringList & relation = QStringList()) 00131 { 00132 QSqlError err; 00133 if (relation.count() == 0) { err = qx::dao::insert(u, this->database()); } 00134 else { err = qx::dao::insert_with_relation(relation, u, this->database()); } 00135 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00136 return err; 00137 } 00138 00139 template <class U> 00140 QSqlError update(U & u, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00141 { 00142 QSqlError err; 00143 if (relation.count() == 0) { err = qx::dao::update_by_query(query, u, this->database(), columns); } 00144 else { err = qx::dao::update_by_query_with_relation(relation, query, u, this->database()); } 00145 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00146 return err; 00147 } 00148 00149 template <class U> 00150 QSqlError save(U & u, const QStringList & relation = QStringList()) 00151 { 00152 QSqlError err; 00153 if (relation.count() == 0) { err = qx::dao::save(u, this->database()); } 00154 else { err = qx::dao::save_with_relation(relation, u, this->database()); } 00155 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00156 return err; 00157 } 00158 00159 QSqlError deleteById(const QVariant & id) 00160 { 00161 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00162 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00163 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00164 boost::shared_ptr<T> t; t.reset(new T()); 00165 pDataMemberId->fromVariant(t.get(), id); 00166 QSqlError err = qx::dao::delete_by_id((* t), this->database()); 00167 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00168 return err; 00169 } 00170 00171 template <class U> 00172 QSqlError deleteById(U & u) 00173 { 00174 QSqlError err = qx::dao::delete_by_id(u, this->database()); 00175 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00176 return err; 00177 } 00178 00179 QSqlError deleteAll() 00180 { 00181 QSqlError err = qx::dao::delete_all<T>(this->database()); 00182 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00183 return err; 00184 } 00185 00186 QSqlError deleteByQuery(const qx::QxSqlQuery & query) 00187 { 00188 QSqlError err = qx::dao::delete_by_query<T>(query, this->database()); 00189 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00190 return err; 00191 } 00192 00193 QSqlError destroyById(const QVariant & id) 00194 { 00195 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00196 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00197 if (! pDataMemberId) { qAssert(false); return QSqlError(); } 00198 boost::shared_ptr<T> t; t.reset(new T()); 00199 pDataMemberId->fromVariant(t.get(), id); 00200 QSqlError err = qx::dao::destroy_by_id((* t), this->database()); 00201 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00202 return err; 00203 } 00204 00205 template <class U> 00206 QSqlError destroyById(U & u) 00207 { 00208 QSqlError err = qx::dao::destroy_by_id(u, this->database()); 00209 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00210 return err; 00211 } 00212 00213 QSqlError destroyAll() 00214 { 00215 QSqlError err = qx::dao::destroy_all<T>(this->database()); 00216 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00217 return err; 00218 } 00219 00220 QSqlError destroyByQuery(const qx::QxSqlQuery & query) 00221 { 00222 QSqlError err = qx::dao::destroy_by_query<T>(query, this->database()); 00223 if (err.isValid() && m_pSession) { (* m_pSession) += err; } 00224 return err; 00225 } 00226 00227 template <class U> 00228 qx_bool exist(U & u) 00229 { return qx::dao::exist(u, this->database()); } 00230 00231 private: 00232 00233 typedef typename qx::trait::get_primary_key<T>::type type_primary_key; 00234 typedef QSharedPointer<T> type_object_ptr; 00235 typedef qx::QxCollection<type_primary_key, type_object_ptr> type_collection; 00236 00237 template <bool bIsQObject /* = false */, int dummy> 00238 struct qxVerifyPointer 00239 { static inline T * get(QObject * p) { Q_UNUSED(p); throw qx::dao::sql_error(QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid pointer, need to inherit from QObject class to use qx::IxRepository interface'")); return NULL; } }; 00240 00241 template <int dummy> 00242 struct qxVerifyPointer<true, dummy> 00243 { static inline T * get(QObject * p) { T * t = dynamic_cast<T *>(p); if (! t) { throw qx::dao::sql_error(QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid pointer, dynamic_cast failed'")); }; return t; } }; 00244 00245 type_collection * qxVerifyPointer_Collection(qx::IxCollection * p) 00246 { type_collection * x = dynamic_cast<type_collection *>(p); if (! x) { throw qx::dao::sql_error(QSqlError("[QxOrm] qx::QxRepository<T> : 'invalid collection pointer, dynamic_cast failed'")); }; return x; } 00247 00248 public: 00249 00250 virtual long _count(const qx::QxSqlQuery & query = qx::QxSqlQuery()) 00251 { return this->count(query); } 00252 00253 virtual void * _fetchById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00254 { return static_cast<void *>(this->fetchById(id, columns, relation)); } 00255 00256 virtual QSqlError _fetchById(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00257 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->fetchById((* t), columns, relation); } 00258 00259 virtual QSqlError _fetchById(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00260 { type_collection * x = qxVerifyPointer_Collection(p); return this->fetchById((* x), columns, relation); } 00261 00262 virtual QSqlError _fetchAll(QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00263 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->fetchAll((* t), columns, relation); } 00264 00265 virtual QSqlError _fetchAll(qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00266 { type_collection * x = qxVerifyPointer_Collection(p); return this->fetchAll((* x), columns, relation); } 00267 00268 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, QObject * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00269 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->fetchByQuery(query, (* t), columns, relation); } 00270 00271 virtual QSqlError _fetchByQuery(const qx::QxSqlQuery & query, qx::IxCollection * p, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00272 { type_collection * x = qxVerifyPointer_Collection(p); return this->fetchByQuery(query, (* x), columns, relation); } 00273 00274 virtual QSqlError _insert(QObject * p, const QStringList & relation = QStringList()) 00275 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->insert((* t), relation); } 00276 00277 virtual QSqlError _insert(qx::IxCollection * p, const QStringList & relation = QStringList()) 00278 { type_collection * x = qxVerifyPointer_Collection(p); return this->insert((* x), relation); } 00279 00280 virtual QSqlError _update(QObject * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00281 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->update((* t), query, columns, relation); } 00282 00283 virtual QSqlError _update(qx::IxCollection * p, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00284 { type_collection * x = qxVerifyPointer_Collection(p); return this->update((* x), query, columns, relation); } 00285 00286 virtual QSqlError _save(QObject * p, const QStringList & relation = QStringList()) 00287 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->save((* t), relation); } 00288 00289 virtual QSqlError _save(qx::IxCollection * p, const QStringList & relation = QStringList()) 00290 { type_collection * x = qxVerifyPointer_Collection(p); return this->save((* x), relation); } 00291 00292 virtual QSqlError _deleteById(const QVariant & id) 00293 { return this->deleteById(id); } 00294 00295 virtual QSqlError _deleteById(QObject * p) 00296 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->deleteById(* t); } 00297 00298 virtual QSqlError _deleteById(qx::IxCollection * p) 00299 { type_collection * x = qxVerifyPointer_Collection(p); return this->deleteById(* x); } 00300 00301 virtual QSqlError _deleteAll() 00302 { return this->deleteAll(); } 00303 00304 virtual QSqlError _deleteByQuery(const qx::QxSqlQuery & query) 00305 { return this->deleteByQuery(query); } 00306 00307 virtual QSqlError _destroyById(const QVariant & id) 00308 { return this->destroyById(id); } 00309 00310 virtual QSqlError _destroyById(QObject * p) 00311 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->destroyById(* t); } 00312 00313 virtual QSqlError _destroyById(qx::IxCollection * p) 00314 { type_collection * x = qxVerifyPointer_Collection(p); return this->destroyById(* x); } 00315 00316 virtual QSqlError _destroyAll() 00317 { return this->destroyAll(); } 00318 00319 virtual QSqlError _destroyByQuery(const qx::QxSqlQuery & query) 00320 { return this->destroyByQuery(query); } 00321 00322 virtual qx_bool _exist(QObject * p) 00323 { T * t = qxVerifyPointer<boost::is_base_of<QObject, T>::value, 0>::get(p); return this->exist(* t); } 00324 00325 virtual qx_bool _exist(qx::IxCollection * p) 00326 { type_collection * x = qxVerifyPointer_Collection(p); return this->exist(* x); } 00327 00328 public: 00329 00330 static T * getById(const QVariant & id, const QStringList & columns = QStringList(), const QStringList & relation = QStringList()) 00331 { 00332 IxDataMemberX * pDataMemberX = QxClass<T>::getSingleton()->getDataMemberX(); 00333 IxDataMember * pDataMemberId = (pDataMemberX ? pDataMemberX->getId_WithDaoStrategy() : NULL); 00334 if (! pDataMemberId) { qAssert(false); return NULL; } 00335 T * t = new T(); QSqlError err; 00336 pDataMemberId->fromVariant(t, id); 00337 if (relation.count() == 0) { err = qx::dao::fetch_by_id((* t), NULL, columns); } 00338 else { err = qx::dao::fetch_by_id_with_relation(relation, (* t), NULL); } 00339 if (err.isValid()) { delete t; t = NULL; } 00340 return t; 00341 } 00342 00343 }; 00344 00345 template <class T> 00346 inline void register_repository(const QString & sKey) 00347 { 00348 // 'pNewRepository' instance will be destroyed by 'qx::QxRepositoryX::unregisterRepository()' method 00349 qx::QxRepository<T> * pNewRepository = new qx::QxRepository<T>(sKey); 00350 Q_UNUSED(pNewRepository); 00351 } 00352 00353 } // namespace qx 00354 00355 #endif // _QX_REPOSITORY_H_