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