Skip to content

Commit

Permalink
[FEATURE] json_to_map() / map_to_json() expression functions
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Sep 14, 2018
1 parent f42f7ac commit 68162a5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 0 deletions.
9 changes: 9 additions & 0 deletions resources/function_help/json/json_to_map
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "json_to_map",
"type": "function",
"description": "Creates a map from a json-formatted string.",
"arguments": [
{"arg":"string", "description":"the input string"}],
"examples": [ { "expression":"json_to_map('{\"qgis\":\"rocks\"}')", "returns":"{ \"qgis\" : \"rocks\" }"}
]
}
9 changes: 9 additions & 0 deletions resources/function_help/json/map_to_json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "map_to_json",
"type": "function",
"description": "Merge map elements into a json-formatted string.",
"arguments": [
{"arg":"map", "description":"the input map"}],
"examples": [ { "expression":"map_to_json(map('qgis','rocks'))", "returns":"{\"qgis\":\"rocks\"}"}
]
}
20 changes: 20 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4349,6 +4349,24 @@ static QVariant fcnStringToArray( const QVariantList &values, const QgsExpressio
return array;
}

static QVariant fcnJsonToMap( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
if ( document.isNull() || !document.isObject() )
return QVariantMap();

return document.object().toVariantMap();
}

static QVariant fcnMapToJson( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
QJsonObject object = QJsonObject::fromVariantMap( map );
QJsonDocument document( object );
return document.toJson( QJsonDocument::Compact );
}

static QVariant fcnMap( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QVariantMap result;
Expand Down Expand Up @@ -5014,6 +5032,8 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "generate_series" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "start" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "stop" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "step" ), true, 1.0 ), fcnGenerateSeries, QStringLiteral( "Arrays" ) )

//functions for maps
<< new QgsStaticExpressionFunction( QStringLiteral( "json_to_map" ), 1, fcnJsonToMap, QStringLiteral( "Maps" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "map_to_json" ), 1, fcnMapToJson, QStringLiteral( "Maps" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "map" ), -1, fcnMap, QStringLiteral( "Maps" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "map_get" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "map" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "key" ) ), fcnMapGet, QStringLiteral( "Maps" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "map_exist" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "map" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "key" ) ), fcnMapExist, QStringLiteral( "Maps" ) )
Expand Down
2 changes: 2 additions & 0 deletions src/core/expression/qgsexpressionfunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <QString>
#include <QVariant>
#include <QSet>
#include <QJsonDocument>
#include <QJsonObject>

#include "qgis.h"
#include "qgis_core.h"
Expand Down
3 changes: 3 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2885,6 +2885,9 @@ class TestQgsExpression: public QObject
concatExpected[QStringLiteral( "3" )] = "three";
QCOMPARE( QgsExpression( "map_concat(map('1', 'one', '2', 'overridden by next map'), map('2', 'two', '3', 'three'))" ).evaluate( &context ), QVariant( concatExpected ) );

QCOMPARE( QgsExpression( "json_to_map('{\"1\":\"one\",\"2\":\"two\",\"3\":\"three\"}')" ).evaluate( &context ), QVariant( concatExpected ) );
QCOMPARE( QgsExpression( "map_to_json(map('1','one','2','two','3','three'))" ).evaluate( &context ), QVariant( "{\"1\":\"one\",\"2\":\"two\",\"3\":\"three\"}" ) );

QStringList keysExpected;
keysExpected << QStringLiteral( "1" ) << QStringLiteral( "2" );
QCOMPARE( QgsExpression( "map_akeys(\"map\")" ).evaluate( &context ), QVariant( keysExpected ) );
Expand Down

0 comments on commit 68162a5

Please sign in to comment.