QxOrm  1.4.5
C++ Object Relational Mapping library
QxModelService.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** https://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_MODEL_SERVICE_H_
00033 #define _QX_MODEL_SERVICE_H_
00034 
00035 #ifdef _MSC_VER
00036 #pragma once
00037 #endif
00038 
00046 #include <QxModelView/QxModel.h>
00047 
00048 namespace qx {
00049 
00057 template <class T, class S, class B = qx::IxModel>
00058 class QxModelService : public qx::QxModel<T, B>
00059 {
00060 
00061 public:
00062 
00063    typedef typename qx::QxModel<T, B>::type_ptr type_ptr;
00064    typedef typename qx::QxModel<T, B>::type_primary_key type_primary_key;
00065    typedef typename qx::QxModel<T, B>::type_collection type_collection;
00066    typedef std::shared_ptr<type_collection> type_collection_ptr;
00067    typedef B type_base_class;
00068 
00069 public:
00070 
00071    QxModelService(QObject * parent = 0) : qx::QxModel<T, B>(parent) { ; }
00072    QxModelService(qx::IxModel * other, QObject * parent) : qx::QxModel<T, B>(other, parent) { ; }
00073    virtual ~QxModelService() { ; }
00074 
00075    virtual long qxCount(const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL)
00076    {
00077       long lCount = 0;
00078       this->qxCount(lCount, query, pDatabase);
00079       return lCount;
00080    }
00081 
00082    virtual QSqlError qxCount(long & lCount, const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL)
00083    {
00084       Q_UNUSED(pDatabase);
00085       S services;
00086       this->m_lastError = services.count(lCount, query);
00087       return this->m_lastError;
00088    }
00089 
00090    virtual QSqlError qxFetchById(const QVariant & id, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00091    {
00092       Q_UNUSED(pDatabase);
00093       this->clear();
00094       type_ptr pItem = type_ptr(new T());
00095       if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxFetchById()' method : '%s'", "data member id not registered"); qAssert(false); }
00096       if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxFetchById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
00097       this->m_pDataMemberId->fromVariant(pItem.get(), id);
00098 
00099       type_primary_key primaryKey;
00100       qx::cvt::from_variant(id, primaryKey);
00101       this->beginInsertRows(QModelIndex(), 0, 0);
00102       this->m_model.insert(primaryKey, pItem);
00103 
00104       S services;
00105       this->m_lastError = services.fetchById(pItem, this->m_lstColumns, relation);
00106       this->updateShowEmptyLine();
00107       this->endInsertRows();
00108       return this->m_lastError;
00109    }
00110 
00111    virtual QSqlError qxFetchAll(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00112    {
00113       Q_UNUSED(pDatabase);
00114       this->clear();
00115 
00116       S services;
00117       type_collection_ptr tmp;
00118       tmp.reset(new type_collection());
00119       this->m_lastError = services.fetchAll(tmp, this->m_lstColumns, relation);
00120 
00121       if (tmp->count() <= 0) { return this->m_lastError; }
00122       this->beginResetModel();
00123       this->m_model = (* tmp);
00124       this->updateShowEmptyLine();
00125       this->endResetModel();
00126       return this->m_lastError;
00127    }
00128 
00129    virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery & query, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00130    {
00131       Q_UNUSED(pDatabase);
00132       this->clear();
00133 
00134       S services;
00135       type_collection_ptr tmp;
00136       tmp.reset(new type_collection());
00137       this->m_lastError = services.fetchByQuery(query, tmp, this->m_lstColumns, relation);
00138 
00139       if (tmp->count() <= 0) { return this->m_lastError; }
00140       this->beginResetModel();
00141       this->m_model = (* tmp);
00142       this->updateShowEmptyLine();
00143       this->endResetModel();
00144       return this->m_lastError;
00145    }
00146 
00147    virtual QSqlError qxFetchRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00148    {
00149       Q_UNUSED(pDatabase);
00150       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00151       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00152 
00153       S services;
00154       this->m_lastError = services.fetchById(pItem, this->m_lstColumns, relation);
00155       if (this->m_lastError.isValid()) { return this->m_lastError; }
00156 
00157       QModelIndex idxTopLeft = this->index(row, 0);
00158       QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1));
00159       this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight);
00160       this->updateKey(row);
00161       return this->m_lastError;
00162    }
00163 
00164    virtual QSqlError qxInsert(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00165    {
00166       Q_UNUSED(pDatabase);
00167       if (relation.count() > 0) { this->syncAllNestedModel(relation); }
00168 
00169       type_collection_ptr tmp;
00170       tmp.reset(new type_collection());
00171       (* tmp) = this->m_model;
00172 
00173       S services;
00174       this->m_lastError = services.insert(tmp, relation);
00175 
00176       if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
00177       return this->m_lastError;
00178    }
00179 
00180    virtual QSqlError qxInsertRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00181    {
00182       Q_UNUSED(pDatabase);
00183       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00184       if (relation.count() > 0) { this->syncNestedModel(row, relation); }
00185       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00186 
00187       S services;
00188       this->m_lastError = services.insert(pItem, relation);
00189 
00190       if (! this->m_lastError.isValid()) { this->updateKey(row); }
00191       return this->m_lastError;
00192    }
00193 
00194    virtual QSqlError qxUpdate(const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00195    {
00196       Q_UNUSED(pDatabase);
00197       if (relation.count() > 0) { this->syncAllNestedModel(relation); }
00198 
00199       type_collection_ptr tmp;
00200       tmp.reset(new type_collection());
00201       (* tmp) = this->m_model;
00202 
00203       S services;
00204       this->m_lastError = services.update(tmp, query, this->m_lstColumns, relation);
00205 
00206       if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
00207       return this->m_lastError;
00208    }
00209 
00210    virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00211    {
00212       Q_UNUSED(pDatabase);
00213       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00214       if (relation.count() > 0) { this->syncNestedModel(row, relation); }
00215       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00216 
00217       S services;
00218       this->m_lastError = services.update(pItem, query, this->m_lstColumns, relation);
00219 
00220       if (! this->m_lastError.isValid()) { this->updateKey(row); }
00221       return this->m_lastError;
00222    }
00223 
00224    virtual QSqlError qxSave(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00225    {
00226       Q_UNUSED(pDatabase);
00227       if (relation.count() > 0) { this->syncAllNestedModel(relation); }
00228 
00229       type_collection_ptr tmp;
00230       tmp.reset(new type_collection());
00231       (* tmp) = this->m_model;
00232 
00233       S services;
00234       this->m_lastError = services.save(tmp, relation);
00235 
00236       if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
00237       return this->m_lastError;
00238    }
00239 
00240    virtual QSqlError qxSaveRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
00241    {
00242       Q_UNUSED(pDatabase);
00243       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00244       if (relation.count() > 0) { this->syncNestedModel(row, relation); }
00245       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00246 
00247       S services;
00248       this->m_lastError = services.save(pItem, relation);
00249 
00250       if (! this->m_lastError.isValid()) { this->updateKey(row); }
00251       return this->m_lastError;
00252    }
00253 
00254    virtual QSqlError qxDeleteById(const QVariant & id, QSqlDatabase * pDatabase = NULL)
00255    {
00256       Q_UNUSED(pDatabase);
00257       type_ptr pItem = type_ptr(new T());
00258       if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); }
00259       if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
00260       this->m_pDataMemberId->fromVariant(pItem.get(), id);
00261 
00262       S services;
00263       this->m_lastError = services.deleteById(pItem);
00264       return this->m_lastError;
00265    }
00266 
00267    virtual QSqlError qxDeleteAll(QSqlDatabase * pDatabase = NULL)
00268    {
00269       Q_UNUSED(pDatabase);
00270       S services;
00271       this->m_lastError = services.deleteAll();
00272       return this->m_lastError;
00273    }
00274 
00275    virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
00276    {
00277       Q_UNUSED(pDatabase);
00278       S services;
00279       this->m_lastError = services.deleteByQuery(query);
00280       return this->m_lastError;
00281    }
00282 
00283    virtual QSqlError qxDeleteRow(int row, QSqlDatabase * pDatabase = NULL)
00284    {
00285       Q_UNUSED(pDatabase);
00286       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00287       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00288 
00289       S services;
00290       this->m_lastError = services.deleteById(pItem);
00291       return this->m_lastError;
00292    }
00293 
00294    virtual QSqlError qxDestroyById(const QVariant & id, QSqlDatabase * pDatabase = NULL)
00295    {
00296       Q_UNUSED(pDatabase);
00297       type_ptr pItem = type_ptr(new T());
00298       if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); }
00299       if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
00300       this->m_pDataMemberId->fromVariant(pItem.get(), id);
00301 
00302       S services;
00303       this->m_lastError = services.destroyById(pItem);
00304       return this->m_lastError;
00305    }
00306 
00307    virtual QSqlError qxDestroyAll(QSqlDatabase * pDatabase = NULL)
00308    {
00309       Q_UNUSED(pDatabase);
00310       S services;
00311       this->m_lastError = services.destroyAll();
00312       return this->m_lastError;
00313    }
00314 
00315    virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
00316    {
00317       Q_UNUSED(pDatabase);
00318       S services;
00319       this->m_lastError = services.destroyByQuery(query);
00320       return this->m_lastError;
00321    }
00322 
00323    virtual QSqlError qxDestroyRow(int row, QSqlDatabase * pDatabase = NULL)
00324    {
00325       Q_UNUSED(pDatabase);
00326       if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); }
00327       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
00328 
00329       S services;
00330       this->m_lastError = services.destroyById(pItem);
00331       return this->m_lastError;
00332    }
00333 
00334    virtual QSqlError qxExecuteQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
00335    {
00336       Q_UNUSED(pDatabase);
00337       this->clear();
00338 
00339       S services;
00340       type_collection_ptr tmp;
00341       tmp.reset(new type_collection());
00342       this->m_lastError = services.executeQuery(query, tmp);
00343 
00344       if (tmp->count() <= 0) { return this->m_lastError; }
00345       this->beginResetModel();
00346       this->m_model = (* tmp);
00347       this->updateShowEmptyLine();
00348       this->endResetModel();
00349       return this->m_lastError;
00350    }
00351 
00352    virtual qx_bool qxExist(const QVariant & id, QSqlDatabase * pDatabase = NULL)
00353    {
00354       Q_UNUSED(pDatabase);
00355       type_ptr pItem = type_ptr(new T());
00356       if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxExist()' method : '%s'", "data member id not registered"); qAssert(false); }
00357       if (! this->m_pDataMemberId) { return qx_bool(false); }
00358       this->m_pDataMemberId->fromVariant(pItem.get(), id);
00359 
00360       S services;
00361       return services.exist(pItem);
00362    }
00363 
00364    virtual qx::QxInvalidValueX qxValidate(const QStringList & groups = QStringList())
00365    {
00366       Q_UNUSED(groups);
00367       S services;
00368       type_collection_ptr tmp;
00369       tmp.reset(new type_collection());
00370       (* tmp) = this->m_model;
00371       return services.isValid(tmp);
00372    }
00373 
00374    virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList & groups = QStringList())
00375    {
00376       Q_UNUSED(groups);
00377       if ((row < 0) || (row >= this->m_model.count())) { return qx::QxInvalidValueX(); }
00378       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return qx::QxInvalidValueX(); }
00379 
00380       S services;
00381       return services.isValid(pItem);
00382    }
00383 
00384 protected:
00385 
00386 #ifndef _QX_NO_JSON
00387 
00388    virtual QVariant getRelationshipValues_Helper(int row, const QString & relation, bool bLoadFromDatabase, const QString & sAppendRelations)
00389    {
00390       if ((row < 0) || (row >= this->m_model.count())) { return QVariant(); }
00391       if (! this->m_pDataMemberId || ! this->m_pDataMemberX || ! this->m_pDataMemberX->exist(relation)) { return QVariant(); }
00392       IxDataMember * pDataMember = this->m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return QVariant(); }
00393       IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return QVariant(); }
00394       type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QVariant(); }
00395       type_ptr pItemTemp = pItem;
00396 
00397       if (bLoadFromDatabase)
00398       {
00399          QString sRelation = relation;
00400          if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
00401          else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
00402          pItemTemp = type_ptr(new T());
00403          QVariant id = this->m_pDataMemberId->toVariant(pItem.get());
00404          this->m_pDataMemberId->fromVariant(pItemTemp.get(), id);
00405 
00406          S services; QStringList columns;
00407          QSqlError daoError = services.fetchById(pItemTemp, columns, QStringList() << sRelation);
00408          if (daoError.isValid()) { return QVariant(); }
00409       }
00410 
00411       QJsonValue json = pDataMember->toJson(pItemTemp.get()); if (json.isNull()) { return QVariant(); }
00412       if (json.isArray()) { return json.toArray().toVariantList(); }
00413       return json.toObject().toVariantMap();
00414    }
00415 
00416 #endif // _QX_NO_JSON
00417 
00418 };
00419 
00420 } // namespace qx
00421 
00422 #endif // _QX_MODEL_SERVICE_H_