QxOrm 1.1.6
C++ Object Relational Mapping library
QxSqlRelation.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_SQL_RELATION_H_
00027 #define _QX_SQL_RELATION_H_
00028 
00029 #ifdef _MSC_VER
00030 #pragma once
00031 #endif
00032 
00040 #include <boost/mpl/if.hpp>
00041 #include <boost/mpl/logical.hpp>
00042 #include <boost/type_traits/is_same.hpp>
00043 #include <boost/type_traits/is_pointer.hpp>
00044 
00045 #include <QxDao/QxDao.h>
00046 #include <QxDao/IxSqlRelation.h>
00047 #include <QxDao/IxSqlQueryBuilder.h>
00048 
00049 #include <QxTraits/remove_attr.h>
00050 #include <QxTraits/remove_smart_ptr.h>
00051 #include <QxTraits/generic_container.h>
00052 #include <QxTraits/is_container.h>
00053 #include <QxTraits/is_valid_primary_key.h>
00054 #include <QxTraits/is_qx_registered.h>
00055 
00056 namespace qx {
00057 
00058 template <class T>
00059 class QxClass;
00060 
00065 template <class DataType, class Owner>
00066 class QxSqlRelation : public IxSqlRelation
00067 {
00068 
00069 protected:
00070 
00071    typedef typename qx::trait::remove_attr<DataType>::type type_tmp_1;
00072    typedef typename qx::trait::remove_smart_ptr<type_tmp_1>::type type_tmp_2;
00073    typedef type_tmp_2 type_container;
00074    typedef qx::trait::generic_container<type_container> type_generic_container;
00075    typedef typename type_generic_container::type_item type_item;
00076    typedef typename boost::mpl::if_c<qx::trait::is_container<type_container>::value, typename type_generic_container::type_value_qx, type_container>::type type_tmp_3;
00077    typedef typename QxSqlRelation<DataType, Owner>::type_tmp_3 type_data;
00078    typedef Owner type_owner;
00079 
00080    enum { is_valid = (qx::trait::is_qx_registered<type_data>::value && qx::trait::is_qx_registered<type_owner>::value) };
00081    enum { is_data_pointer = (boost::is_pointer<DataType>::value || qx::trait::is_smart_ptr<DataType>::value) };
00082    enum { is_data_container = qx::trait::is_container<type_container>::value };
00083    enum { is_same_data_owner = boost::is_same<type_data, type_owner>::value };
00084 
00085 protected:
00086 
00087    static QxCollection<QString, IxDataMember *> m_lstDataMember;     
00088    static IxSqlRelationX m_lstSqlRelation;                           
00089    static QMutex m_oMutex;                                           
00090    bool m_bInitInEvent;                                              
00091 
00092 public:
00093 
00094    QxSqlRelation(IxDataMember * p) : IxSqlRelation(p), m_bInitInEvent(false) { ; }
00095    virtual ~QxSqlRelation() { BOOST_STATIC_ASSERT(is_valid); }
00096 
00097    virtual void init()
00098    {
00099       if (m_bInitInEvent) { return; }; m_bInitInEvent = true;
00100       QMutexLocker locker(& QxSqlRelation<DataType, Owner>::m_oMutex);
00101       m_pDataMemberX = QxClass<type_data>::getSingleton()->dataMemberX();
00102       m_pDataMemberId = (m_pDataMemberX ? m_pDataMemberX->getId_WithDaoStrategy() : NULL);
00103       m_lstDataMemberPtr = (& QxSqlRelation<DataType, Owner>::m_lstDataMember);
00104       m_lstSqlRelationPtr = (& QxSqlRelation<DataType, Owner>::m_lstSqlRelation);
00105       qAssert(m_pDataMember && m_pDataMemberX && m_pDataMemberId);
00106       if (getDataCount() > 0 || getRelationCount() > 0) { m_bInitInEvent = false; return; }
00107       IxDataMember * p = NULL; long lCount = m_pDataMemberX->count_WithDaoStrategy();
00108       for (long l = 0; l < lCount; ++l) { if ((p = isValid_DataMember(l))) { m_lstDataMember.insert(p->getKey(), p); } }
00109       for (long l = 0; l < lCount; ++l) { if ((p = isValid_SqlRelation(l))) { m_lstSqlRelation.insert(p->getKey(), p->getSqlRelation()); } }
00110       m_bInitInEvent = false;
00111    }
00112 
00113 private:
00114 
00115    inline IxDataMember * isValid_DataMember(long lIndex) const
00116    {
00117       IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex);
00118       bool bValid = (p && p->getDao() && ! p->hasSqlRelation());
00119       bValid = (bValid && (p != m_pDataMemberId));
00120       return (bValid ? p : NULL);
00121    }
00122 
00123    inline IxDataMember * isValid_SqlRelation(long lIndex) const
00124    {
00125       IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex);
00126       bool bIsValid = (p && p->getDao() && p->hasSqlRelation());
00127       if (bIsValid && (! is_same_data_owner) && (p != m_pDataMember)) { p->getSqlRelation()->init(); }
00128       return (bIsValid ? p : NULL);
00129    }
00130 
00131 protected:
00132 
00133    inline DataType * getDataTypePtr(QxSqlRelationParams & params) const
00134    { qAssert(params.owner() && m_pDataMember); return static_cast<DataType *>(m_pDataMember->getDataVoidPtr(params.owner())); }
00135 
00136    inline type_owner & getOwner(QxSqlRelationParams & params) const
00137    { qAssert(params.owner()); return (* static_cast<type_owner *>(params.owner())); }
00138 
00139    inline type_data & getData(QxSqlRelationParams & params) const
00140    { return getData_Helper<is_data_pointer, is_data_container, 0>::get(getDataTypePtr(params)); }
00141 
00142    inline type_container & getContainer(QxSqlRelationParams & params) const
00143    { return getContainer_Helper<is_data_pointer, is_data_container, 0>::get(getDataTypePtr(params)); }
00144 
00145    inline type_item createItem() const
00146    { return createItem_Helper<is_data_container, 0>::get(); }
00147 
00148 private:
00149 
00150    template <bool bIsPointer /* = false */, bool bIsContainer /* = false */, int dummy>
00151    struct getData_Helper
00152    { static inline type_data & get(DataType * t) { return (* t); } };
00153 
00154    template <int dummy>
00155    struct getData_Helper<true, false, dummy>
00156    { static inline type_data & get(DataType * t) { if (! (* t)) { qx::trait::construct_ptr<DataType>::get(* t); }; return (** t); } };
00157 
00158    template <int dummy>
00159    struct getData_Helper<false, true, dummy>
00160    { static inline type_data & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_data * pDummy(NULL); return (* pDummy); } };
00161 
00162    template <int dummy>
00163    struct getData_Helper<true, true, dummy>
00164    { static inline type_data & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_data * pDummy(NULL); return (* pDummy); } };
00165 
00166    template <bool bIsPointer /* = false */, bool bIsContainer /* = false */, int dummy>
00167    struct getContainer_Helper
00168    { static inline type_container & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_container * pDummy(NULL); return (* pDummy); } };
00169 
00170    template <int dummy>
00171    struct getContainer_Helper<true, false, dummy>
00172    { static inline type_container & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_container * pDummy(NULL); return (* pDummy); } };
00173 
00174    template <int dummy>
00175    struct getContainer_Helper<false, true, dummy>
00176    { static inline type_container & get(DataType * t) { return (* t); } };
00177 
00178    template <int dummy>
00179    struct getContainer_Helper<true, true, dummy>
00180    { static inline type_container & get(DataType * t) { if (! (* t)) { qx::trait::construct_ptr<DataType>::get(* t); }; return (** t); } };
00181 
00182    template <bool bIsContainer /* = false */, int dummy>
00183    struct createItem_Helper
00184    { static inline type_item get() { qAssert(false); type_item * pDummy(NULL); return (* pDummy); } };
00185 
00186    template <int dummy>
00187    struct createItem_Helper<true, dummy>
00188    { static inline type_item get() { return type_generic_container::createItem(); } };
00189 
00190 };
00191 
00192 template <class DataType, class Owner> QxCollection<QString, IxDataMember *> QxSqlRelation<DataType, Owner>::m_lstDataMember;
00193 template <class DataType, class Owner> IxSqlRelationX QxSqlRelation<DataType, Owner>::m_lstSqlRelation;
00194 template <class DataType, class Owner> QMutex QxSqlRelation<DataType, Owner>::m_oMutex;
00195 
00196 } // namespace qx
00197 
00198 #include <QxDao/QxSqlRelation_OneToOne.h>
00199 #include <QxDao/QxSqlRelation_OneToMany.h>
00200 #include <QxDao/QxSqlRelation_ManyToOne.h>
00201 #include <QxDao/QxSqlRelation_ManyToMany.h>
00202 #include <QxDao/QxSqlRelation_RawData.h>
00203 
00204 #endif // _QX_SQL_RELATION_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines