![]() |
QxOrm
1.2.3
C++ Object Relational Mapping library
|
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_DAO_IS_DIRTY_H_ 00027 #define _QX_DAO_IS_DIRTY_H_ 00028 00029 #ifdef _MSC_VER 00030 #pragma once 00031 #endif 00032 00033 #include <boost/static_assert.hpp> 00034 #include <boost/mpl/if.hpp> 00035 #include <boost/mpl/logical.hpp> 00036 #include <boost/type_traits/is_pointer.hpp> 00037 00038 #include <QtCore/qstringlist.h> 00039 00040 #include <QxDao/QxSqlQueryBuilder.h> 00041 #include <QxDao/IxSqlRelation.h> 00042 00043 #include <QxTraits/is_qx_registered.h> 00044 #include <QxTraits/is_container.h> 00045 #include <QxTraits/is_smart_ptr.h> 00046 #include <QxTraits/generic_container.h> 00047 00048 namespace qx { 00049 namespace dao { 00050 namespace detail { 00051 00052 template <class T> 00053 inline void is_dirty(const T & obj1, const T & obj2, QStringList & lstDiff); 00054 00055 template <class T> 00056 struct QxDao_IsDirty_Generic 00057 { 00058 00059 static void compare(const T & obj1, const T & obj2, QStringList & lstDiff) 00060 { 00061 BOOST_STATIC_ASSERT(qx::trait::is_qx_registered<T>::value); 00062 00063 qx::QxSqlQueryBuilder<T> builder; builder.init(); 00064 qx::IxDataMember * pId = builder.getDataId(); 00065 if (pId && (! pId->isEqual((& obj1), (& obj2)))) { lstDiff.append(pId->getKey()); } 00066 00067 long l = 0; 00068 qx::IxDataMember * p = NULL; 00069 while ((p = builder.nextData(l))) 00070 { if (p && (! p->isEqual((& obj1), (& obj2)))) { lstDiff.append(p->getKey()); } } 00071 } 00072 00073 }; 00074 00075 template <class T> 00076 struct QxDao_IsDirty_Container 00077 { 00078 00079 static void compare(const T & obj1, const T & obj2, QStringList & lstDiff) 00080 { 00081 if (qx::trait::generic_container<T>::size(obj1) <= 0) { return; } 00082 if (qx::trait::generic_container<T>::size(obj1) != qx::trait::generic_container<T>::size(obj2)) { lstDiff.append("*"); return; } 00083 00084 long lCurrIndex = 0; 00085 typename T::const_iterator it2 = obj2.begin(); 00086 00087 for (typename T::const_iterator it1 = obj1.begin(); it1 != obj1.end(); ++it1) 00088 { 00089 QStringList lstDiffItem; 00090 qx::dao::detail::is_dirty((* it1), (* it2), lstDiffItem); 00091 if (lstDiffItem.count() > 0) { lstDiff.append(QString::number(lCurrIndex) + "|" + lstDiffItem.join("|")); } 00092 ++lCurrIndex; ++it2; 00093 } 00094 } 00095 00096 }; 00097 00098 template <class T> 00099 struct QxDao_IsDirty_Ptr 00100 { 00101 00102 static void compare(const T & obj1, const T & obj2, QStringList & lstDiff) 00103 { qx::dao::detail::is_dirty((* obj1), (* obj2), lstDiff); } 00104 00105 }; 00106 00107 template <class T> 00108 struct QxDao_IsDirty 00109 { 00110 00111 static void compare(const T & obj1, const T & obj2, QStringList & lstDiff) 00112 { 00113 typedef typename boost::mpl::if_c< boost::is_pointer<T>::value, qx::dao::detail::QxDao_IsDirty_Ptr<T>, qx::dao::detail::QxDao_IsDirty_Generic<T> >::type type_dao_1; 00114 typedef typename boost::mpl::if_c< qx::trait::is_smart_ptr<T>::value, qx::dao::detail::QxDao_IsDirty_Ptr<T>, type_dao_1 >::type type_dao_2; 00115 typedef typename boost::mpl::if_c< qx::trait::is_container<T>::value, qx::dao::detail::QxDao_IsDirty_Container<T>, type_dao_2 >::type type_dao_3; 00116 type_dao_3::compare(obj1, obj2, lstDiff); 00117 } 00118 00119 }; 00120 00121 template <class T> 00122 inline void is_dirty(const T & obj1, const T & obj2, QStringList & lstDiff) 00123 { return qx::dao::detail::QxDao_IsDirty<T>::compare(obj1, obj2, lstDiff); } 00124 00125 } // namespace detail 00126 } // namespace dao 00127 } // namespace qx 00128 00129 #endif // _QX_DAO_IS_DIRTY_H_