diff --git a/src/app/qgsaddattrdialog.cpp b/src/app/qgsaddattrdialog.cpp index eaf615e5504..141e5fe0f4a 100644 --- a/src/app/qgsaddattrdialog.cpp +++ b/src/app/qgsaddattrdialog.cpp @@ -111,6 +111,7 @@ void QgsAddAttrDialog::accept() QgsField QgsAddAttrDialog::field() const { + QgsDebugMsg( QStringLiteral( "idx:%1 name:%2 type:%3 typeName:%4 length:%5 prec:%6 comment:%7" ) .arg( mTypeBox->currentIndex() ) .arg( mNameEdit->text() ) @@ -126,5 +127,7 @@ QgsField QgsAddAttrDialog::field() const mTypeBox->currentData( Qt::UserRole + 1 ).toString(), mLength->value(), mPrec->value(), - mCommentEdit->text() ); + mCommentEdit->text(), + ( QVariant::Type ) mTypeBox->currentData( Qt::UserRole ).toInt() == QVariant::Map ? QVariant::String : QVariant::Invalid + ); } diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp index eab8db006e3..b8be5da3cd0 100644 --- a/src/providers/ogr/qgsogrprovider.cpp +++ b/src/providers/ogr/qgsogrprovider.cpp @@ -477,7 +477,7 @@ QgsOgrProvider::QgsOgrProvider( QString const &uri, const ProviderOptions &optio << QgsVectorDataProvider::NativeType( tr( "Whole number (integer 64 bit)" ), QStringLiteral( "integer64" ), QVariant::LongLong, 0, nMaxInt64Len ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "double" ), QVariant::Double, 0, nMaxDoubleLen, 0, nMaxDoublePrec ) << QgsVectorDataProvider::NativeType( tr( "Text (string)" ), QStringLiteral( "string" ), QVariant::String, 0, 65535 ) - << QgsVectorDataProvider::NativeType( tr( "Map (json)" ), QStringLiteral( "json" ), QVariant::Map, -1, -1, -1, -1, QVariant::String ); + << QgsVectorDataProvider::NativeType( tr( "Map (JSON)" ), QStringLiteral( "JSON" ), QVariant::Map, 0, 65535, 0, 0, QVariant::String ); bool supportsDate = true; bool supportsTime = mGDALDriverName != QLatin1String( "ESRI Shapefile" ) && mGDALDriverName != QLatin1String( "GPKG" ); @@ -1531,19 +1531,18 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags ) case OFTString: { QString stringValue; - /* - * if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON ) + if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON ) { stringValue = QString::fromUtf8( QJsonDocument::fromVariant( attrVal.toMap() ).toJson().data() ); - if( stringValue == QStringLiteral( "{\n}\n" ) ) + if ( stringValue == QStringLiteral( "{\n}\n" ) ) stringValue = QString::fromUtf8( QJsonDocument::fromVariant( attrVal.toList() ).toJson().data() ); - if( stringValue == QStringLiteral( "[\n]\n" ) ) - stringValue = QString::fromUtf8( QJsonDocument::fromVariant( attrVal.toString() ).toJson().data() ); + if ( stringValue == QStringLiteral( "[\n]\n" ) ) + stringValue = QString::fromUtf8( QJsonDocument::fromVariant( attrVal.toString() ).toJson().data() ); } else { - */ stringValue = attrVal.toString(); - //} + stringValue = attrVal.toString(); + } QgsDebugMsgLevel( QStringLiteral( "Writing string attribute %1 with %2, encoding %3" ) .arg( qgisAttId ) @@ -2122,19 +2121,18 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_ case OFTString: { QString stringValue; - /* - * if ( OGR_Fld_GetSubType( fd ) == OFSTJSON ) + if ( OGR_Fld_GetSubType( fd ) == OFSTJSON ) { stringValue = QString::fromUtf8( QJsonDocument::fromVariant( it2->toMap() ).toJson().data() ); - if( stringValue == QStringLiteral( "{\n}\n" ) ) + if ( stringValue == QStringLiteral( "{\n}\n" ) ) stringValue = QString::fromUtf8( QJsonDocument::fromVariant( it2->toList() ).toJson().data() ); - if( stringValue == QStringLiteral( "[\n]\n" ) ) - stringValue = QString::fromUtf8( QJsonDocument::fromVariant( it2->toString() ).toJson().data() ); + if ( stringValue == QStringLiteral( "[\n]\n" ) ) + stringValue = QString::fromUtf8( QJsonDocument::fromVariant( it2->toString() ).toJson().data() ); } else - {*/ - stringValue = it2->toString(); - //} + { + stringValue = it2->toString(); + } OGR_F_SetFieldString( of.get(), f, textEncoding()->fromUnicode( stringValue ).constData() ); break; diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py index 2c9ae9c08bc..4438921cb26 100644 --- a/tests/src/python/test_provider_ogr_gpkg.py +++ b/tests/src/python/test_provider_ogr_gpkg.py @@ -1258,11 +1258,37 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase): #test changing list value in attribute f['json_content'] = ['eins', 'zwei', 'drei', 4] self.assertEqual(f['json_content'], ['eins', 'zwei', 'drei', 4]) + #test chaning to complex json structure + f['json_content'] = {'name': 'Lily', 'age': '0', 'cars': {'car1': ['fiat tipo', 'fiat punto', 'davoser schlitten'], 'car2': 'bobbycar', 'car3': 'tesla'}} + self.assertEqual(f['json_content'], {'name': 'Lily', 'age': '0', 'cars': {'car1': ['fiat tipo', 'fiat punto', 'davoser schlitten'], 'car2': 'bobbycar', 'car3': 'tesla'}}) - #test adding attribute with list value - #test changing to invalid value in attribute - #test changing list ot string - #test reading string + #test adding attribute + vl.startEditing() + self.assertTrue(vl.addAttribute(QgsField('json_content2', QVariant.Map, "JSON", 60, 0, 'no comment', QVariant.String))) + self.assertTrue(vl.commitChanges()) + + vl.startEditing() + self.assertTrue(vl.addAttribute(QgsField('json_content3', QVariant.Map, "JSON", 60, 0, 'no comment', QVariant.String))) + self.assertTrue(vl.commitChanges()) + + #test setting values to new attributes + while fi.nextFeature(f): + if f['fid'] == 2: + f['json_content'] = {'uno': 'foo'} + f['json_content2'] = ['uno', 'due', 'tre'] + f['json_content3'] = {'uno': ['uno', 'due', 'tre']} + self.assertEqual(f['json_content'], {'foo': 'baz'}) + self.assertEqual(f['json_content2'], ['uno', 'due', 'tre']) + self.assertEqual(f['json_content3'], {'uno': ['uno', 'due', 'tre']}) + + #test deleting attribute + vl.startEditing() + self.assertTrue(vl.deleteAttribute(vl.fields().indexFromName('json_content3'))) + self.assertTrue(vl.commitChanges()) + + #test if index of existent field is not -1 and the one of the deleted is -1 + self.assertNotEqual(vl.fields().indexFromName('json_content2'), -1) + self.assertEqual(vl.fields().indexFromName('json_content3'), -1) if __name__ == '__main__':