Skip to content

Commit

Permalink
Merge pull request #10034 from rldhont/server-feature-id-primary-keys…
Browse files Browse the repository at this point in the history
…-revival

[Server] Use primary keys to build feature id
  • Loading branch information
rldhont committed Jun 28, 2019
2 parents e51c110 + 2a6f568 commit 169de69
Show file tree
Hide file tree
Showing 14 changed files with 529 additions and 129 deletions.
1 change: 1 addition & 0 deletions src/server/CMakeLists.txt
Expand Up @@ -32,6 +32,7 @@ SET(QGIS_SERVER_SRCS
qgsserverinterfaceimpl.cpp
qgsserverlogger.cpp
qgsserverprojectutils.cpp
qgsserverfeatureid.cpp
qgsserverrequest.cpp
qgsserverresponse.cpp
qgsserversettings.cpp
Expand Down
115 changes: 115 additions & 0 deletions src/server/qgsserverfeatureid.cpp
@@ -0,0 +1,115 @@
/***************************************************************************
qgsserverfeatureid.cpp
-----------------------
begin : May 17, 2019
copyright : (C) 2019 by René-Luc DHONT
email : rldhont at 3liz dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsserverfeatureid.h"
#include "qgsfeature.h"
#include "qgsfeaturerequest.h"
#include "qgsvectordataprovider.h"
#include "qgsexpression.h"

QString QgsServerFeatureId::getServerFid( const QgsFeature &feature, const QgsAttributeList &pkAttributes )
{
if ( pkAttributes.isEmpty() )
{
return QString::number( feature.id() );
}

QStringList pkValues;
QgsAttributeList::const_iterator it = pkAttributes.constBegin();
if ( it != pkAttributes.constEnd() )
{
pkValues.append( feature.attribute( *it ).toString() );
}
return pkValues.join( pkSeparator() );
}

QgsFeatureRequest QgsServerFeatureId::updateFeatureRequestFromServerFids( QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider )
{
const QgsAttributeList &pkAttributes = provider->pkAttributeIndexes();

if ( pkAttributes.isEmpty() )
{
QgsFeatureIds fids;
for ( const QString &serverFid : serverFids )
{
fids.insert( serverFid.toLongLong() );
}
featureRequest.setFilterFids( fids );
return featureRequest;
}

QStringList expList;
for ( const QString &serverFid : serverFids )
{
expList.append( QgsServerFeatureId::getExpressionFromServerFid( serverFid, provider ) );
}

if ( expList.count() == 1 )
{
featureRequest.setFilterExpression( expList.at( 0 ) );
}
else
{
QString fullExpression;
for ( const QString &exp : qgis::as_const( expList ) )
{
if ( !fullExpression.isEmpty() )
{
fullExpression.append( QStringLiteral( " OR " ) );
}
fullExpression.append( QStringLiteral( "( " ) );
fullExpression.append( exp );
fullExpression.append( QStringLiteral( " )" ) );
}
featureRequest.setFilterExpression( fullExpression );
}

return featureRequest;
}

QString QgsServerFeatureId::getExpressionFromServerFid( const QString &serverFid, const QgsVectorDataProvider *provider )
{
const QgsAttributeList &pkAttributes = provider->pkAttributeIndexes();

if ( pkAttributes.isEmpty() )
{
return QString();
}

const QgsFields &fields = provider->fields();

QString expressionString;
QStringList pkValues = serverFid.split( pkSeparator() );
int pkExprSize = std::min( pkAttributes.size(), pkValues.size() );
for ( int i = 0; i < pkExprSize; ++i )
{
if ( i > 0 )
{
expressionString.append( QStringLiteral( " AND " ) );
}

QString fieldName = fields[ pkAttributes.at( i ) ].name();
expressionString.append( QgsExpression::createFieldEqualityExpression( fieldName, QVariant( pkValues.at( i ) ) ) );
}

return expressionString;
}

QString QgsServerFeatureId::pkSeparator()
{
return QStringLiteral( "@@" );
}
86 changes: 86 additions & 0 deletions src/server/qgsserverfeatureid.h
@@ -0,0 +1,86 @@
/***************************************************************************
qgsserverfeatureid.h
-----------------------
begin : May 17, 2019
copyright : (C) 2019 by René-Luc DHONT
email : rldhont at 3liz dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSSERVERFEATUREID_H
#define QGSSERVERFEATUREID_H

#define SIP_NO_FILE

#include <QString>
#include <QHash>

#include "qgis_server.h"
#include "qgsfield.h"

class QgsVectorDataProvider;
class QgsFeature;
class QgsFeatureRequest;

#ifdef SIP_RUN
% ModuleHeaderCode
#include "qgsserverfeatureid.h"
% End
#endif


/**
* \ingroup server
* The QgsServerFeatureId namespace provides a way to use primary keys for
* feature id.
* \since QGIS 3.4.9
*/
namespace QgsServerFeatureId
{

/**
* Returns the feature id based on primary keys.
* \param feature the feature
* \param pkAttributes the primary keys list
* \returns the feature id based on primary keys
* \since QGIS 3.4.9
*/
SERVER_EXPORT QString getServerFid( const QgsFeature &feature, const QgsAttributeList &pkAttributes );

/**
* Returns the feature request based on feature ids build with primary keys.
* \param featureRequest the feature request to update
* \param serverFids the feature ids build with QgsServerFeatureId::getServerFid
* \param provider the vector layer provider to provide fields and primary keys list
* \returns the feature request updated
* \since QGIS 3.4.9
*/
SERVER_EXPORT QgsFeatureRequest updateFeatureRequestFromServerFids( QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider );

/**
* Returns the expression feature id based on primary keys.
* \param serverFid the feature id build with primary keys
* \param provider the vector layer provider to provide fields and primary keys list
* \returns the feature id based on primary keys
* \since QGIS 3.4.9
*/
SERVER_EXPORT QString getExpressionFromServerFid( const QString &serverFid, const QgsVectorDataProvider *provider );

/**
* Returns the primary keys separator
* \returns @@ the primary keys separator
* \since QGIS 3.4.9
*/
SERVER_EXPORT QString pkSeparator();

};

#endif

0 comments on commit 169de69

Please sign in to comment.