| QxOrm 1.2.7 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 ** 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)) { qAssert(false); 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)) { qAssert(false); 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)) { qAssert(false); 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) { return false; }
    00297       for (int i = 0; i < columns.count(); i++)
    00298       { if (! m_pDataMemberX->exist_WithDaoStrategy(columns.at(i))) { return false; } }
    00299       return true;
    00300    }
    00301 #else // _QX_MODE_RELEASE
    00302    inline bool verifyColumns(const QStringList & columns) const
    00303    { Q_UNUSED(columns); return true; }
    00304 #endif // _QX_MODE_RELEASE
    00305
    00306 };
    00307
    00308 template <class T> QMutex QxSqlQueryBuilder<T>::m_oMutex(QMutex::Recursive);
    00309 template <class T> QxCollection<QString, IxDataMember *> QxSqlQueryBuilder<T>::m_lstDataMember;
    00310 template <class T> IxSqlRelationX QxSqlQueryBuilder<T>::m_lstSqlRelation;
    00311
    00312 } // namespace qx
    00313
    00314 #endif // _QX_SQL_QUERY_BUILDER_H_