QxOrm 1.1.9
C++ Object Relational Mapping library
QxSqlQueryBuilder.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines