Skip to content
Permalink
Browse files

Merge pull request #3139 from rouault/ogr_concurrent_opening_branch_2_14

[Backport] [BUGFIX / FEATURE] [OGR] Allow concurrent edition of Shapefiles and Tabfiles in QGIS & MapInfo
  • Loading branch information
rouault committed May 30, 2016
2 parents 7d7467f + 8fafd3d commit 52f3ca6b34a810f3ca24108dc095b28cd5d9bf58
@@ -223,6 +223,47 @@ class QgsDataProvider : QObject
*/
virtual void invalidateConnections( const QString& connection );

/** Enter update mode.
*
* This is aimed at providers that can open differently the connection to
* the datasource, according it to be in update mode or in read-only mode.
* A call to this method shall be balanced with a call to leaveUpdateMode(),
* if this method returns true.
*
* Most providers will have an empty implementation for that method.
*
* For backward compatibility, providers that implement enterUpdateMode() should
* still make sure to allow editing operations to work even if enterUpdateMode()
* is not explicitly called.
*
* Several successive calls to enterUpdateMode() can be done. So there is
* a concept of stack of calls that must be handled by the provider. Only the first
* call to enterUpdateMode() will really turn update mode on.
*
* @return true in case of success (or no-op implementation), false in case of failure
*
* @note added in QGIS 2.14.4
*/
virtual bool enterUpdateMode();

/** Leave update mode.
*
* This is aimed at providers that can open differently the connection to
* the datasource, according it to be in update mode or in read-only mode.
* This method shall be balanced with a succesful call to enterUpdateMode().
*
* Most providers will have an empty implementation for that method.
*
* Several successive calls to enterUpdateMode() can be done. So there is
* a concept of stack of calls that must be handled by the provider. Only the last
* call to leaveUpdateMode() will really turn update mode off.
*
* @return true in case of success (or no-op implementation), false in case of failure
*
* @note added in QGIS 2.14.4
*/
virtual bool leaveUpdateMode();

signals:

/**
@@ -311,6 +311,47 @@ class CORE_EXPORT QgsDataProvider : public QObject
*/
virtual void invalidateConnections( const QString& connection ) { Q_UNUSED( connection ); }

/** Enter update mode.
*
* This is aimed at providers that can open differently the connection to
* the datasource, according it to be in update mode or in read-only mode.
* A call to this method shall be balanced with a call to leaveUpdateMode(),
* if this method returns true.
*
* Most providers will have an empty implementation for that method.
*
* For backward compatibility, providers that implement enterUpdateMode() should
* still make sure to allow editing operations to work even if enterUpdateMode()
* is not explicitly called.
*
* Several successive calls to enterUpdateMode() can be done. So there is
* a concept of stack of calls that must be handled by the provider. Only the first
* call to enterUpdateMode() will really turn update mode on.
*
* @return true in case of success (or no-op implementation), false in case of failure.
*
* @note added in QGIS 2.14.4
*/
virtual bool enterUpdateMode() { return true; }

/** Leave update mode.
*
* This is aimed at providers that can open differently the connection to
* the datasource, according it to be in update mode or in read-only mode.
* This method shall be balanced with a succesful call to enterUpdateMode().
*
* Most providers will have an empty implementation for that method.
*
* Several successive calls to enterUpdateMode() can be done. So there is
* a concept of stack of calls that must be handled by the provider. Only the last
* call to leaveUpdateMode() will really turn update mode off.
*
* @return true in case of success (or no-op implementation), false in case of failure.
*
* @note added in QGIS 2.14.4
*/
virtual bool leaveUpdateMode() { return true; }

signals:

/**
@@ -379,6 +379,7 @@ void QgsVectorLayer::reload()
if ( mDataProvider )
{
mDataProvider->reloadData();
updateFields();
}
}

@@ -1380,6 +1381,8 @@ bool QgsVectorLayer::startEditing()

emit beforeEditingStarted();

mDataProvider->enterUpdateMode();

if ( mDataProvider->transaction() )
{
mEditBuffer = new QgsVectorLayerEditPassthrough( this );
@@ -2334,6 +2337,8 @@ bool QgsVectorLayer::commitChanges()
updateFields();
mDataProvider->updateExtents();

mDataProvider->leaveUpdateMode();

emit repaintRequested();

return success;
@@ -2384,6 +2389,8 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer )
if ( rollbackExtent )
updateExtents();

mDataProvider->leaveUpdateMode();

emit repaintRequested();
return true;
}
@@ -36,14 +36,19 @@

QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
: QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request )
, mFeatureFetched( false )
, mConn( nullptr )
, ogrLayer( nullptr )
, mSubsetStringSet( false )
, mFetchGeometry( false )
, mGeometrySimplifier( nullptr )
, mExpressionCompiled( false )
{
mFeatureFetched = false;

mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() );
if ( !mConn->ds )
{
return;
}

if ( mSource->mLayerName.isNull() )
{
@@ -53,10 +58,18 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
{
ogrLayer = OGR_DS_GetLayerByName( mConn->ds, TO8( mSource->mLayerName ) );
}
if ( !ogrLayer )
{
return;
}

if ( !mSource->mSubsetString.isEmpty() )
{
ogrLayer = QgsOgrUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString );
if ( !ogrLayer )
{
return;
}
mSubsetStringSet = true;
}

@@ -204,7 +217,7 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
{
feature.setValid( false );

if ( mClosed )
if ( mClosed || !ogrLayer )
return false;

if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
@@ -249,7 +262,7 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )

bool QgsOgrFeatureIterator::rewind()
{
if ( mClosed )
if ( mClosed || !ogrLayer )
return false;

OGR_L_ResetReading( ogrLayer );

0 comments on commit 52f3ca6

Please sign in to comment.
You can’t perform that action at this time.