Navigation Menu

Skip to content

Commit

Permalink
[ogr] Implement skipConstraintsCheck for fid
Browse files Browse the repository at this point in the history
With test.
  • Loading branch information
elpaso committed Nov 21, 2017
1 parent 53dd5ef commit a12939d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 17 deletions.
23 changes: 14 additions & 9 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -948,10 +948,7 @@ void QgsOgrProvider::loadFields()
mAttributeFields.append(
fidField
);
// Set default value for fid, this is needed because
// the attribute form will not accept a NULL value, passing
// -1 will delegate to the back-end.
mDefaultValues.insert( 0, QStringLiteral( "-1" ) );
mDefaultValues.insert( 0, tr( "Autogenerate" ) );
}

for ( int i = 0; i < fdef.GetFieldCount(); ++i )
Expand Down Expand Up @@ -1207,14 +1204,22 @@ QVariant QgsOgrProvider::defaultValue( int fieldId ) const

QString QgsOgrProvider::defaultValueClause( int fieldIndex ) const
{
QString defVal = mDefaultValues.value( fieldIndex, QString() );
return mDefaultValues.value( fieldIndex, QString() );
}

if ( !providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isEmpty() )
bool QgsOgrProvider::skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value ) const
{
Q_UNUSED( constraint );
// If the field is a fid, skip in case it's the default value
if ( fieldIndex == 0 && mFirstFieldIsFid )
{
return defVal;
return ! mDefaultValues.value( fieldIndex ).isEmpty();
}
else
{
// stricter check
return mDefaultValues.contains( fieldIndex ) && mDefaultValues.value( fieldIndex ) == value.toString() && !value.isNull();
}

return QString();
}

void QgsOgrProvider::updateExtents()
Expand Down
5 changes: 3 additions & 2 deletions src/providers/ogr/qgsogrprovider.h
Expand Up @@ -108,8 +108,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
virtual long featureCount() const override;
virtual QgsFields fields() const override;
virtual QgsRectangle extent() const override;
QVariant defaultValue( int fieldId ) const override;
QString defaultValueClause( int fieldIndex ) const override;
virtual QVariant defaultValue( int fieldId ) const override;
virtual QString defaultValueClause( int fieldIndex ) const override;
virtual bool skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value = QVariant() ) const override;
virtual void updateExtents() override;
virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
Expand Down
32 changes: 26 additions & 6 deletions tests/src/python/test_provider_ogr_gpkg.py
Expand Up @@ -633,16 +633,12 @@ def testGeopackageLargeFID(self):
self.assertTrue(vl.deleteFeature(1234567890123))
self.assertTrue(vl.commitChanges())

def test_SplitFeature(self):
"""Test gpkg feature can be split"""
def test_AddFeatureNullFid(self):
"""Test gpkg feature with NULL fid can be added"""
tmpfile = os.path.join(self.basetestpath, 'testGeopackageSplitFeatures.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPolygon)
lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))'))
lyr.CreateFeature(f)
f = None
ds = None

layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
Expand All @@ -652,6 +648,30 @@ def test_SplitFeature(self):
pkfield = fields.at(0)
self.assertTrue(pkfield.constraints().constraints() & QgsFieldConstraints.ConstraintUnique)

# Test add feature with default Fid (NULL)
layer.startEditing()
f = QgsFeature()
feat = QgsFeature(layer.fields())
feat.setGeometry(QgsGeometry.fromWkt('Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))'))
feat.setAttribute(1, 'test_value')
layer.addFeature(feat)
self.assertTrue(layer.commitChanges())
self.assertEqual(layer.featureCount(), 1)

def test_SplitFeature(self):
"""Test gpkg feature can be split"""
tmpfile = os.path.join(self.basetestpath, 'testGeopackageSplitFeatures.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPolygon)
lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))'))
lyr.CreateFeature(f)
f = None
ds = None

# Split features
layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
self.assertTrue(layer.isValid())
self.assertTrue(layer.isSpatial())
self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))')
Expand Down

0 comments on commit a12939d

Please sign in to comment.