| QxOrm 1.2.3 C++ Object Relational Mapping library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

QxRepository.h
Go to the documentation of this file.

    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_