QxOrm
1.5.0
C++ Object Relational Mapping library
|
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 = std::make_shared<type_collection>(); 00118 this->m_lastError = services.fetchAll(tmp, this->m_lstColumns, relation); 00119 00120 if (tmp->count() <= 0) { return this->m_lastError; } 00121 this->beginResetModel(); 00122 this->m_model = (* tmp); 00123 this->updateShowEmptyLine(); 00124 this->endResetModel(); 00125 return this->m_lastError; 00126 } 00127 00128 virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery & query, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00129 { 00130 Q_UNUSED(pDatabase); 00131 this->clear(); 00132 00133 S services; 00134 type_collection_ptr tmp = std::make_shared<type_collection>(); 00135 this->m_lastError = services.fetchByQuery(query, tmp, this->m_lstColumns, relation); 00136 00137 if (tmp->count() <= 0) { return this->m_lastError; } 00138 this->beginResetModel(); 00139 this->m_model = (* tmp); 00140 this->updateShowEmptyLine(); 00141 this->endResetModel(); 00142 return this->m_lastError; 00143 } 00144 00145 virtual QSqlError qxFetchRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00146 { 00147 Q_UNUSED(pDatabase); 00148 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00149 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00150 00151 S services; 00152 this->m_lastError = services.fetchById(pItem, this->m_lstColumns, relation); 00153 if (this->m_lastError.isValid()) { return this->m_lastError; } 00154 00155 QModelIndex idxTopLeft = this->index(row, 0); 00156 QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1)); 00157 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight); 00158 this->updateKey(row); 00159 return this->m_lastError; 00160 } 00161 00162 virtual QSqlError qxInsert(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false) 00163 { 00164 Q_UNUSED(pDatabase); Q_UNUSED(bUseExecBatch); 00165 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00166 00167 type_collection_ptr tmp = std::make_shared<type_collection>(); 00168 (* tmp) = this->m_model; 00169 00170 S services; 00171 this->m_lastError = services.insert(tmp, relation); 00172 00173 if (! this->m_lastError.isValid()) { this->updateAllKeys(); } 00174 return this->m_lastError; 00175 } 00176 00177 virtual QSqlError qxInsertRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00178 { 00179 Q_UNUSED(pDatabase); 00180 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00181 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00182 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00183 00184 S services; 00185 this->m_lastError = services.insert(pItem, relation); 00186 00187 if (! this->m_lastError.isValid()) { this->updateKey(row); } 00188 return this->m_lastError; 00189 } 00190 00191 virtual QSqlError qxUpdate(const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false) 00192 { 00193 Q_UNUSED(pDatabase); Q_UNUSED(bUseExecBatch); 00194 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00195 00196 type_collection_ptr tmp = std::make_shared<type_collection>(); 00197 (* tmp) = this->m_model; 00198 00199 S services; 00200 this->m_lastError = services.update(tmp, query, this->m_lstColumns, relation); 00201 00202 if (! this->m_lastError.isValid()) { this->updateAllKeys(); } 00203 return this->m_lastError; 00204 } 00205 00206 virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00207 { 00208 Q_UNUSED(pDatabase); 00209 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00210 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00211 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00212 00213 S services; 00214 this->m_lastError = services.update(pItem, query, this->m_lstColumns, relation); 00215 00216 if (! this->m_lastError.isValid()) { this->updateKey(row); } 00217 return this->m_lastError; 00218 } 00219 00220 virtual QSqlError qxSave(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00221 { 00222 Q_UNUSED(pDatabase); 00223 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00224 00225 type_collection_ptr tmp = std::make_shared<type_collection>(); 00226 (* tmp) = this->m_model; 00227 00228 S services; 00229 this->m_lastError = services.save(tmp, relation); 00230 00231 if (! this->m_lastError.isValid()) { this->updateAllKeys(); } 00232 return this->m_lastError; 00233 } 00234 00235 virtual QSqlError qxSaveRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00236 { 00237 Q_UNUSED(pDatabase); 00238 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00239 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00240 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00241 00242 S services; 00243 this->m_lastError = services.save(pItem, relation); 00244 00245 if (! this->m_lastError.isValid()) { this->updateKey(row); } 00246 return this->m_lastError; 00247 } 00248 00249 virtual QSqlError qxDeleteById(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00250 { 00251 Q_UNUSED(pDatabase); 00252 type_ptr pItem = type_ptr(new T()); 00253 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); } 00254 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; } 00255 this->m_pDataMemberId->fromVariant(pItem.get(), id); 00256 00257 S services; 00258 this->m_lastError = services.deleteById(pItem); 00259 return this->m_lastError; 00260 } 00261 00262 virtual QSqlError qxDeleteAll(QSqlDatabase * pDatabase = NULL) 00263 { 00264 Q_UNUSED(pDatabase); 00265 S services; 00266 this->m_lastError = services.deleteAll(); 00267 return this->m_lastError; 00268 } 00269 00270 virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00271 { 00272 Q_UNUSED(pDatabase); 00273 S services; 00274 this->m_lastError = services.deleteByQuery(query); 00275 return this->m_lastError; 00276 } 00277 00278 virtual QSqlError qxDeleteRow(int row, QSqlDatabase * pDatabase = NULL) 00279 { 00280 Q_UNUSED(pDatabase); 00281 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00282 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00283 00284 S services; 00285 this->m_lastError = services.deleteById(pItem); 00286 return this->m_lastError; 00287 } 00288 00289 virtual QSqlError qxDestroyById(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00290 { 00291 Q_UNUSED(pDatabase); 00292 type_ptr pItem = type_ptr(new T()); 00293 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); } 00294 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; } 00295 this->m_pDataMemberId->fromVariant(pItem.get(), id); 00296 00297 S services; 00298 this->m_lastError = services.destroyById(pItem); 00299 return this->m_lastError; 00300 } 00301 00302 virtual QSqlError qxDestroyAll(QSqlDatabase * pDatabase = NULL) 00303 { 00304 Q_UNUSED(pDatabase); 00305 S services; 00306 this->m_lastError = services.destroyAll(); 00307 return this->m_lastError; 00308 } 00309 00310 virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00311 { 00312 Q_UNUSED(pDatabase); 00313 S services; 00314 this->m_lastError = services.destroyByQuery(query); 00315 return this->m_lastError; 00316 } 00317 00318 virtual QSqlError qxDestroyRow(int row, QSqlDatabase * pDatabase = NULL) 00319 { 00320 Q_UNUSED(pDatabase); 00321 if ((row < 0) || (row >= this->m_model.count())) { return QSqlError(); } 00322 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00323 00324 S services; 00325 this->m_lastError = services.destroyById(pItem); 00326 return this->m_lastError; 00327 } 00328 00329 virtual QSqlError qxExecuteQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00330 { 00331 Q_UNUSED(pDatabase); 00332 this->clear(); 00333 00334 S services; 00335 type_collection_ptr tmp = std::make_shared<type_collection>(); 00336 this->m_lastError = services.executeQuery(query, tmp); 00337 00338 if (tmp->count() <= 0) { return this->m_lastError; } 00339 this->beginResetModel(); 00340 this->m_model = (* tmp); 00341 this->updateShowEmptyLine(); 00342 this->endResetModel(); 00343 return this->m_lastError; 00344 } 00345 00346 virtual qx_bool qxExist(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00347 { 00348 Q_UNUSED(pDatabase); 00349 type_ptr pItem = type_ptr(new T()); 00350 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxExist()' method : '%s'", "data member id not registered"); qAssert(false); } 00351 if (! this->m_pDataMemberId) { return qx_bool(false); } 00352 this->m_pDataMemberId->fromVariant(pItem.get(), id); 00353 00354 S services; 00355 return services.exist(pItem); 00356 } 00357 00358 virtual qx::QxInvalidValueX qxValidate(const QStringList & groups = QStringList()) 00359 { 00360 Q_UNUSED(groups); 00361 S services; 00362 type_collection_ptr tmp = std::make_shared<type_collection>(); 00363 (* tmp) = this->m_model; 00364 return services.isValid(tmp); 00365 } 00366 00367 virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList & groups = QStringList()) 00368 { 00369 Q_UNUSED(groups); 00370 if ((row < 0) || (row >= this->m_model.count())) { return qx::QxInvalidValueX(); } 00371 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return qx::QxInvalidValueX(); } 00372 00373 S services; 00374 return services.isValid(pItem); 00375 } 00376 00377 protected: 00378 00379 #ifndef _QX_NO_JSON 00380 00381 virtual QVariant getRelationshipValues_Helper(int row, const QString & relation, bool bLoadFromDatabase, const QString & sAppendRelations) 00382 { 00383 if ((row < 0) || (row >= this->m_model.count())) { return QVariant(); } 00384 if (! this->m_pDataMemberId || ! this->m_pDataMemberX || ! this->m_pDataMemberX->exist(relation)) { return QVariant(); } 00385 IxDataMember * pDataMember = this->m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return QVariant(); } 00386 IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return QVariant(); } 00387 type_ptr pItem = this->m_model.getByIndex(row); if (! pItem) { return QVariant(); } 00388 type_ptr pItemTemp = pItem; 00389 00390 if (bLoadFromDatabase) 00391 { 00392 QString sRelation = relation; 00393 if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; } 00394 else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; } 00395 pItemTemp = type_ptr(new T()); 00396 QVariant id = this->m_pDataMemberId->toVariant(pItem.get()); 00397 this->m_pDataMemberId->fromVariant(pItemTemp.get(), id); 00398 00399 S services; QStringList columns; 00400 QSqlError daoError = services.fetchById(pItemTemp, columns, QStringList() << sRelation); 00401 if (daoError.isValid()) { return QVariant(); } 00402 } 00403 00404 QJsonValue json = pDataMember->toJson(pItemTemp.get()); if (json.isNull()) { return QVariant(); } 00405 if (json.isArray()) { return json.toArray().toVariantList(); } 00406 return json.toObject().toVariantMap(); 00407 } 00408 00409 #endif // _QX_NO_JSON 00410 00411 }; 00412 00413 } // namespace qx 00414 00415 #endif // _QX_MODEL_SERVICE_H_