Move fetching data for data browsing to a separate thread

This moves the data fetching code into a separate thread for
asynchronous execution. The Browse Data and the Execute SQL tabs are
affected by this.

Note that this is a somewhat naive implementation that is meant for some
first testing.
This commit is contained in:
Martin Kleusberg
2017-05-04 18:58:38 +02:00
parent 3ff686d96f
commit 6da71b6788
5 changed files with 93 additions and 32 deletions
+2
View File
@@ -117,6 +117,7 @@ set(SQLB_MOC_HDR
src/PlotDock.h
src/RemoteDock.h
src/RemoteModel.h
src/SqlThread.h
)
set(SQLB_SRC
@@ -154,6 +155,7 @@ set(SQLB_SRC
src/PlotDock.cpp
src/RemoteDock.cpp
src/RemoteModel.cpp
src/SqlThread.cpp
)
set(SQLB_FORMS
+49
View File
@@ -0,0 +1,49 @@
#include "SqlThread.h"
#include "sqlitedb.h"
#include "sqlite.h"
SqlThread::SqlThread(DBBrowserDB& db, const QString& query, int column_count, QList<QByteArrayList>& result)
: m_db(db),
m_query(query),
m_columnCount(column_count),
m_result(result)
{
}
void SqlThread::run()
{
// Prepare statement
QByteArray utf8Query = m_query.toUtf8();
sqlite3_stmt *stmt;
if(sqlite3_prepare_v2(m_db._db, utf8Query, utf8Query.size(), &stmt, NULL) == SQLITE_OK)
{
// Fetch rows
while(sqlite3_step(stmt) == SQLITE_ROW)
{
// Fetch columns
QByteArrayList rowdata;
for(int i=0;i<m_columnCount;++i)
{
// Null?
if(sqlite3_column_type(stmt, i) == SQLITE_NULL)
{
rowdata.append(QByteArray());
} else {
// Some data or empty string?
int bytes = sqlite3_column_bytes(stmt, i);
if(bytes)
rowdata.append(QByteArray(static_cast<const char*>(sqlite3_column_blob(stmt, i)), bytes));
else
rowdata.append(QByteArray(""));
}
}
// Save row
m_result.push_back(rowdata);
}
}
// Clean up
sqlite3_finalize(stmt);
emit done();
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef SQLTHREAD_H
#define SQLTHREAD_H
#include <QThread>
class DBBrowserDB;
class SqlThread : public QThread
{
Q_OBJECT
public:
SqlThread(DBBrowserDB& db, const QString& query, int column_count, QList<QByteArrayList>& result);
void run();
signals:
void done();
private:
DBBrowserDB& m_db;
QString m_query;
int m_columnCount;
QList<QByteArrayList>& m_result;
};
#endif
+11 -30
View File
@@ -2,6 +2,7 @@
#include "sqlitedb.h"
#include "sqlite.h"
#include "Settings.h"
#include "SqlThread.h"
#include <QDebug>
#include <QMessageBox>
@@ -494,39 +495,19 @@ void SqliteTableModel::fetchData(unsigned int from, unsigned to)
sLimitQuery = queryTemp + QString(" LIMIT %1, %2;").arg(from).arg(to-from);
}
m_db.logSQL(sLimitQuery, kLogMsg_App);
QByteArray utf8Query = sLimitQuery.toUtf8();
sqlite3_stmt *stmt;
int status = sqlite3_prepare_v2(m_db._db, utf8Query, utf8Query.size(), &stmt, NULL);
if(SQLITE_OK == status)
{
while(sqlite3_step(stmt) == SQLITE_ROW)
// Fetch data in separate thread
SqlThread* thread = new SqlThread(m_db, sLimitQuery, m_headers.size(), m_data);
connect(thread, &SqlThread::done, [this, currentsize]() {
// Check if there was any new data
if(m_data.size() > currentsize)
{
QByteArrayList rowdata;
for (int i = 0; i < m_headers.size(); ++i)
{
if(sqlite3_column_type(stmt, i) == SQLITE_NULL)
{
rowdata.append(QByteArray());
} else {
int bytes = sqlite3_column_bytes(stmt, i);
if(bytes)
rowdata.append(QByteArray(static_cast<const char*>(sqlite3_column_blob(stmt, i)), bytes));
else
rowdata.append(QByteArray(""));
}
}
m_data.push_back(rowdata);
beginInsertRows(QModelIndex(), currentsize, m_data.size()-1);
endInsertRows();
}
}
sqlite3_finalize(stmt);
// Check if there was any new data
if(m_data.size() > currentsize)
{
beginInsertRows(QModelIndex(), currentsize, m_data.size()-1);
endInsertRows();
}
});
connect(thread, &SqlThread::finished, thread, &QObject::deleteLater);
thread->start();
}
void SqliteTableModel::buildQuery()
+4 -2
View File
@@ -56,7 +56,8 @@ HEADERS += \
ForeignKeyEditorDelegate.h \
PlotDock.h \
RemoteDock.h \
RemoteModel.h
RemoteModel.h \
SqlThread.h
SOURCES += \
sqlitedb.cpp \
@@ -91,7 +92,8 @@ SOURCES += \
ForeignKeyEditorDelegate.cpp \
PlotDock.cpp \
RemoteDock.cpp \
RemoteModel.cpp
RemoteModel.cpp \
SqlThread.cpp
RESOURCES += icons/icons.qrc \
translations/flags/flags.qrc \