QxOrm  1.5.0
C++ Object Relational Mapping library
IxModel.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** https://www.qxorm.com/
00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
00005 **
00006 ** This file is part of the QxOrm library
00007 **
00008 ** This software is provided 'as-is', without any express or implied
00009 ** warranty. In no event will the authors be held liable for any
00010 ** damages arising from the use of this software
00011 **
00012 ** Commercial Usage
00013 ** Licensees holding valid commercial QxOrm licenses may use this file in
00014 ** accordance with the commercial license agreement provided with the
00015 ** Software or, alternatively, in accordance with the terms contained in
00016 ** a written agreement between you and Lionel Marty
00017 **
00018 ** GNU General Public License Usage
00019 ** Alternatively, this file may be used under the terms of the GNU
00020 ** General Public License version 3.0 as published by the Free Software
00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the
00022 ** packaging of this file. Please review the following information to
00023 ** ensure the GNU General Public License version 3.0 requirements will be
00024 ** met : http://www.gnu.org/copyleft/gpl.html
00025 **
00026 ** If you are unsure which license is appropriate for your use, or
00027 ** if you have questions regarding the use of this file, please contact :
00028 ** contact@qxorm.com
00029 **
00030 ****************************************************************************/
00031 
00032 #ifndef _IX_MODEL_H_
00033 #define _IX_MODEL_H_
00034 
00035 #ifdef _MSC_VER
00036 #pragma once
00037 #endif
00038 
00046 #ifdef _QX_NO_PRECOMPILED_HEADER
00047 #ifndef Q_MOC_RUN
00048 #include <QxPrecompiled.h> // Need to include precompiled header for the generated moc file
00049 #endif // Q_MOC_RUN
00050 #endif // _QX_NO_PRECOMPILED_HEADER
00051 
00052 #include <QtCore/qabstractitemmodel.h>
00053 
00054 #ifndef Q_MOC_RUN
00055 #include <QxRegister/IxClass.h>
00056 #include <QxDataMember/IxDataMemberX.h>
00057 #include <QxCollection/QxCollection.h>
00058 #include <QxDao/IxSqlRelation.h>
00059 #include <QxDao/QxSqlQuery.h>
00060 #include <QxDao/QxDao.h>
00061 #include <QxValidator/QxInvalidValueX.h>
00062 #include <QxValidator/QxValidatorFct.h>
00063 #endif // Q_MOC_RUN
00064 
00065 namespace qx {
00066 namespace model_view {
00067 namespace detail {
00068 
00069 template <class T, class M> struct QxNestedModel;
00070 template <class T, class M> struct QxNestedModel_Generic;
00071 template <class T, class M> struct QxNestedModel_Container;
00072 
00073 } // namespace detail
00074 } // namespace model_view
00075 } // namespace qx
00076 
00077 namespace qx {
00078 
00162 class QX_DLL_EXPORT IxModel : public QAbstractItemModel
00163 {
00164 
00165    Q_OBJECT
00166 
00167    template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel;
00168    template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel_Generic;
00169    template <typename U, typename V> friend struct qx::model_view::detail::QxNestedModel_Container;
00170 
00171 public:
00172 
00173    enum e_auto_update_database { e_no_auto_update, e_auto_update_on_field_change };
00174 
00175    typedef QHash<QString, IxModel *> type_relation_by_name;
00176    typedef QList<type_relation_by_name> type_lst_relation_by_name;
00177    typedef QHash<IxModel *, QPair<int, QString> > type_child_to_its_relation;
00178 
00179 protected:
00180 
00181    IxClass * m_pClass;                             
00182    IxClass * m_pModelClass;                        
00183    IxDataMemberX * m_pDataMemberX;                 
00184    IxDataMember * m_pDataMemberId;                 
00185    IxCollection * m_pCollection;                   
00186    QHash<int, QByteArray> m_lstRoleNames;          
00187    QList<IxDataMember *> m_lstDataMember;          
00188    QHash<QString, int> m_lstDataMemberByKey;       
00189    QHash<QString, QVariant> m_lstHeadersData;      
00190    QStringList m_lstColumns;                       
00191    QSqlDatabase m_database;                        
00192    QSqlError m_lastError;                          
00193    IxModel * m_pParent;                            
00194    type_lst_relation_by_name m_lstChild;           
00195    type_child_to_its_relation m_hChild;            
00196    e_auto_update_database m_eAutoUpdateDatabase;   
00197    IxDataMember * m_pDataMemberRelationToParent;   
00198    long m_lManualInsertIndex;                      
00199    QHash<QString, QVariant> m_hCustomProperties;   
00200 
00201 public:
00202 
00203    IxModel(QObject * parent = 0);
00204    virtual ~IxModel();
00205 
00206    IxClass * getClass() const;
00207    IxClass * getModelClass() const;
00208    IxCollection * getCollection() const;
00209    QSqlDatabase getDatabase() const;
00210    QSqlError getLastError() const;
00211    Q_INVOKABLE QString getLastErrorAsString() const;
00212    Q_INVOKABLE QStringList getListOfColumns() const;
00213    QHash<QString, QString> getListOfHeaders() const; 
00214    IxDataMember * getDataMember(int column) const;
00215    Q_INVOKABLE QString getDataMemberKey(int column) const;
00216    Q_INVOKABLE int getRowCount() const;
00217    Q_INVOKABLE QVariant getModelValue(int row, const QString & column) const;
00218    Q_INVOKABLE int getColumnIndex(const QString & sColumnName) const;
00219    Q_INVOKABLE int getAutoUpdateDatabase_() const;
00220    e_auto_update_database getAutoUpdateDatabase() const;
00221    Q_INVOKABLE virtual bool getShowEmptyLine() const = 0; 
00222    Q_INVOKABLE QVariant getCustomProperty(const QString & key) const;
00223    Q_INVOKABLE QObject * getParentModel() const; 
00224    Q_INVOKABLE void dumpModel(bool bJsonFormat = true) const;
00225    Q_INVOKABLE QObject * cloneModel();
00226 
00227    void setDatabase(const QSqlDatabase & db);
00228    Q_INVOKABLE void setListOfColumns(const QStringList & lst);
00229    void setListOfHeaders(const QHash<QString, QString> & lst); 
00230    Q_INVOKABLE bool setModelValue(int row, const QString & column, const QVariant & value);
00231    void setParentModel(IxModel * pParent);
00232    Q_INVOKABLE void setAutoUpdateDatabase_(int i);
00233    void setAutoUpdateDatabase(e_auto_update_database e);
00234    Q_INVOKABLE virtual void setShowEmptyLine(bool b) = 0;
00235    Q_INVOKABLE void setCustomProperty(const QString & key, const QVariant & val);
00236 
00237    Q_INVOKABLE QString toJson(int row = -1) const;                   
00238    Q_INVOKABLE bool fromJson(const QString & json, int row = -1);    
00239 
00240    Q_INVOKABLE QVariant getRelationshipValues(int row, const QString & relation, bool bLoadFromDatabase = false, const QString & sAppendRelations = QString()); 
00241    Q_INVOKABLE bool setRelationshipValues(int row, const QString & relation, const QVariant & values); 
00242 
00243    virtual long qxCount(const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL) = 0;
00244    virtual QSqlError qxCount(long & lCount, const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL) = 0;
00245    virtual QSqlError qxFetchById(const QVariant & id, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00246    virtual QSqlError qxFetchAll(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00247    virtual QSqlError qxFetchByQuery(const qx::QxSqlQuery & query, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00248    virtual QSqlError qxFetchRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00249    virtual QSqlError qxInsert(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false) = 0;
00250    virtual QSqlError qxInsertRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00251    virtual QSqlError qxUpdate(const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL, bool bUseExecBatch = false) = 0;
00252    virtual QSqlError qxUpdateRow(int row, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00253    virtual QSqlError qxSave(const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00254    virtual QSqlError qxSaveRow(int row, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00255    virtual QSqlError qxSaveRowData(int row, const QStringList & column = QStringList(), QSqlDatabase * pDatabase = NULL) = 0;
00256    virtual QSqlError qxDeleteById(const QVariant & id, QSqlDatabase * pDatabase = NULL) = 0;
00257    virtual QSqlError qxDeleteAll(QSqlDatabase * pDatabase = NULL) = 0;
00258    virtual QSqlError qxDeleteByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) = 0;
00259    virtual QSqlError qxDeleteRow(int row, QSqlDatabase * pDatabase = NULL) = 0;
00260    virtual QSqlError qxDestroyById(const QVariant & id, QSqlDatabase * pDatabase = NULL) = 0;
00261    virtual QSqlError qxDestroyAll(QSqlDatabase * pDatabase = NULL) = 0;
00262    virtual QSqlError qxDestroyByQuery(const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) = 0;
00263    virtual QSqlError qxDestroyRow(int row, QSqlDatabase * pDatabase = NULL) = 0;
00264    virtual QSqlError qxExecuteQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL) = 0;
00265    virtual qx_bool qxExist(const QVariant & id, QSqlDatabase * pDatabase = NULL) = 0;
00266    virtual qx::QxInvalidValueX qxValidate(const QStringList & groups = QStringList()) = 0;
00267    virtual qx::QxInvalidValueX qxValidateRow(int row, const QStringList & groups = QStringList()) = 0;
00268 
00269    Q_INVOKABLE int qxCount_(const QString & sQuery);
00270    Q_INVOKABLE bool qxFetchById_(const QVariant & id, const QStringList & relation = QStringList());
00271    Q_INVOKABLE bool qxFetchAll_(const QStringList & relation = QStringList());
00272    Q_INVOKABLE bool qxFetchByQuery_(const QString & sQuery, const QStringList & relation = QStringList());
00273    Q_INVOKABLE bool qxFetchRow_(int row, const QStringList & relation = QStringList());
00274    Q_INVOKABLE bool qxInsert_(const QStringList & relation = QStringList(), bool bUseExecBatch = false);
00275    Q_INVOKABLE bool qxInsertRow_(int row, const QStringList & relation = QStringList());
00276    Q_INVOKABLE bool qxUpdate_(const QString & sQuery, const QStringList & relation = QStringList(), bool bUseExecBatch = false);
00277    Q_INVOKABLE bool qxUpdateRow_(int row, const QString & sQuery, const QStringList & relation = QStringList());
00278    Q_INVOKABLE bool qxSave_(const QStringList & relation = QStringList());
00279    Q_INVOKABLE bool qxSaveRow_(int row, const QStringList & relation = QStringList());
00280    Q_INVOKABLE bool qxDeleteById_(const QVariant & id);
00281    Q_INVOKABLE bool qxDeleteAll_();
00282    Q_INVOKABLE bool qxDeleteByQuery_(const QString & sQuery);
00283    Q_INVOKABLE bool qxDeleteRow_(int row);
00284    Q_INVOKABLE bool qxDestroyById_(const QVariant & id);
00285    Q_INVOKABLE bool qxDestroyAll_();
00286    Q_INVOKABLE bool qxDestroyByQuery_(const QString & sQuery);
00287    Q_INVOKABLE bool qxDestroyRow_(int row);
00288    Q_INVOKABLE bool qxExecuteQuery_(const QString & sQuery);
00289    Q_INVOKABLE bool qxExist_(const QVariant & id);
00290    Q_INVOKABLE QString qxValidate_(const QStringList & groups = QStringList());
00291    Q_INVOKABLE QString qxValidateRow_(int row, const QStringList & groups = QStringList());
00292 
00293    QSqlError saveChildRelations(IxModel * pChild);
00294    QVariant getIdFromChild(IxModel * pChild) const; 
00295    QPair<int, QString> getChildPosition(IxModel * pChild) const;
00296 
00297 protected:
00298 
00299    void raiseEvent_headerDataChanged(Qt::Orientation orientation, int first, int last);
00300 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
00301    void raiseEvent_dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int>());
00302    void raiseEvent_layoutAboutToBeChanged(const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
00303    void raiseEvent_layoutChanged(const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
00304 #else // (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
00305    void raiseEvent_dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
00306    void raiseEvent_layoutAboutToBeChanged();
00307    void raiseEvent_layoutChanged();
00308 #endif // (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
00309 
00310 public:
00311 
00312    Q_INVOKABLE void clear(bool bUpdateColumns = false);
00313 
00314    virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
00315    virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
00316    virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
00317    virtual int columnCount(const QModelIndex & parent = QModelIndex()) const;
00318    virtual QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
00319    virtual QModelIndex parent(const QModelIndex & index) const;
00320    virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) const;
00321    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
00322    virtual Qt::ItemFlags flags(const QModelIndex & index) const;
00323    virtual Qt::DropActions supportedDropActions() const;
00324    virtual bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex());
00325    virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole);
00326    bool setHeaderData(const QString & sColumnName, const QVariant & value, int role = Qt::EditRole);
00327 
00328 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
00329    virtual QHash<int, QByteArray> roleNames() const;
00330    virtual Qt::DropActions supportedDragActions() const;
00331 #endif // (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
00332 
00333 protected:
00334 
00335    virtual QObject * cloneModelImpl() = 0;
00336    virtual void dumpModelImpl(bool bJsonFormat) const = 0;
00337    virtual void * getRowItemAsVoidPtr(int row) const = 0;
00338    virtual bool isDirtyRow(int row) const = 0;
00339    virtual void insertDirtyRowToModel() = 0;
00340    virtual void updateShowEmptyLine() = 0;
00341    virtual void syncNestedModel(int row, const QStringList & relation);
00342    virtual void syncAllNestedModel(const QStringList & relation);
00343    void syncNestedModelRecursive(IxModel * pNestedModel, const QStringList & relation);
00344 
00345    void generateRoleNames();
00346    QSqlDatabase * database(QSqlDatabase * other);
00347    IxModel * getChild(long row, const QString & relation);
00348    void insertChild(long row, const QString & relation, IxModel * pChild);
00349    void removeListOfChild(long row);
00350    bool removeRowsGeneric(int row, int count);
00351    bool removeRowsAutoUpdateOnFieldChange(int row, int count);
00352 
00353 #ifndef _QX_NO_JSON
00354 
00355    virtual QString toJson_Helper(int row) const = 0;
00356    virtual bool fromJson_Helper(const QString & json, int row) = 0;
00357 
00358    virtual QVariant getRelationshipValues_Helper(int row, const QString & relation, bool bLoadFromDatabase, const QString & sAppendRelations) = 0;
00359    virtual bool setRelationshipValues_Helper(int row, const QString & relation, const QVariant & values) = 0;
00360 
00361 #endif // _QX_NO_JSON
00362 
00363 };
00364 
00365 } // namespace qx
00366 
00367 #endif // _IX_MODEL_H_