mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-05-18 11:38:24 -05:00
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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 \
|
||||
|
||||
Reference in New Issue
Block a user