| QxOrm 1.2.4 C++ Object Relational Mapping library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

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 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(QxSqlRelationLinked * 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(QxSqlRelationLinked * 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_