![]() |
QxOrm 1.1.6
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 setSqlQuery(sql); 00104 return (* this); 00105 } 00106 00107 virtual IxSqlQueryBuilder & exist() 00108 { 00109 QX_SQL_BUILDER_INIT_FCT() 00110 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00111 qx::dao::detail::QxSqlQueryHelper_Exist<type_sql>::sql(sql, (* this)); 00112 setSqlQuery(sql); 00113 return (* this); 00114 } 00115 00116 virtual IxSqlQueryBuilder & fetchAll() 00117 { 00118 QX_SQL_BUILDER_INIT_FCT() 00119 qx::dao::detail::QxSqlQueryHelper_FetchAll<type_sql>::sql(sql, (* this)); 00120 setSqlQuery(sql); 00121 return (* this); 00122 } 00123 00124 virtual IxSqlQueryBuilder & fetchById() 00125 { 00126 QX_SQL_BUILDER_INIT_FCT() 00127 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00128 qx::dao::detail::QxSqlQueryHelper_FetchById<type_sql>::sql(sql, (* this)); 00129 setSqlQuery(sql); 00130 return (* this); 00131 } 00132 00133 virtual IxSqlQueryBuilder & insert() 00134 { 00135 QX_SQL_BUILDER_INIT_FCT() 00136 qx::dao::detail::QxSqlQueryHelper_Insert<type_sql>::sql(sql, (* this)); 00137 setSqlQuery(sql); 00138 return (* this); 00139 } 00140 00141 virtual IxSqlQueryBuilder & update() 00142 { 00143 QX_SQL_BUILDER_INIT_FCT() 00144 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00145 qx::dao::detail::QxSqlQueryHelper_Update<type_sql>::sql(sql, (* this)); 00146 setSqlQuery(sql); 00147 return (* this); 00148 } 00149 00150 virtual IxSqlQueryBuilder & deleteAll() 00151 { 00152 QX_SQL_BUILDER_INIT_FCT() 00153 sql = "DELETE FROM " + m_sTableName; 00154 setSqlQuery(sql); 00155 return (* this); 00156 } 00157 00158 virtual IxSqlQueryBuilder & deleteById() 00159 { 00160 QX_SQL_BUILDER_INIT_FCT() 00161 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00162 qx::dao::detail::QxSqlQueryHelper_DeleteById<type_sql>::sql(sql, (* this)); 00163 setSqlQuery(sql); 00164 return (* this); 00165 } 00166 00167 virtual IxSqlQueryBuilder & createTable() 00168 { 00169 QX_SQL_BUILDER_INIT_FCT() 00170 qx::dao::detail::QxSqlQueryHelper_CreateTable<type_sql>::sql(sql, (* this)); 00171 setSqlQuery(sql); 00172 return (* this); 00173 } 00174 00175 virtual IxSqlQueryBuilder & fetchAll_WithRelation(IxSqlRelationX * pRelationX) 00176 { 00177 QX_SQL_BUILDER_INIT_FCT_WITH_RELATION() 00178 qx::dao::detail::QxSqlQueryHelper_FetchAll_WithRelation<type_sql>::sql(pRelationX, sql, (* this)); 00179 if (! m_sHashRelation.isEmpty()) { sqlX.insert(m_sHashRelation, sql); } 00180 setSqlQuery(sql); 00181 return (* this); 00182 } 00183 00184 virtual IxSqlQueryBuilder & fetchById_WithRelation(IxSqlRelationX * pRelationX) 00185 { 00186 QX_SQL_BUILDER_INIT_FCT_WITH_RELATION() 00187 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00188 qx::dao::detail::QxSqlQueryHelper_FetchById_WithRelation<type_sql>::sql(pRelationX, sql, (* this)); 00189 if (! m_sHashRelation.isEmpty()) { sqlX.insert(m_sHashRelation, sql); } 00190 setSqlQuery(sql); 00191 return (* this); 00192 } 00193 00194 virtual IxSqlQueryBuilder & fetchAll(const QStringList & columns) 00195 { 00196 QString sql; 00197 if (columns.count() <= 0) { return fetchAll(); } 00198 if (columns.at(0) == "*") { return fetchAll(); } 00199 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00200 qx::dao::detail::QxSqlQueryHelper_FetchAll<type_sql>::sql(sql, (* this), columns); 00201 setSqlQuery(sql); 00202 return (* this); 00203 } 00204 00205 virtual IxSqlQueryBuilder & fetchById(const QStringList & columns) 00206 { 00207 QString sql; 00208 if (columns.count() <= 0) { return fetchById(); } 00209 if (columns.at(0) == "*") { return fetchById(); } 00210 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00211 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00212 qx::dao::detail::QxSqlQueryHelper_FetchById<type_sql>::sql(sql, (* this), columns); 00213 setSqlQuery(sql); 00214 return (* this); 00215 } 00216 00217 virtual IxSqlQueryBuilder & update(const QStringList & columns) 00218 { 00219 QString sql; 00220 if (columns.count() <= 0) { return update(); } 00221 if (columns.at(0) == "*") { return update(); } 00222 if (! verifyColumns(columns)) { qAssert(false); return (* this); } 00223 if (! getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } 00224 qx::dao::detail::QxSqlQueryHelper_Update<type_sql>::sql(sql, (* this), columns); 00225 setSqlQuery(sql); 00226 return (* this); 00227 } 00228 00229 virtual void init() 00230 { 00231 QMutexLocker locker(& QxSqlQueryBuilder<T>::m_oMutex); 00232 m_pDataMemberX = QxClass<type_sql>::getSingleton()->dataMemberX(); 00233 m_pDataMemberId = m_pDataMemberX->getId_WithDaoStrategy(); 00234 m_sTableName = m_pDataMemberX->getName(); 00235 m_lstDataMemberPtr = (& QxSqlQueryBuilder<T>::m_lstDataMember); 00236 m_lstSqlRelationPtr = (& QxSqlQueryBuilder<T>::m_lstSqlRelation); 00237 if (getDataCount() > 0 || getRelationCount() > 0) { return; } 00238 IxDataMember * p = NULL; long lCount = m_pDataMemberX->count_WithDaoStrategy(); 00239 for (long l = 0; l < lCount; ++l) { if ((p = isValid_DataMember(l))) { m_lstDataMember.insert(p->getKey(), p); } } 00240 for (long l = 0; l < lCount; ++l) { if ((p = isValid_SqlRelation(l))) { m_lstSqlRelation.insert(p->getKey(), p->getSqlRelation()); } } 00241 } 00242 00243 private: 00244 00245 IxDataMember * isValid_DataMember(long lIndex) const 00246 { 00247 IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex); 00248 bool bValid = (p && p->getDao() && ! p->hasSqlRelation()); 00249 bValid = (bValid && (p != m_pDataMemberId)); 00250 return (bValid ? p : NULL); 00251 } 00252 00253 IxDataMember * isValid_SqlRelation(long lIndex) const 00254 { 00255 IxDataMember * p = m_pDataMemberX->get_WithDaoStrategy(lIndex); 00256 bool bIsValid = (p && p->getDao() && p->hasSqlRelation()); 00257 if (bIsValid) { p->getSqlRelation()->init(); } 00258 return (bIsValid ? p : NULL); 00259 } 00260 00261 private: 00262 00263 #ifndef NDEBUG 00264 inline bool verifyColumns(const QStringList & columns) const 00265 { 00266 if (! m_pDataMemberX) { return false; } 00267 for (int i = 0; i < columns.count(); i++) 00268 { if (! m_pDataMemberX->exist_WithDaoStrategy(columns.at(i))) { return false; } } 00269 return true; 00270 } 00271 #else 00272 inline bool verifyColumns(const QStringList & columns) const 00273 { Q_UNUSED(columns); return true; } 00274 #endif // NDEBUG 00275 00276 }; 00277 00278 template <class T> QMutex QxSqlQueryBuilder<T>::m_oMutex(QMutex::Recursive); 00279 template <class T> QxCollection<QString, IxDataMember *> QxSqlQueryBuilder<T>::m_lstDataMember; 00280 template <class T> IxSqlRelationX QxSqlQueryBuilder<T>::m_lstSqlRelation; 00281 00282 } // namespace qx 00283 00284 #endif // _QX_SQL_QUERY_BUILDER_H_