QxOrm 1.5.0
C++ Object Relational Mapping library
Loading...
Searching...
No Matches
QxModel.h
Go to the documentation of this file.
1/****************************************************************************
2**
3** https://www.qxorm.com/
4** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
5**
6** This file is part of the QxOrm library
7**
8** This software is provided 'as-is', without any express or implied
9** warranty. In no event will the authors be held liable for any
10** damages arising from the use of this software
11**
12** Commercial Usage
13** Licensees holding valid commercial QxOrm licenses may use this file in
14** accordance with the commercial license agreement provided with the
15** Software or, alternatively, in accordance with the terms contained in
16** a written agreement between you and Lionel Marty
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3.0 as published by the Free Software
21** Foundation and appearing in the file 'license.gpl3.txt' included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU General Public License version 3.0 requirements will be
24** met : http://www.gnu.org/copyleft/gpl.html
25**
26** If you are unsure which license is appropriate for your use, or
27** if you have questions regarding the use of this file, please contact :
28** contact@qxorm.com
29**
30****************************************************************************/
31
32#ifndef _QX_MODEL_H_
33#define _QX_MODEL_H_
34
35#ifdef _MSC_VER
36#pragma once
37#endif
38
45
46#include <QxModelView/IxModel.h>
48
50
51#include <QxRegister/QxClass.h>
52
56
57#include <QxSerialize/QxDump.h>
58#include <QxSerialize/QxClone.h>
59
60#ifndef _QX_NO_JSON
63#endif // _QX_NO_JSON
64
65namespace qx {
66namespace model_view {
67namespace detail {
68
69template <class T, class M> struct QxNestedModel;
70template <class T, class M> struct QxNestedModel_Generic;
71template <class T, class M> struct QxNestedModel_Container;
72
73} // namespace detail
74} // namespace model_view
75} // namespace qx
76
77namespace qx {
78
162template <class T, class B = qx::IxModel>
163class QxModel : public B // B type must inherit from qx::IxModel and must not define new data-members (use 'm_hCustomProperties' or QObject dynamic properties if you need new properties in your derived class)
164{
165
166 template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel;
167 template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel_Generic;
168 template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel_Container;
169
170public:
171
172 typedef std::shared_ptr<T> type_ptr;
176
177 enum { qx_is_valid = (qx::trait::is_qx_registered<T>::value && std::is_base_of<qx::IxModel, B>::value) };
178
179protected:
180
182 std::shared_ptr<QPair<int, type_ptr> > m_pDirtyRow;
183
184public:
185
186 QxModel(QObject * parent = 0) : B(parent) { qx::QxModel<T, B>::init(); }
187 QxModel(qx::IxModel * other, QObject * parent) : B(parent) { qx::QxModel<T, B>::initFrom(other); }
188 virtual ~QxModel() { ; }
189
190protected:
191
192 void init()
193 {
194 static_assert(qx_is_valid, "qx_is_valid");
195 this->m_pClass = qx::QxClass<T>::getSingleton(); qAssert(this->m_pClass != NULL);
196 this->m_pDataMemberX = (this->m_pClass ? this->m_pClass->getDataMemberX() : NULL); qAssert(this->m_pDataMemberX != NULL);
197 this->m_pDataMemberId = (this->m_pDataMemberX ? this->m_pDataMemberX->getId_WithDaoStrategy() : NULL);
198 this->m_pCollection = (& m_model);
199 this->generateRoleNames();
200 }
201
202 void initFrom(qx::IxModel * pOther)
203 {
204 init();
205 qx::QxModel<T, B> * pOtherWrk = static_cast<qx::QxModel<T, B> *>(pOther);
206 m_model = pOtherWrk->m_model;
208 this->setParentModel(pOtherWrk->m_pParent);
209 if (this->m_pParent) { this->m_eAutoUpdateDatabase = this->m_pParent->getAutoUpdateDatabase(); }
210 this->m_hCustomProperties = pOtherWrk->m_hCustomProperties;
211 }
212
213public:
214
215 virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex())
216 {
217 if (parent.isValid()) { return false; }
218 if ((row < 0) || (count <= 0)) { return false; }
219 this->beginInsertRows(QModelIndex(), row, (row + count - 1));
220 for (int i = 0; i < count; ++i)
221 {
222 type_ptr pItem = type_ptr(new T());
223 insertItem(row, pItem);
224 }
225 this->endInsertRows();
226 return true;
227 }
228
229 virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
230 {
231 IxDataMember * pDataMember = this->getDataMember(column); if (! pDataMember) { return; }
234 }
235
236 virtual bool getShowEmptyLine() const { return m_pDirtyRow.get(); }
237
238 virtual void setShowEmptyLine(bool b)
239 {
240 if (b == getShowEmptyLine()) { return; }
241 if (b) { addDirtyRow(); return; }
242 this->beginRemoveRows(QModelIndex(), this->rowCount(), this->rowCount());
243 m_pDirtyRow.reset();
244 this->endRemoveRows();
245 }
246
247public:
248
254 virtual long qxCount(const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL)
255 {
256 return qx::dao::count<T>(query, this->database(pDatabase));
257 }
258
265 virtual QSqlError qxCount(long & lCount, const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL)
266 {
267 this->m_lastError = qx::dao::count<T>(lCount, query, this->database(pDatabase));
268 return this->m_lastError;
269 }
270
278 virtual QSqlError qxFetchById(const QVariant & id, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
279 {
280 this->clear();
281 type_ptr pItem = type_ptr(new T());
282 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxFetchById()' method : '%s'", "data member id not registered"); qAssert(false); }
283 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxFetchById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
284 this->m_pDataMemberId->fromVariant(pItem.get(), id);
285
286 type_primary_key primaryKey;
287 qx::cvt::from_variant(id, primaryKey);
288 this->beginInsertRows(QModelIndex(), 0, 0);
289 m_model.insert(primaryKey, pItem);
290
291 if (relation.count() == 0) { this->m_lastError = qx::dao::fetch_by_id((* pItem), this->database(pDatabase), this->m_lstColumns); }
292 else { this->m_lastError = qx::dao::fetch_by_id_with_relation(relation, (* pItem), this->database(pDatabase)); }
293 this->updateShowEmptyLine();
294 this->endInsertRows();
295 return this->m_lastError;
296 }
297
304 virtual QSqlError qxFetchAll(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
305 {
306 this->clear();
307 type_collection tmp;
308 if (relation.count() == 0) { this->m_lastError = qx::dao::fetch_all(tmp, this->database(pDatabase), this->m_lstColumns); }
309 else { this->m_lastError = qx::dao::fetch_all_with_relation(relation, tmp, this->database(pDatabase)); }
310
311 if (tmp.count() <= 0) { return this->m_lastError; }
312 this->beginResetModel();
313 m_model = tmp;
314 this->updateShowEmptyLine();
315 this->endResetModel();
316 return this->m_lastError;
317 }
318
326 virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery & query, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
327 {
328 this->clear();
329 type_collection tmp;
330 if (relation.count() == 0) { this->m_lastError = qx::dao::fetch_by_query(query, tmp, this->database(pDatabase), this->m_lstColumns); }
331 else { this->m_lastError = qx::dao::fetch_by_query_with_relation(relation, query, tmp, this->database(pDatabase)); }
332
333 if (tmp.count() <= 0) { return this->m_lastError; }
334 this->beginResetModel();
335 m_model = tmp;
336 this->updateShowEmptyLine();
337 this->endResetModel();
338 return this->m_lastError;
339 }
340
348 virtual QSqlError qxFetchRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
349 {
350 type_ptr pItem = getRowItemAt(row); if (! pItem) { return QSqlError(); }
351 if (relation.count() == 0) { this->m_lastError = qx::dao::fetch_by_id((* pItem), this->database(pDatabase), this->m_lstColumns); }
352 else { this->m_lastError = qx::dao::fetch_by_id_with_relation(relation, (* pItem), this->database(pDatabase)); }
353 if (this->m_lastError.isValid()) { return this->m_lastError; }
354
355 QModelIndex idxTopLeft = this->index(row, 0);
356 QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1));
357 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight);
358 updateKey(row);
359 return this->m_lastError;
360 }
361
369 virtual QSqlError qxInsert(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false)
370 {
371 if (relation.count() > 0) { this->syncAllNestedModel(relation); }
372 if (relation.count() == 0) { this->m_lastError = qx::dao::insert(m_model, this->database(pDatabase), bUseExecBatch); }
373 else { this->m_lastError = qx::dao::insert_with_relation(relation, m_model, this->database(pDatabase)); }
374 if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
375 return this->m_lastError;
376 }
377
385 virtual QSqlError qxInsertRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
386 {
387 type_ptr pItem = getRowItemAt(row); if (! pItem) { return QSqlError(); }
388 if (relation.count() > 0) { this->syncNestedModel(row, relation); }
389 if (relation.count() == 0) { this->m_lastError = qx::dao::insert((* pItem), this->database(pDatabase)); }
390 else { this->m_lastError = qx::dao::insert_with_relation(relation, (* pItem), this->database(pDatabase)); }
391 if (! this->m_lastError.isValid()) { updateKey(row); }
392 return this->m_lastError;
393 }
394
403 virtual QSqlError qxUpdate(const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false)
404 {
405 if (relation.count() > 0) { this->syncAllNestedModel(relation); }
406 if (relation.count() == 0) { this->m_lastError = qx::dao::update_by_query(query, m_model, this->database(pDatabase), this->m_lstColumns, bUseExecBatch); }
407 else { this->m_lastError = qx::dao::update_by_query_with_relation(relation, query, m_model, this->database(pDatabase)); }
408 if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
409 return this->m_lastError;
410 }
411
420 virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
421 {
422 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); }
423 if (relation.count() > 0) { this->syncNestedModel(row, relation); }
424 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
425 if (relation.count() == 0) { this->m_lastError = qx::dao::update_by_query(query, (* pItem), this->database(pDatabase), this->m_lstColumns); }
426 else { this->m_lastError = qx::dao::update_by_query_with_relation(relation, query, (* pItem), this->database(pDatabase)); }
427 if (! this->m_lastError.isValid()) { updateKey(row); }
428 return this->m_lastError;
429 }
430
437 virtual QSqlError qxSave(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
438 {
439 if (relation.count() > 0) { this->syncAllNestedModel(relation); }
440 if (relation.count() == 0) { this->m_lastError = qx::dao::save(m_model, this->database(pDatabase)); }
441 else { this->m_lastError = qx::dao::save_with_relation(relation, m_model, this->database(pDatabase)); }
442 if (! this->m_lastError.isValid()) { this->updateAllKeys(); }
443 return this->m_lastError;
444 }
445
453 virtual QSqlError qxSaveRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL)
454 {
455 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); }
456 if (relation.count() > 0) { this->syncNestedModel(row, relation); }
457 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
458 if (relation.count() == 0) { this->m_lastError = qx::dao::save((* pItem), this->database(pDatabase)); }
459 else { this->m_lastError = qx::dao::save_with_relation(relation, (* pItem), this->database(pDatabase)); }
460 if (! this->m_lastError.isValid()) { updateKey(row); }
461 return this->m_lastError;
462 }
463
471 virtual QSqlError qxSaveRowData(int row, const QStringList & column = QStringList(), QSqlDatabase * pDatabase = NULL)
472 {
473 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxSaveRowData()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
474 type_ptr pItem = getRowItemAt(row); if (! pItem) { return QSqlError(); }
475 QVariant id = this->m_pDataMemberId->toVariant(pItem.get());
476 bool bExist = qx::trait::is_valid_primary_key(id);
477 if (bExist) { bExist = qx::dao::exist((* pItem), this->database(pDatabase)); }
478 if (bExist) { this->m_lastError = qx::dao::update((* pItem), this->database(pDatabase), column); }
479 else { this->m_lastError = qx::dao::insert((* pItem), this->database(pDatabase)); }
480 return this->m_lastError;
481 }
482
489 virtual QSqlError qxDeleteById(const QVariant & id, QSqlDatabase * pDatabase = NULL)
490 {
491 type_ptr pItem = type_ptr(new T());
492 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); }
493 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
494 this->m_pDataMemberId->fromVariant(pItem.get(), id);
495 this->m_lastError = qx::dao::delete_by_id((* pItem), this->database(pDatabase));
496 return this->m_lastError;
497 }
498
504 virtual QSqlError qxDeleteAll(QSqlDatabase * pDatabase = NULL)
505 {
506 this->m_lastError = qx::dao::delete_all<T>(this->database(pDatabase));
507 return this->m_lastError;
508 }
509
516 virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
517 {
518 this->m_lastError = qx::dao::delete_by_query<T>(query, this->database(pDatabase));
519 return this->m_lastError;
520 }
521
528 virtual QSqlError qxDeleteRow(int row, QSqlDatabase * pDatabase = NULL)
529 {
530 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); }
531 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
532 this->m_lastError = qx::dao::delete_by_id((* pItem), this->database(pDatabase));
533 return this->m_lastError;
534 }
535
542 virtual QSqlError qxDestroyById(const QVariant & id, QSqlDatabase * pDatabase = NULL)
543 {
544 type_ptr pItem = type_ptr(new T());
545 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxDeleteById()' method : '%s'", "data member id not registered"); qAssert(false); }
546 if (! this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxDeleteById()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
547 this->m_pDataMemberId->fromVariant(pItem.get(), id);
548 this->m_lastError = qx::dao::destroy_by_id((* pItem), this->database(pDatabase));
549 return this->m_lastError;
550 }
551
557 virtual QSqlError qxDestroyAll(QSqlDatabase * pDatabase = NULL)
558 {
559 this->m_lastError = qx::dao::destroy_all<T>(this->database(pDatabase));
560 return this->m_lastError;
561 }
562
569 virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
570 {
571 this->m_lastError = qx::dao::destroy_by_query<T>(query, this->database(pDatabase));
572 return this->m_lastError;
573 }
574
581 virtual QSqlError qxDestroyRow(int row, QSqlDatabase * pDatabase = NULL)
582 {
583 if ((row < 0) || (row >= m_model.count())) { return QSqlError(); }
584 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QSqlError(); }
585 this->m_lastError = qx::dao::destroy_by_id((* pItem), this->database(pDatabase));
586 return this->m_lastError;
587 }
588
589 virtual QSqlError qxExecuteQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL)
590 {
591 this->clear();
592 type_collection tmp;
593 this->m_lastError = qx::dao::execute_query(query, tmp, this->database(pDatabase));
594
595 if (tmp.count() <= 0) { return this->m_lastError; }
596 this->beginResetModel();
597 m_model = tmp;
598 this->updateShowEmptyLine();
599 this->endResetModel();
600 return this->m_lastError;
601 }
602
603 virtual qx_bool qxExist(const QVariant & id, QSqlDatabase * pDatabase = NULL)
604 {
605 type_ptr pItem = type_ptr(new T());
606 if (! this->m_pDataMemberId) { qDebug("[QxOrm] problem with 'qxExist()' method : '%s'", "data member id not registered"); qAssert(false); }
607 if (! this->m_pDataMemberId) { return qx_bool(false); }
608 this->m_pDataMemberId->fromVariant(pItem.get(), id);
609 return qx::dao::exist((* pItem), this->database(pDatabase));
610 }
611
612 virtual qx::QxInvalidValueX qxValidate(const QStringList & groups = QStringList())
613 {
614 return qx::validate(m_model, groups);
615 }
616
617 virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList & groups = QStringList())
618 {
619 type_ptr pItem = getRowItemAt(row); if (! pItem) { return qx::QxInvalidValueX(); }
620 return qx::validate((* pItem), groups);
621 }
622
623protected:
624
625 type_ptr getRowItemAt(int row) const
626 {
627 if ((row >= 0) && (row < m_model.count())) { return m_model.getByIndex(row); }
628 if (m_pDirtyRow && (m_pDirtyRow->first == row)) { return m_pDirtyRow->second; }
629 return type_ptr();
630 }
631
632 virtual void * getRowItemAsVoidPtr(int row) const { return getRowItemAt(row).get(); }
633
634 virtual void dumpModelImpl(bool bJsonFormat) const { qx::dump(m_model, bJsonFormat); }
635
636 virtual QObject * cloneModelImpl()
637 {
638 qx::QxModel<T, B> * pClone = new qx::QxModel<T, B>(this, NULL);
639 std::shared_ptr<type_collection> pModel = qx::clone(pClone->m_model);
640 if (pModel) { pClone->m_model = (* pModel); }
641 return static_cast<QObject *>(pClone);
642 }
643
644 virtual void updateShowEmptyLine() { if (m_pDirtyRow) { m_pDirtyRow->first = m_model.count(); } }
645
646 virtual bool isDirtyRow(int row) const { return (m_pDirtyRow && (m_pDirtyRow->first == row)); }
647
649 {
650 if (! m_pDirtyRow) { return; }
651 int row = m_pDirtyRow->first;
652 insertItem(row, m_pDirtyRow->second);
653 if (this->m_pParent) { this->m_pParent->saveChildRelations(this); }
654 updateKey(row);
655 addDirtyRow();
656 }
657
659 {
660 this->beginInsertRows(QModelIndex(), m_model.count(), m_model.count());
661 m_pDirtyRow.reset(new QPair<int, type_ptr>(m_model.count(), type_ptr(new T())));
663 IxSqlRelation::relation_type eRelationParentType = (pRelationParent ? pRelationParent->getRelationType() : IxSqlRelation::no_relation);
664 if (this->m_pParent && ((eRelationParentType == IxSqlRelation::many_to_many) || (eRelationParentType == IxSqlRelation::many_to_one)))
665 { this->m_pDataMemberRelationToParent->fromVariant(m_pDirtyRow->second.get(), this->m_pParent->getIdFromChild(this)); }
666 this->endInsertRows();
667 }
668
669 void insertItem(int row, const type_ptr & pItem)
670 {
671 if (! pItem) { return; }
672 type_primary_key primaryKey;
673 this->m_lManualInsertIndex = (this->m_lManualInsertIndex - 1);
674 QVariant vNewId(static_cast<qlonglong>(this->m_lManualInsertIndex));
675 qx::cvt::from_variant(vNewId, primaryKey);
676 m_model.insert(row, primaryKey, pItem);
677 this->updateShowEmptyLine();
678 }
679
680 void updateKey(int row)
681 {
682 if ((row < 0) || (row >= m_model.count())) { return; }
683 type_ptr pItem = m_model.getByIndex(row); if (! pItem || ! this->m_pDataMemberId) { return; }
684 type_primary_key currPrimaryKey = m_model.getKeyByIndex(row);
685 QVariant vCurrPrimaryKey = qx::cvt::to_variant(currPrimaryKey);
686 QVariant vNextPrimaryKey = this->m_pDataMemberId->toVariant(pItem.get());
687 if ((vCurrPrimaryKey == vNextPrimaryKey) || (! vNextPrimaryKey.isValid())) { return; }
688 if (! qx::trait::is_valid_primary_key(vNextPrimaryKey)) { return; }
689 type_primary_key updatedPrimaryKey;
690 qx::cvt::from_variant(vNextPrimaryKey, updatedPrimaryKey);
691 if (m_model.exist(updatedPrimaryKey)) { return; }
692 m_model.removeByIndex(row);
693 m_model.insert(row, updatedPrimaryKey, pItem);
694 }
695
697 {
698 for (long l = 0; l < m_model.count(); l++)
699 { updateKey(l); }
700 }
701
702protected:
703
704#ifndef _QX_NO_JSON
705
706 virtual QString toJson_Helper(int row) const
707 {
708 if (row == -1) { return qx::serialization::json::to_string(m_model); }
709 type_ptr pItem = getRowItemAt(row); if (! pItem) { return QString(); }
711 }
712
713 virtual bool fromJson_Helper(const QString & json, int row)
714 {
715 if (row == -1)
716 {
717 this->clear();
718 type_collection tmp;
719 if (! qx::serialization::json::from_string(tmp, json)) { return false; }
720 this->beginResetModel();
721 m_model = tmp;
722 this->updateShowEmptyLine();
723 this->endResetModel();
724 return true;
725 }
726
727 type_ptr pItem = getRowItemAt(row); if (! pItem) { return false; }
728 if (! qx::serialization::json::from_string((* pItem), json)) { return false; }
729
730 QModelIndex idxTopLeft = this->index(row, 0);
731 QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1));
732 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight);
733 updateKey(row);
734 return true;
735 }
736
737 virtual QVariant getRelationshipValues_Helper(int row, const QString & relation, bool bLoadFromDatabase, const QString & sAppendRelations)
738 {
739 if ((row < 0) || (row >= m_model.count())) { return QVariant(); }
740 if (! this->m_pDataMemberId || ! this->m_pDataMemberX || ! this->m_pDataMemberX->exist(relation)) { return QVariant(); }
741 IxDataMember * pDataMember = this->m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return QVariant(); }
742 IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return QVariant(); }
743 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return QVariant(); }
744 type_ptr pItemTemp = pItem;
745
746 if (bLoadFromDatabase)
747 {
748 QString sRelation = relation;
749 if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
750 else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
751 pItemTemp = type_ptr(new T());
752 QVariant id = this->m_pDataMemberId->toVariant(pItem.get());
753 this->m_pDataMemberId->fromVariant(pItemTemp.get(), id);
754 QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, (* pItemTemp));
755 if (daoError.isValid()) { return QVariant(); }
756 }
757
758 QJsonValue json = pDataMember->toJson(pItemTemp.get()); if (json.isNull()) { return QVariant(); }
759 if (json.isArray()) { return json.toArray().toVariantList(); }
760 return json.toObject().toVariantMap();
761 }
762
763 virtual bool setRelationshipValues_Helper(int row, const QString & relation, const QVariant & values)
764 {
765 if ((row < 0) || (row >= m_model.count())) { return false; }
766 if ((values.type() != QVariant::List) && (values.type() != QVariant::Map)) { return false; }
767 if (! this->m_pDataMemberId || ! this->m_pDataMemberX || ! this->m_pDataMemberX->exist(relation)) { return false; }
768 IxDataMember * pDataMember = this->m_pDataMemberX->get_WithDaoStrategy(relation); if (! pDataMember) { return false; }
769 IxSqlRelation * pRelation = (pDataMember->hasSqlRelation() ? pDataMember->getSqlRelation() : NULL); if (! pRelation) { return false; }
770 type_ptr pItem = m_model.getByIndex(row); if (! pItem) { return false; }
771
772 QJsonValue json;
773 if (values.type() == QVariant::List) { json = QJsonArray::fromVariantList(values.toList()); }
774 else if (values.type() == QVariant::Map) { json = QJsonObject::fromVariantMap(values.toMap()); }
775 if (! pDataMember->fromJson(pItem.get(), json)) { return false; }
776
777 QModelIndex idxTopLeft = this->index(row, 0);
778 QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1));
779 this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight);
780 return true;
781 }
782
783#endif // _QX_NO_JSON
784
785};
786
787} // namespace qx
788
789#endif // _QX_MODEL_H_
Interface to manage Qt model/view architecture with classes registered into QxOrm context (Qt widgets...
qx::QxBool qx_bool
Definition QxBool.h:150
Concrete class registered into QxOrm context.
Clone all classes registered into QxOrm context using QxOrm library serialization engine.
QxOrm thread-safe container (keep insertion order + quick access by index + quick access by key)
Dump all classes registered into QxOrm context using XML and JSON serialization engine.
#define qAssert(x)
Definition QxMacro.h:52
Functor used to provide sort feature for all models based on qx::IxModel interface (please note that ...
Provide a serialization engine with Qt QJson classes (this feature requires Qt5)
Provide a Qt QJson serialization method (save/load) for type qx::QxCollection<Key,...
IxDataMemberX * getDataMemberX() const
qx::IxDataMember : common interface for all class properties registered into QxOrm context
bool hasSqlRelation() const
virtual qx_bool fromJson(void *pOwner, const QJsonValue &j, const QString &sFormat)=0
virtual QJsonValue toJson(const void *pOwner, const QString &sFormat) const =0
virtual qx_bool fromVariant(void *pOwner, const QVariant &v, const QString &sFormat, int iIndexName=-1, qx::cvt::context::ctx_type ctx=qx::cvt::context::e_no_context)=0
IxSqlRelation * getSqlRelation() const
virtual QVariant toVariant(const void *pOwner, const QString &sFormat, int iIndexName=-1, qx::cvt::context::ctx_type ctx=qx::cvt::context::e_no_context) const =0
bool exist(const QString &sKey) const
virtual IxDataMember * getId_WithDaoStrategy() const =0
virtual IxDataMember * get_WithDaoStrategy(long lIndex) const =0
qx::IxModel : interface to manage Qt model/view architecture with classes registered into QxOrm conte...
Definition IxModel.h:163
void raiseEvent_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >())
QList< IxDataMember * > m_lstDataMember
List of data member exposed by the model.
Definition IxModel.h:187
IxModel * m_pParent
Parent model, NULL if current model is the root model.
Definition IxModel.h:193
QSqlError m_lastError
Last SQL error.
Definition IxModel.h:192
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
IxDataMemberX * m_pDataMemberX
List of properties defined into QxOrm context.
Definition IxModel.h:183
IxCollection * m_pCollection
Interface to store a list of items.
Definition IxModel.h:185
virtual void syncAllNestedModel(const QStringList &relation)
void raiseEvent_layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
IxClass * m_pClass
Class introspection registered into QxOrm context associated to the model.
Definition IxModel.h:181
IxDataMember * getDataMember(int column) const
Q_INVOKABLE void clear(bool bUpdateColumns=false)
QStringList m_lstColumns
List of columns exposed by the model (if empty, all columns)
Definition IxModel.h:190
QSqlDatabase * database(QSqlDatabase *other)
QHash< QString, QVariant > m_hCustomProperties
Use this generic hash-table to define extra-properties in your custom classes which inherit from qx::...
Definition IxModel.h:199
void generateRoleNames()
virtual QModelIndex parent(const QModelIndex &index) const
long m_lManualInsertIndex
Index to insert manually items to the collection.
Definition IxModel.h:198
void setParentModel(IxModel *pParent)
QSqlError saveChildRelations(IxModel *pChild)
IxDataMember * m_pDataMemberId
Primary key (property id) defined into QxOrm context.
Definition IxModel.h:184
e_auto_update_database getAutoUpdateDatabase() const
IxDataMember * m_pDataMemberRelationToParent
The data member holding relationship to its parent model (if one exists), used only by nested models.
Definition IxModel.h:197
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
virtual void syncNestedModel(int row, const QStringList &relation)
e_auto_update_database m_eAutoUpdateDatabase
Auto-update database on field change (detected by the setData() method)
Definition IxModel.h:196
qx::IxSqlRelation : common interface for all relationships defined between 2 classes (or between 2 ta...
relation_type getRelationType() const
qx::QxCollection<Key, Value> : QxOrm thread-safe container (keep insertion order + quick access by in...
long count() const
Return the number of items in the list (same as 'size()')
qx::QxInvalidValueX : list of invalid values
qx::QxModel<T, B> : all classes registered into QxOrm context can be used with Qt model/view architec...
Definition QxModel.h:164
virtual bool isDirtyRow(int row) const
Definition QxModel.h:646
virtual QSqlError qxFetchById(const QVariant &id, const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Clear the model and fetch an object (retrieve all its properties) of type T (registered into QxOrm co...
Definition QxModel.h:278
virtual QSqlError qxDestroyById(const QVariant &id, QSqlDatabase *pDatabase=NULL)
Delete a line of a table (even if a logical delete is defined) mapped to a C++ object of type T (regi...
Definition QxModel.h:542
virtual QSqlError qxCount(long &lCount, const qx::QxSqlQuery &query=qx::QxSqlQuery(), QSqlDatabase *pDatabase=NULL)
Return the number of lines in the table (database) mapped to the C++ class T (registered into QxOrm c...
Definition QxModel.h:265
virtual bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex())
Definition QxModel.h:215
virtual void updateShowEmptyLine()
Definition QxModel.h:644
virtual QSqlError qxUpdate(const qx::QxSqlQuery &query=qx::QxSqlQuery(), const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL, bool bUseExecBatch=false)
Update all items in the model into database.
Definition QxModel.h:403
void updateKey(int row)
Definition QxModel.h:680
virtual bool fromJson_Helper(const QString &json, int row)
Definition QxModel.h:713
void addDirtyRow()
Definition QxModel.h:658
virtual QSqlError qxDeleteById(const QVariant &id, QSqlDatabase *pDatabase=NULL)
Delete a line of a table (database) mapped to a C++ object of type T (registered into QxOrm context),...
Definition QxModel.h:489
virtual void dumpModelImpl(bool bJsonFormat) const
Definition QxModel.h:634
virtual QSqlError qxDeleteRow(int row, QSqlDatabase *pDatabase=NULL)
Delete in database the item at line row in the model, if no error occurred then you should remove row...
Definition QxModel.h:528
qx::QxCollection< type_primary_key, type_ptr > type_collection
Definition QxModel.h:174
virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList &groups=QStringList())
Definition QxModel.h:617
virtual QVariant getRelationshipValues_Helper(int row, const QString &relation, bool bLoadFromDatabase, const QString &sAppendRelations)
Definition QxModel.h:737
qx::trait::get_primary_key< T >::type type_primary_key
Definition QxModel.h:173
virtual QSqlError qxDeleteAll(QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (database) mapped to a C++ class T (registered into QxOrm context),...
Definition QxModel.h:504
virtual void insertDirtyRowToModel()
Definition QxModel.h:648
void init()
Definition QxModel.h:192
QxModel(QObject *parent=0)
Definition QxModel.h:186
virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery &query=qx::QxSqlQuery(), const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Update an item of the model at line row into database.
Definition QxModel.h:420
virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery &query, QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (even if a logical delete is defined) mapped to a C++ class T (registered...
Definition QxModel.h:569
virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery &query, const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Clear the model and fetch a list of objects (retrieve all elements and properties associated) of type...
Definition QxModel.h:326
virtual bool setRelationshipValues_Helper(int row, const QString &relation, const QVariant &values)
Definition QxModel.h:763
virtual void sort(int column, Qt::SortOrder order=Qt::AscendingOrder)
Definition QxModel.h:229
QxModel(qx::IxModel *other, QObject *parent)
Definition QxModel.h:187
virtual qx_bool qxExist(const QVariant &id, QSqlDatabase *pDatabase=NULL)
Definition QxModel.h:603
virtual QSqlError qxInsertRow(int row, const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Insert an item of the model at line row into database.
Definition QxModel.h:385
virtual QSqlError qxSaveRow(int row, const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Save an item of the model at line row into database.
Definition QxModel.h:453
virtual QSqlError qxFetchRow(int row, const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Get an item in the model at line row and fetch all its properties mapped to a table in the database,...
Definition QxModel.h:348
virtual bool getShowEmptyLine() const
Can be useful when a model is displayed in a table (QTableView for example) to add automatically an e...
Definition QxModel.h:236
virtual void * getRowItemAsVoidPtr(int row) const
Definition QxModel.h:632
virtual QSqlError qxDestroyAll(QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (even if a logical delete is defined) mapped to a C++ class T (registered...
Definition QxModel.h:557
virtual qx::QxInvalidValueX qxValidate(const QStringList &groups=QStringList())
Definition QxModel.h:612
virtual long qxCount(const qx::QxSqlQuery &query=qx::QxSqlQuery(), QSqlDatabase *pDatabase=NULL)
Return the number of lines in the table (database) mapped to the C++ class T (registered into QxOrm c...
Definition QxModel.h:254
virtual QString toJson_Helper(int row) const
Definition QxModel.h:706
std::shared_ptr< QPair< int, type_ptr > > m_pDirtyRow
Definition QxModel.h:182
virtual QSqlError qxDestroyRow(int row, QSqlDatabase *pDatabase=NULL)
Delete in database (even if a logical delete is defined) the item at line row in the model,...
Definition QxModel.h:581
virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery &query, QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (database) mapped to a C++ class T (registered into QxOrm context) and fi...
Definition QxModel.h:516
std::shared_ptr< T > type_ptr
Definition QxModel.h:172
void initFrom(qx::IxModel *pOther)
Definition QxModel.h:202
void insertItem(int row, const type_ptr &pItem)
Definition QxModel.h:669
virtual QSqlError qxSaveRowData(int row, const QStringList &column=QStringList(), QSqlDatabase *pDatabase=NULL)
Used internally by qx::IxModel::setData() method with e_auto_update_on_field_change option,...
Definition QxModel.h:471
virtual QSqlError qxInsert(const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL, bool bUseExecBatch=false)
Insert all items in the model into database.
Definition QxModel.h:369
void updateAllKeys()
Definition QxModel.h:696
virtual QSqlError qxFetchAll(const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Clear the model and fetch a list of objects (retrieve all elements and properties associated) of type...
Definition QxModel.h:304
virtual QObject * cloneModelImpl()
Definition QxModel.h:636
virtual ~QxModel()
Definition QxModel.h:188
virtual QSqlError qxSave(const QStringList &relation=QStringList(), QSqlDatabase *pDatabase=NULL)
Save all items (insert or update) in the model into database.
Definition QxModel.h:437
virtual void setShowEmptyLine(bool b)
Definition QxModel.h:238
virtual QSqlError qxExecuteQuery(qx::QxSqlQuery &query, QSqlDatabase *pDatabase=NULL)
Definition QxModel.h:589
type_collection m_model
Definition QxModel.h:181
type_ptr getRowItemAt(int row) const
Definition QxModel.h:625
B type_base_class
Definition QxModel.h:175
qx::QxSqlQuery : define a user SQL query added to default SQL query builded by QxOrm library,...
Definition QxSqlQuery.h:245
qx::trait::get_primary_key<T>::type : return primary key type of T, by default primary key is long ty...
QSqlError destroy_all(QSqlDatabase *pDatabase=NULL)
Destroy all lines of a table (database) mapped to a C++ class T (registered into QxOrm context),...
Definition QxDao.h:220
QSqlError execute_query(qx::QxSqlQuery &query, T &t, QSqlDatabase *pDatabase=NULL)
Execute a custom SQL query or a stored procedure, all columns that can be mapped to the instance of t...
Definition QxDao.h:743
QSqlError save(T &t, QSqlDatabase *pDatabase=NULL)
Insert (if no exist) or update (if already exist) an element or a list of elements into database.
Definition QxDao.h:158
QSqlError fetch_by_id(T &t, QSqlDatabase *pDatabase=NULL, const QStringList &columns=QStringList())
Fetch an object t (retrieve all its properties) of type T (registered into QxOrm context) mapped to a...
Definition QxDao.h:636
QSqlError fetch_by_query_with_relation(const QString &relation, const qx::QxSqlQuery &query, T &t, QSqlDatabase *pDatabase=NULL)
Fetch a list of objects (retrieve all elements and properties associated) of type T (container regist...
Definition QxDao.h:382
QSqlError fetch_by_id_with_relation(const QString &relation, T &t, QSqlDatabase *pDatabase=NULL)
Fetch an object t (retrieve all its properties) of type T (registered into QxOrm context) mapped to a...
Definition QxDao.h:293
QSqlError delete_by_id(T &t, QSqlDatabase *pDatabase=NULL, bool bUseExecBatch=false)
Delete a line (or list of lines) of a table (database) mapped to a C++ object of type T (registered i...
Definition QxDao.h:176
qx_bool exist(T &t, QSqlDatabase *pDatabase=NULL)
Search if an element (or list of elements) already exists into database.
Definition QxDao.h:278
QSqlError save_with_relation(const QString &relation, T &t, QSqlDatabase *pDatabase=NULL)
Insert (if no exist) or update (if already exist) an element and its relationships (or a list of elem...
Definition QxDao.h:565
QSqlError insert_with_relation(const QString &relation, T &t, QSqlDatabase *pDatabase=NULL)
Insert an element and its relationships (or a list of elements + relationships) into database.
Definition QxDao.h:428
QSqlError insert(T &t, QSqlDatabase *pDatabase=NULL, bool bUseExecBatch=false)
Insert an element or a list of elements into database.
Definition QxDao.h:142
QSqlError destroy_by_query(const qx::QxSqlQuery &query, QSqlDatabase *pDatabase=NULL)
Destroy all lines of a table (database) mapped to a C++ class T (registered into QxOrm context) and f...
Definition QxDao.h:251
QSqlError delete_all(QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (database) mapped to a C++ class T (registered into QxOrm context)
Definition QxDao.h:207
QSqlError update_by_query(const qx::QxSqlQuery &query, T &t, QSqlDatabase *pDatabase=NULL, const QStringList &columns=QStringList(), bool bUseExecBatch=false)
Update an element or a list of elements into database (adding a user SQL query to the default SQL que...
Definition QxDao.h:700
QSqlError fetch_by_query(const qx::QxSqlQuery &query, T &t, QSqlDatabase *pDatabase=NULL, const QStringList &columns=QStringList())
Fetch a list of objects (retrieve all elements and properties associated) of type T (container regist...
Definition QxDao.h:667
QSqlError update_by_query_with_relation(const QString &relation, const qx::QxSqlQuery &query, T &t, QSqlDatabase *pDatabase=NULL)
Update an element and its relationships (or a list of elements + relationships) into database (adding...
Definition QxDao.h:488
QSqlError update(T &t, QSqlDatabase *pDatabase=NULL, const QStringList &columns=QStringList(), bool bUseExecBatch=false)
Update an element or a list of elements into database.
Definition QxDao.h:683
QSqlError fetch_all(T &t, QSqlDatabase *pDatabase=NULL, const QStringList &columns=QStringList())
Fetch a list of objects (retrieve all elements and properties associated) of type T (container regist...
Definition QxDao.h:651
QSqlError delete_by_query(const qx::QxSqlQuery &query, QSqlDatabase *pDatabase=NULL)
Delete all lines of a table (database) mapped to a C++ class T (registered into QxOrm context) and fi...
Definition QxDao.h:237
QSqlError fetch_all_with_relation(const QString &relation, T &t, QSqlDatabase *pDatabase=NULL)
Fetch a list of objects (retrieve all elements and properties associated) of type T (container regist...
Definition QxDao.h:337
long count(const qx::QxSqlQuery &query=qx::QxSqlQuery(), QSqlDatabase *pDatabase=NULL)
Return the number of lines in the table (database) mapped to the C++ class T (registered into QxOrm c...
Definition QxDao.h:98
QSqlError destroy_by_id(T &t, QSqlDatabase *pDatabase=NULL, bool bUseExecBatch=false)
Destroy a line (or list of lines) of a table (database) mapped to a C++ object of type T (registered ...
Definition QxDao.h:191
std::shared_ptr< T > clone(const T &obj)
qx::clone(const T & obj) : return a boost smart-pointer (std::shared_ptr<T>) of a new instance of typ...
Definition QxClone.h:128
void dump(const T &t, bool bJsonFormat=false)
qx::dump(const T & t, bool bJsonFormat) : dump class of type T registered into QxOrm context using XM...
Definition QxDump.h:63
qx::trait::is_qx_registered<T>::value : return true if T is registered into QxOrm context to provide ...
qx::trait::is_valid_primary_key<T>(const T & t) : return true if t can be a valid primary key to be i...
qx_bool from_variant(const QVariant &v, T &t, const QString &format=QString(), int index=-1, qx::cvt::context::ctx_type ctx=qx::cvt::context::e_no_context)
Definition QxConvert.h:80
QVariant to_variant(const T &t, const QString &format=QString(), int index=-1, qx::cvt::context::ctx_type ctx=qx::cvt::context::e_no_context)
Definition QxConvert.h:79
QString to_string(const T &obj, unsigned int flags=1, const QString &format=QString())
qx_bool from_string(T &obj, const QString &sString, unsigned int flags=1, const QString &format=QString())
bool is_valid_primary_key(const T &t)
Root namespace for all QxOrm library features.
QxInvalidValueX validate(T &t, const QString &group)
qx::QxModelRowCompare : functor used to provide sort feature for all models based on qx::IxModel inte...