Skip to content

Commit 429320d

Browse files
committedNov 12, 2018
[FEATURE] Binary (blob) field support for memory layers
Allows storage of binary blob fields in memory layers
1 parent d96ce7a commit 429320d

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed
 

‎src/core/providers/memory/qgsmemoryprovider.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,17 @@ QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions
9393

9494
// string types
9595
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 )
96+
97+
// blob
98+
<< QgsVectorDataProvider::NativeType( tr( "Binary object (BLOB)" ), QStringLiteral( "binary" ), QVariant::ByteArray )
99+
96100
);
97101

98102
if ( url.hasQueryItem( QStringLiteral( "field" ) ) )
99103
{
100104
QList<QgsField> attributes;
101105
QRegExp reFieldDef( "\\:"
102-
"(int|integer|long|int8|real|double|string|date|time|datetime)" // type
106+
"(int|integer|long|int8|real|double|string|date|time|datetime|binary)" // type
103107
"(?:\\((\\-?\\d+)" // length
104108
"(?:\\,(\\d+))?" // precision
105109
"\\))?(\\[\\])?" // array
@@ -156,6 +160,12 @@ QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions
156160
typeName = QStringLiteral( "datetime" );
157161
length = -1;
158162
}
163+
else if ( typeName == QLatin1String( "binary" ) )
164+
{
165+
type = QVariant::ByteArray;
166+
typeName = QStringLiteral( "binary" );
167+
length = -1;
168+
}
159169

160170
if ( !reFieldDef.cap( 2 ).isEmpty() )
161171
{
@@ -443,6 +453,7 @@ bool QgsMemoryProvider::addAttributes( const QList<QgsField> &attributes )
443453
case QVariant::LongLong:
444454
case QVariant::StringList:
445455
case QVariant::List:
456+
case QVariant::ByteArray:
446457
break;
447458
default:
448459
QgsDebugMsg( "Field type not supported: " + it->typeName() );

‎src/core/providers/memory/qgsmemoryproviderutils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ QString memoryLayerFieldType( QVariant::Type type )
4444
case QVariant::DateTime:
4545
return QStringLiteral( "datetime" );
4646

47+
case QVariant::ByteArray:
48+
return QStringLiteral( "binary" );
49+
4750
default:
4851
break;
4952
}

‎tests/src/python/test_provider_memory.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
)
4343

4444
from providertestbase import ProviderTestCase
45-
from qgis.PyQt.QtCore import QVariant
45+
from qgis.PyQt.QtCore import QVariant, QByteArray
4646

4747
start_app()
4848
TEST_DATA_DIR = unitTestDataPath()
@@ -410,6 +410,7 @@ def testCreateMemoryLayer(self):
410410
fields.append(QgsField("time", QVariant.Time))
411411
fields.append(QgsField("#complex_name", QVariant.String))
412412
fields.append(QgsField("complex/name", QVariant.String))
413+
fields.append(QgsField("binaryfield", QVariant.ByteArray))
413414
layer = QgsMemoryProviderUtils.createMemoryLayer('my name', fields)
414415
self.assertTrue(layer.isValid())
415416
self.assertFalse(layer.fields().isEmpty())
@@ -509,6 +510,46 @@ def testMinMaxCache(self):
509510
self.assertEqual(vl.dataProvider().minimumValue(0), -100)
510511
self.assertEqual(vl.dataProvider().maximumValue(0), 400)
511512

513+
def testBinary(self):
514+
vl = QgsVectorLayer(
515+
'Point?crs=epsg:4326&field=f1:integer&field=f2:binary',
516+
'test', 'memory')
517+
self.assertTrue(vl.isValid())
518+
519+
dp = vl.dataProvider()
520+
fields = dp.fields()
521+
self.assertEqual([f.name() for f in fields], ['f1', 'f2'])
522+
self.assertEqual([f.type() for f in fields], [QVariant.Int, QVariant.ByteArray])
523+
self.assertEqual([f.typeName() for f in fields], ['integer', 'binary'])
524+
525+
f = QgsFeature(dp.fields())
526+
bin_1 = b'xxx'
527+
bin_val1 = QByteArray(bin_1)
528+
f.setAttributes([1, bin_val1])
529+
self.assertTrue(dp.addFeature(f))
530+
531+
f2 = [f for f in dp.getFeatures()][0]
532+
self.assertEqual(f2.attributes(), [1, bin_val1])
533+
534+
# add binary field
535+
self.assertTrue(dp.addAttributes([QgsField('binfield2', QVariant.ByteArray, 'Binary')]))
536+
537+
fields = dp.fields()
538+
bin2_field = fields[fields.lookupField('binfield2')]
539+
self.assertEqual(bin2_field.type(), QVariant.ByteArray)
540+
self.assertEqual(bin2_field.typeName(), 'Binary')
541+
542+
f = QgsFeature(fields)
543+
bin_2 = b'yyy'
544+
bin_val2 = QByteArray(bin_2)
545+
f.setAttributes([2, NULL, bin_val2])
546+
self.assertTrue(dp.addFeature(f))
547+
548+
f1 = [f for f in dp.getFeatures()][0]
549+
self.assertEqual(f1.attributes(), [1, bin_val1, NULL])
550+
f2 = [f for f in dp.getFeatures()][1]
551+
self.assertEqual(f2.attributes(), [2, NULL, bin_val2])
552+
512553

513554
class TestPyQgsMemoryProviderIndexed(unittest.TestCase, ProviderTestCase):
514555

0 commit comments

Comments
 (0)
Please sign in to comment.