Jesus Fernandez
Jesus Fernandez

Reputation: 1290

QThread to send large queries to the database

I have created this class that inherits from QThread for send data to the database server, what do you think about it? Could be impreved?

Thanks

#ifndef QUERYTHREAD_H
#define QUERYTHREAD_H

#include 

class QSqlQuery;

class QueryThread : public QThread {
    public slots:
        bool exec(QSqlQuery *query, Priority priority=InheritPriority);
    protected:
        virtual void run();
    private:
        bool m_hasError;
        QSqlQuery *q;
};

#endif // QUERYTHREAD_H
#include "querythread.h"

#include 
#include 

bool QueryThread::exec(QSqlQuery *query, Priority priority)
{
    q=query;
    start(priority);
    while(isRunning()) qApp->processEvents();
    return m_hasError;
}

void QueryThread::run()
{ m_hasError=q->exec(); }

Upvotes: 3

Views: 799

Answers (1)

spraff
spraff

Reputation: 33405

A couple of opinions:

That while loop in exec elimiates the advantages of having a separate thread. You should pass the query in at the constructor, have one thread per query, don't override exec, prefer to just use start and use signals to asynchronously report any error.

You should also pass the QSqlQuery by value or store it in a managed pointer such as std::auto_ptr (or std::unique_ptr for C++11). Many Qt classes are implicitly shared (although not this one) but managed pointers gain you exception safety.

Personally, I would have simply done something like this

class Query : public QThread {

    QSqlQuery m_query;
    // I prefer values unless there's a particular reason to use pointers.

public:

    Query (const QSqlQuery & query)
    : m_query (query)
    {
    }

    void run ()
    {
        emit finished (m_query .exec ());
        deleteLater ();
    }

public signals:

    void finished (bool);
};

Query * q = new Query ("SELECT foo FROM bar");

connect (q, SIGNAL (finished (bool), ...);

q -> start ();

Upvotes: 3

Related Questions