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