Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix Map-based JSON handling in QgsField's convertCompatible()
  • Loading branch information
nirvn committed Apr 14, 2023
1 parent 5b92283 commit 95b622e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 20 deletions.
26 changes: 19 additions & 7 deletions src/core/qgsfield.cpp
Expand Up @@ -600,16 +600,28 @@ bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
}
}

if ( d->type == QVariant::String && ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) ) )
if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName.compare( QLatin1String( "jsonb" ), Qt::CaseInsensitive ) == 0 )
{
const QJsonDocument doc = QJsonDocument::fromVariant( v );
if ( !doc.isNull() )
if ( d->type == QVariant::String )
{
v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
return true;
const QJsonDocument doc = QJsonDocument::fromVariant( v );
if ( !doc.isNull() )
{
v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
return true;
}
v = QVariant( d->type );
return false;
}
else if ( d->type == QVariant::Map )
{
if ( v.type() == QVariant::StringList || v.type() == QVariant::List || v.type() == QVariant::Map )
{
return true;
}
v = QVariant( d->type );
return false;
}
v = QVariant( d->type );
return false;
}

if ( ( d->type == QVariant::StringList || ( d->type == QVariant::List && d->subType == QVariant::String ) )
Expand Down
44 changes: 31 additions & 13 deletions tests/src/core/testqgsfield.cpp
Expand Up @@ -828,19 +828,37 @@ void TestQgsField::convertCompatible()
QVariant vZero = 0;
QVERIFY( intField.convertCompatible( vZero ) );

// Test json field conversion
const QgsField jsonField( QStringLiteral( "json" ), QVariant::String, QStringLiteral( "json" ) );
QVariant jsonValue = QVariant::fromValue( QVariantList() << 1 << 5 << 8 );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::String );
QCOMPARE( jsonValue, QString( "[1,5,8]" ) );
QVariantMap variantMap;
variantMap.insert( QStringLiteral( "a" ), 1 );
variantMap.insert( QStringLiteral( "c" ), 3 );
jsonValue = QVariant::fromValue( variantMap );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::String );
QCOMPARE( jsonValue, QString( "{\"a\":1,\"c\":3}" ) );
// Test string-based json field conversion
{
const QgsField jsonField( QStringLiteral( "json" ), QVariant::String, QStringLiteral( "json" ) );
QVariant jsonValue = QVariant::fromValue( QVariantList() << 1 << 5 << 8 );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::String );
QCOMPARE( jsonValue, QString( "[1,5,8]" ) );
QVariantMap variantMap;
variantMap.insert( QStringLiteral( "a" ), 1 );
variantMap.insert( QStringLiteral( "c" ), 3 );
jsonValue = QVariant::fromValue( variantMap );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::String );
QCOMPARE( jsonValue, QString( "{\"a\":1,\"c\":3}" ) );
}

// Test map-based json field (i.e. OGR geopackage JSON fields) conversion
{
const QgsField jsonField( QStringLiteral( "json" ), QVariant::Map, QStringLiteral( "json" ) );
QVariant jsonValue = QVariant::fromValue( QVariantList() << 1 << 5 << 8 );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::List );
QCOMPARE( jsonValue, QVariantList() << 1 << 5 << 8 );
QVariantMap variantMap;
variantMap.insert( QStringLiteral( "a" ), 1 );
variantMap.insert( QStringLiteral( "c" ), 3 );
jsonValue = QVariant::fromValue( variantMap );
QVERIFY( jsonField.convertCompatible( jsonValue ) );
QCOMPARE( jsonValue.type(), QVariant::Map );
QCOMPARE( jsonValue, variantMap );
}

// geometry field conversion
const QgsField geometryField( QStringLiteral( "geometry" ), QVariant::UserType, QStringLiteral( "geometry" ) );
Expand Down

0 comments on commit 95b622e

Please sign in to comment.