Skip to content
Permalink
Browse files

[FEATURE] Boolean field support for memory layers

Adds support for boolean field types to memory layers

Fixes #20844
  • Loading branch information
nyalldawson committed Dec 20, 2018
1 parent 497a53b commit 055a166136f29972571944bc741fbc68af42b4ea
@@ -94,6 +94,9 @@ QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions
// string types
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 )

// boolean
<< QgsVectorDataProvider::NativeType( tr( "Boolean" ), QStringLiteral( "bool" ), QVariant::Bool )

// blob
<< QgsVectorDataProvider::NativeType( tr( "Binary object (BLOB)" ), QStringLiteral( "binary" ), QVariant::ByteArray )

@@ -103,7 +106,7 @@ QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions
{
QList<QgsField> attributes;
QRegExp reFieldDef( "\\:"
"(int|integer|long|int8|real|double|string|date|time|datetime|binary)" // type
"(int|integer|long|int8|real|double|string|date|time|datetime|binary|bool|boolean)" // type
"(?:\\((\\-?\\d+)" // length
"(?:\\,(\\d+))?" // precision
"\\))?(\\[\\])?" // array
@@ -160,6 +163,12 @@ QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions
typeName = QStringLiteral( "datetime" );
length = -1;
}
else if ( typeName == QLatin1String( "bool" ) || typeName == QLatin1String( "boolean" ) )
{
type = QVariant::Bool;
typeName = QStringLiteral( "boolean" );
length = -1;
}
else if ( typeName == QLatin1String( "binary" ) )
{
type = QVariant::ByteArray;
@@ -453,6 +462,7 @@ bool QgsMemoryProvider::addAttributes( const QList<QgsField> &attributes )
case QVariant::LongLong:
case QVariant::StringList:
case QVariant::List:
case QVariant::Bool:
case QVariant::ByteArray:
break;
default:
@@ -47,6 +47,9 @@ QString memoryLayerFieldType( QVariant::Type type )
case QVariant::ByteArray:
return QStringLiteral( "binary" );

case QVariant::Bool:
return QStringLiteral( "boolean" );

default:
break;
}
@@ -411,6 +411,7 @@ def testCreateMemoryLayer(self):
fields.append(QgsField("#complex_name", QVariant.String))
fields.append(QgsField("complex/name", QVariant.String))
fields.append(QgsField("binaryfield", QVariant.ByteArray))
fields.append(QgsField("boolfield", QVariant.Bool))
layer = QgsMemoryProviderUtils.createMemoryLayer('my name', fields)
self.assertTrue(layer.isValid())
self.assertFalse(layer.fields().isEmpty())
@@ -550,6 +551,42 @@ def testBinary(self):
f2 = [f for f in dp.getFeatures()][1]
self.assertEqual(f2.attributes(), [2, NULL, bin_val2])

def testBool(self):
vl = QgsVectorLayer(
'Point?crs=epsg:4326&field=f1:integer&field=f2:bool',
'test', 'memory')
self.assertTrue(vl.isValid())

dp = vl.dataProvider()
fields = dp.fields()
self.assertEqual([f.name() for f in fields], ['f1', 'f2'])
self.assertEqual([f.type() for f in fields], [QVariant.Int, QVariant.Bool])
self.assertEqual([f.typeName() for f in fields], ['integer', 'boolean'])

f = QgsFeature(dp.fields())
f.setAttributes([1, True])
f2 = QgsFeature(dp.fields())
f2.setAttributes([2, False])
f3 = QgsFeature(dp.fields())
f3.setAttributes([3, NULL])
self.assertTrue(dp.addFeatures([f, f2, f3]))

self.assertEqual([f.attributes() for f in dp.getFeatures()], [[1, True], [2, False], [3, NULL]])

# add boolean field
self.assertTrue(dp.addAttributes([QgsField('boolfield2', QVariant.Bool, 'Boolean')]))

fields = dp.fields()
bool2_field = fields[fields.lookupField('boolfield2')]
self.assertEqual(bool2_field.type(), QVariant.Bool)
self.assertEqual(bool2_field.typeName(), 'Boolean')

f = QgsFeature(fields)
f.setAttributes([2, NULL, True])
self.assertTrue(dp.addFeature(f))

self.assertEqual([f.attributes() for f in dp.getFeatures()], [[1, True, NULL], [2, False, NULL], [3, NULL, NULL], [2, NULL, True]])


class TestPyQgsMemoryProviderIndexed(unittest.TestCase, ProviderTestCase):

0 comments on commit 055a166

Please sign in to comment.
You can’t perform that action at this time.