23 changes: 13 additions & 10 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@


QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p ), ogrDataSource(0), ogrLayer(0), mSubsetStringSet(false)
: QgsAbstractFeatureIterator( request )
, P( p )
, ogrDataSource( 0 )
, ogrLayer( 0 )
, mSubsetStringSet( false )
{
mFeatureFetched = false;
P->mActiveIterators.insert( this );

ogrDataSource = OGROpen( TO8F( P->filePath() ), false, NULL );

Expand All @@ -50,12 +53,12 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatur

if ( !P->subsetString().isEmpty() )
{
QString sql = QString( "SELECT * FROM %1 WHERE %2" )
.arg( P->quotedIdentifier( FROM8( OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) ) ) ) )
.arg( P->subsetString() );
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
ogrLayer = OGR_DS_ExecuteSQL( ogrDataSource, P->textEncoding()->fromUnicode( sql ).constData(), NULL, NULL );
mSubsetStringSet = true;
QString sql = QString( "SELECT * FROM %1 WHERE %2" )
.arg( P->quotedIdentifier( FROM8( OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) ) ) ) )
.arg( P->subsetString() );
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
ogrLayer = OGR_DS_ExecuteSQL( ogrDataSource, P->textEncoding()->fromUnicode( sql ).constData(), NULL, NULL );
mSubsetStringSet = true;
}

ensureRelevantFields();
Expand Down Expand Up @@ -162,9 +165,9 @@ bool QgsOgrFeatureIterator::close()

P->mActiveIterators.remove( this );

if (mSubsetStringSet)
if ( mSubsetStringSet )
{
OGR_DS_ReleaseResultSet(ogrDataSource, ogrLayer );
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );
}

OGR_DS_Destroy( ogrDataSource );
Expand Down
6 changes: 3 additions & 3 deletions src/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,10 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )

QgsOgrProvider::~QgsOgrProvider()
{
// Do we need to close all active iterators here?

foreach ( QgsOgrFeatureIterator* it, mActiveIterators )
while ( !mActiveIterators.empty() )
{
QgsOgrFeatureIterator *it = *mActiveIterators.begin();
QgsDebugMsg( "closing active iterator" );
it->close();
}

Expand Down
2 changes: 1 addition & 1 deletion src/providers/ogr/qgsogrprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,5 +339,5 @@ class QgsOgrProvider : public QgsVectorDataProvider
bool syncToDisc();

friend class QgsOgrFeatureIterator;
QSet< QgsOgrFeatureIterator*> mActiveIterators;
QSet< QgsOgrFeatureIterator* > mActiveIterators;
};
4 changes: 4 additions & 0 deletions src/providers/oracle/qgsoraclefeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleProvider *p, const
, P( p )
, mRewind( false )
{
P->mActiveIterators << this;

mQry = QSqlQuery( *P->mConnection );

if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
Expand Down Expand Up @@ -238,6 +240,8 @@ bool QgsOracleFeatureIterator::close()

mQry.finish();

P->mActiveIterators.remove( this );

return true;
}

Expand Down
8 changes: 8 additions & 0 deletions src/providers/oracle/qgsoracleprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ QgsOracleProvider::QgsOracleProvider( QString const & uri )
QgsOracleProvider::~QgsOracleProvider()
{
QgsDebugMsg( "deconstructing." );

while ( !mActiveIterators.empty() )
{
QgsOracleFeatureIterator *it = *mActiveIterators.begin();
QgsDebugMsg( "closing active iterator" );
it->close();
}

disconnectDb();
}

Expand Down
1 change: 1 addition & 0 deletions src/providers/oracle/qgsoracleprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ class QgsOracleProvider : public QgsVectorDataProvider
bool mHasSpatial; //! Oracle Spatial is installed

friend class QgsOracleFeatureIterator;
QSet< QgsOracleFeatureIterator * > mActiveIterators;
};

#endif
40 changes: 3 additions & 37 deletions src/providers/postgres/qgspostgresfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,9 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresProvider* p,
: QgsAbstractFeatureIterator( request ), P( p )
, mFeatureQueueSize( sFeatureQueueSize )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
{
QgsMessageLog::logMessage( QObject::tr( "Already active iterator on this provider was closed." ), QObject::tr( "PostgreSQL" ) );
P->mActiveIterator->close();
}
mCursorName = QString( "qgisf%1_%2" ).arg( P->mProviderId ).arg( P->mIteratorCounter++ );

mCursorName = QString( "qgisf%1" ).arg( P->mProviderId );
P->mActiveIterators << this;

QString whereClause;

Expand All @@ -81,8 +76,6 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresProvider* p,
return;
}

P->mActiveIterator = this;

mFetched = 0;
}

Expand All @@ -100,32 +93,6 @@ bool QgsPostgresFeatureIterator::nextFeature( QgsFeature& feature )
if ( mClosed )
return false;

#if 0
// featureAtId used to have some special checks - necessary?
if ( !mUseQueue )
{
QgsPostgresResult queryResult = P->mConnectionRO->PQexec( QString( "FETCH FORWARD 1 FROM %1" ).arg( mCursorName ) );

int rows = queryResult.PQntuples();
if ( rows == 0 )
{
QgsMessageLog::logMessage( tr( "feature %1 not found" ).arg( featureId ), tr( "PostGIS" ) );
P->mConnectionRO->closeCursor( cursorName );
return false;
}
else if ( rows != 1 )
{
QgsMessageLog::logMessage( tr( "found %1 features instead of just one." ).arg( rows ), tr( "PostGIS" ) );
}

bool gotit = getFeature( queryResult, 0, feature );

feature.setValid( gotit );
feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups
return gotit;
}
#endif

if ( mFeatureQueue.empty() )
{
QString fetch = QString( "FETCH FORWARD %1 FROM %2" ).arg( mFeatureQueueSize ).arg( mCursorName );
Expand Down Expand Up @@ -220,8 +187,7 @@ bool QgsPostgresFeatureIterator::close()
mFeatureQueue.dequeue();
}

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;
P->mActiveIterators.remove( this );

mClosed = true;
return true;
Expand Down
37 changes: 33 additions & 4 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
, mConnectionRO( 0 )
, mConnectionRW( 0 )
, mFidCounter( 0 )
, mActiveIterator( 0 )
, mIteratorCounter( 0 )
{
mProviderId = sProviderIds++;

Expand Down Expand Up @@ -219,8 +219,12 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )

QgsPostgresProvider::~QgsPostgresProvider()
{
if ( mActiveIterator )
mActiveIterator->close();
while ( !mActiveIterators.empty() )
{
QgsPostgresFeatureIterator *it = *mActiveIterators.begin();
QgsDebugMsg( "closing active iterator" );
it->close();
}

disconnectDb();

Expand Down Expand Up @@ -347,6 +351,7 @@ QgsFeatureIterator QgsPostgresProvider::getFeatures( const QgsFeatureRequest& re
QgsMessageLog::logMessage( tr( "Read attempt on an invalid postgresql data source" ), tr( "PostGIS" ) );
return QgsFeatureIterator();
}

return QgsFeatureIterator( new QgsPostgresFeatureIterator( this, request ) );
}

Expand Down Expand Up @@ -3096,7 +3101,31 @@ QString QgsPostgresProvider::name() const

QString QgsPostgresProvider::description() const
{
return POSTGRES_DESCRIPTION;
QString pgVersion( tr( "PostgreSQL version: unknown" ) );
QString postgisVersion( tr( "unknown" ) );

if ( mConnectionRO )
{
QgsPostgresResult result;

result = mConnectionRO->PQexec( "SELECT version()" );
if ( result.PQresultStatus() == PGRES_TUPLES_OK )
{
pgVersion = result.PQgetvalue( 0, 0 );
}

result = mConnectionRO->PQexec( "SELECT postgis_version()" );
if ( result.PQresultStatus() == PGRES_TUPLES_OK )
{
postgisVersion = result.PQgetvalue( 0, 0 );
}
}
else
{
pgVersion = tr( "PostgreSQL not connected" );
}

return tr( "PostgreSQL/PostGIS provider\n%1\nPostGIS %2" ).arg( pgVersion ).arg( postgisVersion );
} // QgsPostgresProvider::description()

/**
Expand Down
9 changes: 5 additions & 4 deletions src/providers/postgres/qgspostgresprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,13 +472,14 @@ class QgsPostgresProvider : public QgsVectorDataProvider

static int sProviderIds;

QMap<QVariant, QgsFeatureId> mKeyToFid; // map key values to feature id
QMap<QgsFeatureId, QVariant> mFidToKey; // map feature back to fea
QgsFeatureId mFidCounter; // next feature id if map is used
QMap<QVariant, QgsFeatureId> mKeyToFid; // map key values to feature id
QMap<QgsFeatureId, QVariant> mFidToKey; // map feature back to fea
QgsFeatureId mFidCounter; // next feature id if map is used
QgsFeatureId lookupFid( const QVariant &v ); // lookup existing mapping or add a new one
int mIteratorCounter; // iterator counter

friend class QgsPostgresFeatureIterator;
QgsPostgresFeatureIterator* mActiveIterator; //!< pointer to currently active iterator (0 if none)
QSet< QgsPostgresFeatureIterator * > mActiveIterators;
};

#endif
14 changes: 3 additions & 11 deletions src/providers/spatialite/qgsspatialitefeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,9 @@ QgsSpatiaLiteFeatureIterator::QgsSpatiaLiteFeatureIterator( QgsSpatiaLiteProvide
, P( p )
, sqliteStatement( NULL )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
{
QgsMessageLog::logMessage( QObject::tr( "Already active iterator on this provider was closed." ), QObject::tr( "SpatiaLite" ) );
P->mActiveIterator->close();
}
P->mActiveIterator = this;
P->mActiveIterators << this;

QString whereClause;

if ( request.filterType() == QgsFeatureRequest::FilterRect && !P->mGeometryColumn.isNull() )
{
// some kind of MBR spatial filtering is required
Expand Down Expand Up @@ -125,15 +118,14 @@ bool QgsSpatiaLiteFeatureIterator::close()
if ( mClosed )
return false;

P->mActiveIterators.remove( this );

if ( sqliteStatement )
{
sqlite3_finalize( sqliteStatement );
sqliteStatement = NULL;
}

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
Expand Down
9 changes: 6 additions & 3 deletions src/providers/spatialite/qgsspatialiteprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,6 @@ QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri )
, spatialIndexRTree( false )
, spatialIndexMbrCache( false )
, mGotSpatialiteVersion( false )
, mActiveIterator( 0 )
{
nDims = GAIA_XY;
QgsDataSourceURI anUri = QgsDataSourceURI( uri );
Expand Down Expand Up @@ -577,8 +576,12 @@ QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri )

QgsSpatiaLiteProvider::~QgsSpatiaLiteProvider()
{
if ( mActiveIterator )
mActiveIterator->close();
while ( !mActiveIterators.empty() )
{
QgsSpatiaLiteFeatureIterator *it = *mActiveIterators.begin();
QgsDebugMsg( "closing active iterator" );
it->close();
}

closeDb();
}
Expand Down
2 changes: 1 addition & 1 deletion src/providers/spatialite/qgsspatialiteprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,5 +510,5 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
SqliteHandles *handle;

friend class QgsSpatiaLiteFeatureIterator;
QgsSpatiaLiteFeatureIterator* mActiveIterator;
QSet< QgsSpatiaLiteFeatureIterator * > mActiveIterators;
};
18 changes: 7 additions & 11 deletions src/providers/wfs/qgswfsfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#include "qgswfsprovider.h"
#include "qgsmessagelog.h"

QgsWFSFeatureIterator::QgsWFSFeatureIterator( QgsWFSProvider* provider, const QgsFeatureRequest& request ):
QgsAbstractFeatureIterator( request ), mProvider( provider )
QgsWFSFeatureIterator::QgsWFSFeatureIterator( QgsWFSProvider* provider, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request )
, mProvider( provider )
{
//select ids
//get iterator
Expand All @@ -27,12 +28,7 @@ QgsWFSFeatureIterator::QgsWFSFeatureIterator( QgsWFSProvider* provider, const Qg
return;
}

if ( mProvider->mActiveIterator )
{
QgsMessageLog::logMessage( QObject::tr( "Already active iterator on this provider was closed." ), QObject::tr( "WFS" ) );
mProvider->mActiveIterator->close();
}
mProvider->mActiveIterator = this;
mProvider->mActiveIterators << this;

switch ( request.filterType() )
{
Expand Down Expand Up @@ -107,10 +103,10 @@ bool QgsWFSFeatureIterator::rewind()
bool QgsWFSFeatureIterator::close()
{
if ( !mProvider )
{
return false;
}
mProvider->mActiveIterator = 0;

mProvider->mActiveIterators.remove( this );

mProvider = 0;
return true;
}
34 changes: 18 additions & 16 deletions src/providers/wfs/qgswfsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,17 @@ static const QString WFS_NAMESPACE = "http://www.opengis.net/wfs";
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";

QgsWFSProvider::QgsWFSProvider( const QString& uri )
: QgsVectorDataProvider( uri ),
mNetworkRequestFinished( true ),
mActiveIterator( 0 ),
mRequestEncoding( QgsWFSProvider::GET ),
mUseIntersect( false ),
mWKBType( QGis::WKBUnknown ),
mSourceCRS( 0 ),
mFeatureCount( 0 ),
mValid( true ),
mLayer( 0 ),
mGetRenderedOnly( false ),
mInitGro( false )
: QgsVectorDataProvider( uri )
, mNetworkRequestFinished( true )
, mRequestEncoding( QgsWFSProvider::GET )
, mUseIntersect( false )
, mWKBType( QGis::WKBUnknown )
, mSourceCRS( 0 )
, mFeatureCount( 0 )
, mValid( true )
, mLayer( 0 )
, mGetRenderedOnly( false )
, mInitGro( false )
{
mSpatialIndex = 0;
if ( uri.isEmpty() )
Expand Down Expand Up @@ -123,12 +122,15 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )

QgsWFSProvider::~QgsWFSProvider()
{
deleteData();
delete mSpatialIndex;
if ( mActiveIterator )
while ( !mActiveIterators.empty() )
{
mActiveIterator->close();
QgsWFSFeatureIterator *it = *mActiveIterators.begin();
QgsDebugMsg( "closing active iterator" );
it->close();
}

deleteData();
delete mSpatialIndex;
}

void QgsWFSProvider::reloadData()
Expand Down
2 changes: 1 addition & 1 deletion src/providers/wfs/qgswfsprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class QgsWFSProvider: public QgsVectorDataProvider
private:
bool mNetworkRequestFinished;
friend class QgsWFSFeatureIterator;
QgsWFSFeatureIterator* mActiveIterator;
QSet< QgsWFSFeatureIterator * > mActiveIterators;

protected:
/**Thematic attributes*/
Expand Down