Skip to content
Permalink
Browse files

[FEATURE] Not null constraint detection for ogr provider

Implements not null constraint detection for the OGR layers, where
supported for the data format by OGR.

(only available for GDAL >= 2.0)
  • Loading branch information
nyalldawson committed Nov 2, 2016
1 parent 210c98b commit bb6fc32eec3bc5576ee0810f5e6b38f5f66a2270
Showing with 50 additions and 10 deletions.
  1. +18 −9 src/providers/ogr/qgsogrprovider.cpp
  2. +32 −1 tests/src/python/test_provider_ogr_sqlite.py
@@ -927,18 +927,27 @@ void QgsOgrProvider::loadFields()
if ( prec > 0 )
width -= 1;

mAttributeFields.append(
QgsField(
name,
varType,
QgsField newField = QgsField(
name,
varType,
#ifdef ANDROID
OGR_GetFieldTypeName( ogrType ),
OGR_GetFieldTypeName( ogrType ),
#else
textEncoding()->toUnicode( OGR_GetFieldTypeName( ogrType ) ),
textEncoding()->toUnicode( OGR_GetFieldTypeName( ogrType ) ),
#endif
width, prec
)
);
width, prec
);

#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
// check if field is nullable
bool nullable = OGR_Fld_IsNullable( fldDef );
if ( !nullable )
{
newField.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
}
#endif

mAttributeFields.append( newField );
}
}
}
@@ -20,7 +20,7 @@
import glob
from osgeo import gdal, ogr

from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsFeatureRequest
from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsFeatureRequest, QgsField
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath

@@ -129,6 +129,37 @@ def testFidSupport(self):
got = [(f.attribute('fid'), f.attribute('intfield')) for f in vl.dataProvider().getFeatures(QgsFeatureRequest().setFilterExpression("fid = 12"))]
self.assertEqual(got, [(12, 123)])

@unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0))
def testNotNullConstraint(self):
""" test detection of not null constraint on OGR layer """

tmpfile = os.path.join(self.basetestpath, 'testNotNullConstraint.sqlite')
ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid'])
lyr.CreateField(ogr.FieldDefn('field1', ogr.OFTInteger))
fld2 = ogr.FieldDefn('field2', ogr.OFTInteger)
fld2.SetNullable(False)
lyr.CreateField(fld2)
ds = None

vl = QgsVectorLayer('{}'.format(tmpfile), 'test', 'ogr')
self.assertTrue(vl.isValid())

# test some bad indexes
self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsField.Constraints())
self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsField.Constraints())

self.assertFalse(vl.dataProvider().fieldConstraints(0) & QgsField.ConstraintNotNull)
self.assertFalse(vl.dataProvider().fieldConstraints(1) & QgsField.ConstraintNotNull)
self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsField.ConstraintNotNull)

# test that constraints have been saved to fields correctly
fields = vl.fields()
self.assertFalse(fields.at(0).constraints() & QgsField.ConstraintNotNull)
self.assertFalse(fields.at(1).constraints() & QgsField.ConstraintNotNull)
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintNotNull)
self.assertEqual(fields.at(2).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)


if __name__ == '__main__':
unittest.main()

0 comments on commit bb6fc32

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