QxOrm  1.4.9
C++ Object Relational Mapping library
IxDataMember.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_DATA_MEMBER_H_
00033 #define _IX_DATA_MEMBER_H_
00034 
00035 #ifdef _MSC_VER
00036 #pragma once
00037 #endif
00038 
00046 #ifdef _MSC_VER
00047 #pragma warning(push)
00048 #pragma warning(disable:4996)
00049 #endif // _MSC_VER
00050 
00051 #include <QtSql/qsqlquery.h>
00052 
00053 #ifndef _QX_NO_JSON
00054 #include <QtCore/qjsonvalue.h>
00055 #endif // _QX_NO_JSON
00056 
00057 #include <QxCommon/QxAny.h>
00058 #include <QxCommon/QxBool.h>
00059 #include <QxCommon/QxPropertyBag.h>
00060 
00061 #include <QxCollection/QxCollection.h>
00062 
00063 #include <QxSerialize/boost/QxSerializeInclude.h>
00064 
00065 #include <QxConvert/QxConvert.h>
00066 
00067 #ifdef _MSC_VER
00068 #pragma warning(pop)
00069 #endif // _MSC_VER
00070 
00071 #define QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(ArchiveInput, ArchiveOutput) \
00072 virtual void toArchive(const void * pOwner, ArchiveOutput & ar) const = 0; \
00073 virtual void fromArchive(void * pOwner, ArchiveInput & ar) = 0;
00074 
00075 namespace qx {
00076 
00077 class IxDataMemberX;
00078 class IxSqlRelation;
00079 class IxSqlQueryBuilder;
00080 struct IxDataMemberSqlCallbackParams;
00081 
00082 namespace dao {
00083 namespace detail {
00084 
00085 class IxDao_Helper;
00086 
00087 } // namespace detail
00088 } // namespace dao
00089 
00094 class QX_DLL_EXPORT IxDataMember : public qx::QxPropertyBag
00095 {
00096 
00097    template <typename DataType, class Owner>
00098    friend class QxDataMember;
00099 
00100 public:
00101 
00102    typedef std::function<void (IxDataMemberSqlCallbackParams &)> type_fct_sql_callback;
00103 
00104 private:
00105 
00106    struct IxDataMemberImpl;
00107    std::unique_ptr<IxDataMemberImpl> m_pImpl; 
00108 
00109 public:
00110 
00111    IxDataMember(const QString & sKey, long lVersion, bool bSerialize, bool bDao, IxDataMember * pImpl);
00112    virtual ~IxDataMember() = 0;
00113 
00114    QString getKey() const;
00115    QString getName() const;
00116    int getNameCount() const;
00117    QString getNameParent() const;
00118    const char * getNamePtr() const;
00119    QString getDescription() const;
00120    QString getFormat() const;
00121    long getVersion() const;
00122    bool getSerialize() const;
00123    bool getDao() const;
00124    QVariant getDefaultValue() const;
00125    QVariant getMinValue() const;
00126    QVariant getMaxValue() const;
00127    int getPrecision() const;
00128    int getMinLength() const;
00129    int getMaxLength() const;
00130    bool getRequired() const;
00131    bool getReadOnly() const;
00132    bool getAutoIncrement() const;
00133    bool getNotNull() const;
00134    bool getIsPrimaryKey() const;
00135    bool getIsIndex() const;
00136    bool getIsUnique() const;
00137    IxDataMemberX * getParent() const;
00138    IxSqlRelation * getSqlRelation() const;
00139    bool hasSqlRelation() const;
00140    bool getAccessDataPointer() const;
00141    virtual QString getType() const;
00142    QString getTypeParent() const;
00143    IxDataMember * getPImpl() const;
00144 
00145    void setName(const QString & s);
00146    void setNameParent(const QString & s);
00147    void setDescription(const QString & s);
00148    void setFormat(const QString & s);
00149    void setSqlType(const QString & s);
00150    void setSqlAlias(const QString & s);
00151    void setVersion(long l);
00152    void setSerialize(bool b);
00153    void setDao(bool b);
00154    void setDefaultValue(const QVariant & v);
00155    void setPrecision(int i);
00156    void setRequired(bool b);
00157    void setReadOnly(bool b);
00158    void setAutoIncrement(bool b);
00159    void setIsPrimaryKey(bool b);
00160    void setIsIndex(bool b);
00161    void setIsUnique(bool b);
00162    void setParent(IxDataMemberX * p);
00163    void setSqlRelation(IxSqlRelation * p);
00164    void setAccessDataPointer(bool b);
00165 
00166    void setMinValue(long lMinValue, const QString & sMessage = QString());
00167    void setMinValue(double dMinValue, const QString & sMessage = QString());
00168    void setMaxValue(long lMaxValue, const QString & sMessage = QString());
00169    void setMaxValue(double dMaxValue, const QString & sMessage = QString());
00170    void setMinLength(int iMinLength, const QString & sMessage = QString());
00171    void setMaxLength(int iMaxLength, const QString & sMessage = QString());
00172    void setNotNull(bool bNotNull, const QString & sMessage = QString());
00173 
00174    bool isThereRelationPartOfPrimaryKey(int iIndexNamePK, IxSqlRelation * & pRelation, int & iIndexNameFK) const;
00175    bool isPartOfPrimaryKey(int iIndexNameFK, IxDataMember * & pPrimaryKey, int & iIndexNamePK) const;
00176    void setRelationPartOfPrimaryKey(int iIndexNamePK, IxSqlRelation * pRelation, int iIndexNameFK);
00177    void setPartOfPrimaryKey(int iIndexNameFK, IxDataMember * pPrimaryKey, int iIndexNamePK);
00178 
00179    QString getName(int iIndex, const QString & sOtherName = QString()) const;
00180    QString getSqlAlias(const QString & sTable = QString(), bool bClauseWhere = false, int iIndexName = 0, qx::IxSqlQueryBuilder * pSqlQueryBuilder = NULL) const;
00181    QString getSqlType(int iIndexName = -1) const;
00182    QString getSqlTypeAndParams(int iIndexName = -1) const;
00183    QString getSqlPlaceHolder(const QString & sAppend = QString(), int iIndexName = 0, const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const;
00184    void setSqlPlaceHolder(QSqlQuery & query, void * pOwner, const QString & sAppend = QString(), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false, qx::QxCollection<QString, QVariantList> * pLstExecBatch = NULL) const;
00185    QString getSqlAliasEqualToPlaceHolder(const QString & sTable = QString(), bool bClauseWhere = false, const QString & sAppend = QString(), const QString & sSep = QString(" AND "), bool bCheckFKPartOfPK = false, qx::IxSqlQueryBuilder * pSqlQueryBuilder = NULL) const;
00186    QString getSqlNameEqualToPlaceHolder(const QString & sAppend = QString(), const QString & sSep = QString(" AND "), bool bCheckFKPartOfPK = false, qx::IxSqlQueryBuilder * pSqlQueryBuilder = NULL) const;
00187    QString getSqlTablePointNameAsAlias(const QString & sTable, const QString & sSep = QString(", "), const QString & sSuffixAlias = QString(), bool bCheckFKPartOfPK = false, const QString & sCustomAlias = QString(), qx::IxSqlQueryBuilder * pSqlQueryBuilder = NULL) const;
00188    QString getSqlName(const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false, qx::IxSqlQueryBuilder * pSqlQueryBuilder = NULL) const;
00189    QString getSqlNameAndTypeAndParams(const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const;
00190 
00191    void customGetSqlName(type_fct_sql_callback fct);
00192    void customGetSqlTablePointNameAsAlias(type_fct_sql_callback fct);
00193    void customGetSqlNameEqualToPlaceHolder(type_fct_sql_callback fct);
00194    void customGetSqlAliasEqualToPlaceHolder(type_fct_sql_callback fct);
00195    void customGetSqlAlias(type_fct_sql_callback fct);
00196 
00197    static QString getSqlFromTable(const QString & sTable, const QString & sCustomAlias = QString());
00198    static QString getSqlTableName(const QString & sTable);
00199    static QString getSqlColumnName(const QString & sColumn);
00200    static QString getSqlTableNameAlias(const QString & sTable);
00201    static QString getSqlColumnNameAlias(const QString & sColumn);
00202 
00203    virtual bool isEqual(const void * pOwner1, const void * pOwner2) const = 0;
00204    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;
00205    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;
00206 
00207    QVariant toVariant(const void * pOwner, int iIndexName = -1, qx::cvt::context::ctx_type ctx = qx::cvt::context::e_no_context) const;
00208    qx_bool fromVariant(void * pOwner, const QVariant & v, int iIndexName = -1, qx::cvt::context::ctx_type ctx = qx::cvt::context::e_no_context);
00209 
00210 #ifndef _QX_NO_JSON
00211    virtual QJsonValue toJson(const void * pOwner, const QString & sFormat) const = 0;
00212    virtual qx_bool fromJson(void * pOwner, const QJsonValue & j, const QString & sFormat) = 0;
00213 
00214    QJsonValue toJson(const void * pOwner) const;
00215    qx_bool fromJson(void * pOwner, const QJsonValue & j);
00216 #endif // _QX_NO_JSON
00217 
00218 protected:
00219 
00220    virtual qx::any getDataPtr(const void * pOwner) const = 0;
00221    virtual qx::any getDataPtr(void * pOwner) = 0;
00222    virtual void * getDataVoidPtr(const void * pOwner) const = 0;
00223    virtual void * getDataVoidPtr(void * pOwner) = 0;
00224 
00225 public:
00226 
00227    qx::any getValueAnyPtr(const void * pOwner) const    { return this->getDataPtr(pOwner); }
00228    qx::any getValueAnyPtr(void * pOwner)                { return this->getDataPtr(pOwner); }
00229    void * getValueVoidPtr(const void * pOwner) const       { return this->getDataVoidPtr(pOwner); }
00230    void * getValueVoidPtr(void * pOwner)                   { return this->getDataVoidPtr(pOwner); }
00231 
00232    template <typename T>
00233    T * getValuePtr(void * pOwner, bool * bOk = NULL)
00234    {
00235       if (bOk) { (* bOk) = false; }
00236       if (! getAccessDataPointer()) { qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "cannot access data-member pointer"); return NULL; }
00237       qx::any a = this->getDataPtr(pOwner);
00238       try { T * t = qx::any_cast<T *>(a); if (bOk) { (* bOk) = (t != NULL); }; return t; }
00239       catch (const qx::bad_any_cast & err) { Q_UNUSED(err); qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "bad any cast exception"); return NULL; }
00240       catch (...) { qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "unknown cast exception"); return NULL; }
00241    }
00242 
00243    template <typename T>
00244    T getValue(void * pOwner, bool * bOk = NULL)
00245    {
00246       if (! getAccessDataPointer()) { return qxCannotAccessDataPointer<T, 0>::getValue(this, pOwner, bOk); }
00247       T * t = this->getValuePtr<T>(pOwner, bOk);
00248       return (t ? (* t) : T());
00249    }
00250 
00251    template <typename T>
00252    bool setValue(void * pOwner, const T & val)
00253    {
00254       if (! getAccessDataPointer()) { return qxCannotAccessDataPointer<T, 0>::setValue(this, pOwner, val); }
00255       T * t = this->getValuePtr<T>(pOwner);
00256       if (t) { (* t) = val; }
00257       return (t != NULL);
00258    }
00259 
00260 private:
00261 
00262    template <typename T, int dummy>
00263    struct qxCannotAccessDataPointer
00264    {
00265       static T getValue(IxDataMember * pData, void * pOwner, bool * bOk)
00266       { Q_UNUSED(pData); Q_UNUSED(pOwner); qDebug("[QxOrm] qx::IxDataMember::qxCannotAccessDataPointer<T>::getValue() : '%s'", "type T not supported"); if (bOk) { (* bOk) = false; }; return T(); }
00267       static bool setValue(IxDataMember * pData, void * pOwner, const T & val)
00268       { Q_UNUSED(pData); Q_UNUSED(pOwner); Q_UNUSED(val); qDebug("[QxOrm] qx::IxDataMember::qxCannotAccessDataPointer<T>::setValue() : '%s'", "type T not supported"); return false; }
00269    };
00270 
00271    template <int dummy>
00272    struct qxCannotAccessDataPointer<QVariant, dummy>
00273    {
00274       static QVariant getValue(IxDataMember * pData, void * pOwner, bool * bOk)
00275       { if (bOk) { (* bOk) = (pData != NULL); }; return (pData ? pData->toVariant(pOwner, "") : QVariant()); }
00276       static bool setValue(IxDataMember * pData, void * pOwner, const QVariant & val)
00277       { return (pData ? pData->fromVariant(pOwner, val, "").getValue() : false); }
00278    };
00279 
00280    template <int dummy>
00281    struct qxCannotAccessDataPointer<QString, dummy>
00282    {
00283       static QString getValue(IxDataMember * pData, void * pOwner, bool * bOk)
00284       { if (bOk) { (* bOk) = (pData != NULL); }; return (pData ? pData->toVariant(pOwner, "").toString() : QString()); }
00285       static bool setValue(IxDataMember * pData, void * pOwner, const QString & val)
00286       { QVariant tmp(val); return (pData ? pData->fromVariant(pOwner, tmp, "").getValue() : false); }
00287    };
00288 
00289 public:
00290 
00291 #ifdef _QX_ENABLE_BOOST_SERIALIZATION
00292 
00293 #if _QX_SERIALIZE_POLYMORPHIC
00294    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::polymorphic_iarchive, boost::archive::polymorphic_oarchive)
00295 #endif // _QX_SERIALIZE_POLYMORPHIC
00296 
00297 #if _QX_SERIALIZE_BINARY
00298    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::binary_iarchive, boost::archive::binary_oarchive)
00299 #endif // _QX_SERIALIZE_BINARY
00300 
00301 #if _QX_SERIALIZE_TEXT
00302    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::text_iarchive, boost::archive::text_oarchive)
00303 #endif // _QX_SERIALIZE_TEXT
00304 
00305 #if _QX_SERIALIZE_XML
00306    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::xml_iarchive, boost::archive::xml_oarchive)
00307 #endif // _QX_SERIALIZE_XML
00308 
00309 #if _QX_SERIALIZE_PORTABLE_BINARY
00310    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(eos::portable_iarchive, eos::portable_oarchive)
00311 #endif // _QX_SERIALIZE_PORTABLE_BINARY
00312 
00313 #if _QX_SERIALIZE_WIDE_BINARY
00314    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::binary_wiarchive, boost::archive::binary_woarchive)
00315 #endif // _QX_SERIALIZE_WIDE_BINARY
00316 
00317 #if _QX_SERIALIZE_WIDE_TEXT
00318    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::text_wiarchive, boost::archive::text_woarchive)
00319 #endif // _QX_SERIALIZE_WIDE_TEXT
00320 
00321 #if _QX_SERIALIZE_WIDE_XML
00322    QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::xml_wiarchive, boost::archive::xml_woarchive)
00323 #endif // _QX_SERIALIZE_WIDE_XML
00324 
00325 #endif // _QX_ENABLE_BOOST_SERIALIZATION
00326 
00327 private:
00328 
00329 #ifdef _QX_ENABLE_BOOST_SERIALIZATION
00330    template <class Archive>
00331    void serialize(Archive & ar, const unsigned int version);
00332 #endif // _QX_ENABLE_BOOST_SERIALIZATION
00333 
00334 };
00335 
00336 typedef std::shared_ptr<IxDataMember> IxDataMember_ptr;
00337 
00342 struct IxDataMemberSqlCallbackParams
00343 {
00344 
00345    const IxDataMember * pDataMember;                  
00346    QString & sSQL;                                    
00347    QString sTable;                                    
00348    QString sSep;                                      
00349    QString sCustomAlias;                              
00350    QString sSuffixAlias;                              
00351    QString sAppend;                                   
00352    QString sOtherName;                                
00353    bool bClauseWhere;                                 
00354    bool bCheckFKPartOfPK;                             
00355    int iIndexName;                                    
00356    qx::dao::detail::IxDao_Helper * pDaoHelper;        
00357    qx::IxSqlQueryBuilder * pSqlQueryBuilder;          
00358 
00359    IxDataMemberSqlCallbackParams(const IxDataMember * p, QString & sql);
00360    ~IxDataMemberSqlCallbackParams();
00361 
00362 };
00363 
00364 } // namespace qx
00365 
00366 QX_DLL_EXPORT_INLINE_FCT bool operator< (const qx::IxDataMember & i1, const qx::IxDataMember & i2);
00367 QX_DLL_EXPORT_INLINE_FCT bool operator> (const qx::IxDataMember & i1, const qx::IxDataMember & i2);
00368 
00369 #endif // _IX_DATA_MEMBER_H_