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