239 lines
10 KiB
C++
239 lines
10 KiB
C++
/****************************************************************************
|
|
**
|
|
** https://www.qxorm.com/
|
|
** Copyright (C) 2013 XDL Team (ic-east.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 XDL Team
|
|
**
|
|
** 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 :
|
|
** ic-east.com
|
|
**
|
|
****************************************************************************/
|
|
|
|
#ifndef _QX_DAO_ASYNC_H_
|
|
#define _QX_DAO_ASYNC_H_
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma once
|
|
#endif
|
|
|
|
/*!
|
|
* \file QxDaoAsync.h
|
|
* \author XDL Team
|
|
* \ingroup QxDao
|
|
* \brief Helper class to execute SQL queries in another thread (asynchronous way) using qx::IxPersistable interface
|
|
*/
|
|
|
|
#ifdef _QX_NO_PRECOMPILED_HEADER
|
|
#ifndef Q_MOC_RUN
|
|
#include <QxPrecompiled.h> // Need to include precompiled header for the generated moc file
|
|
#endif // Q_MOC_RUN
|
|
#endif // _QX_NO_PRECOMPILED_HEADER
|
|
|
|
#include <QtCore/qqueue.h>
|
|
|
|
#include <QtSql/qsqlerror.h>
|
|
|
|
#ifndef Q_MOC_RUN
|
|
#include <QxDao/IxPersistable.h>
|
|
#include <QxDao/QxSqlQuery.h>
|
|
#endif // Q_MOC_RUN
|
|
|
|
namespace qx
|
|
{
|
|
namespace dao
|
|
{
|
|
namespace detail
|
|
{
|
|
|
|
/*!
|
|
* \ingroup QxDao
|
|
* \brief qx::dao::detail::QxDaoAsyncParams : all parameters for qx::QxDaoAsync class to execute queries
|
|
*/
|
|
struct QxDaoAsyncParams
|
|
{
|
|
|
|
enum dao_action
|
|
{
|
|
dao_none,
|
|
dao_count,
|
|
dao_fetch_by_id,
|
|
dao_fetch_all,
|
|
dao_fetch_by_query,
|
|
dao_insert,
|
|
dao_update,
|
|
dao_save,
|
|
dao_delete_by_id,
|
|
dao_delete_all,
|
|
dao_delete_by_query,
|
|
dao_destroy_by_id,
|
|
dao_destroy_all,
|
|
dao_destroy_by_query,
|
|
dao_execute_query,
|
|
dao_call_query
|
|
};
|
|
|
|
dao_action daoAction; //!< Action to execute into the thread (asynchronous way)
|
|
QString className; //!< Classname parameter to execute action (must implement qx::IxPersistable interface)
|
|
qx::QxSqlQuery query; //!< Query parameter to execute action
|
|
QSqlDatabase *pDatabase; //!< Database parameter to execute action
|
|
IxPersistable_ptr pInstance; //!< Current instance parameter to execute action
|
|
IxPersistableCollection_ptr pListOfInstances; //!< List of instances fetched by query
|
|
QStringList listColumns; //!< List of columns parameter to execute action
|
|
QStringList listRelations; //!< List of relationships parameter to execute action
|
|
QVariant id; //!< Current instance id parameter to execute action
|
|
long daoCount; //!< Dao count value returned by qx::dao::count query
|
|
bool useExecBatch; //!< If true then use the QSqlQuery::execBatch() method to improve performance inserting/updating/deleting a list of instances to database (but doesn't fill the last inserted identifier in the C++ instances)
|
|
|
|
QxDaoAsyncParams() : daoAction(dao_none), pDatabase(NULL), daoCount(0), useExecBatch(false) { ; }
|
|
~QxDaoAsyncParams() { ; }
|
|
};
|
|
|
|
typedef std::shared_ptr<QxDaoAsyncParams> QxDaoAsyncParams_ptr;
|
|
|
|
/*!
|
|
* \ingroup QxDao
|
|
* \brief qx::dao::detail::QxDaoAsyncRunner : class with a slot to execute queries in another thread
|
|
*/
|
|
class QX_DLL_EXPORT QxDaoAsyncRunner : public QObject
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
QxDaoAsyncRunner();
|
|
virtual ~QxDaoAsyncRunner();
|
|
|
|
protected:
|
|
QSqlError runQuery(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
|
|
Q_SIGNALS:
|
|
|
|
void queryFinished(const QSqlError &daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
|
|
public Q_SLOTS:
|
|
|
|
void onQueryStarted(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
};
|
|
|
|
} // namespace detail
|
|
} // namespace dao
|
|
|
|
/*!
|
|
* \ingroup QxDao
|
|
* \brief qx::QxDaoAsync : helper class to execute SQL queries in another thread (asynchronous way) using qx::IxPersistable interface
|
|
*
|
|
* To use <i>qx::QxDaoAsync</i> helper class :
|
|
* 1- be careful to work only with classes implementing <i>qx::IxPersistable</i> interface ;
|
|
* 2- create an instance of <i>qx::QxDaoAsync</i> type (for example, a property of a QWidget derived class) ;
|
|
* 3- connect a SLOT to the <i>qx::QxDaoAsync::queryFinished()</i> SIGNAL (for example, a SLOT of a QWidget derived class) ;
|
|
* 4- run a query using one of <i>qx::QxDaoAsync::asyncXXXX()</i> methods.
|
|
*
|
|
* For example, with a <i>MyWidget</i> class :
|
|
* \code
|
|
class MyWidget : public QWidget
|
|
{
|
|
Q_OBJECT
|
|
//...
|
|
qx::QxDaoAsync m_daoAsync;
|
|
//...
|
|
Q_SLOTS:
|
|
void onQueryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
//...
|
|
};
|
|
* \endcode
|
|
* And here is the implementation of <i>MyWidget</i> class :
|
|
* \code
|
|
MyWidget::MyWidget() : QObject()
|
|
{
|
|
//...
|
|
QObject::connect((& m_daoAsync), SIGNAL(queryFinished(const QSqlError &, qx::dao::detail::QxDaoAsyncParams_ptr)), this, SLOT(onQueryFinished(const QSqlError &, qx::dao::detail::QxDaoAsyncParams_ptr)));
|
|
//...
|
|
}
|
|
void MyWidget::onQueryFinished(const QSqlError & daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams)
|
|
{
|
|
if (! pDaoParams) { return; }
|
|
qx::QxSqlQuery query = pDaoParams->query;
|
|
if (! daoError.isValid()) { ; }
|
|
// If the async query is associated to a simple object, just use 'pDaoParams->pInstance' method
|
|
qx::IxPersistable_ptr ptr = pDaoParams->pInstance;
|
|
// If the async query is associated to a list of objects, just use 'pDaoParams->pListOfInstances' method
|
|
qx::IxPersistableCollection_ptr lst = pDaoParams->pListOfInstances;
|
|
//...
|
|
}
|
|
* \endcode
|
|
*/
|
|
class QX_DLL_EXPORT QxDaoAsync : public QThread
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
protected:
|
|
QMutex m_mutex; //!< Mutex => qx::QxDaoAsync is thread-safe
|
|
qx::dao::detail::QxDaoAsyncParams_ptr m_pDaoParams; //!< Parameters to execute query
|
|
|
|
public:
|
|
QxDaoAsync();
|
|
virtual ~QxDaoAsync();
|
|
|
|
bool asyncCount(const QString &className, const qx::QxSqlQuery &query = qx::QxSqlQuery(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncFetchById(IxPersistable_ptr pToFetch, const QVariant &id = QVariant(), const QStringList &columns = QStringList(), const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncFetchAll(const QString &className, const QStringList &columns = QStringList(), const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncFetchByQuery(const QString &className, const qx::QxSqlQuery &query, const QStringList &columns = QStringList(), const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncInsert(IxPersistable_ptr pToInsert, const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncUpdate(IxPersistable_ptr pToUpdate, const qx::QxSqlQuery &query = qx::QxSqlQuery(), const QStringList &columns = QStringList(), const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncSave(IxPersistable_ptr pToSave, const QStringList &relation = QStringList(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDeleteById(IxPersistable_ptr pToDelete, const QVariant &id = QVariant(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDeleteAll(const QString &className, QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDeleteByQuery(const QString &className, const qx::QxSqlQuery &query, QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDestroyById(IxPersistable_ptr pToDestroy, const QVariant &id = QVariant(), QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDestroyAll(const QString &className, QSqlDatabase *pDatabase = NULL);
|
|
bool asyncDestroyByQuery(const QString &className, const qx::QxSqlQuery &query, QSqlDatabase *pDatabase = NULL);
|
|
bool asyncExecuteQuery(const QString &className, qx::QxSqlQuery &query, QSqlDatabase *pDatabase = NULL);
|
|
bool asyncCallQuery(qx::QxSqlQuery &query, QSqlDatabase *pDatabase = NULL);
|
|
|
|
bool isQueryRunning() const { return (m_pDaoParams.get() != NULL); }
|
|
|
|
protected:
|
|
virtual void run();
|
|
|
|
void startQuery();
|
|
|
|
Q_SIGNALS:
|
|
|
|
void queryStarted(qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
void queryFinished(const QSqlError &daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
|
|
private Q_SLOTS:
|
|
|
|
void onQueryFinished(const QSqlError &daoError, qx::dao::detail::QxDaoAsyncParams_ptr pDaoParams);
|
|
};
|
|
|
|
typedef std::shared_ptr<QxDaoAsync> QxDaoAsync_ptr;
|
|
|
|
} // namespace qx
|
|
|
|
QX_DLL_EXPORT QDataStream &operator<<(QDataStream &stream, const qx::dao::detail::QxDaoAsyncParams &t) QX_USED;
|
|
QX_DLL_EXPORT QDataStream &operator>>(QDataStream &stream, qx::dao::detail::QxDaoAsyncParams &t) QX_USED;
|
|
|
|
#endif // _QX_DAO_ASYNC_H_
|