Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #9113 from rouault/fix_20865_3.4_backport
Ensure stability of QGIS FeatureId when reloading layer [WFS provider]
  • Loading branch information
rouault committed Feb 6, 2019
2 parents c2f958d + 4910b73 commit da4a0c0
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 32 deletions.
15 changes: 15 additions & 0 deletions src/core/qgssqliteutils.cpp
Expand Up @@ -91,6 +91,21 @@ sqlite3_statement_unique_ptr sqlite3_database_unique_ptr::prepare( const QString
return s;
}

int sqlite3_database_unique_ptr::exec( const QString &sql, QString &errorMessage ) const
{
char *errMsg;

int ret = sqlite3_exec( get(), sql.toUtf8(), nullptr, nullptr, &errMsg );

if ( errMsg )
{
errorMessage = QString::fromUtf8( errMsg );
sqlite3_free( errMsg );
}

return ret;
}

QString QgsSqliteUtils::quotedString( const QString &value )
{
if ( value.isNull() )
Expand Down
13 changes: 12 additions & 1 deletion src/core/qgssqliteutils.h
Expand Up @@ -21,6 +21,8 @@
#define SIP_NO_FILE

#include "qgis_core.h"
#include "qgis_sip.h"

#include <memory>
#include <QString>

Expand Down Expand Up @@ -134,8 +136,17 @@ class CORE_EXPORT sqlite3_database_unique_ptr : public std::unique_ptr< sqlite3,
* Prepares a \a sql statement, returning the result. The \a resultCode
* argument will be filled with the sqlite3 result code.
*/
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode ) const;
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode SIP_OUT ) const;

/**
* Executes the \a sql command in the database. Multiple sql queries can be run within
* one single command.
* Errors are reported to \a errorMessage.
* Returns SQLITE_OK in case of success or an sqlite error code.
*
* \since QGIS 3.4.5
*/
int exec( const QString &sql, QString &errorMessage SIP_OUT ) const;
};

/**
Expand Down
26 changes: 25 additions & 1 deletion src/providers/wfs/qgswfsfeatureiterator.cpp
Expand Up @@ -32,13 +32,16 @@
#include "qgssettings.h"
#include "qgsexception.h"
#include "qgsfeedback.h"
#include "qgssqliteutils.h"

#include <algorithm>
#include <QDir>
#include <QProgressDialog>
#include <QTimer>
#include <QStyle>

#include <sqlite3.h>

QgsWFSFeatureHitsAsyncRequest::QgsWFSFeatureHitsAsyncRequest( QgsWFSDataSourceURI &uri )
: QgsWfsRequest( uri )
, mNumberMatched( -1 )
Expand Down Expand Up @@ -986,7 +989,15 @@ QgsFeatureRequest QgsWFSFeatureIterator::buildRequestCache( int genCounter )
QgsFeatureRequest requestCache;
if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ||
mRequest.filterType() == QgsFeatureRequest::FilterFids )
requestCache = mRequest;
{
QgsFeatureIds qgisIds;
if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
qgisIds.insert( mRequest.filterFid() );
else
qgisIds = mRequest.filterFids();

requestCache.setFilterFids( mShared->dbIdsFromQgisIds( qgisIds ) );
}
else
{
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
Expand Down Expand Up @@ -1238,6 +1249,19 @@ bool QgsWFSFeatureIterator::fetchFeature( QgsFeature &f )

copyFeature( cachedFeature, f );
geometryToDestinationCrs( f, mTransform );

// Retrieve the user-visible id from the Spatialite cache database Id
if ( mShared->mCacheIdDb.get() )
{
auto sql = QgsSqlite3Mprintf( "SELECT qgisId FROM id_cache WHERE dbId = %lld", cachedFeature.id() );
int resultCode;
auto stmt = mShared->mCacheIdDb.prepare( sql, resultCode );
if ( stmt.step() == SQLITE_ROW )
{
f.setId( stmt.columnAsInt64( 0 ) );
}
}

return true;
}

Expand Down

0 comments on commit da4a0c0

Please sign in to comment.