![]() |
QxOrm
1.4.3
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://www.qxorm.com/ 00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com) 00005 ** 00006 ** This file is part of the QxOrm library 00007 ** 00008 ** This software is provided 'as-is', without any express or implied 00009 ** warranty. In no event will the authors be held liable for any 00010 ** damages arising from the use of this software 00011 ** 00012 ** Commercial Usage 00013 ** Licensees holding valid commercial QxOrm licenses may use this file in 00014 ** accordance with the commercial license agreement provided with the 00015 ** Software or, alternatively, in accordance with the terms contained in 00016 ** a written agreement between you and Lionel Marty 00017 ** 00018 ** GNU General Public License Usage 00019 ** Alternatively, this file may be used under the terms of the GNU 00020 ** General Public License version 3.0 as published by the Free Software 00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the 00022 ** packaging of this file. Please review the following information to 00023 ** ensure the GNU General Public License version 3.0 requirements will be 00024 ** met : http://www.gnu.org/copyleft/gpl.html 00025 ** 00026 ** If you are unsure which license is appropriate for your use, or 00027 ** if you have questions regarding the use of this file, please contact : 00028 ** contact@qxorm.com 00029 ** 00030 ****************************************************************************/ 00031 00032 #ifndef _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 <boost/any.hpp> 00052 00053 #ifndef _QX_NO_JSON 00054 #include <QtCore/qjsonvalue.h> 00055 #endif // _QX_NO_JSON 00056 00057 #include <QxCommon/QxBool.h> 00058 #include <QxCommon/QxPropertyBag.h> 00059 00060 #include <QxSerialize/boost/QxSerializeInclude.h> 00061 00062 #include <QxDao/IxSqlRelation.h> 00063 00064 #include <QxConvert/QxConvert.h> 00065 00066 #ifdef _MSC_VER 00067 #pragma warning(pop) 00068 #endif // _MSC_VER 00069 00070 #define QX_CONSTRUCT_IX_DATA_MEMBER() \ 00071 m_iPrecision(6), m_iMinLength(-1), m_iMaxLength(-1), m_bRequired(false), \ 00072 m_bReadOnly(false), m_bAutoIncrement(false), m_bNotNull(false), \ 00073 m_bIsPrimaryKey(false), m_bAccessDataPointer(false), m_bIndex(false), \ 00074 m_bUnique(false), m_pName(NULL), m_pParent(NULL) 00075 00076 #define QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(ArchiveInput, ArchiveOutput) \ 00077 virtual void toArchive(const void * pOwner, ArchiveOutput & ar) const = 0; \ 00078 virtual void fromArchive(void * pOwner, ArchiveInput & ar) = 0; 00079 00080 namespace qx { 00081 00082 class IxDataMemberX; 00083 00088 class QX_DLL_EXPORT IxDataMember : public qx::QxPropertyBag 00089 { 00090 00091 public: 00092 00093 typedef QMap<int, QPair<IxSqlRelation *, int> > type_fk_part_of_pk; 00094 typedef boost::scoped_ptr<type_fk_part_of_pk> type_fk_part_of_pk_ptr; 00095 typedef QMap<int, QPair<IxDataMember *, int> > type_part_of_pk; 00096 typedef boost::scoped_ptr<type_part_of_pk> type_part_of_pk_ptr; 00097 00098 protected: 00099 00100 QString m_sKey; 00101 QString m_sName; 00102 QString m_sNameParent; 00103 QString m_sDescription; 00104 QString m_sFormat; 00105 QString m_sSqlType; 00106 QString m_sSqlAlias; 00107 long m_lVersion; 00108 bool m_bSerialize; 00109 bool m_bDao; 00110 QVariant m_vDefaultValue; 00111 QVariant m_vMinValue; 00112 QVariant m_vMaxValue; 00113 int m_iPrecision; 00114 int m_iMinLength; 00115 int m_iMaxLength; 00116 bool m_bRequired; 00117 bool m_bReadOnly; 00118 bool m_bAutoIncrement; 00119 bool m_bNotNull; 00120 bool m_bIsPrimaryKey; 00121 bool m_bAccessDataPointer; 00122 bool m_bIndex; 00123 bool m_bUnique; 00124 00125 QByteArray m_byteName; 00126 const char * m_pName; 00127 QStringList m_lstNames; 00128 00129 boost::scoped_ptr<IxSqlRelation> m_pSqlRelation; 00130 IxDataMemberX * m_pParent; 00131 00132 type_fk_part_of_pk_ptr m_pListRelationPartOfPrimaryKey; 00133 type_part_of_pk_ptr m_pListPartOfPrimaryKey; 00134 00135 public: 00136 00137 IxDataMember(const QString & sKey) : qx::QxPropertyBag(), m_sKey(sKey), m_lVersion(-1), m_bSerialize(true), m_bDao(true), QX_CONSTRUCT_IX_DATA_MEMBER() { qAssert(! m_sKey.isEmpty()); updateNamePtr(); } 00138 IxDataMember(const QString & sKey, long lVersion, bool bSerialize, bool bDao) : qx::QxPropertyBag(), m_sKey(sKey), m_lVersion(lVersion), m_bSerialize(bSerialize), m_bDao(bDao), QX_CONSTRUCT_IX_DATA_MEMBER() { qAssert(! m_sKey.isEmpty()); updateNamePtr(); } 00139 virtual ~IxDataMember() = 0; 00140 00141 inline QString getKey() const { return m_sKey; } 00142 inline QString getName() const { return (m_sName.isEmpty() ? m_sKey : m_sName); } 00143 inline int getNameCount() const { return m_lstNames.count(); } 00144 inline QString getNameParent() const { return m_sNameParent; } 00145 inline const char * getNamePtr() const { return m_pName; } 00146 inline QString getDescription() const { return m_sDescription; } 00147 inline QString getFormat() const { return m_sFormat; } 00148 inline long getVersion() const { return m_lVersion; } 00149 inline bool getSerialize() const { return m_bSerialize; } 00150 inline bool getDao() const { return m_bDao; } 00151 inline QVariant getDefaultValue() const { return m_vDefaultValue; } 00152 inline QVariant getMinValue() const { return m_vMinValue; } 00153 inline QVariant getMaxValue() const { return m_vMaxValue; } 00154 inline int getPrecision() const { return m_iPrecision; } 00155 inline int getMinLength() const { return m_iMinLength; } 00156 inline int getMaxLength() const { return m_iMaxLength; } 00157 inline bool getRequired() const { return m_bRequired; } 00158 inline bool getReadOnly() const { return m_bReadOnly; } 00159 inline bool getAutoIncrement() const { return m_bAutoIncrement; } 00160 inline bool getNotNull() const { return m_bNotNull; } 00161 inline bool getIsPrimaryKey() const { return m_bIsPrimaryKey; } 00162 inline bool getIsIndex() const { return m_bIndex; } 00163 inline bool getIsUnique() const { return m_bUnique; } 00164 inline IxDataMemberX * getParent() const { return m_pParent; } 00165 inline IxSqlRelation * getSqlRelation() const { return m_pSqlRelation.get(); } 00166 inline bool hasSqlRelation() const { return (m_pSqlRelation.get() != NULL); } 00167 00168 inline void setName(const QString & sName) { m_sName = sName; updateNamePtr(); } 00169 inline void setNameParent(const QString & sName) { m_sNameParent = sName; } 00170 inline void setDescription(const QString & sDesc) { m_sDescription = sDesc; } 00171 inline void setFormat(const QString & sFormat) { m_sFormat = sFormat; } 00172 inline void setSqlType(const QString & sSqlType) { m_sSqlType = sSqlType; } 00173 inline void setSqlAlias(const QString & sSqlAlias) { m_sSqlAlias = sSqlAlias; } 00174 inline void setVersion(long lVersion) { m_lVersion = lVersion; } 00175 inline void setSerialize(bool bSerialize) { m_bSerialize = bSerialize; } 00176 inline void setDao(bool bDao) { m_bDao = bDao; } 00177 inline void setDefaultValue(const QVariant & var) { m_vDefaultValue = var; } 00178 inline void setPrecision(int iPrecision) { m_iPrecision = iPrecision; } 00179 inline void setRequired(bool bRequired) { m_bRequired = bRequired; } 00180 inline void setReadOnly(bool bReadOnly) { m_bReadOnly = bReadOnly; } 00181 inline void setAutoIncrement(bool bAutoIncrement) { m_bAutoIncrement = bAutoIncrement; } 00182 inline void setIsPrimaryKey(bool bIsPrimaryKey) { m_bIsPrimaryKey = bIsPrimaryKey; } 00183 inline void setIsIndex(bool bIsIndex) { m_bIndex = bIsIndex; } 00184 inline void setIsUnique(bool bIsUnique) { m_bUnique = bIsUnique; } 00185 inline void setParent(IxDataMemberX * pParent) { m_pParent = pParent; } 00186 inline void setSqlRelation(IxSqlRelation * pSqlRelation) { m_pSqlRelation.reset(pSqlRelation); } 00187 00188 void setMinValue(long lMinValue, const QString & sMessage = QString()); 00189 void setMinValue(double dMinValue, const QString & sMessage = QString()); 00190 void setMaxValue(long lMaxValue, const QString & sMessage = QString()); 00191 void setMaxValue(double dMaxValue, const QString & sMessage = QString()); 00192 void setMinLength(int iMinLength, const QString & sMessage = QString()); 00193 void setMaxLength(int iMaxLength, const QString & sMessage = QString()); 00194 void setNotNull(bool bNotNull, const QString & sMessage = QString()); 00195 00196 bool isThereRelationPartOfPrimaryKey(int iIndexNamePK, IxSqlRelation * & pRelation, int & iIndexNameFK) const; 00197 bool isPartOfPrimaryKey(int iIndexNameFK, IxDataMember * & pPrimaryKey, int & iIndexNamePK) const; 00198 void setRelationPartOfPrimaryKey(int iIndexNamePK, IxSqlRelation * pRelation, int iIndexNameFK); 00199 void setPartOfPrimaryKey(int iIndexNameFK, IxDataMember * pPrimaryKey, int iIndexNamePK); 00200 00201 QString getName(int iIndex, const QString & sOtherName = QString()) const; 00202 QString getSqlAlias(const QString & sTable = QString(), bool bClauseWhere = false, int iIndexName = 0) const; 00203 QString getSqlType(int iIndexName = -1) const; 00204 QString getSqlTypeAndParams(int iIndexName = -1) const; 00205 QString getSqlPlaceHolder(const QString & sAppend = QString(), int iIndexName = 0, const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const; 00206 void setSqlPlaceHolder(QSqlQuery & query, void * pOwner, const QString & sAppend = QString(), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const; 00207 QString getSqlAliasEqualToPlaceHolder(const QString & sTable = QString(), bool bClauseWhere = false, const QString & sAppend = QString(), const QString & sSep = QString(" AND "), bool bCheckFKPartOfPK = false) const; 00208 QString getSqlNameEqualToPlaceHolder(const QString & sAppend = QString(), const QString & sSep = QString(" AND "), bool bCheckFKPartOfPK = false) const; 00209 QString getSqlTablePointNameAsAlias(const QString & sTable, const QString & sSep = QString(", "), const QString & sSuffixAlias = QString(), bool bCheckFKPartOfPK = false) const; 00210 QString getSqlName(const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const; 00211 QString getSqlNameAndTypeAndParams(const QString & sSep = QString(", "), const QString & sOtherName = QString(), bool bCheckFKPartOfPK = false) const; 00212 00213 static QString getSqlFromTable(const QString & sTable); 00214 00215 virtual bool isEqual(const void * pOwner1, const void * pOwner2) const = 0; 00216 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; 00217 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; 00218 00219 inline QVariant toVariant(const void * pOwner, int iIndexName = -1, qx::cvt::context::ctx_type ctx = qx::cvt::context::e_no_context) const { return this->toVariant(pOwner, m_sFormat, iIndexName, ctx); } 00220 inline qx_bool fromVariant(void * pOwner, const QVariant & v, int iIndexName = -1, qx::cvt::context::ctx_type ctx = qx::cvt::context::e_no_context) { return this->fromVariant(pOwner, v, m_sFormat, iIndexName, ctx); } 00221 00222 #ifndef _QX_NO_JSON 00223 virtual QJsonValue toJson(const void * pOwner, const QString & sFormat) const = 0; 00224 virtual qx_bool fromJson(void * pOwner, const QJsonValue & j, const QString & sFormat) = 0; 00225 00226 inline QJsonValue toJson(const void * pOwner) const { return this->toJson(pOwner, m_sFormat); } 00227 inline qx_bool fromJson(void * pOwner, const QJsonValue & j) { return this->fromJson(pOwner, j, m_sFormat); } 00228 #endif // _QX_NO_JSON 00229 00230 protected: 00231 00232 virtual boost::any getDataPtr(const void * pOwner) const = 0; 00233 virtual boost::any getDataPtr(void * pOwner) = 0; 00234 virtual void * getDataVoidPtr(const void * pOwner) const = 0; 00235 virtual void * getDataVoidPtr(void * pOwner) = 0; 00236 00237 public: 00238 00239 inline boost::any getValueAnyPtr(const void * pOwner) const { return this->getDataPtr(pOwner); } 00240 inline boost::any getValueAnyPtr(void * pOwner) { return this->getDataPtr(pOwner); } 00241 inline void * getValueVoidPtr(const void * pOwner) const { return this->getDataVoidPtr(pOwner); } 00242 inline void * getValueVoidPtr(void * pOwner) { return this->getDataVoidPtr(pOwner); } 00243 00244 template <typename T> 00245 T * getValuePtr(void * pOwner, bool * bOk = NULL) 00246 { 00247 if (bOk) { (* bOk) = false; } 00248 if (! m_bAccessDataPointer) { qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "cannot access data-member pointer"); return NULL; } 00249 boost::any a = this->getDataPtr(pOwner); 00250 try { T * t = boost::any_cast<T *>(a); if (bOk) { (* bOk) = (t != NULL); }; return t; } 00251 catch (const boost::bad_any_cast & err) { Q_UNUSED(err); qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "bad any cast exception"); return NULL; } 00252 catch (...) { qDebug("[QxOrm] qx::IxDataMember::getValuePtr<T>() : '%s'", "unknown cast exception"); return NULL; } 00253 } 00254 00255 template <typename T> 00256 T getValue(void * pOwner, bool * bOk = NULL) 00257 { 00258 if (! m_bAccessDataPointer) { return qxCannotAccessDataPointer<T, 0>::getValue(this, pOwner, bOk); } 00259 T * t = this->getValuePtr<T>(pOwner, bOk); 00260 return (t ? (* t) : T()); 00261 } 00262 00263 template <typename T> 00264 bool setValue(void * pOwner, const T & val) 00265 { 00266 if (! m_bAccessDataPointer) { return qxCannotAccessDataPointer<T, 0>::setValue(this, pOwner, val); } 00267 T * t = this->getValuePtr<T>(pOwner); 00268 if (t) { (* t) = val; } 00269 return (t != NULL); 00270 } 00271 00272 private: 00273 00274 template <typename T, int dummy> 00275 struct qxCannotAccessDataPointer 00276 { 00277 static inline T getValue(IxDataMember * pData, void * pOwner, bool * bOk) 00278 { Q_UNUSED(pData); Q_UNUSED(pOwner); qDebug("[QxOrm] qx::IxDataMember::qxCannotAccessDataPointer<T>::getValue() : '%s'", "type T not supported"); if (bOk) { (* bOk) = false; }; return T(); } 00279 static inline bool setValue(IxDataMember * pData, void * pOwner, const T & val) 00280 { Q_UNUSED(pData); Q_UNUSED(pOwner); Q_UNUSED(val); qDebug("[QxOrm] qx::IxDataMember::qxCannotAccessDataPointer<T>::setValue() : '%s'", "type T not supported"); return false; } 00281 }; 00282 00283 template <int dummy> 00284 struct qxCannotAccessDataPointer<QVariant, dummy> 00285 { 00286 static inline QVariant getValue(IxDataMember * pData, void * pOwner, bool * bOk) 00287 { if (bOk) { (* bOk) = (pData != NULL); }; return (pData ? pData->toVariant(pOwner, "") : QVariant()); } 00288 static inline bool setValue(IxDataMember * pData, void * pOwner, const QVariant & val) 00289 { return (pData ? pData->fromVariant(pOwner, val, "").getValue() : false); } 00290 }; 00291 00292 template <int dummy> 00293 struct qxCannotAccessDataPointer<QString, dummy> 00294 { 00295 static inline QString getValue(IxDataMember * pData, void * pOwner, bool * bOk) 00296 { if (bOk) { (* bOk) = (pData != NULL); }; return (pData ? pData->toVariant(pOwner, "").toString() : QString()); } 00297 static inline bool setValue(IxDataMember * pData, void * pOwner, const QString & val) 00298 { QVariant tmp(val); return (pData ? pData->fromVariant(pOwner, tmp, "").getValue() : false); } 00299 }; 00300 00301 public: 00302 00303 #ifdef _QX_ENABLE_BOOST_SERIALIZATION 00304 00305 #if _QX_SERIALIZE_POLYMORPHIC 00306 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::polymorphic_iarchive, boost::archive::polymorphic_oarchive) 00307 #endif // _QX_SERIALIZE_POLYMORPHIC 00308 00309 #if _QX_SERIALIZE_BINARY 00310 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::binary_iarchive, boost::archive::binary_oarchive) 00311 #endif // _QX_SERIALIZE_BINARY 00312 00313 #if _QX_SERIALIZE_TEXT 00314 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::text_iarchive, boost::archive::text_oarchive) 00315 #endif // _QX_SERIALIZE_TEXT 00316 00317 #if _QX_SERIALIZE_XML 00318 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::xml_iarchive, boost::archive::xml_oarchive) 00319 #endif // _QX_SERIALIZE_XML 00320 00321 #if _QX_SERIALIZE_PORTABLE_BINARY 00322 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(eos::portable_iarchive, eos::portable_oarchive) 00323 #endif // _QX_SERIALIZE_PORTABLE_BINARY 00324 00325 #if _QX_SERIALIZE_WIDE_BINARY 00326 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::binary_wiarchive, boost::archive::binary_woarchive) 00327 #endif // _QX_SERIALIZE_WIDE_BINARY 00328 00329 #if _QX_SERIALIZE_WIDE_TEXT 00330 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::text_wiarchive, boost::archive::text_woarchive) 00331 #endif // _QX_SERIALIZE_WIDE_TEXT 00332 00333 #if _QX_SERIALIZE_WIDE_XML 00334 QX_IX_DATA_MEMBER_PURE_VIRTUAL_ARCHIVE(boost::archive::xml_wiarchive, boost::archive::xml_woarchive) 00335 #endif // _QX_SERIALIZE_WIDE_XML 00336 00337 #endif // _QX_ENABLE_BOOST_SERIALIZATION 00338 00339 private: 00340 00341 inline void updateNamePtr() 00342 { 00343 QString sNamePtr = (m_sName.isEmpty() ? m_sKey : m_sName); 00344 sNamePtr.replace("|", "-"); // valid xml tag 00345 m_byteName = sNamePtr.toLatin1(); 00346 m_pName = m_byteName.constData(); 00347 m_lstNames = (m_sName.isEmpty() ? m_sKey.split("|") : m_sName.split("|")); 00348 } 00349 00350 #ifdef _QX_ENABLE_BOOST_SERIALIZATION 00351 template <class Archive> 00352 void serialize(Archive & ar, const unsigned int version); 00353 #endif // _QX_ENABLE_BOOST_SERIALIZATION 00354 00355 }; 00356 00357 typedef qx_shared_ptr<IxDataMember> IxDataMember_ptr; 00358 00359 } // namespace qx 00360 00361 QX_DLL_EXPORT_INLINE_FCT inline bool operator< (const qx::IxDataMember & i1, const qx::IxDataMember & i2); 00362 QX_DLL_EXPORT_INLINE_FCT inline bool operator> (const qx::IxDataMember & i1, const qx::IxDataMember & i2); 00363 00364 #endif // _IX_DATA_MEMBER_H_