Skip to content

Commit bb6fc32

Browse files
committedNov 2, 2016
[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)
1 parent 210c98b commit bb6fc32

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -927,18 +927,27 @@ void QgsOgrProvider::loadFields()
927927
if ( prec > 0 )
928928
width -= 1;
929929

930-
mAttributeFields.append(
931-
QgsField(
932-
name,
933-
varType,
930+
QgsField newField = QgsField(
931+
name,
932+
varType,
934933
#ifdef ANDROID
935-
OGR_GetFieldTypeName( ogrType ),
934+
OGR_GetFieldTypeName( ogrType ),
936935
#else
937-
textEncoding()->toUnicode( OGR_GetFieldTypeName( ogrType ) ),
936+
textEncoding()->toUnicode( OGR_GetFieldTypeName( ogrType ) ),
938937
#endif
939-
width, prec
940-
)
941-
);
938+
width, prec
939+
);
940+
941+
#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
942+
// check if field is nullable
943+
bool nullable = OGR_Fld_IsNullable( fldDef );
944+
if ( !nullable )
945+
{
946+
newField.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
947+
}
948+
#endif
949+
950+
mAttributeFields.append( newField );
942951
}
943952
}
944953
}

‎tests/src/python/test_provider_ogr_sqlite.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import glob
2121
from osgeo import gdal, ogr
2222

23-
from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsFeatureRequest
23+
from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsFeatureRequest, QgsField
2424
from qgis.testing import start_app, unittest
2525
from utilities import unitTestDataPath
2626

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

132+
@unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0))
133+
def testNotNullConstraint(self):
134+
""" test detection of not null constraint on OGR layer """
135+
136+
tmpfile = os.path.join(self.basetestpath, 'testNotNullConstraint.sqlite')
137+
ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
138+
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid'])
139+
lyr.CreateField(ogr.FieldDefn('field1', ogr.OFTInteger))
140+
fld2 = ogr.FieldDefn('field2', ogr.OFTInteger)
141+
fld2.SetNullable(False)
142+
lyr.CreateField(fld2)
143+
ds = None
144+
145+
vl = QgsVectorLayer('{}'.format(tmpfile), 'test', 'ogr')
146+
self.assertTrue(vl.isValid())
147+
148+
# test some bad indexes
149+
self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsField.Constraints())
150+
self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsField.Constraints())
151+
152+
self.assertFalse(vl.dataProvider().fieldConstraints(0) & QgsField.ConstraintNotNull)
153+
self.assertFalse(vl.dataProvider().fieldConstraints(1) & QgsField.ConstraintNotNull)
154+
self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsField.ConstraintNotNull)
155+
156+
# test that constraints have been saved to fields correctly
157+
fields = vl.fields()
158+
self.assertFalse(fields.at(0).constraints() & QgsField.ConstraintNotNull)
159+
self.assertFalse(fields.at(1).constraints() & QgsField.ConstraintNotNull)
160+
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintNotNull)
161+
self.assertEqual(fields.at(2).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)
162+
132163

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

0 commit comments

Comments
 (0)
Please sign in to comment.