QxOrm  1.2.4
C++ Object Relational Mapping library
QxClass.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** http://www.qxorm.com/
00004 ** http://sourceforge.net/projects/qxorm/
00005 ** Original file by Lionel Marty
00006 **
00007 ** This file is part of the QxOrm library
00008 **
00009 ** This software is provided 'as-is', without any express or implied
00010 ** warranty. In no event will the authors be held liable for any
00011 ** damages arising from the use of this software.
00012 **
00013 ** GNU Lesser General Public License Usage
00014 ** This file must be used under the terms of the GNU Lesser
00015 ** General Public License version 2.1 as published by the Free Software
00016 ** Foundation and appearing in the file 'license.lgpl.txt' included in the
00017 ** packaging of this file.  Please review the following information to
00018 ** ensure the GNU Lesser General Public License version 2.1 requirements
00019 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00020 **
00021 ** If you have questions regarding the use of this file, please contact :
00022 ** contact@qxorm.com
00023 **
00024 ****************************************************************************/
00025 
00026 #ifndef _QX_CLASS_H_
00027 #define _QX_CLASS_H_
00028 
00029 #ifdef _MSC_VER
00030 #pragma once
00031 #endif
00032 
00040 #include <boost/static_assert.hpp>
00041 #include <boost/type_traits/is_same.hpp>
00042 #include <boost/type_traits/is_base_of.hpp>
00043 #include <boost/type_traits/is_abstract.hpp>
00044 #include <boost/serialization/version.hpp>
00045 
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 = ((! 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)) };
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    inline QxDataMemberX<T> * dataMemberX() const   { return static_cast<QxDataMemberX<T> *>(m_pDataMemberX); }
00103    inline IxFunctionX * fctMemberX() const         { return m_pFctMemberX.get(); }
00104 
00105    IxDataMember * id(type_primary_key T::* pDataMemberId, const QString & sKey);
00106    IxDataMember * id(type_primary_key T::* pDataMemberId, const QString & sKey, long lVersion);
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);
00111    template <typename V, typename U> IxDataMember * data(V U::* pData, const QString & sKey, long lVersion);
00112    template <typename V, typename U> IxDataMember * data(V U::* pData, const QString & sKey, long lVersion, bool bSerialize);
00113    template <typename V, typename U> IxDataMember * data(V U::* pData, const QString & sKey, long lVersion, bool bSerialize, bool bDao);
00114 
00115    template <typename V, typename U> IxSqlRelation * relationOneToOne(V U::* pData, const QString & sKey);
00116    template <typename V, typename U> IxSqlRelation * relationOneToOne(V U::* pData, const QString & sKey, long lVersion);
00117    template <typename V, typename U> IxSqlRelation * relationManyToOne(V U::* pData, const QString & sKey);
00118    template <typename V, typename U> IxSqlRelation * relationManyToOne(V U::* pData, const QString & sKey, long lVersion);
00119    template <typename V, typename U> IxSqlRelation * relationOneToMany(V U::* pData, const QString & sKey, const QString & sForeignKey);
00120    template <typename V, typename U> IxSqlRelation * relationOneToMany(V U::* pData, const QString & sKey, const QString & sForeignKey, long lVersion);
00121    template <typename V, typename U> IxSqlRelation * relationManyToMany(V U::* pData, const QString & sKey, const QString & sExtraTable, const QString & sForeignKeyOwner, const QString & sForeignKeyDataType);
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);
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    static qx_bool invoke(const QString & sKey, T * pOwner, const QString & params = QString(), boost::any * ret = NULL) { return QxClass<T>::getSingleton()->invokeHelper(sKey, pOwner, params, ret); }
00136    static qx_bool invoke(const QString & sKey, T * pOwner, const type_any_params & params, boost::any * ret = NULL)     { return QxClass<T>::getSingleton()->invokeHelper(sKey, pOwner, params, ret); }
00137 
00138    virtual bool isAbstract() const
00139    { return boost::is_abstract<T>::value; }
00140 
00141    virtual bool implementIxPersistable() const
00142    { return implementIxPersistable_Helper<T, 0>::get(); }
00143 
00144    virtual const std::type_info & typeInfo() const
00145    { return typeid(T); }
00146 
00147    virtual IxClass * getBaseClass() const
00148    { return (boost::is_same<type_base_class, qx::trait::no_base_class_defined>::value ? NULL : QxClass<type_base_class>::getSingleton()); }
00149 
00150 #if _QX_SUPPORT_COVARIANT_RETURN_TYPE
00151    virtual QxValidatorX<T> * getAllValidator()
00152    {
00153       if (! m_pAllValidator) { m_pAllValidator.reset(new QxValidatorX<T>()); IxClass::getAllValidator(); }
00154       return static_cast<QxValidatorX<T> *>(m_pAllValidator.get());
00155    }
00156 #else // _QX_SUPPORT_COVARIANT_RETURN_TYPE
00157    virtual IxValidatorX * getAllValidator()
00158    {
00159       if (! m_pAllValidator) { m_pAllValidator.reset(new QxValidatorX<T>()); IxClass::getAllValidator(); }
00160       return m_pAllValidator.get();
00161    }
00162 #endif // _QX_SUPPORT_COVARIANT_RETURN_TYPE
00163 
00164 private:
00165 
00166    void init();
00167    IxFunction * insertFct(IxFunction_ptr pFct, const QString & sKey);
00168 
00169    void registerClass() { qx::register_class(* this); }
00170 
00171    void beforeRegisterClass()
00172    {
00173       BOOST_STATIC_ASSERT(is_valid_base_class);
00174       QMutexLocker locker(& m_oMutexClass);
00175       QxClass<type_base_class>::getSingleton();
00176       bool bNeedReg = (m_pDataMemberX && (m_pDataMemberX->count() <= 0));
00177       bNeedReg = (bNeedReg && m_pFctMemberX && (m_pFctMemberX->count() <= 0));
00178       if (bNeedReg) { registerClass(); }
00179    }
00180 
00181    qx_bool invokeHelper(const QString & sKey, T * pOwner, const QString & params, boost::any * ret)
00182    { return ((pOwner && m_pFctMemberX && m_pFctMemberX->exist(sKey)) ? m_pFctMemberX->getByKey(sKey)->invoke(pOwner, params, ret) : QxClass<type_base_class>::invoke(sKey, dynamic_cast<type_base_class *>(pOwner), params, ret)); }
00183 
00184    qx_bool invokeHelper(const QString & sKey, T * pOwner, const type_any_params & params, boost::any * ret)
00185    { return ((pOwner && m_pFctMemberX && m_pFctMemberX->exist(sKey)) ? m_pFctMemberX->getByKey(sKey)->invoke(pOwner, params, ret) : QxClass<type_base_class>::invoke(sKey, dynamic_cast<type_base_class *>(pOwner), params, ret)); }
00186 
00187 private:
00188 
00189    template <typename U, int dummy>
00190    struct implementIxPersistable_Helper
00191    { static bool get() { return qx::trait::is_ix_persistable<U>::value; } };
00192 
00193    template <int dummy>
00194    struct implementIxPersistable_Helper<qx::trait::no_base_class_defined, dummy>
00195    { static bool get() { return false; } };
00196 
00197    template <int dummy>
00198    struct implementIxPersistable_Helper<QObject, dummy>
00199    { static bool get() { return false; } };
00200 
00201 };
00202 
00203 } // namespace qx
00204 
00205 #include "../../inl/QxRegister/QxClass.inl"
00206 
00207 #endif // _QX_CLASS_H_