![]() |
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_SQL_QUERY_BUILDER_H_ 00027 #define _QX_SQL_QUERY_BUILDER_H_ 00028 00029 #ifdef _MSC_VER 00030 #pragma once 00031 #endif 00032 00040 #include <QtCore/qmutex.h> 00041 00042 #include <QxDao/IxSqlQueryBuilder.h> 00043 #include <QxDao/QxSqlQueryHelper.h> 00044 00045 #include <QxRegister/QxClass.h> 00046 00047 #include <QxTraits/remove_attr.h> 00048 #include <QxTraits/remove_smart_ptr.h> 00049 00050 #define QX_SQL_ERR_NO_DATA_MEMBER_REGISTERED "'QxSqlQueryBuilder<T>' error : 'qx::register_class()' not called or no data member registered" 00051 #define QX_SQL_ERR_NO_ID_REGISTERED "'QxSqlQueryBuilder<T>' error : no id registered" 00052 00053 #define QX_SQL_BUILDER_INIT_FCT() \ 00054 static QString sql = ""; \ 00055 QMutexLocker locker(& QxSqlQueryBuilder<T>::m_oMutex); \ 00056 if (! sql.isEmpty()) { setSqlQuery(sql); return (* this); } 00057 00058 #define QX_SQL_BUILDER_INIT_FCT_WITH_RELATION() \ 00059 static QHash<QString, QString> sqlX; \ 00060 static QHash<QString, QHash<QString, QString> > sqlAliasX; \ 00061 QMutexLocker locker(& QxSqlQueryBuilder<T>::m_oMutex); \ 00062 QString sql = sqlX.value(m_sHashRelation); \ 00063 if (! sql.isEmpty()) { setSqlQuery(sql); m_lstSqlQueryAlias = sqlAliasX.value(m_sHashRelation); return (* this); } 00064 00065 namespace qx { 00066 00071 template <class T> 00072 class QxSqlQueryBuilder : public IxSqlQueryBuilder 00073 { 00074 00075 private: 00076 00077 typedef typename qx::trait::remove_attr<T>::type type_sql_tmp_1; 00078 typedef typename qx::trait::remove_smart_ptr<type_sql_tmp_1>::type type_sql_tmp_2; 00079 00080 public: 00081 00082 typedef typename qx::QxSqlQueryBuilder<T>::type_sql_tmp_2 type_sql; 00083 00084 protected: 00085 00086 QxDataMemberX<type_sql> * m_pDataMemberX; 00087 00088 static QxCollection<QString, IxDataMember *> m_lstDataMember; 00089 static IxSqlRelationX m_lstSqlRelation; 00090 static QMutex m_oMutex; 00091 00092 public: 00093 00094 QxSqlQueryBuilder() : IxSqlQueryBuilder(), m_pDataMemberX(NULL) { ; } 00095 QxSqlQueryBuilder(const QString & sql) : IxSqlQueryBuilder(sql), m_pDataMemberX(NULL) { ; } 00096 virtual ~QxSqlQueryBuilder() { ; } 00097 00098 virtual IxDataMemberX * getDataMemberX() const { return m_pDataMemberX; } 00099 00100 virtual IxSqlQueryBuilder & count() 00101 { 00102 QX_SQL_BUILDER_INIT_FCT() 00103 sql = "SELECT COUNT(*) FROM " + m_sTableName; 00104 if (! m_oSoftDelete.isEmpty()) { sql += " WHERE " + m_oSoftDelete.buildSqlQueryToFetch(); } 00105 setSqlQuery(sql); 00106 return (* this); 00107 } 00108 00109 virtual IxSqlQueryBuilder & exist() 00110 { 00111 QX_SQL_BUILDER_INIT_FCT() 00112 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00113 qx::dao::detail::QxSqlQueryHelper_Exist<type_sql>::sql(sql, (* this)); 00114 setSqlQuery(sql); 00115 return (* this); 00116 } 00117 00118 virtual IxSqlQueryBuilder & fetchAll() 00119 { 00120 QX_SQL_BUILDER_INIT_FCT() 00121 qx::dao::detail::QxSqlQueryHelper_FetchAll<type_sql>::sql(sql, (* this)); 00122 setSqlQuery(sql); 00123 return (* this); 00124 } 00125 00126 virtual IxSqlQueryBuilder & fetchById() 00127 { 00128 QX_SQL_BUILDER_INIT_FCT() 00129 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00130 qx::dao::detail::QxSqlQueryHelper_FetchById<type_sql>::sql(sql, (* this)); 00131 setSqlQuery(sql); 00132 return (* this); 00133 } 00134 00135 virtual IxSqlQueryBuilder & insert() 00136 { 00137 QX_SQL_BUILDER_INIT_FCT() 00138 qx::dao::detail::QxSqlQueryHelper_Insert<type_sql>::sql(sql, (* this)); 00139 setSqlQuery(sql); 00140 return (* this); 00141 } 00142 00143 virtual IxSqlQueryBuilder & update() 00144 { 00145 QX_SQL_BUILDER_INIT_FCT() 00146 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00147 qx::dao::detail::QxSqlQueryHelper_Update<type_sql>::sql(sql, (* this)); 00148 setSqlQuery(sql); 00149 return (* this); 00150 } 00151 00152 virtual IxSqlQueryBuilder & deleteAll() 00153 { 00154 QX_SQL_BUILDER_INIT_FCT() 00155 sql = "DELETE FROM " + m_sTableName; 00156 setSqlQuery(sql); 00157 return (* this); 00158 } 00159 00160 virtual IxSqlQueryBuilder & softDeleteAll() 00161 { 00162 QX_SQL_BUILDER_INIT_FCT() 00163 if (! m_oSoftDelete.isEmpty()) { sql = "UPDATE " + m_sTableName + " SET " + m_oSoftDelete.buildSqlQueryToUpdate(); } 00164 else { qAssert(false); } 00165 setSqlQuery(sql); 00166 return (* this); 00167 } 00168 00169 virtual IxSqlQueryBuilder & deleteById() 00170 { 00171 QX_SQL_BUILDER_INIT_FCT() 00172 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00173 qx::dao::detail::QxSqlQueryHelper_DeleteById<type_sql>::sql(sql, (* this), false); 00174 setSqlQuery(sql); 00175 return (* this); 00176 } 00177 00178 virtual IxSqlQueryBuilder & softDeleteById() 00179 { 00180 QX_SQL_BUILDER_INIT_FCT() 00181 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00182 if (m_oSoftDelete.isEmpty()) { qAssert(false); return (* this); } 00183 qx::dao::detail::QxSqlQueryHelper_DeleteById<type_sql>::sql(sql, (* this), true); 00184 setSqlQuery(sql); 00185 return (* this); 00186 } 00187 00188 virtual IxSqlQueryBuilder & createTable() 00189 { 00190 QX_SQL_BUILDER_INIT_FCT() 00191 qx::dao::detail::QxSqlQueryHelper_CreateTable<type_sql>::sql(sql, (* this)); 00192 setSqlQuery(sql); 00193 return (* this); 00194 } 00195 00196 virtual IxSqlQueryBuilder & fetchAll_WithRelation(IxSqlRelationX * pRelationX) 00197 { 00198 QX_SQL_BUILDER_INIT_FCT_WITH_RELATION() 00199 qx::dao::detail::QxSqlQueryHelper_FetchAll_WithRelation<type_sql>::sql(pRelationX, sql, (* this)); 00200 if (! m_sHashRelation.isEmpty()) { sqlX.insert(m_sHashRelation, sql); } 00201 if (! m_sHashRelation.isEmpty()) { sqlAliasX.insert(m_sHashRelation, m_lstSqlQueryAlias); } 00202 setSqlQuery(sql); 00203 return (* this); 00204 } 00205 00206 virtual IxSqlQueryBuilder & fetchById_WithRelation(IxSqlRelationX * pRelationX) 00207 { 00208 QX_SQL_BUILDER_INIT_FCT_WITH_RELATION() 00209 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00210 qx::dao::detail::QxSqlQueryHelper_FetchById_WithRelation<type_sql>::sql(pRelationX, sql, (* this)); 00211 if (! m_sHashRelation.isEmpty()) { sqlX.insert(m_sHashRelation, sql); } 00212 if (! m_sHashRelation.isEmpty()) { sqlAliasX.insert(m_sHashRelation, m_lstSqlQueryAlias); } 00213 setSqlQuery(sql); 00214 return (* this); 00215 } 00216 00217 virtual IxSqlQueryBuilder & fetchAll(const QStringList & columns) 00218 { 00219 QString sql; 00220 if (columns.count() <= 0) { return fetchAll(); } 00221 if (columns.at(0) == "*") { return fetchAll(); } 00222 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00223 qx::dao::detail::QxSqlQueryHelper_FetchAll<type_sql>::sql(sql, (* this), columns); 00224 setSqlQuery(sql); 00225 return (* this); 00226 } 00227 00228 virtual IxSqlQueryBuilder & fetchById(const QStringList & columns) 00229 { 00230 QString sql; 00231 if (columns.count() <= 0) { return fetchById(); } 00232 if (columns.at(0) == "*") { return fetchById(); } 00233 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00234 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00235 qx::dao::detail::QxSqlQueryHelper_FetchById<type_sql>::sql(sql, (* this), columns); 00236 setSqlQuery(sql); 00237 return (* this); 00238 } 00239 00240 virtual IxSqlQueryBuilder & update(const QStringList & columns) 00241 { 00242 QString sql; 00243 if (columns.count() <= 0) { return update(); } 00244 if (columns.at(0) == "*") { return update(); } 00245 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00246 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00247 qx::dao::detail::QxSqlQueryHelper_Update<type_sql>::sql(sql, (* this), columns); 00248 setSqlQuery(sql); 00249 return (* this); 00250 } 00251 00252 virtual void init() 00253 { 00254 QMutexLocker locker(& QxSqlQueryBuilder<T>::m_oMutex); 00255 m_pDataMemberX = QxClass<type_sql>::getSingleton()->dataMemberX(); 00256 m_pDataMemberId = m_pDataMemberX->getId_WithDaoStrategy(); 00257 m_sTableName = m_pDataMemberX->getName(); 00258 m_lstDataMemberPtr = (& QxSqlQueryBuilder<T>::m_lstDataMember); 00259 m_lstSqlRelationPtr = (& QxSqlQueryBuilder<T>::m_lstSqlRelation); 00260 m_oSoftDelete = QxClass<type_sql>::getSingleton()->getSoftDelete(); 00261 if (getDataCount() > 0 || getRelationCount() > 0) { return; } 00262 IxDataMember * p = NULL; long lCount = m_pDataMemberX->count_WithDaoStrategy(); 00263 for (long l = 0; l < lCount; ++l) { if ((p = isValid_DataMember(l))) { m_lstDataMember.insert(p->getKey(), p); } } 00264 for (long l = 0; l < lCount; ++l) { if ((p = isValid_SqlRelation(l))) { m_lstSqlRelation.insert(p->getKey(), p->getSqlRelation()); } } 00265 } 00266 00267 private: 00268 00269 IxDataMember * isValid_DataMember(long lIndex) const 00270 { 00271 IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex); 00272 bool bValid = (p && p->getDao() && ! p->hasSqlRelation()); 00273 bValid = (bValid && (p != m_pDataMemberId)); 00274 return (bValid ? p : NULL); 00275 } 00276 00277 IxDataMember * isValid_SqlRelation(long lIndex) const 00278 { 00279 IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex); 00280 bool bIsValid = (p && p->getDao() && p->hasSqlRelation()); 00281 if (bIsValid) { p->getSqlRelation()->init(); } 00282 return (bIsValid ? p : NULL); 00283 } 00284 00285 private: 00286 00287 #ifndef NDEBUG 00288 inline bool verifyColumns(const QStringList & columns) const 00289 { 00290 if (! m_pDataMemberX) { return false; } 00291 for (int i = 0; i < columns.count(); i++) 00292 { if (! m_pDataMemberX->exist_WithDaoStrategy(columns.at(i))) { return false; } } 00293 return true; 00294 } 00295 #else 00296 inline bool verifyColumns(const QStringList & columns) const 00297 { Q_UNUSED(columns); return true; } 00298 #endif // NDEBUG 00299 00300 }; 00301 00302 template <class T> QMutex QxSqlQueryBuilder<T>::m_oMutex(QMutex::Recursive); 00303 template <class T> QxCollection<QString, IxDataMember *> QxSqlQueryBuilder<T>::m_lstDataMember; 00304 template <class T> IxSqlRelationX QxSqlQueryBuilder<T>::m_lstSqlRelation; 00305 00306 } // namespace qx 00307 00308 #endif // _QX_SQL_QUERY_BUILDER_H_