Navigation Menu

Skip to content

Commit

Permalink
Final touches
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Jul 6, 2021
1 parent d819069 commit 06495f0
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 14 deletions.
6 changes: 4 additions & 2 deletions python/core/auto_generated/qgsqueryresultmodel.sip.in
Expand Up @@ -76,17 +76,19 @@ Cancels the row fetching.

void fetchingComplete();
%Docstring
Emitted when all rows have been fetched or when the fetching has been stopped
Emitted when all rows have been fetched or when the fetching has been stopped (canceled)
%End

void fetchMoreRows( qlonglong maxRows );
%Docstring
Emitted when more rows are requested

:param maxRows: the number of rows that will be fetched
%End

void fetchingStarted();
%Docstring
Emitted when fetching of rows starts
Emitted when fetching of rows has started
%End

};
Expand Down
13 changes: 7 additions & 6 deletions src/core/qgsqueryresultmodel.cpp
Expand Up @@ -15,6 +15,8 @@
***************************************************************************/
#include "qgsqueryresultmodel.h"

const int QgsQueryResultModel::FETCH_MORE_ROWS_COUNT = 400;

QgsQueryResultModel::QgsQueryResultModel( const QgsAbstractDatabaseProviderConnection::QueryResult &queryResult, QObject *parent )
: QAbstractTableModel( parent )
, mQueryResult( queryResult )
Expand All @@ -23,7 +25,6 @@ QgsQueryResultModel::QgsQueryResultModel( const QgsAbstractDatabaseProviderConne
qRegisterMetaType< QList<QList<QVariant>>>( "QList<QList<QVariant>>" );
mWorker = std::make_unique<QgsQueryResultFetcher>( &mQueryResult );
mWorker->moveToThread( &mWorkerThread );
//connect( &mWorkerThread, &QThread::started, mWorker.get(), [ = ] () { mWorker->fetchRows( 1000 ); }, Qt::ConnectionType::QueuedConnection );
// Forward signals to the model
connect( mWorker.get(), &QgsQueryResultFetcher::rowsReady, this, &QgsQueryResultModel::rowsReady );
connect( mWorker.get(), &QgsQueryResultFetcher::fetchingComplete, this, &QgsQueryResultModel::fetchingComplete );
Expand Down Expand Up @@ -56,7 +57,7 @@ void QgsQueryResultModel::fetchMore( const QModelIndex &parent )
if ( ! parent.isValid() )
{
emit fetchingStarted();
emit fetchMoreRows( 1000 );
emit fetchMoreRows( FETCH_MORE_ROWS_COUNT );
}
}

Expand Down Expand Up @@ -138,25 +139,25 @@ QVariant QgsQueryResultModel::headerData( int section, Qt::Orientation orientati

///@cond private

const int QgsQueryResultFetcher::ROWS_TO_FETCH = 200;
const int QgsQueryResultFetcher::ROWS_BATCH_COUNT = 200;

void QgsQueryResultFetcher::fetchRows( qlonglong maxRows )
{
qlonglong rowCount { 0 };
QList<QList<QVariant>> newRows;
newRows.reserve( ROWS_TO_FETCH );
newRows.reserve( ROWS_BATCH_COUNT );
while ( mStopFetching == 0 && mQueryResult->hasNextRow() && ( maxRows < 0 || rowCount < maxRows ) )
{
newRows.append( mQueryResult->nextRow() );
++rowCount;
if ( rowCount % ROWS_TO_FETCH == 0 && mStopFetching == 0 )
if ( rowCount % ROWS_BATCH_COUNT == 0 && mStopFetching == 0 )
{
emit rowsReady( newRows );
newRows.clear();
}
}

if ( rowCount % ROWS_TO_FETCH && mStopFetching == 0 )
if ( rowCount % ROWS_BATCH_COUNT && mStopFetching == 0 )
{
emit rowsReady( newRows );
}
Expand Down
20 changes: 15 additions & 5 deletions src/core/qgsqueryresultmodel.h
Expand Up @@ -61,8 +61,8 @@ class QgsQueryResultFetcher: public QObject

const QgsAbstractDatabaseProviderConnection::QueryResult *mQueryResult = nullptr;
QAtomicInt mStopFetching = 0;
// Batch of rows to fetch before emitting rowsReady
static const int ROWS_TO_FETCH;
// Number of rows rows to fetch before emitting rowsReady
static const int ROWS_BATCH_COUNT;

};

Expand Down Expand Up @@ -124,13 +124,20 @@ class CORE_EXPORT QgsQueryResultModel : public QAbstractTableModel

signals:

//! Emitted when all rows have been fetched or when the fetching has been stopped
/**
* Emitted when all rows have been fetched or when the fetching has been stopped (canceled)
*/
void fetchingComplete();

//! Emitted when more rows are requested
/**
* Emitted when more rows are requested
* \param maxRows the number of rows that will be fetched
*/
void fetchMoreRows( qlonglong maxRows );

//! Emitted when fetching of rows starts
/**
* Emitted when fetching of rows has started
*/
void fetchingStarted();

private:
Expand All @@ -141,6 +148,9 @@ class CORE_EXPORT QgsQueryResultModel : public QAbstractTableModel
std::unique_ptr<QgsQueryResultFetcher> mWorker;
QList<QVariantList> mRows;

//! Number of rows to fetch when more rows are required, generally bigger than ROWS_BATCH_COUNT
static const int FETCH_MORE_ROWS_COUNT;

};

#endif // qgsqueryresultmodel.h
3 changes: 3 additions & 0 deletions tests/src/gui/testqgsqueryresultwidget.cpp
Expand Up @@ -88,7 +88,10 @@ void TestQgsQueryResultWidget::testWidgetCrash()
QTimer::singleShot( 1, model, [ & ] { delete res; } );
QTimer::singleShot( 2, model, [ & ] { exited = true; } );
while ( ! exited )
{
model->fetchMore( QModelIndex( ) );
QgsApplication::processEvents();
}
const auto rowCount { model->rowCount( model->index( -1, -1 ) ) };
QVERIFY( rowCount > 0 && rowCount < 100000 );
delete model;
Expand Down
6 changes: 5 additions & 1 deletion tests/src/python/test_qgsqueryresultmodel.py
Expand Up @@ -21,7 +21,7 @@
QgsAbstractDatabaseProviderConnection,
)
from qgis.testing import unittest, start_app
from qgis.PyQt.QtCore import QCoreApplication, QVariant, Qt, QTimer
from qgis.PyQt.QtCore import QCoreApplication, QVariant, Qt, QTimer, QModelIndex
from qgis.PyQt.QtWidgets import QListView, QDialog, QVBoxLayout, QLabel
from qgis.PyQt.QtTest import QAbstractItemModelTester

Expand Down Expand Up @@ -111,6 +111,10 @@ def loop_exiter():
QTimer.singleShot(600, loop_exiter)

while self.running:
try:
self.model.fetchMore(QModelIndex())
except:
pass
QCoreApplication.processEvents()

row_count = res.fetchedRowCount()
Expand Down

0 comments on commit 06495f0

Please sign in to comment.