QxOrm 1.4.9
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
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; }
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
QVariant getIdFromChild(IxModel *pChild) const
Used to save foreign key in a nested model.
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_bool : boolean type with code and description message when an error occured
Definition QxBool.h:71
qx::QxCollection<Key, Value> : QxOrm thread-safe container (keep insertion order + quick access by in...
bool insert(const Key &key, const Value &value)
Add element 'value' at the end of the list indexed by 'key'.
void sort(Compare comp)
const_reference_key getKeyByIndex(long index) const
Return the key associated with the element at index position 'index'.
long count() const
Return the number of items in the list (same as 'size()')
bool removeByIndex(long index)
Remove the item at index position 'index'.
const_reference_value getByIndex(long index) const
Return the item at index position 'index'.
bool exist(const Key &key) const
Return 'true' if the list contains an occurrence of 'key', otherwise return 'false' (same as 'contain...
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
When displayed in a QTableView, this will cause an empty line awaiting user input to be displayed at ...
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
Model associated to a class registered into QxOrm context.
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...
qx::trait::is_qx_registered<T>::value : return true if T is registered into QxOrm context to provide ...