![]() |
QxOrm
1.4.3
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://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_H_ 00033 #define _QX_MODEL_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #include <QxModelView/IxModel.h> 00047 00048 #include <QxCollection/QxCollection.h> 00049 00050 #include <QxRegister/QxClass.h> 00051 00052 #include <QxTraits/get_primary_key.h> 00053 #include <QxTraits/is_qx_registered.h> 00054 #include <QxTraits/is_valid_primary_key.h> 00055 00056 #include <QxSerialize/QxDump.h> 00057 #include <QxSerialize/QxClone.h> 00058 00059 #ifndef _QX_NO_JSON 00060 #include <QxSerialize/QJson/QxSerializeQJson_QxCollection.h> 00061 #include <QxSerialize/QxSerializeQJson.h> 00062 #endif // _QX_NO_JSON 00063 00064 namespace qx { 00065 namespace model_view { 00066 namespace detail { 00067 00068 template <class T> struct QxNestedModel; 00069 template <class T> struct QxNestedModel_Generic; 00070 template <class T> struct QxNestedModel_Container; 00071 00072 } // namespace detail 00073 } // namespace model_view 00074 } // namespace qx 00075 00076 namespace qx { 00077 00161 template <class T> 00162 class QxModel : public qx::IxModel 00163 { 00164 00165 friend struct qx::model_view::detail::QxNestedModel<T>; 00166 friend struct qx::model_view::detail::QxNestedModel_Generic<T>; 00167 template <typename U> friend struct qx::model_view::detail::QxNestedModel_Container; 00168 00169 public: 00170 00171 typedef qx_shared_ptr<T> type_ptr; 00172 typedef typename qx::trait::get_primary_key<T>::type type_primary_key; 00173 typedef qx::QxCollection<type_primary_key, type_ptr> type_collection; 00174 00175 enum { qx_is_valid = qx::trait::is_qx_registered<T>::value }; 00176 00177 protected: 00178 00179 type_collection m_model; 00180 long m_lManualInsertIndex; 00181 00182 public: 00183 00184 QxModel(QObject * parent = 0) : qx::IxModel(parent), m_lManualInsertIndex(0) { qx::QxModel<T>::init(); } 00185 QxModel(qx::IxModel * other, QObject * parent) : qx::IxModel(parent), m_lManualInsertIndex(0) { qx::QxModel<T>::initFrom(other); } 00186 virtual ~QxModel() { ; } 00187 00188 protected: 00189 00190 void init() 00191 { 00192 BOOST_STATIC_ASSERT(qx_is_valid); 00193 m_pClass = qx::QxClass<T>::getSingleton(); qAssert(m_pClass != NULL); 00194 m_pDataMemberX = (m_pClass ? m_pClass->getDataMemberX() : NULL); qAssert(m_pDataMemberX != NULL); 00195 m_pDataMemberId = (m_pDataMemberX ? m_pDataMemberX->getId_WithDaoStrategy() : NULL); 00196 m_pCollection = (& m_model); 00197 generateRoleNames(); 00198 } 00199 00200 void initFrom(qx::IxModel * pOther) 00201 { 00202 init(); 00203 qx::QxModel<T> * pOtherWrk = static_cast<qx::QxModel<T> *>(pOther); 00204 this->m_model = pOtherWrk->m_model; 00205 this->m_lManualInsertIndex = pOtherWrk->m_lManualInsertIndex; 00206 this->m_pParent = pOtherWrk->m_pParent; 00207 if (this->m_pParent) { this->m_eAutoUpdateDatabase = this->m_pParent->getAutoUpdateDatabase(); } 00208 } 00209 00210 public: 00211 00212 virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const 00213 { 00214 if (! index.isValid()) { return QVariant(); } 00215 if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) 00216 { 00217 if ((index.column() < 0) || (index.column() >= m_lstDataMember.count())) { return QVariant(); } 00218 else if ((index.row() < 0) || (index.row() >= m_model.count())) { return QVariant(); } 00219 IxDataMember * pDataMember = m_lstDataMember.at(index.column()); 00220 type_ptr pItem = m_model.getByIndex(index.row()); 00221 if (! pDataMember || ! pItem) { return QVariant(); } 00222 return pDataMember->toVariant(pItem.get()); 00223 } 00224 else if (role >= (Qt::UserRole + 1)) 00225 { 00226 QModelIndex idx = this->index(index.row(), (role - Qt::UserRole - 1), QModelIndex()); 00227 return data(idx, Qt::DisplayRole); 00228 } 00229 return QVariant(); 00230 } 00231 00232 virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) 00233 { 00234 if (! index.isValid()) { return false; } 00235 if (role == Qt::EditRole) 00236 { 00237 if ((index.column() < 0) || (index.column() >= m_lstDataMember.count())) { return false; } 00238 else if ((index.row() < 0) || (index.row() >= m_model.count())) { return false; } 00239 IxDataMember * pDataMember = m_lstDataMember.at(index.column()); 00240 type_ptr pItem = m_model.getByIndex(index.row()); 00241 if (! pDataMember || ! pItem) { return false; } 00242 QVariant vCurrentValue = pDataMember->toVariant(pItem.get()); 00243 if (vCurrentValue == value) { return true; } 00244 qx_bool bSetData = pDataMember->fromVariant(pItem.get(), value); 00245 if (bSetData) { raiseEvent_dataChanged(index, index); } 00246 if (bSetData && (m_eAutoUpdateDatabase == qx::IxModel::e_auto_update_on_field_change) && m_pDataMemberId) 00247 { 00248 QVariant vId = m_pDataMemberId->toVariant(pItem.get()); 00249 bool bExist = qx::trait::is_valid_primary_key(vId); 00250 if (bExist) { bExist = qx::dao::exist((* pItem), database(NULL)); } 00251 if (bExist) { m_lastError = qx::dao::update((* pItem), database(NULL), (QStringList() << pDataMember->getKey())); } 00252 else { m_lastError = qx::dao::insert((* pItem), database(NULL)); } 00253 } 00254 return bSetData; 00255 } 00256 else if (role >= (Qt::UserRole + 1)) 00257 { 00258 QModelIndex idx = this->index(index.row(), (role - Qt::UserRole - 1), QModelIndex()); 00259 return setData(idx, value, Qt::EditRole); 00260 } 00261 return false; 00262 } 00263 00264 virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex()) 00265 { 00266 if (parent.isValid()) { return false; } 00267 if ((row < 0) || (count <= 0)) { return false; } 00268 beginInsertRows(QModelIndex(), row, (row + count - 1)); 00269 for (int i = 0; i < count; ++i) 00270 { 00271 type_primary_key primaryKey; 00272 m_lManualInsertIndex = (m_lManualInsertIndex - 1); 00273 QVariant vNewId(static_cast<qlonglong>(m_lManualInsertIndex)); 00274 qx::cvt::from_variant(vNewId, primaryKey); 00275 type_ptr pItem = type_ptr(new T()); 00276 m_model.insert(row, primaryKey, pItem); 00277 } 00278 endInsertRows(); 00279 return true; 00280 } 00281 00282 public: 00283 00289 virtual long qxCount(const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL) 00290 { 00291 return qx::dao::count<T>(query, database(pDatabase)); 00292 } 00293 00300 virtual QSqlError qxCount(long & lCount, const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL) 00301 { 00302 m_lastError = qx::dao::count<T>(lCount, query, database(pDatabase)); 00303 return m_lastError; 00304 } 00305 00313 virtual QSqlError qxFetchById(const QVariant & id, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00314 { 00315 clear(); 00316 type_ptr pItem = type_ptr(new T()); 00317 if (! m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxFetchById()' method : '%s'", "data member id not registered"); qAssert(false); } 00318 if (! m_pDataMemberId) { m_lastError = QSqlError("[QxOrm] problem with 'qxFetchById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return m_lastError; } 00319 m_pDataMemberId->fromVariant(pItem.get(), id); 00320 00321 type_primary_key primaryKey; 00322 qx::cvt::from_variant(id, primaryKey); 00323 beginInsertRows(QModelIndex(), 0, 0); 00324 m_model.insert(primaryKey, pItem); 00325 00326 if (relation.count() == 0) { m_lastError = qx::dao::fetch_by_id((* pItem), database(pDatabase), m_lstColumns); } 00327 else { m_lastError = qx::dao::fetch_by_id_with_relation(relation, (* pItem), database(pDatabase)); } 00328 endInsertRows(); 00329 return m_lastError; 00330 } 00331 00338 virtual QSqlError qxFetchAll(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00339 { 00340 clear(); 00341 type_collection tmp; 00342 if (relation.count() == 0) { m_lastError = qx::dao::fetch_all(tmp, database(pDatabase), m_lstColumns); } 00343 else { m_lastError = qx::dao::fetch_all_with_relation(relation, tmp, database(pDatabase)); } 00344 00345 if (tmp.count() <= 0) { return m_lastError; } 00346 beginInsertRows(QModelIndex(), 0, (tmp.count() - 1)); 00347 m_model = tmp; 00348 endInsertRows(); 00349 return m_lastError; 00350 } 00351 00359 virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery & query, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00360 { 00361 clear(); 00362 type_collection tmp; 00363 if (relation.count() == 0) { m_lastError = qx::dao::fetch_by_query(query, tmp, database(pDatabase), m_lstColumns); } 00364 else { m_lastError = qx::dao::fetch_by_query_with_relation(relation, query, tmp, database(pDatabase)); } 00365 00366 if (tmp.count() <= 0) { return m_lastError; } 00367 beginInsertRows(QModelIndex(), 0, (tmp.count() - 1)); 00368 m_model = tmp; 00369 endInsertRows(); 00370 return m_lastError; 00371 } 00372 00380 virtual QSqlError qxFetchRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00381 { 00382 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00383 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00384 if (relation.count() == 0) { m_lastError = qx::dao::fetch_by_id((* pItem), database(pDatabase), m_lstColumns); } 00385 else { m_lastError = qx::dao::fetch_by_id_with_relation(relation, (* pItem), database(pDatabase)); } 00386 if (m_lastError.isValid()) { return m_lastError; } 00387 00388 QModelIndex idxTopLeft = this->index(row, 0); 00389 QModelIndex idxBottomRight = this->index(row, (m_lstDataMember.count() - 1)); 00390 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight); 00391 this->updateKey(row); 00392 return m_lastError; 00393 } 00394 00401 virtual QSqlError qxInsert(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00402 { 00403 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00404 if (relation.count() == 0) { m_lastError = qx::dao::insert(m_model, database(pDatabase)); } 00405 else { m_lastError = qx::dao::insert_with_relation(relation, m_model, database(pDatabase)); } 00406 if (! m_lastError.isValid()) { this->updateAllKeys(); } 00407 return m_lastError; 00408 } 00409 00417 virtual QSqlError qxInsertRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00418 { 00419 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00420 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00421 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00422 if (relation.count() == 0) { m_lastError = qx::dao::insert((* pItem), database(pDatabase)); } 00423 else { m_lastError = qx::dao::insert_with_relation(relation, (* pItem), database(pDatabase)); } 00424 if (! m_lastError.isValid()) { this->updateKey(row); } 00425 return m_lastError; 00426 } 00427 00435 virtual QSqlError qxUpdate(const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00436 { 00437 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00438 if (relation.count() == 0) { m_lastError = qx::dao::update_by_query(query, m_model, database(pDatabase), m_lstColumns); } 00439 else { m_lastError = qx::dao::update_by_query_with_relation(relation, query, m_model, database(pDatabase)); } 00440 if (! m_lastError.isValid()) { this->updateAllKeys(); } 00441 return m_lastError; 00442 } 00443 00452 virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00453 { 00454 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00455 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00456 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00457 if (relation.count() == 0) { m_lastError = qx::dao::update_by_query(query, (* pItem), database(pDatabase), m_lstColumns); } 00458 else { m_lastError = qx::dao::update_by_query_with_relation(relation, query, (* pItem), database(pDatabase)); } 00459 if (! m_lastError.isValid()) { this->updateKey(row); } 00460 return m_lastError; 00461 } 00462 00469 virtual QSqlError qxSave(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00470 { 00471 if (relation.count() > 0) { this->syncAllNestedModel(relation); } 00472 if (relation.count() == 0) { m_lastError = qx::dao::save(m_model, database(pDatabase)); } 00473 else { m_lastError = qx::dao::save_with_relation(relation, m_model, database(pDatabase)); } 00474 if (! m_lastError.isValid()) { this->updateAllKeys(); } 00475 return m_lastError; 00476 } 00477 00485 virtual QSqlError qxSaveRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) 00486 { 00487 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00488 if (relation.count() > 0) { this->syncNestedModel(row, relation); } 00489 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00490 if (relation.count() == 0) { m_lastError = qx::dao::save((* pItem), database(pDatabase)); } 00491 else { m_lastError = qx::dao::save_with_relation(relation, (* pItem), database(pDatabase)); } 00492 if (! m_lastError.isValid()) { this->updateKey(row); } 00493 return m_lastError; 00494 } 00495 00502 virtual QSqlError qxDeleteById(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00503 { 00504 type_ptr pItem = type_ptr(new T()); 00505 if (! m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); } 00506 if (! m_pDataMemberId) { m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return m_lastError; } 00507 m_pDataMemberId->fromVariant(pItem.get(), id); 00508 m_lastError = qx::dao::delete_by_id((* pItem), database(pDatabase)); 00509 return m_lastError; 00510 } 00511 00517 virtual QSqlError qxDeleteAll(QSqlDatabase * pDatabase = NULL) 00518 { 00519 m_lastError = qx::dao::delete_all<T>(database(pDatabase)); 00520 return m_lastError; 00521 } 00522 00529 virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00530 { 00531 m_lastError = qx::dao::delete_by_query<T>(query, database(pDatabase)); 00532 return m_lastError; 00533 } 00534 00541 virtual QSqlError qxDeleteRow(int row, QSqlDatabase * pDatabase = NULL) 00542 { 00543 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00544 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00545 m_lastError = qx::dao::delete_by_id((* pItem), database(pDatabase)); 00546 return m_lastError; 00547 } 00548 00555 virtual QSqlError qxDestroyById(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00556 { 00557 type_ptr pItem = type_ptr(new T()); 00558 if (! m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); } 00559 if (! m_pDataMemberId) { m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return m_lastError; } 00560 m_pDataMemberId->fromVariant(pItem.get(), id); 00561 m_lastError = qx::dao::destroy_by_id((* pItem), database(pDatabase)); 00562 return m_lastError; 00563 } 00564 00570 virtual QSqlError qxDestroyAll(QSqlDatabase * pDatabase = NULL) 00571 { 00572 m_lastError = qx::dao::destroy_all<T>(database(pDatabase)); 00573 return m_lastError; 00574 } 00575 00582 virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00583 { 00584 m_lastError = qx::dao::destroy_by_query<T>(query, database(pDatabase)); 00585 return m_lastError; 00586 } 00587 00594 virtual QSqlError qxDestroyRow(int row, QSqlDatabase * pDatabase = NULL) 00595 { 00596 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); } 00597 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); } 00598 m_lastError = qx::dao::destroy_by_id((* pItem), database(pDatabase)); 00599 return m_lastError; 00600 } 00601 00602 virtual QSqlError qxExecuteQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) 00603 { 00604 clear(); 00605 type_collection tmp; 00606 m_lastError = qx::dao::execute_query(query, tmp, database(pDatabase)); 00607 00608 if (tmp.count() <= 0) { return m_lastError; } 00609 beginInsertRows(QModelIndex(), 0, (tmp.count() - 1)); 00610 m_model = tmp; 00611 endInsertRows(); 00612 return m_lastError; 00613 } 00614 00615 virtual qx_bool qxExist(const QVariant & id, QSqlDatabase * pDatabase = NULL) 00616 { 00617 type_ptr pItem = type_ptr(new T()); 00618 if (! m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxExist()' method : '%s'", "data member id not registered"); qAssert(false); } 00619 if (! m_pDataMemberId) { return qx_bool(false); } 00620 m_pDataMemberId->fromVariant(pItem.get(), id); 00621 return qx::dao::exist((* pItem), database(pDatabase)); 00622 } 00623 00624 virtual qx::QxInvalidValueX qxValidate(const QStringList & groups = QStringList()) 00625 { 00626 return qx::validate(m_model, groups); 00627 } 00628 00629 virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList & groups = QStringList()) 00630 { 00631 if ((row < 0) || (row >= m_model.count())) { return qx::QxInvalidValueX(); } 00632 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return qx::QxInvalidValueX(); } 00633 return qx::validate((* pItem), groups); 00634 } 00635 00636 protected: 00637 00638 virtual void dumpModelImpl(bool bJsonFormat) const { qx::dump(m_model, bJsonFormat); } 00639 00640 virtual QObject * cloneModelImpl() 00641 { 00642 qx::QxModel<T> * pClone = new qx::QxModel<T>(this, NULL); 00643 qx_shared_ptr<type_collection> pModel = qx::clone(pClone->m_model); 00644 if (pModel) { pClone->m_model = (* pModel); } 00645 return static_cast<QObject *>(pClone); 00646 } 00647 00648 void updateKey(int row) 00649 { 00650 if ((row < 0) || (row >= m_model.count())) { return; } 00651 type_ptr pItem = m_model.getByIndex(row); if (! pItem || ! m_pDataMemberId) { return; } 00652 type_primary_key currPrimaryKey = m_model.getKeyByIndex(row); 00653 QVariant vCurrPrimaryKey = qx::cvt::to_variant(currPrimaryKey); 00654 QVariant vNextPrimaryKey = m_pDataMemberId->toVariant(pItem.get()); 00655 if ((vCurrPrimaryKey == vNextPrimaryKey) || (! vNextPrimaryKey.isValid())) { return; } 00656 if (! qx::trait::is_valid_primary_key(vNextPrimaryKey)) { return; } 00657 type_primary_key updatedPrimaryKey; 00658 qx::cvt::from_variant(vNextPrimaryKey, updatedPrimaryKey); 00659 if (m_model.exist(updatedPrimaryKey)) { return; } 00660 m_model.removeByIndex(row); 00661 m_model.insert(row, updatedPrimaryKey, pItem); 00662 } 00663 00664 void updateAllKeys() 00665 { 00666 for (long l = 0; l < m_model.count(); l++) 00667 { this->updateKey(l); } 00668 } 00669 00670 protected: 00671 00672 #ifndef _QX_NO_JSON 00673 00674 virtual QString toJson_Helper(int row) const 00675 { 00676 if (row == -1) { return qx::serialization::json::to_string(m_model); } 00677 if ((row < 0) || (row >= m_model.count())) { return QString(); } 00678 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QString(); } 00679 return qx::serialization::json::to_string(* pItem); 00680 } 00681 00682 virtual bool fromJson_Helper(const QString & json, int row) 00683 { 00684 if (row == -1) 00685 { 00686 clear(); 00687 type_collection tmp; 00688 if (! qx::serialization::json::from_string(tmp, json)) { return false; } 00689 beginInsertRows(QModelIndex(), 0, (tmp.count() - 1)); 00690 m_model = tmp; 00691 endInsertRows(); 00692 return true; 00693 } 00694 00695 if ((row < 0) || (row >= m_model.count())) { return false; } 00696 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return false; } 00697 if (! qx::serialization::json::from_string((* pItem), json)) { return false; } 00698 00699 QModelIndex idxTopLeft = this->index(row, 0); 00700 QModelIndex idxBottomRight = this->index(row, (m_lstDataMember.count() - 1)); 00701 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight); 00702 this->updateKey(row); 00703 return true; 00704 } 00705 00706 virtual QVariant getRelationshipValues_Helper(int row, const QString & relation, bool bLoadFromDatabase, const QString & sAppendRelations) 00707 { 00708 if ((row < 0) || (row >= m_model.count())) { return QVariant(); } 00709 if (! m_pDataMemberId || ! m_pDataMemberX || ! m_pDataMemberX->exist(relation)) { return QVariant(); } 00710 IxDataMember * pDataMember = m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return QVariant(); } 00711 IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return QVariant(); } 00712 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QVariant(); } 00713 type_ptr pItemTemp = pItem; 00714 00715 if (bLoadFromDatabase) 00716 { 00717 QString sRelation = relation; 00718 if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; } 00719 else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; } 00720 pItemTemp = type_ptr(new T()); 00721 QVariant id = m_pDataMemberId->toVariant(pItem.get()); 00722 m_pDataMemberId->fromVariant(pItemTemp.get(), id); 00723 QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, (* pItemTemp)); 00724 if (daoError.isValid()) { return QVariant(); } 00725 } 00726 00727 QJsonValue json = pDataMember->toJson(pItemTemp.get()); if (json.isNull()) { return QVariant(); } 00728 if (json.isArray()) { return json.toArray().toVariantList(); } 00729 return json.toObject().toVariantMap(); 00730 } 00731 00732 virtual bool setRelationshipValues_Helper(int row, const QString & relation, const QVariant & values) 00733 { 00734 if ((row < 0) || (row >= m_model.count())) { return false; } 00735 if ((values.type() != QVariant::List) && (values.type() != QVariant::Map)) { return false; } 00736 if (! m_pDataMemberId || ! m_pDataMemberX || ! m_pDataMemberX->exist(relation)) { return false; } 00737 IxDataMember * pDataMember = m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return false; } 00738 IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return false; } 00739 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return false; } 00740 00741 QJsonValue json; 00742 if (values.type() == QVariant::List) { json = QJsonArray::fromVariantList(values.toList()); } 00743 else if (values.type() == QVariant::Map) { json = QJsonObject::fromVariantMap(values.toMap()); } 00744 if (! pDataMember->fromJson(pItem.get(), json)) { return false; } 00745 00746 QModelIndex idxTopLeft = this->index(row, 0); 00747 QModelIndex idxBottomRight = this->index(row, (m_lstDataMember.count() - 1)); 00748 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight); 00749 return true; 00750 } 00751 00752 #endif // _QX_NO_JSON 00753 00754 }; 00755 00756 } // namespace qx 00757 00758 #endif // _QX_MODEL_H_