Skip to content

Commit

Permalink
Merge pull request #3034 from rouault/ogr_concurrent_opening
Browse files Browse the repository at this point in the history
[BUGFIX / FEATURE] [OGR] Allow concurrent edition of Shapefiles and Tabfiles in QGIS & MapInfo
  • Loading branch information
nyalldawson committed May 10, 2016
2 parents 7ae80b1 + 52de4fb commit 0f6838d
Show file tree
Hide file tree
Showing 10 changed files with 631 additions and 30 deletions.
41 changes: 41 additions & 0 deletions python/core/qgsdataprovider.sip
Expand Up @@ -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.16
*/
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.16
*/
virtual bool leaveUpdateMode();

signals:

/**
Expand Down
41 changes: 41 additions & 0 deletions src/core/qgsdataprovider.h
Expand Up @@ -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.16
*/
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.16
*/
virtual bool leaveUpdateMode() { return true; }

signals:

/**
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -377,6 +377,7 @@ void QgsVectorLayer::reload()
if ( mDataProvider )
{
mDataProvider->reloadData();
updateFields();
}
}

Expand Down Expand Up @@ -1454,6 +1455,8 @@ bool QgsVectorLayer::startEditing()

emit beforeEditingStarted();

mDataProvider->enterUpdateMode();

if ( mDataProvider->transaction() )
{
mEditBuffer = new QgsVectorLayerEditPassthrough( this );
Expand Down Expand Up @@ -2424,6 +2427,8 @@ bool QgsVectorLayer::commitChanges()
updateFields();
mDataProvider->updateExtents();

mDataProvider->leaveUpdateMode();

emit repaintRequested();

return success;
Expand Down Expand Up @@ -2474,6 +2479,8 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer )
if ( rollbackExtent )
updateExtents();

mDataProvider->leaveUpdateMode();

emit repaintRequested();
return true;
}
Expand Down
16 changes: 14 additions & 2 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -46,6 +46,10 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
mFeatureFetched = false;

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

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

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

Expand Down Expand Up @@ -212,7 +224,7 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
{
feature.setValid( false );

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

if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
Expand Down Expand Up @@ -257,7 +269,7 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )

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

OGR_L_ResetReading( ogrLayer );
Expand Down

0 comments on commit 0f6838d

Please sign in to comment.