/**************************************************************************** ** ** https://www.qxorm.com/ ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com) ** ** This file is part of the QxOrm library ** ** This software is provided 'as-is', without any express or implied ** warranty. In no event will the authors be held liable for any ** damages arising from the use of this software ** ** Commercial Usage ** Licensees holding valid commercial QxOrm licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Lionel Marty ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file 'license.gpl3.txt' included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met : http://www.gnu.org/copyleft/gpl.html ** ** If you are unsure which license is appropriate for your use, or ** if you have questions regarding the use of this file, please contact : ** contact@qxorm.com ** ****************************************************************************/ #ifndef _QX_SQL_QUERY_BUILDER_H_ #define _QX_SQL_QUERY_BUILDER_H_ #ifdef _MSC_VER #pragma once #endif /*! * \file QxSqlQueryBuilder.h * \author Lionel Marty * \ingroup QxDao * \brief Concrete SQL query builder by class with a cache mechanism to backup and restore queries already built by the program */ #include #include #include #include #include #include #define QX_SQL_ERR_NO_DATA_MEMBER_REGISTERED "'QxSqlQueryBuilder' error : 'qx::register_class()' not called or no data member registered" #define QX_SQL_ERR_NO_ID_REGISTERED "'QxSqlQueryBuilder' error : no id registered" #define QX_SQL_BUILDER_INIT_FCT(oper) \ qx::dao::detail::IxDao_Timer timer(this->getDaoHelper(), qx::dao::detail::IxDao_Helper::timer_build_sql); \ QString joinQueryHash = (this->getDaoHelper() ? this->getDaoHelper()->qxQuery().getJoinQueryHash() : QString()); \ QString ignoreSoftDeleteHash = (this->getDaoHelper() ? this->getDaoHelper()->getIgnoreSoftDeleteHash() : QString()); \ QString key = QxClass::getSingleton()->getKey() + joinQueryHash + ignoreSoftDeleteHash + oper; \ if ((joinQueryHash.isEmpty()) && (this->findSqlQuery(key))) { return (* this); } \ QString sql; Q_UNUSED(sql); #define QX_SQL_BUILDER_INIT_FCT_WITH_RELATION(oper) \ qx::dao::detail::IxDao_Timer timer(this->getDaoHelper(), qx::dao::detail::IxDao_Helper::timer_build_sql); \ QString joinQueryHash = (this->getDaoHelper() ? this->getDaoHelper()->qxQuery().getJoinQueryHash() : QString()); \ QString ignoreSoftDeleteHash = (this->getDaoHelper() ? this->getDaoHelper()->getIgnoreSoftDeleteHash() : QString()); \ QString key = QxClass::getSingleton()->getKey() + joinQueryHash + this->getHashRelation() + ignoreSoftDeleteHash + oper; \ if ((joinQueryHash.isEmpty()) && (this->findSqlQuery(key))) { this->findSqlAlias(key); return (* this); } \ QString sql; Q_UNUSED(sql); namespace qx { /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder : concrete SQL query builder for class T with a cache mechanism to backup and restore queries already built by the program */ template class QxSqlQueryBuilder : public IxSqlQueryBuilder { private: typedef typename qx::trait::remove_attr::type type_sql_tmp_1; typedef typename qx::trait::remove_smart_ptr::type type_sql_tmp_2; public: typedef typename qx::QxSqlQueryBuilder::type_sql_tmp_2 type_sql; public: QxSqlQueryBuilder() : IxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder() { static_assert(qx::trait::is_qx_registered::value, "qx::trait::is_qx_registered::value"); } virtual void init() { if (isInitDone()) { return; } setDataMemberX(QxClass::getSingleton()->dataMemberX()); setSoftDelete(QxClass::getSingleton()->getSoftDelete()); IxSqlQueryBuilder::init(); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_Count : concrete SQL query builder for class T to build a COUNT SQL query */ template class QxSqlQueryBuilder_Count : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_Count() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_Count() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("Count") sql = "SELECT COUNT(*) FROM " + qx::IxDataMember::getSqlFromTable(this->table()); if (! this->softDelete().isEmpty()) { sql += " WHERE " + this->softDelete().buildSqlQueryToFetch(); } this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_Exist : concrete SQL query builder for class T to build an EXIST SQL query */ template class QxSqlQueryBuilder_Exist : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_Exist() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_Exist() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("Exist") if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } qx::dao::detail::QxSqlQueryHelper_Exist::sql(sql, (* this)); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_FetchAll : concrete SQL query builder for class T to build a FETCH ALL SQL query */ template class QxSqlQueryBuilder_FetchAll : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_FetchAll() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_FetchAll() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(pRelationX); if ((columns.count() <= 0) || (columns.at(0) == "*")) { QX_SQL_BUILDER_INIT_FCT("FetchAll") qx::dao::detail::QxSqlQueryHelper_FetchAll::sql(sql, (* this)); this->setSqlQuery(sql, key); } else { QString sql; if (! this->verifyColumns(columns)) { return (* this); } qx::dao::detail::QxSqlQueryHelper_FetchAll::sql(sql, (* this), columns); this->setSqlQuery(sql); } return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_FetchById : concrete SQL query builder for class T to build a FETCH BY ID SQL query */ template class QxSqlQueryBuilder_FetchById : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_FetchById() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_FetchById() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(pRelationX); if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } QxSqlQueryBuilder_FetchAll builder; builder.clone(* this); if ((columns.count() <= 0) || (columns.at(0) == "*")) { QX_SQL_BUILDER_INIT_FCT("FetchById") qx::dao::detail::QxSqlQueryHelper_FetchById::sql(sql, builder); this->setSqlQuery(sql, key); } else { QString sql; if (! this->verifyColumns(columns)) { return (* this); } qx::dao::detail::QxSqlQueryHelper_FetchById::sql(sql, builder, columns); this->setSqlQuery(sql); } return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_Insert : concrete SQL query builder for class T to build an INSERT SQL query */ template class QxSqlQueryBuilder_Insert : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_Insert() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_Insert() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("Insert") qx::dao::detail::QxSqlQueryHelper_Insert::sql(sql, (* this)); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_Update : concrete SQL query builder for class T to build an UPDATE SQL query */ template class QxSqlQueryBuilder_Update : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_Update() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_Update() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(pRelationX); if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } if ((columns.count() <= 0) || (columns.at(0) == "*")) { QX_SQL_BUILDER_INIT_FCT("Update") qx::dao::detail::QxSqlQueryHelper_Update::sql(sql, (* this)); this->setSqlQuery(sql, key); } else { QString sql; if (! this->verifyColumns(columns)) { return (* this); } qx::dao::detail::QxSqlQueryHelper_Update::sql(sql, (* this), columns); this->setSqlQuery(sql); } return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_DeleteAll : concrete SQL query builder for class T to build a DELETE ALL SQL query */ template class QxSqlQueryBuilder_DeleteAll : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_DeleteAll() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_DeleteAll() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("DeleteAll") sql = "DELETE FROM " + this->table(); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_SoftDeleteAll : concrete SQL query builder for class T to build a SOFT DELETE ALL SQL query */ template class QxSqlQueryBuilder_SoftDeleteAll : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_SoftDeleteAll() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_SoftDeleteAll() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("SoftDeleteAll") if (! this->softDelete().isEmpty()) { sql = "UPDATE " + this->table() + " SET " + this->softDelete().buildSqlQueryToUpdate(); } else { qAssert(false); } this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_DeleteById : concrete SQL query builder for class T to build a DELETE BY ID SQL query */ template class QxSqlQueryBuilder_DeleteById : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_DeleteById() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_DeleteById() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("DeleteById") if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } qx::dao::detail::QxSqlQueryHelper_DeleteById::sql(sql, (* this), false); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_SoftDeleteById : concrete SQL query builder for class T to build a SOFT DELETE BY ID SQL query */ template class QxSqlQueryBuilder_SoftDeleteById : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_SoftDeleteById() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_SoftDeleteById() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("SoftDeleteById") if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } if (this->softDelete().isEmpty()) { qAssert(false); return (* this); } qx::dao::detail::QxSqlQueryHelper_DeleteById::sql(sql, (* this), true); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_CreateTable : concrete SQL query builder for class T to build a CREATE TABLE SQL query */ template class QxSqlQueryBuilder_CreateTable : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_CreateTable() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_CreateTable() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); Q_UNUSED(pRelationX); QX_SQL_BUILDER_INIT_FCT("CreateTable") qx::dao::detail::QxSqlQueryHelper_CreateTable::sql(sql, (* this)); this->setSqlQuery(sql, key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_Count_WithRelation : concrete SQL query builder for class T to build a COUNT WITH RELATION SQL query */ template class QxSqlQueryBuilder_Count_WithRelation : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_Count_WithRelation() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_Count_WithRelation() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); QX_SQL_BUILDER_INIT_FCT_WITH_RELATION("Count_WithRelation") IxSqlQueryBuilder::sql_Count_WithRelation(pRelationX, sql, (* this)); this->setSqlQuery(sql, key); this->insertSqlAlias(key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_FetchAll_WithRelation : concrete SQL query builder for class T to build a FETCH ALL WITH RELATION SQL query */ template class QxSqlQueryBuilder_FetchAll_WithRelation : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_FetchAll_WithRelation() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_FetchAll_WithRelation() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); QX_SQL_BUILDER_INIT_FCT_WITH_RELATION("FetchAll_WithRelation") qx::dao::detail::QxSqlQueryHelper_FetchAll_WithRelation::sql(pRelationX, sql, (* this)); this->setSqlQuery(sql, key); this->insertSqlAlias(key); return (* this); } }; /*! * \ingroup QxDao * \brief qx::QxSqlQueryBuilder_FetchById_WithRelation : concrete SQL query builder for class T to build a FETCH BY ID WITH RELATION SQL query */ template class QxSqlQueryBuilder_FetchById_WithRelation : public QxSqlQueryBuilder { public: typedef typename QxSqlQueryBuilder::type_sql type_sql; QxSqlQueryBuilder_FetchById_WithRelation() : QxSqlQueryBuilder() { ; } virtual ~QxSqlQueryBuilder_FetchById_WithRelation() { ; } virtual IxSqlQueryBuilder & buildSql(const QStringList & columns = QStringList(), QxSqlRelationLinked * pRelationX = NULL) { Q_UNUSED(columns); QX_SQL_BUILDER_INIT_FCT_WITH_RELATION("FetchById_WithRelation") if (! this->getDataId()) { qDebug("[QxOrm] %s", QX_SQL_ERR_NO_ID_REGISTERED); qAssert(false); return (* this); } QxSqlQueryBuilder_FetchAll_WithRelation builder; builder.clone(* this); qx::dao::detail::QxSqlQueryHelper_FetchById_WithRelation::sql(pRelationX, sql, builder); this->setSqlQuery(sql, key); this->insertSqlAlias(key); return (* this); } }; } // namespace qx #endif // _QX_SQL_QUERY_BUILDER_H_