QxDaoAsync.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /****************************************************************************
  2. **
  3. ** https://www.qxorm.com/
  4. ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
  5. **
  6. ** This file is part of the QxOrm library
  7. **
  8. ** This software is provided 'as-is', without any express or implied
  9. ** warranty. In no event will the authors be held liable for any
  10. ** damages arising from the use of this software
  11. **
  12. ** Commercial Usage
  13. ** Licensees holding valid commercial QxOrm licenses may use this file in
  14. ** accordance with the commercial license agreement provided with the
  15. ** Software or, alternatively, in accordance with the terms contained in
  16. ** a written agreement between you and Lionel Marty
  17. **
  18. ** GNU General Public License Usage
  19. ** Alternatively, this file may be used under the terms of the GNU
  20. ** General Public License version 3.0 as published by the Free Software
  21. ** Foundation and appearing in the file 'license.gpl3.txt' included in the
  22. ** packaging of this file. Please review the following information to
  23. ** ensure the GNU General Public License version 3.0 requirements will be
  24. ** met : http://www.gnu.org/copyleft/gpl.html
  25. **
  26. ** If you are unsure which license is appropriate for your use, or
  27. ** if you have questions regarding the use of this file, please contact :
  28. ** contact@qxorm.com
  29. **
  30. ****************************************************************************/
  31. #ifndef _QX_DAO_ASYNC_H_
  32. #define _QX_DAO_ASYNC_H_
  33. #ifdef _MSC_VER
  34. #pragma once
  35. #endif
  36. /*!
  37. * \file QxDaoAsync.h
  38. * \author Lionel Marty
  39. * \ingroup QxDao
  40. * \brief Helper class to execute SQL queries in another thread (asynchronous way) using qx::IxPersistable interface
  41. */
  42. #ifdef _QX_NO_PRECOMPILED_HEADER
  43. #ifndef Q_MOC_RUN
  44. #include <QxPrecompiled.h> // Need to include precompiled header for the generated moc file
  45. #endif // Q_MOC_RUN
  46. #endif // _QX_NO_PRECOMPILED_HEADER
  47. #include <QtCore/qqueue.h>
  48. #include <QtSql/qsqlerror.h>
  49. #ifndef Q_MOC_RUN
  50. #include <QxDao/IxPersistable.h>
  51. #include <QxDao/QxSqlQuery.h>
  52. #endif // Q_MOC_RUN
  53. namespace qx {
  54. namespace dao {
  55. namespace detail {
  56. /*!
  57. * \ingroup QxDao
  58. * \brief qx::dao::detail::QxDaoAsyncParams : all parameters for qx::QxDaoAsync class to execute queries
  59. */
  60. struct QxDaoAsyncParams
  61. {
  62. enum dao_action { dao_none, dao_count, dao_fetch_by_id, dao_fetch_all, dao_fetch_by_query, dao_insert,
  63. dao_update, dao_save, dao_delete_by_id, dao_delete_all, dao_delete_by_query,
  64. dao_destroy_by_id, dao_destroy_all, dao_destroy_by_query, dao_execute_query, dao_call_query };
  65. dao_action daoAction; //!< Action to execute into the thread (asynchronous way)
  66. QString className; //!< Classname parameter to execute action (must implement qx::IxPersistable interface)
  67. qx::QxSqlQuery query; //!< Query parameter to execute action
  68. QSqlDatabase * pDatabase; //!< Database parameter to execute action
  69. IxPersistable_ptr pInstance; //!< Current instance parameter to execute action
  70. IxPersistableCollection_ptr pListOfInstances; //!< List of instances fetched by query
  71. QStringList listColumns; //!< List of columns parameter to execute action
  72. QStringList listRelations; //!< List of relationships parameter to execute action
  73. QVariant id; //!< Current instance id parameter to execute action
  74. long daoCount; //!< Dao count value returned by qx::dao::count query
  75. QxDaoAsyncParams() : daoAction(dao_none), pDatabase(NULL), daoCount(0) { ; }
  76. ~QxDaoAsyncParams() { ; }
  77. };
  78. typedef std::shared_ptr<QxDaoAsyncParams> QxDaoAsyncParams_ptr;
  79. /*!
  80. * \ingroup QxDao
  81. * \brief qx::dao::detail::QxDaoAsyncRunner : class with a slot to execute queries in another thread
  82. */
  83. class QX_DLL_EXPORT QxDaoAsyncRunner : public QObject
  84. {
  85. Q_OBJECT
  86. public:
  87. QxDaoAsyncRunner();
  88. virtual ~QxDaoAsyncRunner();
  89. protected:
  90. QSqlError runQuery(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  91. Q_SIGNALS:
  92. void queryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  93. public Q_SLOTS:
  94. void onQueryStarted(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  95. };
  96. } // namespace detail
  97. } // namespace dao
  98. /*!
  99. * \ingroup QxDao
  100. * \brief qx::QxDaoAsync : helper class to execute SQL queries in another thread (asynchronous way) using qx::IxPersistable interface
  101. *
  102. * To use <i>qx::QxDaoAsync</i> helper class :
  103. * 1- be careful to work only with classes implementing <i>qx::IxPersistable</i> interface ;
  104. * 2- create an instance of <i>qx::QxDaoAsync</i> type (for example, a property of a QWidget derived class) ;
  105. * 3- connect a SLOT to the <i>qx::QxDaoAsync::queryFinished()</i> SIGNAL (for example, a SLOT of a QWidget derived class) ;
  106. * 4- run a query using one of <i>qx::QxDaoAsync::asyncXXXX()</i> methods.
  107. *
  108. * For example, with a <i>MyWidget</i> class :
  109. * \code
  110. class MyWidget : public QWidget
  111. {
  112. Q_OBJECT
  113. //...
  114. qx::QxDaoAsync m_daoAsync;
  115. //...
  116. Q_SLOTS:
  117. void onQueryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  118. //...
  119. };
  120. * \endcode
  121. * And here is the implementation of <i>MyWidget</i> class :
  122. * \code
  123. MyWidget::MyWidget() : QObject()
  124. {
  125. //...
  126. QObject::connect((& m_daoAsync), SIGNAL(queryFinished(const QSqlError &, qx::dao::detail::QxDaoAsyncParams_ptr)), this, SLOT(onQueryFinished(const QSqlError &, qx::dao::detail::QxDaoAsyncParams_ptr)));
  127. //...
  128. }
  129. void MyWidget::onQueryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams)
  130. {
  131. if (! pDaoParams) { return; }
  132. qx::QxSqlQuery query = pDaoParams->query;
  133. if (! daoError.isValid()) { ; }
  134. // If the async query is associated to a simple object, just use 'pDaoParams->pInstance' method
  135. qx::IxPersistable_ptr ptr = pDaoParams->pInstance;
  136. // If the async query is associated to a list of objects, just use 'pDaoParams->pListOfInstances' method
  137. qx::IxPersistableCollection_ptr lst = pDaoParams->pListOfInstances;
  138. //...
  139. }
  140. * \endcode
  141. */
  142. class QX_DLL_EXPORT QxDaoAsync : public QThread
  143. {
  144. Q_OBJECT
  145. protected:
  146. QMutex m_mutex; //!< Mutex => qx::QxDaoAsync is thread-safe
  147. qx::dao::detail::QxDaoAsyncParams_ptr m_pDaoParams; //!< Parameters to execute query
  148. public:
  149. QxDaoAsync();
  150. virtual ~QxDaoAsync();
  151. bool asyncCount(const QString & className, const qx::QxSqlQuery & query = qx::QxSqlQuery(), QSqlDatabase * pDatabase = NULL);
  152. bool asyncFetchById(IxPersistable_ptr pToFetch, const QVariant & id = QVariant(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  153. bool asyncFetchAll(const QString & className, const QStringList & columns = QStringList(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  154. bool asyncFetchByQuery(const QString & className, const qx::QxSqlQuery & query, const QStringList & columns = QStringList(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  155. bool asyncInsert(IxPersistable_ptr pToInsert, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  156. bool asyncUpdate(IxPersistable_ptr pToUpdate, const qx::QxSqlQuery & query = qx::QxSqlQuery(), const QStringList & columns = QStringList(), const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  157. bool asyncSave(IxPersistable_ptr pToSave, const QStringList & relation = QStringList(), QSqlDatabase * pDatabase = NULL);
  158. bool asyncDeleteById(IxPersistable_ptr pToDelete, const QVariant & id = QVariant(), QSqlDatabase * pDatabase = NULL);
  159. bool asyncDeleteAll(const QString & className, QSqlDatabase * pDatabase = NULL);
  160. bool asyncDeleteByQuery(const QString & className, const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL);
  161. bool asyncDestroyById(IxPersistable_ptr pToDestroy, const QVariant & id = QVariant(), QSqlDatabase * pDatabase = NULL);
  162. bool asyncDestroyAll(const QString & className, QSqlDatabase * pDatabase = NULL);
  163. bool asyncDestroyByQuery(const QString & className, const qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL);
  164. bool asyncExecuteQuery(const QString & className, qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL);
  165. bool asyncCallQuery(qx::QxSqlQuery & query, QSqlDatabase * pDatabase = NULL);
  166. bool isQueryRunning() const { return (m_pDaoParams.get() != NULL); }
  167. protected:
  168. virtual void run();
  169. void startQuery();
  170. Q_SIGNALS:
  171. void queryStarted(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  172. void queryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  173. private Q_SLOTS:
  174. void onQueryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
  175. };
  176. typedef std::shared_ptr<QxDaoAsync> QxDaoAsync_ptr;
  177. } // namespace qx
  178. #endif // _QX_DAO_ASYNC_H_