Skip to content

Commit b8e5a34

Browse files
committedNov 30, 2011
[FEATURE] allow to disable SelectAtId capability for PostgreSQL provider to
force usage of the attribute table memory model. Apparently the memory model was completely disfunctional before. Fixes included, but it probably needs more testing.
1 parent ee9b8d7 commit b8e5a34

13 files changed

+140
-37
lines changed
 

‎src/core/qgsdatasourceuri.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,20 @@
2222
#include <QStringList>
2323
#include <QRegExp>
2424

25-
QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
25+
QgsDataSourceURI::QgsDataSourceURI()
26+
: mSSLmode( SSLprefer )
27+
, mKeyColumn( "" )
28+
, mUseEstimatedMetadata( false )
29+
, mSelectAtIdDisabled( false )
2630
{
2731
// do nothing
2832
}
2933

30-
QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
34+
QgsDataSourceURI::QgsDataSourceURI( QString uri )
35+
: mSSLmode( SSLprefer )
36+
, mKeyColumn( "" )
37+
, mUseEstimatedMetadata( false )
38+
, mSelectAtIdDisabled( false )
3139
{
3240
int i = 0;
3341
while ( i < uri.length() )
@@ -115,6 +123,10 @@ QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyC
115123
{
116124
mUseEstimatedMetadata = pval == "true";
117125
}
126+
else if ( pname == "selectatid" )
127+
{
128+
mSelectAtIdDisabled = pval == "false";
129+
}
118130
else if ( pname == "service" )
119131
{
120132
mService = pval;
@@ -309,6 +321,16 @@ bool QgsDataSourceURI::useEstimatedMetadata() const
309321
return mUseEstimatedMetadata;
310322
}
311323

324+
void QgsDataSourceURI::disableSelectAtId( bool theFlag )
325+
{
326+
mSelectAtIdDisabled = theFlag;
327+
}
328+
329+
bool QgsDataSourceURI::selectAtIdDisabled() const
330+
{
331+
return mSelectAtIdDisabled;
332+
}
333+
312334
void QgsDataSourceURI::setSql( QString sql )
313335
{
314336
mSql = sql;
@@ -461,6 +483,11 @@ QString QgsDataSourceURI::uri() const
461483
theUri += QString( " estimatedmetadata=true" );
462484
}
463485

486+
if ( mSelectAtIdDisabled )
487+
{
488+
theUri += QString( " selectatid=false" );
489+
}
490+
464491
theUri += QString( " table=%1%2 sql=%3" )
465492
.arg( quotedTablename() )
466493
.arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )

‎src/core/qgsdatasourceuri.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class CORE_EXPORT QgsDataSourceURI
9797
void setUseEstimatedMetadata( bool theFlag );
9898
bool useEstimatedMetadata() const;
9999

100+
void disableSelectAtId( bool theFlag );
101+
bool selectAtIdDisabled() const;
102+
100103
void clearSchema();
101104
void setSql( QString sql );
102105

@@ -147,6 +150,8 @@ class CORE_EXPORT QgsDataSourceURI
147150
QString mKeyColumn;
148151
//Use estimated metadata flag
149152
bool mUseEstimatedMetadata;
153+
//Disable SelectAtId capability (eg. to trigger the attribute table memory model for expensive views)
154+
bool mSelectAtIdDisabled;
150155
};
151156

152157
#endif //QGSDATASOURCEURI_H

‎src/core/qgsdbtablemodel.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ QgsDbTableModel::QgsDbTableModel(): QStandardItemModel(), mTableCount( 0 )
2626
headerLabels << tr( "Type" );
2727
headerLabels << tr( "Geometry column" );
2828
headerLabels << tr( "Primary key column" );
29+
headerLabels << tr( "Select at id" );
2930
headerLabels << tr( "Sql" );
3031
setHorizontalHeaderLabels( headerLabels );
3132
}
@@ -60,17 +61,27 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
6061
QIcon iconFile = iconForType( wkbType );
6162

6263
QList<QStandardItem*> childItemList;
64+
6365
QStandardItem* schemaNameItem = new QStandardItem( schemaName );
6466
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
67+
6568
QStandardItem* typeItem = new QStandardItem( QIcon( iconFile ), type );
6669
typeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
70+
6771
QStandardItem* tableItem = new QStandardItem( tableName );
6872
tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
73+
6974
QStandardItem* geomItem = new QStandardItem( geometryColName );
7075
geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
76+
7177
QStandardItem* pkItem = new QStandardItem( "" );
7278
pkItem->setData( pkCols );
7379
pkItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
80+
81+
QStandardItem* selItem = new QStandardItem( "" );
82+
selItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable );
83+
selItem->setCheckState( Qt::Checked );
84+
7485
QStandardItem* sqlItem = new QStandardItem( sql );
7586
sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
7687

@@ -79,6 +90,7 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
7990
childItemList.push_back( typeItem );
8091
childItemList.push_back( geomItem );
8192
childItemList.push_back( pkItem );
93+
childItemList.push_back( selItem );
8294
childItemList.push_back( sqlItem );
8395

8496
schemaItem->appendRow( childItemList );

‎src/core/qgsdbtablemodel.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,19 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
2828
public:
2929
QgsDbTableModel();
3030
~QgsDbTableModel();
31+
3132
/**Adds entry for one database table to the model*/
3233
void addTableEntry( QString type, QString schemaName, QString tableName, QString geometryColName, const QStringList &pkCols, QString Sql );
34+
3335
/**Sets an sql statement that belongs to a cell specified by a model index*/
3436
void setSql( const QModelIndex& index, const QString& sql );
37+
3538
/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
3639
This is for tables where the type is dectected later by thread*/
3740
void setGeometryTypesForTable( const QString& schema, const QString& table, const QString& attribute, const QString& type );
41+
3842
/**Returns the number of tables in the model*/
39-
int tableCount() const {return mTableCount;}
43+
int tableCount() const { return mTableCount; }
4044

4145
enum columns
4246
{
@@ -45,6 +49,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
4549
dbtmType,
4650
dbtmGeomCol,
4751
dbtmPkCol,
52+
dbtmSelectAtId,
4853
dbtmSql,
4954
dbtmColumns
5055
};
@@ -55,6 +60,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
5560

5661
QIcon iconForType( QGis::WkbType type ) const;
5762
QString displayStringForType( QGis::WkbType type ) const;
63+
5864
/**Returns qgis wkbtype from database typename*/
5965
QGis::WkbType qgisTypeFromDbType( const QString& dbType ) const;
6066
};

‎src/gui/attributetable/qgsattributetablememorymodel.cpp

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,59 @@
2727
// In-Memory model //
2828
/////////////////////
2929

30+
QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer )
31+
: QgsAttributeTableModel( theLayer )
32+
{
33+
QgsDebugMsg( "entered." );
34+
}
35+
3036
void QgsAttributeTableMemoryModel::loadLayer()
3137
{
32-
QgsAttributeTableModel::loadLayer();
33-
mLayer->select( mLayer->pendingAllAttributesList(), QgsRectangle(), false );
38+
QgsDebugMsg( "entered." );
39+
40+
QSettings settings;
41+
int behaviour = settings.value( "/qgis/attributeTableBehaviour", 0 ).toInt();
42+
43+
QgsRectangle rect;
44+
if ( behaviour == 2 )
45+
{
46+
// current canvas only
47+
rect = mCurrentExtent;
48+
}
49+
50+
mLayer->select( mLayer->pendingAllAttributesList(), rect, false );
3451

35-
mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
52+
if( behaviour != 1 )
53+
mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
54+
else
55+
mFeatureMap.reserve( mLayer->selectedFeatureCount() );
56+
57+
int n = 0;
3658

3759
QgsFeature f;
3860
while ( mLayer->nextFeature( f ) )
61+
{
62+
if( behaviour == 1 && !mLayer->selectedFeaturesIds().contains( f.id() ) )
63+
continue;
64+
65+
mIdRowMap.insert( f.id(), n );
66+
mRowIdMap.insert( n, f.id() );
3967
mFeatureMap.insert( f.id(), f );
68+
n++;
69+
}
70+
71+
mFieldCount = mAttributes.size();
4072
}
4173

42-
QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel
43-
( QgsVectorLayer *theLayer )
44-
: QgsAttributeTableModel( theLayer )
74+
int QgsAttributeTableMemoryModel::rowCount( const QModelIndex &parent ) const
4575
{
46-
loadLayer();
76+
Q_UNUSED( parent );
77+
return mFeatureMap.size();
4778
}
4879

49-
bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid )
80+
bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid ) const
5081
{
82+
QgsDebugMsg( QString( "entered featureAtId: %1." ).arg( fid ) );
5183
if ( mFeatureMap.contains( fid ) )
5284
{
5385
mFeat = mFeatureMap[ fid ];
@@ -70,17 +102,14 @@ void QgsAttributeTableMemoryModel::featureDeleted( QgsFeatureId fid )
70102
void QgsAttributeTableMemoryModel::featureAdded( QgsFeatureId fid )
71103
{
72104
QgsDebugMsg( "entered." );
73-
QgsFeature f;
74-
mLayer->featureAtId( fid, f, false, true );
75-
mFeatureMap.insert( fid, f );
76-
QgsAttributeTableModel::featureAdded( fid );
105+
Q_UNUSED( fid );
106+
loadLayer();
77107
}
78108

79109
void QgsAttributeTableMemoryModel::layerDeleted()
80110
{
81111
QgsDebugMsg( "entered." );
82-
mFeatureMap.clear();
83-
QgsAttributeTableModel::layerDeleted();
112+
loadLayer();
84113
}
85114

86115
void QgsAttributeTableMemoryModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )

‎src/gui/attributetable/qgsattributetablememorymodel.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
3232
{
33-
Q_OBJECT;
33+
Q_OBJECT
3434

3535
public:
3636
/**
@@ -39,6 +39,12 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
3939
*/
4040
QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer );
4141

42+
/**
43+
* Returns the number of rows
44+
* @param parent parent index
45+
*/
46+
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
47+
4248
/**
4349
* Remove rows
4450
*/
@@ -75,7 +81,7 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
7581
* @param fid feature id
7682
* @return feature exists
7783
*/
78-
virtual bool featureAtId( QgsFeatureId fid );
84+
virtual bool featureAtId( QgsFeatureId fid ) const;
7985

8086
/**
8187
* Loads the layer into the model

‎src/gui/attributetable/qgsattributetablemodel.cpp

100755100644
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ QgsRectangle QgsAttributeTableModel::mCurrentExtent; // static member
3232
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent )
3333
: QAbstractTableModel( parent )
3434
{
35+
QgsDebugMsg( "entered." );
36+
3537
mFeat.setFeatureId( std::numeric_limits<int>::min() );
3638
mFeatureMap.clear();
3739
mFeatureQueue.clear();
@@ -44,8 +46,6 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObjec
4446
connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
4547
connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
4648
connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
47-
48-
loadLayer();
4949
}
5050

5151
bool QgsAttributeTableModel::featureAtId( QgsFeatureId fid ) const

‎src/gui/attributetable/qgsattributetablemodel.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,16 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
3838
* @param parent parent pointer
3939
*/
4040
QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent = 0 );
41-
4241
/**
4342
* Returns the number of rows
4443
* @param parent parent index
4544
*/
46-
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
45+
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
4746
/**
4847
* Returns the number of columns
4948
* @param parent parent index
5049
*/
5150
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
52-
5351
/**
5452
* Returns header data
5553
* @param section required section
@@ -214,26 +212,26 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
214212
*/
215213
void initIdMaps();
216214

215+
/**
216+
* Gets mFieldCount, mAttributes and mValueMaps
217+
*/
218+
virtual void loadAttributes();
219+
220+
public:
217221
/**
218222
* Loads the layer into the model
219223
*/
220224
virtual void loadLayer();
221225

222-
/**
223-
* Gets mFieldCount, mAttributes and mValueMaps
224-
*/
225-
virtual void loadAttributes();
226+
private:
227+
mutable QQueue<QgsFeatureId> mFeatureQueue;
226228

227229
/**
228230
* load feature fid into mFeat
229231
* @param fid feature id
230232
* @return feature exists
231233
*/
232234
virtual bool featureAtId( QgsFeatureId fid ) const;
233-
234-
private:
235-
mutable QQueue<QgsFeatureId> mFeatureQueue;
236-
237235
};
238236

239237

‎src/gui/attributetable/qgsattributetableview.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
#include "qgsattributetablememorymodel.h"
2424
#include "qgsattributetabledelegate.h"
2525
#include "qgsattributetablefiltermodel.h"
26-
2726
#include "qgsvectorlayer.h"
2827
#include "qgsvectordataprovider.h"
28+
#include "qgslogger.h"
2929

3030
QgsAttributeTableView::QgsAttributeTableView( QWidget* parent )
3131
: QTableView( parent ), mModel( 0 ), mFilterModel( 0 ), mActionPopup( 0 )
@@ -63,9 +63,17 @@ void QgsAttributeTableView::setLayer( QgsVectorLayer* layer )
6363
// features in the current view. Otherwise we'll have to store
6464
// everything in the memory because using featureAtId() would be too slow
6565
if ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SelectAtId )
66+
{
67+
QgsDebugMsg( "SelectAtId supported" );
6668
mModel = new QgsAttributeTableModel( layer );
69+
}
6770
else
71+
{
72+
QgsDebugMsg( "SelectAtId NOT supported" );
6873
mModel = new QgsAttributeTableMemoryModel( layer );
74+
}
75+
76+
mModel->loadLayer();
6977

7078
mFilterModel = new QgsAttributeTableFilterModel( layer );
7179
mFilterModel->setSourceModel( mModel );

‎src/providers/postgres/qgspgsourceselect.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ QString QgsPgSourceSelect::layerURI( const QModelIndex &index )
353353
QString tableName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmTable ) )->text();
354354
QString geomColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmGeomCol ) )->text();
355355
QString pkColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmPkCol ) )->text();
356+
bool selectAtId = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmSelectAtId ) )->checkState() == Qt::Checked;
356357
QString sql = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmSql ) )->text();
357358

358359
if ( geomColumnName.contains( " AS " ) )
@@ -389,6 +390,7 @@ QString QgsPgSourceSelect::layerURI( const QModelIndex &index )
389390
QgsDataSourceURI uri( m_connInfo );
390391
uri.setDataSource( schemaName, tableName, geomColumnName, sql, pkColumnName );
391392
uri.setUseEstimatedMetadata( mUseEstimatedMetadata );
393+
uri.disableSelectAtId( !selectAtId );
392394

393395
return uri.uri();
394396
}

‎src/providers/postgres/qgspgsourceselect.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ class QgsPgSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
151151
void setSql( const QModelIndex& index );
152152
//! Store the selected database
153153
void on_cmbConnections_activated( int );
154-
void setLayerType( QString schema, QString table, QString column,
155-
QString type );
154+
void setLayerType( QString schema, QString table, QString column, QString type );
156155
void on_mTablesTreeView_clicked( const QModelIndex &index );
157156
void on_mTablesTreeView_doubleClicked( const QModelIndex &index );
158157
//!Sets a new regular expression to the model

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
422422
, geomType( QGis::WKBUnknown )
423423
, mFeatureQueueSize( 200 )
424424
, mUseEstimatedMetadata( false )
425+
, mSelectAtIdDisabled( false )
425426
, mPrimaryKeyDefault( QString::null )
426427
{
427428
// assume this is a valid layer until we determine otherwise
@@ -463,6 +464,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
463464

464465
primaryKey = mUri.keyColumn();
465466
mUseEstimatedMetadata = mUri.useEstimatedMetadata();
467+
mSelectAtIdDisabled = mUri.selectAtIdDisabled();
466468

467469
QgsDebugMsg( "Connection info is " + mUri.connectionInfo() );
468470
QgsDebugMsg( "Geometry column is: " + geometryColumn );
@@ -1834,7 +1836,10 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()
18341836

18351837
// postgres has fast access to features at id (thanks to primary key / unique index)
18361838
// the latter flag is here just for compatibility
1837-
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
1839+
if ( !mSelectAtIdDisabled )
1840+
{
1841+
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
1842+
}
18381843

18391844
if ( !inRecovery )
18401845
{
@@ -1963,7 +1968,10 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()
19631968
return false;
19641969
}
19651970

1966-
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
1971+
if ( !mSelectAtIdDisabled )
1972+
{
1973+
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
1974+
}
19671975
}
19681976

19691977
return true;

‎src/providers/postgres/qgspostgresprovider.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ class QgsPostgresProvider : public QgsVectorDataProvider
525525
/* Use estimated metadata. Uses fast table counts, geometry type and extent determination */
526526
bool mUseEstimatedMetadata;
527527

528+
/* Disable support for SelectAtId */
529+
bool mSelectAtIdDisabled;
530+
528531
// Produces a QMessageBox with the given title and text. Doesn't
529532
// return until the user has dismissed the dialog box.
530533
static void showMessageBox( const QString& title, const QString &text );

0 commit comments

Comments
 (0)
Please sign in to comment.