QxOrm
1.5.0
C++ Object Relational Mapping library
|
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 _QX_CLASS_H_ 00033 #define _QX_CLASS_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #include <QxRegister/IxClass.h> 00047 00048 #include <QxDataMember/QxDataMemberX.h> 00049 00050 #include <QxFunction/QxFunctionInclude.h> 00051 00052 #include <QxSingleton/QxSingleton.h> 00053 00054 #include <QxTraits/get_class_name.h> 00055 #include <QxTraits/get_base_class.h> 00056 #include <QxTraits/get_primary_key.h> 00057 00058 #include <QxValidator/QxValidatorX.h> 00059 00060 namespace qx { 00061 00062 namespace trait { 00063 template <typename T> struct is_ix_persistable; 00064 } // namespace trait 00065 00070 template <class T> 00071 void register_class(T & t) { Q_UNUSED(t); qAssert(false); }; 00072 00077 template <class T> 00078 class QxClass : public IxClass, public QxSingleton< QxClass<T> > 00079 { 00080 00081 friend class QxSingleton< QxClass<T> >; 00082 00083 public: 00084 00085 typedef typename qx::trait::get_primary_key<T>::type type_primary_key; 00086 typedef typename qx::trait::get_base_class<T>::type type_base_class; 00087 typedef IxFunction::type_any_params type_any_params; 00088 00089 enum { is_valid_base_class = ((! std::is_same<type_base_class, T>::value) && (std::is_base_of<type_base_class, T>::value || std::is_same<type_base_class, qx::trait::no_base_class_defined>::value)) }; 00090 00091 protected: 00092 00093 QMutex m_oMutexClass; 00094 00095 protected: 00096 00097 QxClass() : IxClass(), QxSingleton< QxClass<T> >(QString("qx::QxClass_") + qx::trait::get_class_name<T>::get_xml_tag()) { init(); } 00098 virtual ~QxClass() { ; } 00099 00100 public: 00101 00102 QxDataMemberX<T> * dataMemberX() const { return static_cast<QxDataMemberX<T> *>(this->getDataMemberX()); } 00103 IxFunctionX * fctMemberX() const { return this->getFctMemberX(); } 00104 IxFunctionX * fctStaticX() const { return this->getFctStaticX(); } 00105 00106 IxDataMember * id(type_primary_key T::* pDataMemberId, const QString & sKey, long lVersion = 0); 00107 IxDataMember * id(const QString & sKey, long lVersion); 00108 IxDataMember * data(const QString & sKey, long lVersion); 00109 00110 template <typename V, typename U> IxDataMember * data(V U::* pData, const QString & sKey, long lVersion = 0, bool bSerialize = true, bool bDao = true); 00111 template <typename V, typename U> IxSqlRelation * relationOneToOne(V U::* pData, const QString & sKey, long lVersion = 0); 00112 template <typename V, typename U> IxSqlRelation * relationManyToOne(V U::* pData, const QString & sKey, long lVersion = 0); 00113 template <typename V, typename U> IxSqlRelation * relationOneToMany(V U::* pData, const QString & sKey, const QString & sForeignKey, long lVersion = 0); 00114 template <typename V, typename U> IxSqlRelation * relationManyToMany(V U::* pData, const QString & sKey, const QString & sExtraTable, const QString & sForeignKeyOwner, const QString & sForeignKeyDataType, long lVersion = 0); 00115 00116 template <typename V, typename U> IxDataMember * pimpl(V U::* pData, const QString & sKey = QString("_PIMPL_")); 00117 template <typename U> IxDataMember * id(type_primary_key U::* pDataMemberId, const QString & sKey, long lVersion, IxDataMember * pImpl); 00118 template <typename V, typename U> IxDataMember * data(V U::* pData, const QString & sKey, long lVersion, bool bSerialize, bool bDao, IxDataMember * pImpl); 00119 template <typename V, typename U> IxSqlRelation * relationOneToOne(V U::* pData, const QString & sKey, long lVersion, IxDataMember * pImpl); 00120 template <typename V, typename U> IxSqlRelation * relationManyToOne(V U::* pData, const QString & sKey, long lVersion, IxDataMember * pImpl); 00121 template <typename V, typename U> IxSqlRelation * relationOneToMany(V U::* pData, const QString & sKey, const QString & sForeignKey, long lVersion, IxDataMember * pImpl); 00122 template <typename V, typename U> IxSqlRelation * relationManyToMany(V U::* pData, const QString & sKey, const QString & sExtraTable, const QString & sForeignKeyOwner, const QString & sForeignKeyDataType, long lVersion, IxDataMember * pImpl); 00123 00124 template <typename R> IxFunction * fct_0(const typename QxFunction_0<T, R>::type_fct & fct, const QString & sKey); 00125 template <typename R, typename P1> IxFunction * fct_1(const typename QxFunction_1<T, R, P1>::type_fct & fct, const QString & sKey); 00126 template <typename R, typename P1, typename P2> IxFunction * fct_2(const typename QxFunction_2<T, R, P1, P2>::type_fct & fct, const QString & sKey); 00127 template <typename R, typename P1, typename P2, typename P3> IxFunction * fct_3(const typename QxFunction_3<T, R, P1, P2, P3>::type_fct & fct, const QString & sKey); 00128 template <typename R, typename P1, typename P2, typename P3, typename P4> IxFunction * fct_4(const typename QxFunction_4<T, R, P1, P2, P3, P4>::type_fct & fct, const QString & sKey); 00129 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5> IxFunction * fct_5(const typename QxFunction_5<T, R, P1, P2, P3, P4, P5>::type_fct & fct, const QString & sKey); 00130 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> IxFunction * fct_6(const typename QxFunction_6<T, R, P1, P2, P3, P4, P5, P6>::type_fct & fct, const QString & sKey); 00131 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> IxFunction * fct_7(const typename QxFunction_7<T, R, P1, P2, P3, P4, P5, P6, P7>::type_fct & fct, const QString & sKey); 00132 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> IxFunction * fct_8(const typename QxFunction_8<T, R, P1, P2, P3, P4, P5, P6, P7, P8>::type_fct & fct, const QString & sKey); 00133 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> IxFunction * fct_9(const typename QxFunction_9<T, R, P1, P2, P3, P4, P5, P6, P7, P8, P9>::type_fct & fct, const QString & sKey); 00134 00135 template <typename R> IxFunction * fctStatic_0(const typename QxFunction_0<void, R>::type_fct & fct, const QString & sKey); 00136 template <typename R, typename P1> IxFunction * fctStatic_1(const typename QxFunction_1<void, R, P1>::type_fct & fct, const QString & sKey); 00137 template <typename R, typename P1, typename P2> IxFunction * fctStatic_2(const typename QxFunction_2<void, R, P1, P2>::type_fct & fct, const QString & sKey); 00138 template <typename R, typename P1, typename P2, typename P3> IxFunction * fctStatic_3(const typename QxFunction_3<void, R, P1, P2, P3>::type_fct & fct, const QString & sKey); 00139 template <typename R, typename P1, typename P2, typename P3, typename P4> IxFunction * fctStatic_4(const typename QxFunction_4<void, R, P1, P2, P3, P4>::type_fct & fct, const QString & sKey); 00140 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5> IxFunction * fctStatic_5(const typename QxFunction_5<void, R, P1, P2, P3, P4, P5>::type_fct & fct, const QString & sKey); 00141 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> IxFunction * fctStatic_6(const typename QxFunction_6<void, R, P1, P2, P3, P4, P5, P6>::type_fct & fct, const QString & sKey); 00142 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> IxFunction * fctStatic_7(const typename QxFunction_7<void, R, P1, P2, P3, P4, P5, P6, P7>::type_fct & fct, const QString & sKey); 00143 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> IxFunction * fctStatic_8(const typename QxFunction_8<void, R, P1, P2, P3, P4, P5, P6, P7, P8>::type_fct & fct, const QString & sKey); 00144 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> IxFunction * fctStatic_9(const typename QxFunction_9<void, R, P1, P2, P3, P4, P5, P6, P7, P8, P9>::type_fct & fct, const QString & sKey); 00145 00146 static qx_bool invoke(const QString & sKey, T * pOwner, const QString & params = QString(), qx::any * ret = NULL) { IxFunctionX * pFctX = QxClass<T>::getSingleton()->fctMemberX(); IxFunction_ptr pFct = ((pFctX && pFctX->exist(sKey)) ? pFctX->getByKey(sKey) : IxFunction_ptr()); return invokeHelper<T, type_base_class, 0>::invoke(sKey, pOwner, params, ret, pFct); } 00147 static qx_bool invoke(const QString & sKey, T * pOwner, const type_any_params & params, qx::any * ret = NULL) { IxFunctionX * pFctX = QxClass<T>::getSingleton()->fctMemberX(); IxFunction_ptr pFct = ((pFctX && pFctX->exist(sKey)) ? pFctX->getByKey(sKey) : IxFunction_ptr()); return invokeHelper<T, type_base_class, 0>::invoke(sKey, pOwner, params, ret, pFct); } 00148 static qx_bool invokeStatic(const QString & sKey, const QString & params = QString(), qx::any * ret = NULL) { IxFunctionX * pFctX = QxClass<T>::getSingleton()->fctStaticX(); IxFunction_ptr pFct = ((pFctX && pFctX->exist(sKey)) ? pFctX->getByKey(sKey) : IxFunction_ptr()); return invokeHelper<T, type_base_class, 0>::invoke(sKey, params, ret, pFct); } 00149 static qx_bool invokeStatic(const QString & sKey, const type_any_params & params, qx::any * ret = NULL) { IxFunctionX * pFctX = QxClass<T>::getSingleton()->fctStaticX(); IxFunction_ptr pFct = ((pFctX && pFctX->exist(sKey)) ? pFctX->getByKey(sKey) : IxFunction_ptr()); return invokeHelper<T, type_base_class, 0>::invoke(sKey, params, ret, pFct); } 00150 00151 virtual bool isAbstract() const 00152 { return std::is_abstract<T>::value; } 00153 00154 virtual bool implementIxPersistable() const 00155 { return implementIxPersistable_Helper<T, 0>::get(); } 00156 00157 #ifndef _QX_NO_RTTI 00158 virtual const std::type_info & typeInfo() const 00159 { return typeid(T); } 00160 #endif // _QX_NO_RTTI 00161 00162 virtual IxClass * getBaseClass() const 00163 { return (std::is_same<type_base_class, qx::trait::no_base_class_defined>::value ? NULL : QxClass<type_base_class>::getSingleton()); } 00164 00165 #if _QX_SUPPORT_COVARIANT_RETURN_TYPE 00166 virtual QxValidatorX<T> * getAllValidator() 00167 { 00168 if (! this->getAllValidatorRef()) { this->getAllValidatorRef().reset(new QxValidatorX<T>()); IxClass::getAllValidator(); } 00169 return static_cast<QxValidatorX<T> *>(this->getAllValidatorRef().get()); 00170 } 00171 #else // _QX_SUPPORT_COVARIANT_RETURN_TYPE 00172 virtual IxValidatorX * getAllValidator() 00173 { 00174 if (! this->getAllValidatorRef()) { this->getAllValidatorRef().reset(new QxValidatorX<T>()); IxClass::getAllValidator(); } 00175 return this->getAllValidatorRef().get(); 00176 } 00177 #endif // _QX_SUPPORT_COVARIANT_RETURN_TYPE 00178 00179 private: 00180 00181 void init(); 00182 IxFunction * insertFct(IxFunction_ptr pFct, const QString & sKey); 00183 IxFunction * insertFctStatic(IxFunction_ptr pFct, const QString & sKey); 00184 00185 void registerClass() { qx::register_class< QxClass<T> >(* this); } 00186 00187 void beforeRegisterClass() 00188 { 00189 static_assert(is_valid_base_class, "is_valid_base_class"); 00190 QMutexLocker locker(& m_oMutexClass); 00191 QxClass<type_base_class>::getSingleton(); 00192 bool bNeedReg = (! this->isRegistered()); 00193 this->setRegistered(true); 00194 if (bNeedReg) { registerClass(); } 00195 } 00196 00197 template <typename U, typename V, int dummy> 00198 struct invokeHelper 00199 { 00200 static qx_bool invoke(const QString & sKey, U * pOwner, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00201 { return ((pOwner && pFct) ? pFct->invoke(pOwner, params, ret) : QxClass<V>::invoke(sKey, static_cast<V *>(pOwner), params, ret)); } 00202 00203 static qx_bool invoke(const QString & sKey, U * pOwner, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00204 { return ((pOwner && pFct) ? pFct->invoke(pOwner, params, ret) : QxClass<V>::invoke(sKey, static_cast<V *>(pOwner), params, ret)); } 00205 00206 static qx_bool invoke(const QString & sKey, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00207 { return (pFct ? pFct->invoke(params, ret) : QxClass<V>::invokeStatic(sKey, params, ret)); } 00208 00209 static qx_bool invoke(const QString & sKey, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00210 { return (pFct ? pFct->invoke(params, ret) : QxClass<V>::invokeStatic(sKey, params, ret)); } 00211 }; 00212 00213 template <typename U, int dummy> 00214 struct invokeHelper<U, qx::trait::no_base_class_defined, dummy> 00215 { 00216 static qx_bool invoke(const QString & sKey, U * pOwner, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00217 { Q_UNUSED(sKey); return ((pOwner && pFct) ? pFct->invoke(pOwner, params, ret) : qx_bool(false)); } 00218 00219 static qx_bool invoke(const QString & sKey, U * pOwner, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00220 { Q_UNUSED(sKey); return ((pOwner && pFct) ? pFct->invoke(pOwner, params, ret) : qx_bool(false)); } 00221 00222 static qx_bool invoke(const QString & sKey, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00223 { Q_UNUSED(sKey); return (pFct ? pFct->invoke(params, ret) : qx_bool(false)); } 00224 00225 static qx_bool invoke(const QString & sKey, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00226 { Q_UNUSED(sKey); return (pFct ? pFct->invoke(params, ret) : qx_bool(false)); } 00227 }; 00228 00229 template <int dummy> 00230 struct invokeHelper<qx::trait::no_base_class_defined, qx::trait::no_base_class_defined, dummy> 00231 { 00232 static qx_bool invoke(const QString & sKey, qx::trait::no_base_class_defined * pOwner, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00233 { Q_UNUSED(sKey); Q_UNUSED(pOwner); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00234 00235 static qx_bool invoke(const QString & sKey, qx::trait::no_base_class_defined * pOwner, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00236 { Q_UNUSED(sKey); Q_UNUSED(pOwner); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00237 00238 static qx_bool invoke(const QString & sKey, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00239 { Q_UNUSED(sKey); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00240 00241 static qx_bool invoke(const QString & sKey, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00242 { Q_UNUSED(sKey); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00243 }; 00244 00245 template <int dummy> 00246 struct invokeHelper<QObject, qx::trait::no_base_class_defined, dummy> 00247 { 00248 static qx_bool invoke(const QString & sKey, QObject * pOwner, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00249 { Q_UNUSED(sKey); Q_UNUSED(pOwner); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00250 00251 static qx_bool invoke(const QString & sKey, QObject * pOwner, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00252 { Q_UNUSED(sKey); Q_UNUSED(pOwner); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00253 00254 static qx_bool invoke(const QString & sKey, const QString & params, qx::any * ret, IxFunction_ptr pFct) 00255 { Q_UNUSED(sKey); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00256 00257 static qx_bool invoke(const QString & sKey, const type_any_params & params, qx::any * ret, IxFunction_ptr pFct) 00258 { Q_UNUSED(sKey); Q_UNUSED(params); Q_UNUSED(ret); Q_UNUSED(pFct); return qx_bool(false); } 00259 }; 00260 00261 private: 00262 00263 template <typename U, int dummy> 00264 struct implementIxPersistable_Helper 00265 { static bool get() { return qx::trait::is_ix_persistable<U>::value; } }; 00266 00267 template <int dummy> 00268 struct implementIxPersistable_Helper<qx::trait::no_base_class_defined, dummy> 00269 { static bool get() { return false; } }; 00270 00271 template <int dummy> 00272 struct implementIxPersistable_Helper<QObject, dummy> 00273 { static bool get() { return false; } }; 00274 00275 }; 00276 00277 } // namespace qx 00278 00279 #include "../../inl/QxRegister/QxClass.inl" 00280 00281 #endif // _QX_CLASS_H_