Move constraints to QgsField

This commit is contained in:
Nyall Dawson 2016-10-19 13:42:06 +10:00
parent f6c1bf7f5b
commit 4efad04bd8
15 changed files with 163 additions and 59 deletions

View File

@ -14,6 +14,18 @@ class QgsField
%End %End
public: public:
/**
* Constraints which may be present on a field.
* @note added in QGIS 3.0
*/
enum Constraint
{
ConstraintNotNull, //!< Field may not be null
ConstraintUnique, //!< Field must have a unique value
};
typedef QFlags<QgsField::Constraint> Constraints;
/** Constructor. Constructs a new QgsField object. /** Constructor. Constructs a new QgsField object.
* @param name Field name * @param name Field name
* @param type Field variant type, currently supported: String / Int / Double * @param type Field variant type, currently supported: String / Int / Double
@ -162,6 +174,20 @@ class QgsField
*/ */
void setDefaultValueExpression( const QString& expression ); void setDefaultValueExpression( const QString& expression );
/**
* Returns any constraints which are present for the field.
* @note added in QGIS 3.0
* @see setConstraints()
*/
Constraints constraints() const;
/**
* Sets constraints which are present for the field.
* @note added in QGIS 3.0
* @see constraints()
*/
void setConstraints( Constraints constraints );
/** Returns the alias for the field (the friendly displayed name of the field ), /** Returns the alias for the field (the friendly displayed name of the field ),
* or an empty string if there is no alias. * or an empty string if there is no alias.
* @see setAlias() * @see setAlias()
@ -254,3 +280,5 @@ class QgsField
*/ */
const QgsEditorWidgetSetup& editorWidgetSetup() const; const QgsEditorWidgetSetup& editorWidgetSetup() const;
}; // class QgsField }; // class QgsField
QFlags<QgsField::Constraint> operator|(QgsField::Constraint f1, QFlags<QgsField::Constraint> f2);

View File

@ -55,17 +55,6 @@ class QgsVectorDataProvider : QgsDataProvider
/** Bitmask of all provider's editing capabilities */ /** Bitmask of all provider's editing capabilities */
static const int EditingCapabilities; static const int EditingCapabilities;
/**
* Constraints which may be present on a field.
* @note added in QGIS 3.0
*/
enum Constraint
{
ConstraintNotNull, //!< Field may not be null
ConstraintUnique, //!< Field must have a unique value
};
typedef QFlags<QgsVectorDataProvider::Constraint> Constraints;
/** /**
* Constructor of the vector provider * Constructor of the vector provider
* @param uri uniform resource locator (URI) for a dataset * @param uri uniform resource locator (URI) for a dataset
@ -246,7 +235,7 @@ class QgsVectorDataProvider : QgsDataProvider
* field index. * field index.
* @note added in QGIS 3.0 * @note added in QGIS 3.0
*/ */
virtual QgsVectorDataProvider::Constraints fieldConstraints( int fieldIndex ) const; virtual QgsField::Constraints fieldConstraints( int fieldIndex ) const;
/** /**
* Changes geometries of existing features * Changes geometries of existing features
@ -452,4 +441,3 @@ class QgsVectorDataProvider : QgsDataProvider
}; };
QFlags<QgsVectorDataProvider::Capability> operator|(QgsVectorDataProvider::Capability f1, QFlags<QgsVectorDataProvider::Capability> f2); QFlags<QgsVectorDataProvider::Capability> operator|(QgsVectorDataProvider::Capability f1, QFlags<QgsVectorDataProvider::Capability> f2);
QFlags<QgsVectorDataProvider::Constraint> operator|(QgsVectorDataProvider::Constraint f1, QFlags<QgsVectorDataProvider::Constraint> f2);

View File

@ -176,16 +176,16 @@ bool QgsAttributeTypeDialog::fieldEditable() const
return isFieldEditableCheckBox->isChecked(); return isFieldEditableCheckBox->isChecked();
} }
void QgsAttributeTypeDialog::setProviderConstraints( QgsVectorDataProvider::Constraints constraints ) void QgsAttributeTypeDialog::setProviderConstraints( QgsField::Constraints constraints )
{ {
if ( constraints & QgsVectorDataProvider::ConstraintNotNull ) if ( constraints & QgsField::ConstraintNotNull )
{ {
notNullCheckBox->setChecked( true ); notNullCheckBox->setChecked( true );
notNullCheckBox->setEnabled( false ); notNullCheckBox->setEnabled( false );
notNullCheckBox->setToolTip( tr( "The provider for this layer has a NOT NULL constraint set on the field." ) ); notNullCheckBox->setToolTip( tr( "The provider for this layer has a NOT NULL constraint set on the field." ) );
} }
if ( constraints & QgsVectorDataProvider::ConstraintUnique ) if ( constraints & QgsField::ConstraintUnique )
{ {
mUniqueCheckBox->setChecked( true ); mUniqueCheckBox->setChecked( true );
mUniqueCheckBox->setEnabled( false ); mUniqueCheckBox->setEnabled( false );

View File

@ -73,7 +73,7 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
/** /**
* Sets any provider side constraints which may affect this field's behaviour. * Sets any provider side constraints which may affect this field's behaviour.
*/ */
void setProviderConstraints( QgsVectorDataProvider::Constraints constraints ); void setProviderConstraints( QgsField::Constraints constraints );
/** /**
* Setter for checkbox for not null * Setter for checkbox for not null

View File

@ -180,6 +180,16 @@ void QgsField::setDefaultValueExpression( const QString& expression )
d->defaultValueExpression = expression; d->defaultValueExpression = expression;
} }
QgsField::Constraints QgsField::constraints() const
{
return d->constraints;
}
void QgsField::setConstraints( Constraints constraints )
{
d->constraints = constraints;
}
QString QgsField::alias() const QString QgsField::alias() const
{ {
return d->alias; return d->alias;
@ -303,15 +313,16 @@ QDataStream& operator<<( QDataStream& out, const QgsField& field )
out << field.comment(); out << field.comment();
out << field.alias(); out << field.alias();
out << field.defaultValueExpression(); out << field.defaultValueExpression();
out << field.constraints();
out << static_cast< quint32 >( field.subType() ); out << static_cast< quint32 >( field.subType() );
return out; return out;
} }
QDataStream& operator>>( QDataStream& in, QgsField& field ) QDataStream& operator>>( QDataStream& in, QgsField& field )
{ {
quint32 type, subType, length, precision; quint32 type, subType, length, precision, constraints;
QString name, typeName, comment, alias, defaultValueExpression; QString name, typeName, comment, alias, defaultValueExpression;
in >> name >> type >> typeName >> length >> precision >> comment >> alias >> defaultValueExpression >> subType; in >> name >> type >> typeName >> length >> precision >> comment >> alias >> defaultValueExpression >> constraints >> subType;
field.setName( name ); field.setName( name );
field.setType( static_cast< QVariant::Type >( type ) ); field.setType( static_cast< QVariant::Type >( type ) );
field.setTypeName( typeName ); field.setTypeName( typeName );
@ -320,6 +331,7 @@ QDataStream& operator>>( QDataStream& in, QgsField& field )
field.setComment( comment ); field.setComment( comment );
field.setAlias( alias ); field.setAlias( alias );
field.setDefaultValueExpression( defaultValueExpression ); field.setDefaultValueExpression( defaultValueExpression );
field.setConstraints( static_cast< QgsField::Constraints>( constraints ) );
field.setSubType( static_cast< QVariant::Type >( subType ) ); field.setSubType( static_cast< QVariant::Type >( subType ) );
return in; return in;
} }

View File

@ -54,8 +54,21 @@ class CORE_EXPORT QgsField
Q_PROPERTY( QString name READ name WRITE setName ) Q_PROPERTY( QString name READ name WRITE setName )
Q_PROPERTY( QString alias READ alias WRITE setAlias ) Q_PROPERTY( QString alias READ alias WRITE setAlias )
Q_PROPERTY( QString defaultValueExpression READ defaultValueExpression WRITE setDefaultValueExpression ) Q_PROPERTY( QString defaultValueExpression READ defaultValueExpression WRITE setDefaultValueExpression )
Q_PROPERTY( Constraints constraints READ constraints WRITE setConstraints )
public: public:
/**
* Constraints which may be present on a field.
* @note added in QGIS 3.0
*/
enum Constraint
{
ConstraintNotNull = 1, //!< Field may not be null
ConstraintUnique = 1 << 1, //!< Field must have a unique value
};
Q_DECLARE_FLAGS( Constraints, Constraint )
/** Constructor. Constructs a new QgsField object. /** Constructor. Constructs a new QgsField object.
* @param name Field name * @param name Field name
* @param type Field variant type, currently supported: String / Int / Double * @param type Field variant type, currently supported: String / Int / Double
@ -208,6 +221,20 @@ class CORE_EXPORT QgsField
*/ */
void setDefaultValueExpression( const QString& expression ); void setDefaultValueExpression( const QString& expression );
/**
* Returns any constraints which are present for the field.
* @note added in QGIS 3.0
* @see setConstraints()
*/
Constraints constraints() const;
/**
* Sets constraints which are present for the field.
* @note added in QGIS 3.0
* @see constraints()
*/
void setConstraints( Constraints constraints );
/** Returns the alias for the field (the friendly displayed name of the field ), /** Returns the alias for the field (the friendly displayed name of the field ),
* or an empty string if there is no alias. * or an empty string if there is no alias.
* @see setAlias() * @see setAlias()
@ -261,6 +288,8 @@ class CORE_EXPORT QgsField
}; // class QgsField }; // class QgsField
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsField::Constraints )
Q_DECLARE_METATYPE( QgsField ) Q_DECLARE_METATYPE( QgsField )
//! Writes the field to stream out. QGIS version compatibility is not guaranteed. //! Writes the field to stream out. QGIS version compatibility is not guaranteed.

View File

@ -55,6 +55,7 @@ class QgsFieldPrivate : public QSharedData
, length( len ) , length( len )
, precision( prec ) , precision( prec )
, comment( comment ) , comment( comment )
, constraints( 0 )
{ {
} }
@ -69,6 +70,7 @@ class QgsFieldPrivate : public QSharedData
, comment( other.comment ) , comment( other.comment )
, alias( other.alias ) , alias( other.alias )
, defaultValueExpression( other.defaultValueExpression ) , defaultValueExpression( other.defaultValueExpression )
, constraints( other.constraints )
{ {
} }
@ -78,7 +80,8 @@ class QgsFieldPrivate : public QSharedData
{ {
return (( name == other.name ) && ( type == other.type ) && ( subType == other.subType ) return (( name == other.name ) && ( type == other.type ) && ( subType == other.subType )
&& ( length == other.length ) && ( precision == other.precision ) && ( length == other.length ) && ( precision == other.precision )
&& ( alias == other.alias ) && ( defaultValueExpression == other.defaultValueExpression ) ); && ( alias == other.alias ) && ( defaultValueExpression == other.defaultValueExpression )
&& ( constraints == other.constraints ) );
} }
//! Name //! Name
@ -108,6 +111,9 @@ class QgsFieldPrivate : public QSharedData
//! Default value expression //! Default value expression
QString defaultValueExpression; QString defaultValueExpression;
//! Constraints
QgsField::Constraints constraints;
QgsEditorWidgetSetup editorWidgetSetup; QgsEditorWidgetSetup editorWidgetSetup;
}; };

View File

@ -98,7 +98,7 @@ QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const
return QVariant(); return QVariant();
} }
QgsVectorDataProvider::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const QgsField::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const
{ {
Q_UNUSED( fieldIndex ); Q_UNUSED( fieldIndex );
return 0; return 0;

View File

@ -106,17 +106,6 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
ChangeAttributeValues | ChangeGeometries | AddAttributes | DeleteAttributes | ChangeAttributeValues | ChangeGeometries | AddAttributes | DeleteAttributes |
RenameAttributes; RenameAttributes;
/**
* Constraints which may be present on a field.
* @note added in QGIS 3.0
*/
enum Constraint
{
ConstraintNotNull = 1, //!< Field may not be null
ConstraintUnique = 1 << 1, //!< Field must have a unique value
};
Q_DECLARE_FLAGS( Constraints, Constraint )
/** /**
* Constructor of the vector provider * Constructor of the vector provider
* @param uri uniform resource locator (URI) for a dataset * @param uri uniform resource locator (URI) for a dataset
@ -297,7 +286,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
* field index. * field index.
* @note added in QGIS 3.0 * @note added in QGIS 3.0
*/ */
virtual Constraints fieldConstraints( int fieldIndex ) const; virtual QgsField::Constraints fieldConstraints( int fieldIndex ) const;
/** /**
* Changes geometries of existing features * Changes geometries of existing features
@ -538,7 +527,5 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorDataProvider::Capabilities ) Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorDataProvider::Capabilities )
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorDataProvider::Constraints )
#endif #endif

View File

@ -4189,3 +4189,19 @@ bool QgsVectorLayer::setDependencies( const QSet<QgsMapLayerDependency>& oDeps )
return true; return true;
} }
QgsField::Constraints QgsVectorLayer::fieldConstraints( int fieldIndex ) const
{
if ( fieldIndex < 0 || fieldIndex >= mFields.count() )
return 0;
QgsField::Constraints constraints = mFields.at( fieldIndex ).constraints();
// make sure provider constraints are always present!
if ( mFields.fieldOrigin( fieldIndex ) == QgsFields::OriginProvider )
{
constraints |= mDataProvider->fieldConstraints( mFields.fieldOriginIndex( fieldIndex ) );
}
return constraints;
}

View File

@ -1396,6 +1396,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/ */
QString defaultValueExpression( int index ) const; QString defaultValueExpression( int index ) const;
/**
* Returns any constraints which are present for a specified
* field index. These constraints may be inherited from the layer's data provider
* or may be set manually on the vector layer from within QGIS.
* @note added in QGIS 3.0
*/
QgsField::Constraints fieldConstraints( int fieldIndex ) const;
/** Calculates a list of unique values contained within an attribute in the layer. Note that /** Calculates a list of unique values contained within an attribute in the layer. Note that
* in some circumstances when unsaved changes are present for the layer then the returned list * in some circumstances when unsaved changes are present for the layer then the returned list
* may contain outdated values (for instance when the attribute value in a saved feature has * may contain outdated values (for instance when the attribute value in a saved feature has

View File

@ -998,14 +998,16 @@ bool QgsPostgresProvider::loadFields()
mAttrPalIndexName.insert( i, fieldName ); mAttrPalIndexName.insert( i, fieldName );
mDefaultValues.insert( mAttributeFields.size(), defValMap[tableoid][attnum] ); mDefaultValues.insert( mAttributeFields.size(), defValMap[tableoid][attnum] );
Constraints constraints = 0; QgsField newField = QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType );
if ( notNullMap[tableoid][attnum] )
constraints |= ConstraintNotNull;
if ( uniqueMap[tableoid][attnum] )
constraints |= ConstraintUnique;
mFieldConstraints.insert( mAttributeFields.size(), constraints );
mAttributeFields.append( QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType ) ); QgsField::Constraints constraints = 0;
if ( notNullMap[tableoid][attnum] )
constraints |= QgsField::ConstraintNotNull;
if ( uniqueMap[tableoid][attnum] )
constraints |= QgsField::ConstraintUnique;
newField.setConstraints( constraints );
mAttributeFields.append( newField );
} }
setEditorWidgets(); setEditorWidgets();
@ -1736,9 +1738,12 @@ QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
return defVal; return defVal;
} }
QgsVectorDataProvider::Constraints QgsPostgresProvider::fieldConstraints( int fieldIndex ) const QgsField::Constraints QgsPostgresProvider::fieldConstraints( int fieldIndex ) const
{ {
return mFieldConstraints.value( fieldIndex, 0 ); if ( fieldIndex < 0 || fieldIndex >= mAttributeFields.count() )
return 0;
return mAttributeFields.at( fieldIndex ).constraints();
} }
QString QgsPostgresProvider::paramValue( const QString& fieldValue, const QString &defaultValue ) const QString QgsPostgresProvider::paramValue( const QString& fieldValue, const QString &defaultValue ) const

View File

@ -161,7 +161,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
QgsAttributeList attributeIndexes() const override; QgsAttributeList attributeIndexes() const override;
QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; } QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; }
QVariant defaultValue( int fieldId ) const override; QVariant defaultValue( int fieldId ) const override;
Constraints fieldConstraints( int fieldIndex ) const override; QgsField::Constraints fieldConstraints( int fieldIndex ) const override;
/** Adds a list of features /** Adds a list of features
@return true in case of success and false in case of failure*/ @return true in case of success and false in case of failure*/
@ -494,7 +494,6 @@ class QgsPostgresProvider : public QgsVectorDataProvider
void setTransaction( QgsTransaction* transaction ) override; void setTransaction( QgsTransaction* transaction ) override;
QHash<int, QString> mDefaultValues; QHash<int, QString> mDefaultValues;
QHash<int, QgsVectorDataProvider::Constraints > mFieldConstraints;
}; };

View File

@ -84,6 +84,7 @@ void TestQgsField::create()
void TestQgsField::copy() void TestQgsField::copy()
{ {
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) ); QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
original.setConstraints( QgsField::ConstraintNotNull );
QgsField copy( original ); QgsField copy( original );
QVERIFY( copy == original ); QVERIFY( copy == original );
@ -95,6 +96,7 @@ void TestQgsField::copy()
void TestQgsField::assignment() void TestQgsField::assignment()
{ {
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) ); QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
original.setConstraints( QgsField::ConstraintNotNull );
QgsField copy; QgsField copy;
copy = original; copy = original;
QVERIFY( copy == original ); QVERIFY( copy == original );
@ -123,6 +125,8 @@ void TestQgsField::gettersSetters()
QCOMPARE( field.alias(), QString( "alias" ) ); QCOMPARE( field.alias(), QString( "alias" ) );
field.setDefaultValueExpression( QStringLiteral( "1+2" ) ); field.setDefaultValueExpression( QStringLiteral( "1+2" ) );
QCOMPARE( field.defaultValueExpression(), QString( "1+2" ) ); QCOMPARE( field.defaultValueExpression(), QString( "1+2" ) );
field.setConstraints( QgsField::ConstraintNotNull );
QCOMPARE( field.constraints(), QgsField::ConstraintNotNull );
} }
void TestQgsField::isNumeric() void TestQgsField::isNumeric()
@ -157,6 +161,7 @@ void TestQgsField::equality()
field1.setPrecision( 2 ); field1.setPrecision( 2 );
field1.setTypeName( QStringLiteral( "typename1" ) ); //typename is NOT required for equality field1.setTypeName( QStringLiteral( "typename1" ) ); //typename is NOT required for equality
field1.setComment( QStringLiteral( "comment1" ) ); //comment is NOT required for equality field1.setComment( QStringLiteral( "comment1" ) ); //comment is NOT required for equality
field1.setConstraints( QgsField::ConstraintNotNull );
QgsField field2; QgsField field2;
field2.setName( QStringLiteral( "name" ) ); field2.setName( QStringLiteral( "name" ) );
field2.setType( QVariant::Int ); field2.setType( QVariant::Int );
@ -164,6 +169,7 @@ void TestQgsField::equality()
field2.setPrecision( 2 ); field2.setPrecision( 2 );
field2.setTypeName( QStringLiteral( "typename2" ) ); //typename is NOT required for equality field2.setTypeName( QStringLiteral( "typename2" ) ); //typename is NOT required for equality
field2.setComment( QStringLiteral( "comment2" ) ); //comment is NOT required for equality field2.setComment( QStringLiteral( "comment2" ) ); //comment is NOT required for equality
field2.setConstraints( QgsField::ConstraintNotNull );
QVERIFY( field1 == field2 ); QVERIFY( field1 == field2 );
QVERIFY( !( field1 != field2 ) ); QVERIFY( !( field1 != field2 ) );
@ -192,11 +198,16 @@ void TestQgsField::equality()
QVERIFY( !( field1 == field2 ) ); QVERIFY( !( field1 == field2 ) );
QVERIFY( field1 != field2 ); QVERIFY( field1 != field2 );
field2.setDefaultValueExpression( QString() ); field2.setDefaultValueExpression( QString() );
field2.setConstraints( QgsField::ConstraintUnique );
QVERIFY( !( field1 == field2 ) );
QVERIFY( field1 != field2 );
field2.setConstraints( QgsField::ConstraintNotNull );
} }
void TestQgsField::asVariant() void TestQgsField::asVariant()
{ {
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) ); QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
original.setConstraints( QgsField::ConstraintNotNull );
//convert to and from a QVariant //convert to and from a QVariant
QVariant var = QVariant::fromValue( original ); QVariant var = QVariant::fromValue( original );
@ -375,6 +386,7 @@ void TestQgsField::dataStream()
original.setComment( QStringLiteral( "comment1" ) ); original.setComment( QStringLiteral( "comment1" ) );
original.setAlias( QStringLiteral( "alias" ) ); original.setAlias( QStringLiteral( "alias" ) );
original.setDefaultValueExpression( QStringLiteral( "default" ) ); original.setDefaultValueExpression( QStringLiteral( "default" ) );
original.setConstraints( QgsField::ConstraintNotNull );
QByteArray ba; QByteArray ba;
QDataStream ds( &ba, QIODevice::ReadWrite ); QDataStream ds( &ba, QIODevice::ReadWrite );

View File

@ -26,7 +26,7 @@ from qgis.core import (
QgsFeatureRequest, QgsFeatureRequest,
QgsFeature, QgsFeature,
QgsTransactionGroup, QgsTransactionGroup,
QgsVectorDataProvider, QgsField,
NULL NULL
) )
from qgis.gui import QgsEditorWidgetRegistry from qgis.gui import QgsEditorWidgetRegistry
@ -444,13 +444,20 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
self.assertEqual(len(vl.fields()), 4) self.assertEqual(len(vl.fields()), 4)
# test some bad field indexes # test some bad field indexes
self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsVectorDataProvider.Constraints()) self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsField.Constraints())
self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsVectorDataProvider.Constraints()) self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsField.Constraints())
self.assertTrue(vl.dataProvider().fieldConstraints(0) & QgsVectorDataProvider.ConstraintNotNull) self.assertTrue(vl.dataProvider().fieldConstraints(0) & QgsField.ConstraintNotNull)
self.assertFalse(vl.dataProvider().fieldConstraints(1) & QgsVectorDataProvider.ConstraintNotNull) self.assertFalse(vl.dataProvider().fieldConstraints(1) & QgsField.ConstraintNotNull)
self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsVectorDataProvider.ConstraintNotNull) self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsField.ConstraintNotNull)
self.assertFalse(vl.dataProvider().fieldConstraints(3) & QgsVectorDataProvider.ConstraintNotNull) self.assertFalse(vl.dataProvider().fieldConstraints(3) & QgsField.ConstraintNotNull)
# test that constraints have been saved to fields correctly
fields = vl.fields()
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintNotNull)
self.assertFalse(fields.at(1).constraints() & QgsField.ConstraintNotNull)
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintNotNull)
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintNotNull)
def testUniqueConstraint(self): def testUniqueConstraint(self):
vl = QgsVectorLayer('%s table="qgis_test"."constraints" sql=' % (self.dbconn), "constraints", "postgres") vl = QgsVectorLayer('%s table="qgis_test"."constraints" sql=' % (self.dbconn), "constraints", "postgres")
@ -458,13 +465,20 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
self.assertEqual(len(vl.fields()), 4) self.assertEqual(len(vl.fields()), 4)
# test some bad field indexes # test some bad field indexes
self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsVectorDataProvider.Constraints()) self.assertEqual(vl.dataProvider().fieldConstraints(-1), QgsField.Constraints())
self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsVectorDataProvider.Constraints()) self.assertEqual(vl.dataProvider().fieldConstraints(1001), QgsField.Constraints())
self.assertTrue(vl.dataProvider().fieldConstraints(0) & QgsVectorDataProvider.ConstraintUnique) self.assertTrue(vl.dataProvider().fieldConstraints(0) & QgsField.ConstraintUnique)
self.assertTrue(vl.dataProvider().fieldConstraints(1) & QgsVectorDataProvider.ConstraintUnique) self.assertTrue(vl.dataProvider().fieldConstraints(1) & QgsField.ConstraintUnique)
self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsVectorDataProvider.ConstraintUnique) self.assertTrue(vl.dataProvider().fieldConstraints(2) & QgsField.ConstraintUnique)
self.assertFalse(vl.dataProvider().fieldConstraints(3) & QgsVectorDataProvider.ConstraintUnique) self.assertFalse(vl.dataProvider().fieldConstraints(3) & QgsField.ConstraintUnique)
# test that constraints have been saved to fields correctly
fields = vl.fields()
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintUnique)
self.assertTrue(fields.at(1).constraints() & QgsField.ConstraintUnique)
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintUnique)
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintUnique)
# See http://hub.qgis.org/issues/15188 # See http://hub.qgis.org/issues/15188
def testNumericPrecision(self): def testNumericPrecision(self):