Skip to content

Commit 091f488

Browse files
nyalldawsonm-kuhn
authored andcommittedNov 16, 2016
Make sure primary keys are always marked with a unique, not null
constraint for all providers
1 parent b5864cd commit 091f488

File tree

7 files changed

+89
-101
lines changed

7 files changed

+89
-101
lines changed
 

‎src/providers/arcgisrest/qgsafsprovider.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ QgsAfsProvider::QgsAfsProvider( const QString& uri )
132132
if ( mFields.at( idx ).name() == mObjectIdFieldName )
133133
{
134134
mObjectIdFieldIdx = idx;
135+
136+
// primary key is not null, unique
137+
QgsFieldConstraints constraints = mFields.at( idx ).constraints();
138+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
139+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
140+
mFields[ idx ].setConstraints( constraints );
141+
135142
break;
136143
}
137144
}

‎src/providers/db2/qgsdb2provider.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ int QgsDb2Provider::sConnectionId = 0;
3333
QgsDb2Provider::QgsDb2Provider( const QString& uri )
3434
: QgsVectorDataProvider( uri )
3535
, mNumberFeatures( 0 )
36+
, mFidColIdx( -1 )
3637
, mEnvironment( ENV_LUW )
3738
, mWkbType( QgsWkbTypes::Unknown )
3839
{
@@ -330,12 +331,25 @@ void QgsDb2Provider::loadFields()
330331
}
331332
// Hack to get primary key since the primaryIndex function above doesn't work
332333
// on z/OS. Pick first integer column.
333-
if ( mFidColName.length() == 0 &&
334+
if ( mFidColName.isEmpty() &&
334335
( sqlType == QVariant::LongLong || sqlType == QVariant::Int ) )
335336
{
336337
mFidColName = f.name();
337338
}
338339
}
340+
341+
if ( !mFidColName.isEmpty() )
342+
{
343+
mFidColIdx = mAttributeFields.indexFromName( mFidColName );
344+
if ( mFidColIdx >= 0 )
345+
{
346+
// primary key has not null, unique constraints
347+
QgsFieldConstraints constraints = mAttributeFields.at( mFidColIdx ).constraints();
348+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
349+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
350+
mAttributeFields[ mFidColIdx ].setConstraints( constraints );
351+
}
352+
}
339353
}
340354

341355
QVariant::Type QgsDb2Provider::decodeSqlType( int typeId )
@@ -1664,6 +1678,14 @@ QString QgsDb2Provider::description() const
16641678
return PROVIDER_DESCRIPTION;
16651679
}
16661680

1681+
QgsAttributeList QgsDb2Provider::pkAttributeIndexes() const
1682+
{
1683+
QgsAttributeList list;
1684+
if ( mFidColIdx >= 0 )
1685+
list << mFidColIdx;
1686+
return list;
1687+
}
1688+
16671689
QGISEXTERN QgsDb2Provider *classFactory( const QString *uri )
16681690
{
16691691
return new QgsDb2Provider( *uri );

‎src/providers/db2/qgsdb2provider.h

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,8 @@ class QgsDb2Provider : public QgsVectorDataProvider
5454

5555
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() ) const override;
5656

57-
/**
58-
* Get feature type.
59-
* @return int representing the feature type
60-
*/
6157
virtual QgsWkbTypes::Type wkbType() const override;
6258

63-
/**
64-
* Number of features in the layer
65-
* @return long containing number of features
66-
*/
6759
virtual long featureCount() const override;
6860

6961
/**
@@ -79,45 +71,24 @@ class QgsDb2Provider : public QgsVectorDataProvider
7971
virtual bool isValid() const override;
8072
QString subsetString() const override;
8173

82-
/**
83-
* Mutator for SQL WHERE clause used to limit dataset size.
84-
*/
8574
bool setSubsetString( const QString& theSQL, bool updateFeatureCount = true ) override;
8675

8776
virtual bool supportsSubsetString() const override { return true; }
8877

89-
/** Return a provider name
90-
91-
Essentially just returns the provider key. Should be used to build file
92-
dialogs so that providers can be shown with their supported types. Thus
93-
if more than one provider supports a given format, the user is able to
94-
select a specific provider to open that file.
95-
*/
9678
virtual QString name() const override;
9779

98-
/** Return description
99-
100-
Return a terse string describing what the provider is.
101-
*/
10280
virtual QString description() const override;
10381

104-
/** Returns a bitmask containing the supported capabilities
105-
Note, some capabilities may change depending on whether
106-
a spatial filter is active on this provider, so it may
107-
be prudent to check this value per intended operation.
108-
*/
82+
QgsAttributeList pkAttributeIndexes() const override;
83+
10984
virtual QgsVectorDataProvider::Capabilities capabilities() const override;
11085

111-
//! Writes a list of features to the database
11286
virtual bool addFeatures( QgsFeatureList & flist ) override;
11387

114-
//! Deletes a feature
11588
virtual bool deleteFeatures( const QgsFeatureIds & id ) override;
11689

117-
//! Changes attribute values of existing features
11890
virtual bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
11991

120-
//! Changes existing geometries
12192
virtual bool changeGeometryValues( const QgsGeometryMap &geometry_map ) override;
12293

12394
//! Import a vector layer into the database
@@ -155,6 +126,7 @@ class QgsDb2Provider : public QgsVectorDataProvider
155126
bool mUseEstimatedMetadata;
156127
bool mSkipFailures;
157128
long mNumberFeatures;
129+
int mFidColIdx;
158130
QString mFidColName;
159131
QString mExtents;
160132
mutable long mSRId;

‎src/providers/mssql/qgsmssqlprovider.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ int QgsMssqlProvider::sConnectionId = 0;
5656
QgsMssqlProvider::QgsMssqlProvider( const QString& uri )
5757
: QgsVectorDataProvider( uri )
5858
, mNumberFeatures( 0 )
59+
, mFidColIdx( -1 )
5960
, mCrs()
6061
, mWkbType( QgsWkbTypes::Unknown )
6162
{
@@ -472,6 +473,19 @@ void QgsMssqlProvider::loadFields()
472473
mValid = false;
473474
setLastError( error );
474475
}
476+
477+
if ( !mFidColName.isEmpty() )
478+
{
479+
mFidColIdx = mAttributeFields.indexFromName( mFidColName );
480+
if ( mFidColIdx >= 0 )
481+
{
482+
// primary key has not null, unique constraints
483+
QgsFieldConstraints constraints = mAttributeFields.at( mFidColIdx ).constraints();
484+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
485+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
486+
mAttributeFields[ mFidColIdx ].setConstraints( constraints );
487+
}
488+
}
475489
}
476490
}
477491

@@ -1481,7 +1495,15 @@ bool QgsMssqlProvider::setSubsetString( const QString& theSQL, bool )
14811495
QString QgsMssqlProvider::description() const
14821496
{
14831497
return TEXT_PROVIDER_DESCRIPTION;
1484-
} // QgsMssqlProvider::name()
1498+
}
1499+
1500+
QgsAttributeList QgsMssqlProvider::pkAttributeIndexes() const
1501+
{
1502+
QgsAttributeList list;
1503+
if ( mFidColIdx >= 0 )
1504+
list << mFidColIdx;
1505+
return list;
1506+
}
14851507

14861508
QStringList QgsMssqlProvider::subLayers() const
14871509
{

‎src/providers/mssql/qgsmssqlprovider.h

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -62,33 +62,15 @@ class QgsMssqlProvider : public QgsVectorDataProvider
6262

6363
/* Implementation of functions from QgsVectorDataProvider */
6464

65-
/**
66-
* Returns the permanent storage type for this layer as a friendly name.
67-
*/
6865
virtual QString storageType() const override;
69-
70-
/**
71-
* Sub-layers handled by this provider, in order from bottom to top
72-
*
73-
* Sub-layers are used when the provider's source can combine layers
74-
* it knows about in some way before it hands them off to the provider.
75-
*/
7666
virtual QStringList subLayers() const override;
7767
virtual QVariant minimumValue( int index ) const override;
7868
virtual QVariant maximumValue( int index ) const override;
7969
virtual void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 ) const override;
8070
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request ) const override;
8171

82-
/**
83-
* Get feature type.
84-
* @return int representing the feature type
85-
*/
8672
virtual QgsWkbTypes::Type wkbType() const override;
8773

88-
/**
89-
* Number of features in the layer
90-
* @return long containing number of features
91-
*/
9274
virtual long featureCount() const override;
9375

9476
//! Update the extent, feature count, wkb type and srid for this layer
@@ -98,86 +80,41 @@ class QgsMssqlProvider : public QgsVectorDataProvider
9880

9981
QString subsetString() const override;
10082

101-
//! Mutator for sql where clause used to limit dataset size
10283
bool setSubsetString( const QString& theSQL, bool updateFeatureCount = true ) override;
10384

10485
virtual bool supportsSubsetString() const override { return true; }
10586

106-
/** Returns a bitmask containing the supported capabilities
107-
Note, some capabilities may change depending on whether
108-
a spatial filter is active on this provider, so it may
109-
be prudent to check this value per intended operation.
110-
*/
11187
virtual QgsVectorDataProvider::Capabilities capabilities() const override;
11288

11389

11490
/* Implementation of functions from QgsDataProvider */
11591

116-
/** Return a provider name
117-
118-
Essentially just returns the provider key. Should be used to build file
119-
dialogs so that providers can be shown with their supported types. Thus
120-
if more than one provider supports a given format, the user is able to
121-
select a specific provider to open that file.
122-
123-
@note
124-
125-
Instead of being pure virtual, might be better to generalize this
126-
behavior and presume that none of the sub-classes are going to do
127-
anything strange with regards to their name or description?
128-
*/
12992
QString name() const override;
13093

131-
/** Return description
132-
133-
Return a terse string describing what the provider is.
134-
135-
@note
136-
137-
Instead of being pure virtual, might be better to generalize this
138-
behavior and presume that none of the sub-classes are going to do
139-
anything strange with regards to their name or description?
140-
*/
14194
QString description() const override;
14295

96+
QgsAttributeList pkAttributeIndexes() const override;
97+
14398
virtual QgsRectangle extent() const override;
14499

145100
bool isValid() const override;
146101

147102
virtual bool isSaveAndLoadStyleToDBSupported() const override { return true; }
148103

149-
//! Writes a list of features to the database
150104
virtual bool addFeatures( QgsFeatureList & flist ) override;
151105

152-
//! Deletes a feature
153106
virtual bool deleteFeatures( const QgsFeatureIds & id ) override;
154107

155-
/**
156-
* Adds new attributes
157-
* @param attributes list of new attributes
158-
* @return true in case of success and false in case of failure
159-
*/
160108
virtual bool addAttributes( const QList<QgsField> &attributes ) override;
161109

162-
/**
163-
* Deletes existing attributes
164-
* @param attributes a set containing names of attributes
165-
* @return true in case of success and false in case of failure
166-
*/
167110
virtual bool deleteAttributes( const QgsAttributeIds &attributes ) override;
168111

169-
//! Changes attribute values of existing features
170112
virtual bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
171113

172-
//! Changes existing geometries
173114
virtual bool changeGeometryValues( const QgsGeometryMap &geometry_map ) override;
174115

175-
/**
176-
* Create a spatial index for the current layer
177-
*/
178116
virtual bool createSpatialIndex() override;
179117

180-
//! Create an attribute index on the datasource
181118
virtual bool createAttributeIndex( int field ) override;
182119

183120
//! Convert a QgsField to work with MSSQL
@@ -227,6 +164,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
227164

228165
long mNumberFeatures;
229166
QString mFidColName;
167+
int mFidColIdx;
230168
mutable long mSRId;
231169
QString mGeometryColName;
232170
QString mGeometryColType;

‎src/providers/oracle/qgsoracleprovider.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,16 @@ bool QgsOracleProvider::loadFields()
752752
type = QVariant::Date;
753753
}
754754

755-
mAttributeFields.append( QgsField( field.name(), type, types.value( field.name() ), field.length(), field.precision(), comments.value( field.name() ) ) );
755+
QgsField newField( field.name(), type, types.value( field.name() ), field.length(), field.precision(), comments.value( field.name() ) );
756+
757+
QgsFieldConstraints constraints;
758+
if ( mPrimaryKeyAttrs.contains( i ) )
759+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
760+
if ( mPrimaryKeyAttrs.contains( i ) )
761+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
762+
newField.setConstraints( constraints );
763+
764+
mAttributeFields.append( newField );
756765
mDefaultValues.append( defvalues.value( field.name(), QVariant() ) );
757766
}
758767

@@ -987,6 +996,15 @@ bool QgsOracleProvider::determinePrimaryKey()
987996

988997
mValid = mPrimaryKeyType != pktUnknown;
989998

999+
Q_FOREACH ( int fieldIdx, mPrimaryKeyAttrs )
1000+
{
1001+
//primary keys are unique, not null
1002+
QgsFieldConstraints constraints = mAttributeFields.at( fieldIdx ).constraints();
1003+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
1004+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
1005+
mAttributeFields[ fieldIdx ].setConstraints( constraints );
1006+
}
1007+
9901008
return mValid;
9911009
}
9921010

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,9 +1002,9 @@ bool QgsPostgresProvider::loadFields()
10021002
QgsField newField = QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType );
10031003

10041004
QgsFieldConstraints constraints;
1005-
if ( notNullMap[tableoid][attnum] )
1005+
if ( notNullMap[tableoid][attnum] || mPrimaryKeyAttrs.contains( i ) )
10061006
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
1007-
if ( uniqueMap[tableoid][attnum] )
1007+
if ( uniqueMap[tableoid][attnum] || mPrimaryKeyAttrs.contains( i ) )
10081008
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
10091009
newField.setConstraints( constraints );
10101010

@@ -1375,6 +1375,15 @@ bool QgsPostgresProvider::determinePrimaryKey()
13751375
determinePrimaryKeyFromUriKeyColumn();
13761376
}
13771377

1378+
Q_FOREACH ( int fieldIdx, mPrimaryKeyAttrs )
1379+
{
1380+
//primary keys are unique, not null
1381+
QgsFieldConstraints constraints = mAttributeFields.at( fieldIdx ).constraints();
1382+
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider );
1383+
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
1384+
mAttributeFields[ fieldIdx ].setConstraints( constraints );
1385+
}
1386+
13781387
mValid = mPrimaryKeyType != pktUnknown;
13791388

13801389
return mValid;

0 commit comments

Comments
 (0)
Please sign in to comment.