Skip to content

Commit

Permalink
Merge pull request #4394 from nyalldawson/bad_iterator_go_and_sit_in_…
Browse files Browse the repository at this point in the history
…a_corner

Fix crash when OGR layer is removed when source is stored
  • Loading branch information
nyalldawson committed Apr 23, 2017
2 parents 82c66f8 + 94c56aa commit 716ff6c
Show file tree
Hide file tree
Showing 30 changed files with 195 additions and 167 deletions.
2 changes: 1 addition & 1 deletion python/core/qgsfeaturerequest.sip
Expand Up @@ -343,7 +343,7 @@ class QgsAbstractFeatureSource
* @param request The request
* @return A feature iterator
*/
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request ) = 0;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() ) = 0;

protected:
void iteratorOpened( QgsAbstractFeatureIterator* it );
Expand Down
17 changes: 17 additions & 0 deletions python/core/qgsvectorlayerfeatureiterator.sip
Expand Up @@ -2,6 +2,23 @@
// abstract feature iterator implementations are not part of public API


class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource
{
%TypeHeaderCode
#include <qgsvectorlayerfeatureiterator.h>
%End
public:

/** Constructor for QgsVectorLayerFeatureSource.
* \param layer source layer
*/
explicit QgsVectorLayerFeatureSource( const QgsVectorLayer *layer );

~QgsVectorLayerFeatureSource();

virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() );
};

class QgsVectorLayerFeatureIterator : QgsAbstractFeatureIterator
{
%TypeHeaderCode
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsfeaturerequest.h
Expand Up @@ -437,7 +437,7 @@ class CORE_EXPORT QgsAbstractFeatureSource
* \param request The request
* \returns A feature iterator
*/
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) = 0;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) = 0;

protected:
void iteratorOpened( QgsAbstractFeatureIterator *it );
Expand Down
3 changes: 1 addition & 2 deletions src/core/qgsvectorlayerfeatureiterator.h
Expand Up @@ -36,7 +36,6 @@ class QgsVectorLayerFeatureIterator;

/** \ingroup core
* Partial snapshot of vector layer's state (only the members necessary for access to features)
* \note not available in Python bindings
*/
class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
{
Expand All @@ -49,7 +48,7 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource

~QgsVectorLayerFeatureSource();

virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override;

friend class QgsVectorLayerFeatureIterator;

Expand Down
1 change: 0 additions & 1 deletion src/providers/arcgisrest/CMakeLists.txt
Expand Up @@ -25,7 +25,6 @@ SET (AFS_SRCS
SET (AFS_MOC_HDRS
qgsarcgisrestutils.h
qgsafsdataitems.h
qgsafsfeatureiterator.h
qgsafsprovider.h
qgsafssourceselect.h
)
Expand Down
4 changes: 1 addition & 3 deletions src/providers/arcgisrest/qgsafsfeatureiterator.cpp
Expand Up @@ -39,9 +39,7 @@ QgsAfsProvider *QgsAfsFeatureSource::provider() const

QgsAfsFeatureIterator::QgsAfsFeatureIterator( QgsAfsFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
: QgsAbstractFeatureIteratorFromSource<QgsAfsFeatureSource>( source, ownSource, request )
{
mFeatureIterator = 0;
}
{}

QgsAfsFeatureIterator::~QgsAfsFeatureIterator()
{
Expand Down
8 changes: 2 additions & 6 deletions src/providers/arcgisrest/qgsafsfeatureiterator.h
Expand Up @@ -21,18 +21,14 @@ class QgsAfsProvider;
class QgsSpatialIndex;


class QgsAfsFeatureSource : public QObject, public QgsAbstractFeatureSource
class QgsAfsFeatureSource : public QgsAbstractFeatureSource
{
Q_OBJECT

public:
QgsAfsFeatureSource( const QgsAfsProvider *provider );
QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;
QgsAfsProvider *provider() const;

signals:
void extentRequested( const QgsRectangle & );

protected:
QgsAfsProvider *mProvider = nullptr;

Expand All @@ -51,7 +47,7 @@ class QgsAfsFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsAfs
bool fetchFeature( QgsFeature &f ) override;

private:
QgsFeatureId mFeatureIterator;
QgsFeatureId mFeatureIterator = 0;
};

#endif // QGSAFSFEATUREITERATOR_H
11 changes: 4 additions & 7 deletions src/providers/db2/qgsdb2featureiterator.cpp
Expand Up @@ -32,8 +32,6 @@ QgsDb2FeatureIterator::QgsDb2FeatureIterator( QgsDb2FeatureSource *source, bool
: QgsAbstractFeatureIteratorFromSource<QgsDb2FeatureSource>( source, ownSource, request )
{
mClosed = false;
mQuery = nullptr;
mFetchCount = 0;

BuildStatement( request );

Expand All @@ -48,7 +46,7 @@ QgsDb2FeatureIterator::QgsDb2FeatureIterator( QgsDb2FeatureSource *source, bool
}

// create sql query
mQuery = new QSqlQuery( mDatabase );
mQuery.reset( new QSqlQuery( mDatabase ) );

// start selection
rewind();
Expand Down Expand Up @@ -428,7 +426,7 @@ bool QgsDb2FeatureIterator::close()
{
mQuery->finish();
}
delete mQuery;
mQuery.reset();
}

if ( mDatabase.isOpen() )
Expand All @@ -447,15 +445,14 @@ bool QgsDb2FeatureIterator::close()
QgsDb2FeatureSource::QgsDb2FeatureSource( const QgsDb2Provider *p )
: mFields( p->mAttributeFields )
, mFidColName( p->mFidColName )
, mSRId( p->mSRId )
, mGeometryColName( p->mGeometryColName )
, mGeometryColType( p->mGeometryColType )
, mSchemaName( p->mSchemaName )
, mTableName( p->mTableName )
, mConnInfo( p->mConnInfo )
, mSqlWhereClause( p->mSqlWhereClause )
{
mSRId = p->mSRId;
}
{}

QgsDb2FeatureSource::~QgsDb2FeatureSource()
{
Expand Down
6 changes: 3 additions & 3 deletions src/providers/db2/qgsdb2featureiterator.h
Expand Up @@ -34,7 +34,7 @@ class QgsDb2FeatureSource : public QgsAbstractFeatureSource

virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;

protected:
private:
QgsFields mFields;
QString mFidColName;
long mSRId;
Expand Down Expand Up @@ -85,7 +85,7 @@ class QgsDb2FeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsDb2
QString mOrderByClause;

// The current sql query
QSqlQuery *mQuery = nullptr;
std::unique_ptr< QSqlQuery > mQuery;

// The current sql statement
QString mStatement;
Expand All @@ -99,7 +99,7 @@ class QgsDb2FeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsDb2
bool mExpressionCompiled;
bool mOrderByCompiled;

int mFetchCount;
int mFetchCount = 0;
};

#endif // QGSDB2FEATUREITERATOR_H
17 changes: 3 additions & 14 deletions src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
Expand Up @@ -28,8 +28,7 @@

QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTextFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
: QgsAbstractFeatureIteratorFromSource<QgsDelimitedTextFeatureSource>( source, ownSource, request )
, mNextId( 0 )
, mTestGeometryExact( false )
, mTestSubset( mSource->mSubsetExpression )
{

// Determine mode to use based on request...
Expand All @@ -39,14 +38,6 @@ QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTe
// load it.
bool hasGeometry = mSource->mGeomRep != QgsDelimitedTextProvider::GeomNone;

// Does the layer have an explicit or implicit subset (implicit subset is if we have geometry which can
// be invalid)

mTestSubset = mSource->mSubsetExpression;
mTestGeometry = false;

mMode = FileScan;

if ( !request.filterRect().isNull() && hasGeometry )
{
QgsDebugMsg( "Configuring for rectangle select" );
Expand Down Expand Up @@ -271,7 +262,7 @@ bool QgsDelimitedTextFeatureIterator::nextFeatureInternal( QgsFeature &feature )
{
QStringList tokens;

QgsDelimitedTextFile *file = mSource->mFile;
QgsDelimitedTextFile *file = mSource->mFile.get();

// If the iterator is not scanning the file, then it will have requested a specific
// record, so only need to load that one.
Expand Down Expand Up @@ -506,7 +497,7 @@ QgsDelimitedTextFeatureSource::QgsDelimitedTextFeatureSource( const QgsDelimited
url.removeQueryItem( QStringLiteral( "watchFile" ) );
}

mFile = new QgsDelimitedTextFile();
mFile.reset( new QgsDelimitedTextFile() );
mFile->setFromUrl( url );

mExpressionContext << QgsExpressionContextUtils::globalScope()
Expand All @@ -517,8 +508,6 @@ QgsDelimitedTextFeatureSource::QgsDelimitedTextFeatureSource( const QgsDelimited
QgsDelimitedTextFeatureSource::~QgsDelimitedTextFeatureSource()
{
delete mSubsetExpression;
delete mSpatialIndex;
delete mFile;
}

QgsFeatureIterator QgsDelimitedTextFeatureSource::getFeatures( const QgsFeatureRequest &request )
Expand Down
20 changes: 11 additions & 9 deletions src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.h
Expand Up @@ -30,16 +30,16 @@ class QgsDelimitedTextFeatureSource : public QgsAbstractFeatureSource

virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;

protected:
private:
QgsDelimitedTextProvider::GeomRepresentationType mGeomRep;
QgsExpression *mSubsetExpression = nullptr;
QgsExpressionContext mExpressionContext;
QgsRectangle mExtent;
bool mUseSpatialIndex;
QgsSpatialIndex *mSpatialIndex = nullptr;
std::unique_ptr< QgsSpatialIndex > mSpatialIndex;
bool mUseSubsetIndex;
QList<quintptr> mSubsetIndex;
QgsDelimitedTextFile *mFile = nullptr;
std::unique_ptr< QgsDelimitedTextFile > mFile;
QgsFields mFields;
int mFieldCount; // Note: this includes field count for wkt field
int mXFieldIndex;
Expand Down Expand Up @@ -78,6 +78,8 @@ class QgsDelimitedTextFeatureIterator : public QgsAbstractFeatureIteratorFromSou
protected:
virtual bool fetchFeature( QgsFeature &feature ) override;

private:

bool setNextFeatureId( qint64 fid );

bool nextFeatureInternal( QgsFeature &feature );
Expand All @@ -86,12 +88,12 @@ class QgsDelimitedTextFeatureIterator : public QgsAbstractFeatureIteratorFromSou
void fetchAttribute( QgsFeature &feature, int fieldIdx, const QStringList &tokens );

QList<QgsFeatureId> mFeatureIds;
IteratorMode mMode;
long mNextId;
bool mTestSubset;
bool mTestGeometry;
bool mTestGeometryExact;
bool mLoadGeometry;
IteratorMode mMode = FileScan;
long mNextId = 0;
bool mTestSubset = false;
bool mTestGeometry = false;
bool mTestGeometryExact = false;
bool mLoadGeometry = false;
};


Expand Down
1 change: 0 additions & 1 deletion src/providers/gpx/qgsgpxfeatureiterator.cpp
Expand Up @@ -27,7 +27,6 @@

QgsGPXFeatureIterator::QgsGPXFeatureIterator( QgsGPXFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
: QgsAbstractFeatureIteratorFromSource<QgsGPXFeatureSource>( source, ownSource, request )
, mFetchedFid( false )
{
rewind();
}
Expand Down
8 changes: 4 additions & 4 deletions src/providers/gpx/qgsgpxfeatureiterator.h
Expand Up @@ -31,7 +31,7 @@ class QgsGPXFeatureSource : public QgsAbstractFeatureSource

virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) override;

protected:
private:
QString mFileName;
QgsGPXProvider::DataType mFeatureType;
QgsGPSData *data = nullptr;
Expand All @@ -56,6 +56,8 @@ class QgsGPXFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsGPX

virtual bool fetchFeature( QgsFeature &feature ) override;

private:

bool readFid( QgsFeature &feature );

bool readWaypoint( const QgsWaypoint &wpt, QgsFeature &feature );
Expand All @@ -70,16 +72,14 @@ class QgsGPXFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsGPX
void readAttributes( QgsFeature &feature, const QgsRoute &rte );
void readAttributes( QgsFeature &feature, const QgsTrack &trk );

protected:

//! Current waypoint iterator
QgsGPSData::WaypointIterator mWptIter;
//! Current route iterator
QgsGPSData::RouteIterator mRteIter;
//! Current track iterator
QgsGPSData::TrackIterator mTrkIter;

bool mFetchedFid;
bool mFetchedFid = false;
};

#endif // QGSGPXFEATUREITERATOR_H
3 changes: 0 additions & 3 deletions src/providers/grass/qgsgrassfeatureiterator.cpp
Expand Up @@ -69,9 +69,6 @@ void copy_boxlist_and_destroy( struct boxlist *blist, struct ilist *list )

QgsGrassFeatureIterator::QgsGrassFeatureIterator( QgsGrassFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
: QgsAbstractFeatureIteratorFromSource<QgsGrassFeatureSource>( source, ownSource, request )
, mCanceled( false )
, mNextCidx( 0 )
, mNextLid( 1 )
{

// WARNING: the iterater cannot use mutex lock for its whole life, because QgsVectorLayerFeatureIterator is opening
Expand Down

0 comments on commit 716ff6c

Please sign in to comment.