Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] allow to disable SelectAtId capability for PostgreSQL provi…
…der 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.
  • Loading branch information
jef-n committed Nov 30, 2011
1 parent ee9b8d7 commit b8e5a34
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 37 deletions.
31 changes: 29 additions & 2 deletions src/core/qgsdatasourceuri.cpp
Expand Up @@ -22,12 +22,20 @@
#include <QStringList>
#include <QRegExp>

QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
QgsDataSourceURI::QgsDataSourceURI()
: mSSLmode( SSLprefer )
, mKeyColumn( "" )
, mUseEstimatedMetadata( false )
, mSelectAtIdDisabled( false )
{
// do nothing
}

QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
QgsDataSourceURI::QgsDataSourceURI( QString uri )
: mSSLmode( SSLprefer )
, mKeyColumn( "" )
, mUseEstimatedMetadata( false )
, mSelectAtIdDisabled( false )
{
int i = 0;
while ( i < uri.length() )
Expand Down Expand Up @@ -115,6 +123,10 @@ QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyC
{
mUseEstimatedMetadata = pval == "true";
}
else if ( pname == "selectatid" )
{
mSelectAtIdDisabled = pval == "false";
}
else if ( pname == "service" )
{
mService = pval;
Expand Down Expand Up @@ -309,6 +321,16 @@ bool QgsDataSourceURI::useEstimatedMetadata() const
return mUseEstimatedMetadata;
}

void QgsDataSourceURI::disableSelectAtId( bool theFlag )
{
mSelectAtIdDisabled = theFlag;
}

bool QgsDataSourceURI::selectAtIdDisabled() const
{
return mSelectAtIdDisabled;
}

void QgsDataSourceURI::setSql( QString sql )
{
mSql = sql;
Expand Down Expand Up @@ -461,6 +483,11 @@ QString QgsDataSourceURI::uri() const
theUri += QString( " estimatedmetadata=true" );
}

if ( mSelectAtIdDisabled )
{
theUri += QString( " selectatid=false" );
}

theUri += QString( " table=%1%2 sql=%3" )
.arg( quotedTablename() )
.arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsdatasourceuri.h
Expand Up @@ -97,6 +97,9 @@ class CORE_EXPORT QgsDataSourceURI
void setUseEstimatedMetadata( bool theFlag );
bool useEstimatedMetadata() const;

void disableSelectAtId( bool theFlag );
bool selectAtIdDisabled() const;

void clearSchema();
void setSql( QString sql );

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

#endif //QGSDATASOURCEURI_H
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsdbtablemodel.cpp
Expand Up @@ -26,6 +26,7 @@ QgsDbTableModel::QgsDbTableModel(): QStandardItemModel(), mTableCount( 0 )
headerLabels << tr( "Type" );
headerLabels << tr( "Geometry column" );
headerLabels << tr( "Primary key column" );
headerLabels << tr( "Select at id" );
headerLabels << tr( "Sql" );
setHorizontalHeaderLabels( headerLabels );
}
Expand Down Expand Up @@ -60,17 +61,27 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
QIcon iconFile = iconForType( wkbType );

QList<QStandardItem*> childItemList;

QStandardItem* schemaNameItem = new QStandardItem( schemaName );
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* typeItem = new QStandardItem( QIcon( iconFile ), type );
typeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* tableItem = new QStandardItem( tableName );
tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* geomItem = new QStandardItem( geometryColName );
geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* pkItem = new QStandardItem( "" );
pkItem->setData( pkCols );
pkItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

QStandardItem* selItem = new QStandardItem( "" );
selItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable );
selItem->setCheckState( Qt::Checked );

QStandardItem* sqlItem = new QStandardItem( sql );
sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

Expand All @@ -79,6 +90,7 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
childItemList.push_back( typeItem );
childItemList.push_back( geomItem );
childItemList.push_back( pkItem );
childItemList.push_back( selItem );
childItemList.push_back( sqlItem );

schemaItem->appendRow( childItemList );
Expand Down
8 changes: 7 additions & 1 deletion src/core/qgsdbtablemodel.h
Expand Up @@ -28,15 +28,19 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
public:
QgsDbTableModel();
~QgsDbTableModel();

/**Adds entry for one database table to the model*/
void addTableEntry( QString type, QString schemaName, QString tableName, QString geometryColName, const QStringList &pkCols, QString Sql );

/**Sets an sql statement that belongs to a cell specified by a model index*/
void setSql( const QModelIndex& index, const QString& sql );

/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
This is for tables where the type is dectected later by thread*/
void setGeometryTypesForTable( const QString& schema, const QString& table, const QString& attribute, const QString& type );

/**Returns the number of tables in the model*/
int tableCount() const {return mTableCount;}
int tableCount() const { return mTableCount; }

enum columns
{
Expand All @@ -45,6 +49,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
dbtmType,
dbtmGeomCol,
dbtmPkCol,
dbtmSelectAtId,
dbtmSql,
dbtmColumns
};
Expand All @@ -55,6 +60,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel

QIcon iconForType( QGis::WkbType type ) const;
QString displayStringForType( QGis::WkbType type ) const;

/**Returns qgis wkbtype from database typename*/
QGis::WkbType qgisTypeFromDbType( const QString& dbType ) const;
};
Expand Down
57 changes: 43 additions & 14 deletions src/gui/attributetable/qgsattributetablememorymodel.cpp
Expand Up @@ -27,27 +27,59 @@
// In-Memory model //
/////////////////////

QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer )
: QgsAttributeTableModel( theLayer )
{
QgsDebugMsg( "entered." );
}

void QgsAttributeTableMemoryModel::loadLayer()
{
QgsAttributeTableModel::loadLayer();
mLayer->select( mLayer->pendingAllAttributesList(), QgsRectangle(), false );
QgsDebugMsg( "entered." );

QSettings settings;
int behaviour = settings.value( "/qgis/attributeTableBehaviour", 0 ).toInt();

QgsRectangle rect;
if ( behaviour == 2 )
{
// current canvas only
rect = mCurrentExtent;
}

mLayer->select( mLayer->pendingAllAttributesList(), rect, false );

mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
if( behaviour != 1 )
mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
else
mFeatureMap.reserve( mLayer->selectedFeatureCount() );

int n = 0;

QgsFeature f;
while ( mLayer->nextFeature( f ) )
{
if( behaviour == 1 && !mLayer->selectedFeaturesIds().contains( f.id() ) )
continue;

mIdRowMap.insert( f.id(), n );
mRowIdMap.insert( n, f.id() );
mFeatureMap.insert( f.id(), f );
n++;
}

mFieldCount = mAttributes.size();
}

QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel
( QgsVectorLayer *theLayer )
: QgsAttributeTableModel( theLayer )
int QgsAttributeTableMemoryModel::rowCount( const QModelIndex &parent ) const
{
loadLayer();
Q_UNUSED( parent );
return mFeatureMap.size();
}

bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid )
bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid ) const
{
QgsDebugMsg( QString( "entered featureAtId: %1." ).arg( fid ) );
if ( mFeatureMap.contains( fid ) )
{
mFeat = mFeatureMap[ fid ];
Expand All @@ -70,17 +102,14 @@ void QgsAttributeTableMemoryModel::featureDeleted( QgsFeatureId fid )
void QgsAttributeTableMemoryModel::featureAdded( QgsFeatureId fid )
{
QgsDebugMsg( "entered." );
QgsFeature f;
mLayer->featureAtId( fid, f, false, true );
mFeatureMap.insert( fid, f );
QgsAttributeTableModel::featureAdded( fid );
Q_UNUSED( fid );
loadLayer();
}

void QgsAttributeTableMemoryModel::layerDeleted()
{
QgsDebugMsg( "entered." );
mFeatureMap.clear();
QgsAttributeTableModel::layerDeleted();
loadLayer();
}

void QgsAttributeTableMemoryModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
Expand Down
10 changes: 8 additions & 2 deletions src/gui/attributetable/qgsattributetablememorymodel.h
Expand Up @@ -30,7 +30,7 @@

class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
{
Q_OBJECT;
Q_OBJECT

public:
/**
Expand All @@ -39,6 +39,12 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
*/
QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer );

/**
* Returns the number of rows
* @param parent parent index
*/
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;

/**
* Remove rows
*/
Expand Down Expand Up @@ -75,7 +81,7 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
* @param fid feature id
* @return feature exists
*/
virtual bool featureAtId( QgsFeatureId fid );
virtual bool featureAtId( QgsFeatureId fid ) const;

/**
* Loads the layer into the model
Expand Down
4 changes: 2 additions & 2 deletions src/gui/attributetable/qgsattributetablemodel.cpp 100755 → 100644
Expand Up @@ -32,6 +32,8 @@ QgsRectangle QgsAttributeTableModel::mCurrentExtent; // static member
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent )
: QAbstractTableModel( parent )
{
QgsDebugMsg( "entered." );

mFeat.setFeatureId( std::numeric_limits<int>::min() );
mFeatureMap.clear();
mFeatureQueue.clear();
Expand All @@ -44,8 +46,6 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObjec
connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );

loadLayer();
}

bool QgsAttributeTableModel::featureAtId( QgsFeatureId fid ) const
Expand Down
20 changes: 9 additions & 11 deletions src/gui/attributetable/qgsattributetablemodel.h
Expand Up @@ -38,18 +38,16 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
* @param parent parent pointer
*/
QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent = 0 );

/**
* Returns the number of rows
* @param parent parent index
*/
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
/**
* Returns the number of columns
* @param parent parent index
*/
int columnCount( const QModelIndex &parent = QModelIndex() ) const;

/**
* Returns header data
* @param section required section
Expand Down Expand Up @@ -214,26 +212,26 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/
void initIdMaps();

/**
* Gets mFieldCount, mAttributes and mValueMaps
*/
virtual void loadAttributes();

public:
/**
* Loads the layer into the model
*/
virtual void loadLayer();

/**
* Gets mFieldCount, mAttributes and mValueMaps
*/
virtual void loadAttributes();
private:
mutable QQueue<QgsFeatureId> mFeatureQueue;

/**
* load feature fid into mFeat
* @param fid feature id
* @return feature exists
*/
virtual bool featureAtId( QgsFeatureId fid ) const;

private:
mutable QQueue<QgsFeatureId> mFeatureQueue;

};


Expand Down
10 changes: 9 additions & 1 deletion src/gui/attributetable/qgsattributetableview.cpp
Expand Up @@ -23,9 +23,9 @@
#include "qgsattributetablememorymodel.h"
#include "qgsattributetabledelegate.h"
#include "qgsattributetablefiltermodel.h"

#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgslogger.h"

QgsAttributeTableView::QgsAttributeTableView( QWidget* parent )
: QTableView( parent ), mModel( 0 ), mFilterModel( 0 ), mActionPopup( 0 )
Expand Down Expand Up @@ -63,9 +63,17 @@ void QgsAttributeTableView::setLayer( QgsVectorLayer* layer )
// features in the current view. Otherwise we'll have to store
// everything in the memory because using featureAtId() would be too slow
if ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SelectAtId )
{
QgsDebugMsg( "SelectAtId supported" );
mModel = new QgsAttributeTableModel( layer );
}
else
{
QgsDebugMsg( "SelectAtId NOT supported" );
mModel = new QgsAttributeTableMemoryModel( layer );
}

mModel->loadLayer();

mFilterModel = new QgsAttributeTableFilterModel( layer );
mFilterModel->setSourceModel( mModel );
Expand Down

0 comments on commit b8e5a34

Please sign in to comment.