QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsqueryresultmodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsqueryresultmodel.cpp - QgsQueryResultModel
3 
4  ---------------------
5  begin : 24.12.2020
6  copyright : (C) 2020 by Alessandro Pasotti
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 #include "qgsqueryresultmodel.h"
17 
19  : QAbstractTableModel( parent )
20  , mQueryResult( queryResult )
21  , mColumns( queryResult.columns() )
22 {
23  qRegisterMetaType< QList<QList<QVariant>>>( "QList<QList<QVariant>>" );
24  if ( mQueryResult.hasNextRow() )
25  {
26  mWorker = new QgsQueryResultFetcher( &mQueryResult );
27  mWorker->moveToThread( &mWorkerThread );
28  connect( &mWorkerThread, &QThread::started, mWorker, &QgsQueryResultFetcher::fetchRows );
29  connect( mWorker, &QgsQueryResultFetcher::rowsReady, this, &QgsQueryResultModel::rowsReady );
30  mWorkerThread.start();
31  }
32 }
33 
34 void QgsQueryResultModel::rowsReady( const QList<QList<QVariant>> &rows )
35 {
36  beginInsertRows( QModelIndex(), mRows.count( ), mRows.count( ) + rows.count() - 1 );
37  mRows.append( rows );
38  endInsertRows();
39 }
40 
42 {
43  if ( mWorker )
44  {
45  mWorker->stopFetching();
46  }
47 }
48 
50 {
51  if ( mWorker )
52  {
53  mWorker->stopFetching();
54  mWorkerThread.quit();
55  mWorkerThread.wait();
56  mWorker->deleteLater();
57  }
58 }
59 
60 int QgsQueryResultModel::rowCount( const QModelIndex &parent ) const
61 {
62  if ( parent.isValid() )
63  return 0;
64  return mRows.count();
65 }
66 
67 int QgsQueryResultModel::columnCount( const QModelIndex &parent ) const
68 {
69  if ( parent.isValid() )
70  return 0;
71  return mColumns.count();
72 }
73 
74 QVariant QgsQueryResultModel::data( const QModelIndex &index, int role ) const
75 {
76  if ( !index.isValid() || index.row() < 0 || index.column() >= mColumns.count() ||
77  index.row() >= mRows.count( ) )
78  return QVariant();
79 
80  switch ( role )
81  {
82  case Qt::DisplayRole:
83  {
84  const QList<QVariant> result = mRows.at( index.row() );
85  if ( index.column() < result.count( ) )
86  {
87  return result.at( index.column() );
88  }
89  break;
90  }
91  }
92  return QVariant();
93 }
94 
95 QVariant QgsQueryResultModel::headerData( int section, Qt::Orientation orientation, int role ) const
96 {
97  if ( orientation == Qt::Orientation::Horizontal && role == Qt::ItemDataRole::DisplayRole && section < mColumns.count() )
98  {
99  return mColumns.at( section );
100  }
101  return QAbstractTableModel::headerData( section, orientation, role );
102 }
103 
105 
106 const int QgsQueryResultFetcher::ROWS_TO_FETCH = 200;
107 
108 void QgsQueryResultFetcher::fetchRows()
109 {
110  qlonglong rowCount { 0 };
111  QList<QList<QVariant>> newRows;
112  while ( mStopFetching == 0 && mQueryResult->hasNextRow() )
113  {
114  newRows.append( mQueryResult->nextRow() );
115  ++rowCount;
116  if ( rowCount % ROWS_TO_FETCH == 0 && mStopFetching == 0 )
117  {
118  emit rowsReady( newRows );
119  newRows.clear();
120  }
121  }
122 
123  if ( rowCount % ROWS_TO_FETCH && mStopFetching == 0 )
124  {
125  emit rowsReady( newRows );
126  }
127 }
128 
129 void QgsQueryResultFetcher::stopFetching()
130 {
131  mStopFetching = 1;
132 }
133 
134 
int rowCount(const QModelIndex &parent) const override
QgsQueryResultModel(const QgsAbstractDatabaseProviderConnection::QueryResult &queryResult, QObject *parent=nullptr)
Constructs a QgsQueryResultModel from a queryResult with optional parent.
void rowsReady(const QList< QList< QVariant > > &rows)
Triggered when newRows have been fetched and can be added to the model.
QVariant data(const QModelIndex &index, int role) const override
int columnCount(const QModelIndex &parent) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void cancel()
Cancels the row fetching.
The QueryResult class represents the result of a query executed by execSql()
bool hasNextRow() const
Returns true if there are more rows to fetch.