1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#ifndef ASYNCQUERYRUNNER_H
#define ASYNCQUERYRUNNER_H
#include "db.h"
#include <QVariant>
#include <QHash>
#include <QRunnable>
#include <QString>
#include <QPointer>
#include <QByteArray>
/**
* @brief Direct query executor to be run in a thread.
*
* It's an implementation of QRunnable (so it can be run simply within QThread),
* that takes query string and arguments for the query and executes the query
* in separate thread (the one that is owning the runner).
*
* The runner is not deleted automatically. Instead the slot for finished() signal
* has to delete it. It's done like that because the slot will also be interested
* in execution results and asyncId, before the runner gets deleted.
*
* What it does is simply execute Db::exec() from another thread.
*
* It's a kind of helper class that is used to implement Db::asyncExec().
*/
class AsyncQueryRunner : public QObject, public QRunnable
{
Q_OBJECT
public:
/**
* @brief Creates runner and defines basic parameters.
* @param query Query string to be executed.
* @param args Parameters to the query (can be either QHash or QList).
* @param flags Execution flags, that will be later passed to Db::exec().
*
* It's not enough to just create runner. You also need to define db with setDb()
* and asyncId with setAsyncId().
*/
AsyncQueryRunner(const QString& query, const QVariant& args, Db::Flags flags);
/**
* @brief Executes query.
*
* This is the major method inherited from QRunnable. It's called from another thread
* and it executes the query.
*/
void run();
/**
* @brief Provides result from execution.
* @return Execution results.
*/
SqlQueryPtr getResults();
/**
* @brief Defines database for execution.
* @param db Database object.
*/
void setDb(Db* db);
/**
* @brief Defines asynchronous ID for this execution.
* @param id Unique ID.
*/
void setAsyncId(quint32 id);
/**
* @brief Provides previously defined asynchronous ID.
* @return Unique asynchronous ID.
*/
quint32 getAsyncId();
private:
/**
* @brief Initializes default values.
*/
void init();
/**
* @brief Database to execute the query on.
*/
Db* db = nullptr;
/**
* @brief Query to execute.
*/
QString query;
/**
* @brief Results from execution.
*/
SqlQueryPtr results;
/**
* @brief Parameters for execution.
*
* It's either QList<QVariant> or QHash<QString,QVariant>. If it's anything else,
* then no execution will be performed and critical error will be logged.
*/
QVariant args;
/**
* @brief The unique asynchronous ID for this query execution.
*/
quint32 asyncId;
/**
* @brief Execution flags passed to Db::exec().
*/
Db::Flags flags;
signals:
/**
* @brief Emitted after the runner has finished its job.
*
* Slot connected to this signal should at least delete the runner,
* but it can also extract execution results.
*/
void finished(AsyncQueryRunner*);
};
#endif // ASYNCQUERYRUNNER_H
|