mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Refactor constraint handling
- store constraint origin in QgsField - move handling of constraint expressions to QgsField
This commit is contained in:
parent
1cecf37b40
commit
f99ea26bdf
@ -26,6 +26,17 @@ class QgsField
|
||||
};
|
||||
typedef QFlags<QgsField::Constraint> Constraints;
|
||||
|
||||
/**
|
||||
* Origin of constraints.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
enum ConstraintOrigin
|
||||
{
|
||||
ConstraintOriginNotSet, //!< Constraint is not set
|
||||
ConstraintOriginProvider, //!< Constraint was set at data provider
|
||||
ConstraintOriginLayer, //!< Constraint was set by layer
|
||||
};
|
||||
|
||||
/** Constructor. Constructs a new QgsField object.
|
||||
* @param name Field name
|
||||
* @param type Field variant type, currently supported: String / Int / Double
|
||||
@ -178,15 +189,60 @@ class QgsField
|
||||
* Returns any constraints which are present for the field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see setConstraints()
|
||||
* @see constraintOrigin()
|
||||
*/
|
||||
Constraints constraints() const;
|
||||
|
||||
/**
|
||||
* Sets constraints which are present for the field.
|
||||
* Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint
|
||||
* is not present on this field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraints( Constraints constraints );
|
||||
ConstraintOrigin constraintOrigin( Constraint constraint ) const;
|
||||
|
||||
/**
|
||||
* Sets a constraint on the field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see removeConstraint()
|
||||
*/
|
||||
void setConstraint( Constraint constraint, ConstraintOrigin origin = ConstraintOriginLayer );
|
||||
|
||||
/**
|
||||
* Removes a constraint from the field.
|
||||
* @see setConstraint()
|
||||
* @see constraints()
|
||||
*/
|
||||
void removeConstraint( Constraint constraint );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression for the field, if set.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintDescription()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintExpression() const;
|
||||
|
||||
/**
|
||||
* Returns the descriptive name for the constraint expression.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintExpression()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintDescription() const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for the field. An optional descriptive name for the constraint
|
||||
* can also be set. Setting an empty expression will clear any existing expression constraint.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraintExpression()
|
||||
* @see constraintDescription()
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraintExpression( const QString& expression, const QString& description = QString() );
|
||||
|
||||
/** Returns the alias for the field (the friendly displayed name of the field ),
|
||||
* or an empty string if there is no alias.
|
||||
|
@ -235,7 +235,7 @@ class QgsVectorDataProvider : QgsDataProvider
|
||||
* field index.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
virtual QgsField::Constraints fieldConstraints( int fieldIndex ) const;
|
||||
QgsField::Constraints fieldConstraints( int fieldIndex ) const;
|
||||
|
||||
/**
|
||||
* Changes geometries of existing features
|
||||
|
@ -562,10 +562,12 @@ void QgsFieldsProperties::attributeTypeDialog()
|
||||
attributeTypeDialog.setUnique( cfg.mConstraints & QgsField::ConstraintUnique );
|
||||
|
||||
QgsField::Constraints providerConstraints = 0;
|
||||
if ( mLayer->fields().fieldOrigin( index ) == QgsFields::OriginProvider )
|
||||
{
|
||||
providerConstraints = mLayer->dataProvider()->fieldConstraints( mLayer->fields().fieldOriginIndex( index ) );
|
||||
}
|
||||
if ( mLayer->fields().at( index ).constraintOrigin( QgsField::ConstraintNotNull ) == QgsField::ConstraintOriginProvider )
|
||||
providerConstraints |= QgsField::ConstraintNotNull;
|
||||
if ( mLayer->fields().at( index ).constraintOrigin( QgsField::ConstraintUnique ) == QgsField::ConstraintOriginProvider )
|
||||
providerConstraints |= QgsField::ConstraintUnique;
|
||||
if ( mLayer->fields().at( index ).constraintOrigin( QgsField::ConstraintExpression ) == QgsField::ConstraintOriginProvider )
|
||||
providerConstraints |= QgsField::ConstraintExpression;
|
||||
attributeTypeDialog.setProviderConstraints( providerConstraints );
|
||||
|
||||
attributeTypeDialog.setConstraintExpression( cfg.mConstraint );
|
||||
@ -1059,7 +1061,7 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
|
||||
mEditableEnabled = layer->fields().fieldOrigin( idx ) != QgsFields::OriginJoin
|
||||
&& layer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression;
|
||||
mLabelOnTop = layer->editFormConfig().labelOnTop( idx );
|
||||
mConstraints = layer->fieldConstraints( idx );
|
||||
mConstraints = layer->fields().at( idx ).constraints();
|
||||
mConstraint = layer->editFormConfig().constraintExpression( idx );
|
||||
mConstraintDescription = layer->editFormConfig().constraintDescription( idx );
|
||||
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( layer, layer->fields().field( idx ).name() );
|
||||
|
@ -185,9 +185,55 @@ QgsField::Constraints QgsField::constraints() const
|
||||
return d->constraints;
|
||||
}
|
||||
|
||||
void QgsField::setConstraints( Constraints constraints )
|
||||
QgsField::ConstraintOrigin QgsField::constraintOrigin( QgsField::Constraint constraint ) const
|
||||
{
|
||||
d->constraints = constraints;
|
||||
if ( !( d->constraints & constraint ) )
|
||||
return ConstraintOriginNotSet;
|
||||
|
||||
return d->constraintOrigins.value( constraint, ConstraintOriginNotSet );
|
||||
}
|
||||
|
||||
void QgsField::setConstraint( QgsField::Constraint constraint, QgsField::ConstraintOrigin origin )
|
||||
{
|
||||
if ( origin == ConstraintOriginNotSet )
|
||||
{
|
||||
d->constraints &= ~constraint;
|
||||
d->constraintOrigins.remove( constraint );
|
||||
}
|
||||
else
|
||||
{
|
||||
d->constraints |= constraint;
|
||||
d->constraintOrigins.insert( constraint, origin );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsField::removeConstraint( QgsField::Constraint constraint )
|
||||
{
|
||||
d->constraints &= ~constraint;
|
||||
}
|
||||
|
||||
QString QgsField::constraintExpression() const
|
||||
{
|
||||
return d->constraints & QgsField::ConstraintExpression ? d->expressionConstraint : QString();
|
||||
}
|
||||
|
||||
QString QgsField::constraintDescription() const
|
||||
{
|
||||
return d->expressionConstraintDescription;
|
||||
}
|
||||
|
||||
void QgsField::setConstraintExpression( const QString& expression, const QString& description )
|
||||
{
|
||||
if ( expression.isEmpty() )
|
||||
d->constraints &= ~QgsField::ConstraintExpression;
|
||||
else
|
||||
{
|
||||
d->constraints |= QgsField::ConstraintExpression;
|
||||
d->constraintOrigins.insert( QgsField::ConstraintExpression, QgsField::ConstraintOriginLayer );
|
||||
}
|
||||
|
||||
d->expressionConstraint = expression;
|
||||
d->expressionConstraintDescription = description;
|
||||
}
|
||||
|
||||
QString QgsField::alias() const
|
||||
@ -314,15 +360,22 @@ QDataStream& operator<<( QDataStream& out, const QgsField& field )
|
||||
out << field.alias();
|
||||
out << field.defaultValueExpression();
|
||||
out << field.constraints();
|
||||
out << static_cast< quint32 >( field.constraintOrigin( QgsField::ConstraintNotNull ) );
|
||||
out << static_cast< quint32 >( field.constraintOrigin( QgsField::ConstraintUnique ) );
|
||||
out << static_cast< quint32 >( field.constraintOrigin( QgsField::ConstraintExpression ) );
|
||||
out << field.constraintExpression();
|
||||
out << field.constraintDescription();
|
||||
out << static_cast< quint32 >( field.subType() );
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>( QDataStream& in, QgsField& field )
|
||||
{
|
||||
quint32 type, subType, length, precision, constraints;
|
||||
QString name, typeName, comment, alias, defaultValueExpression;
|
||||
in >> name >> type >> typeName >> length >> precision >> comment >> alias >> defaultValueExpression >> constraints >> subType;
|
||||
quint32 type, subType, length, precision, constraints, originNotNull, originUnique, originExpression;
|
||||
QString name, typeName, comment, alias, defaultValueExpression, constraintExpression, constraintDescription;
|
||||
in >> name >> type >> typeName >> length >> precision >> comment >> alias
|
||||
>> defaultValueExpression >> constraints >> originNotNull >> originUnique >> originExpression >>
|
||||
constraintExpression >> constraintDescription >> subType;
|
||||
field.setName( name );
|
||||
field.setType( static_cast< QVariant::Type >( type ) );
|
||||
field.setTypeName( typeName );
|
||||
@ -331,7 +384,19 @@ QDataStream& operator>>( QDataStream& in, QgsField& field )
|
||||
field.setComment( comment );
|
||||
field.setAlias( alias );
|
||||
field.setDefaultValueExpression( defaultValueExpression );
|
||||
field.setConstraints( static_cast< QgsField::Constraints>( constraints ) );
|
||||
if ( constraints & QgsField::ConstraintNotNull )
|
||||
field.setConstraint( QgsField::ConstraintNotNull, static_cast< QgsField::ConstraintOrigin>( originNotNull ) );
|
||||
else
|
||||
field.removeConstraint( QgsField::ConstraintNotNull );
|
||||
if ( constraints & QgsField::ConstraintUnique )
|
||||
field.setConstraint( QgsField::ConstraintUnique, static_cast< QgsField::ConstraintOrigin>( originUnique ) );
|
||||
else
|
||||
field.removeConstraint( QgsField::ConstraintUnique );
|
||||
if ( constraints & QgsField::ConstraintExpression )
|
||||
field.setConstraint( QgsField::ConstraintExpression, static_cast< QgsField::ConstraintOrigin>( originExpression ) );
|
||||
else
|
||||
field.removeConstraint( QgsField::ConstraintExpression );
|
||||
field.setConstraintExpression( constraintExpression, constraintDescription );
|
||||
field.setSubType( static_cast< QVariant::Type >( subType ) );
|
||||
return in;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class CORE_EXPORT QgsField
|
||||
Q_PROPERTY( QString name READ name WRITE setName )
|
||||
Q_PROPERTY( QString alias READ alias WRITE setAlias )
|
||||
Q_PROPERTY( QString defaultValueExpression READ defaultValueExpression WRITE setDefaultValueExpression )
|
||||
Q_PROPERTY( Constraints constraints READ constraints WRITE setConstraints )
|
||||
Q_PROPERTY( Constraints constraints READ constraints )
|
||||
|
||||
public:
|
||||
|
||||
@ -66,9 +66,21 @@ class CORE_EXPORT QgsField
|
||||
{
|
||||
ConstraintNotNull = 1, //!< Field may not be null
|
||||
ConstraintUnique = 1 << 1, //!< Field must have a unique value
|
||||
ConstraintExpression = 1 << 2, //!< Field has an expression constraint set. See constraintExpression().
|
||||
};
|
||||
Q_DECLARE_FLAGS( Constraints, Constraint )
|
||||
|
||||
/**
|
||||
* Origin of constraints.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
enum ConstraintOrigin
|
||||
{
|
||||
ConstraintOriginNotSet = 0, //!< Constraint is not set
|
||||
ConstraintOriginProvider, //!< Constraint was set at data provider
|
||||
ConstraintOriginLayer, //!< Constraint was set by layer
|
||||
};
|
||||
|
||||
/** Constructor. Constructs a new QgsField object.
|
||||
* @param name Field name
|
||||
* @param type Field variant type, currently supported: String / Int / Double
|
||||
@ -225,15 +237,60 @@ class CORE_EXPORT QgsField
|
||||
* Returns any constraints which are present for the field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see setConstraints()
|
||||
* @see constraintOrigin()
|
||||
*/
|
||||
Constraints constraints() const;
|
||||
|
||||
/**
|
||||
* Sets constraints which are present for the field.
|
||||
* Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint
|
||||
* is not present on this field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraints( Constraints constraints );
|
||||
ConstraintOrigin constraintOrigin( Constraint constraint ) const;
|
||||
|
||||
/**
|
||||
* Sets a constraint on the field.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see removeConstraint()
|
||||
*/
|
||||
void setConstraint( Constraint constraint, ConstraintOrigin origin = ConstraintOriginLayer );
|
||||
|
||||
/**
|
||||
* Removes a constraint from the field.
|
||||
* @see setConstraint()
|
||||
* @see constraints()
|
||||
*/
|
||||
void removeConstraint( Constraint constraint );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression for the field, if set.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintDescription()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintExpression() const;
|
||||
|
||||
/**
|
||||
* Returns the descriptive name for the constraint expression.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintExpression()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintDescription() const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for the field. An optional descriptive name for the constraint
|
||||
* can also be set. Setting an empty expression will clear any existing expression constraint.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraintExpression()
|
||||
* @see constraintDescription()
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraintExpression( const QString& expression, const QString& description = QString() );
|
||||
|
||||
/** Returns the alias for the field (the friendly displayed name of the field ),
|
||||
* or an empty string if there is no alias.
|
||||
|
@ -71,6 +71,9 @@ class QgsFieldPrivate : public QSharedData
|
||||
, alias( other.alias )
|
||||
, defaultValueExpression( other.defaultValueExpression )
|
||||
, constraints( other.constraints )
|
||||
, constraintOrigins( other.constraintOrigins )
|
||||
, expressionConstraint( other.expressionConstraint )
|
||||
, expressionConstraintDescription( other.expressionConstraintDescription )
|
||||
{
|
||||
}
|
||||
|
||||
@ -81,7 +84,10 @@ class QgsFieldPrivate : public QSharedData
|
||||
return (( name == other.name ) && ( type == other.type ) && ( subType == other.subType )
|
||||
&& ( length == other.length ) && ( precision == other.precision )
|
||||
&& ( alias == other.alias ) && ( defaultValueExpression == other.defaultValueExpression )
|
||||
&& ( constraints == other.constraints ) );
|
||||
&& ( constraints == other.constraints )
|
||||
&& ( expressionConstraint == other.expressionConstraint )
|
||||
&& ( expressionConstraintDescription == other.expressionConstraintDescription )
|
||||
&& ( constraintOrigins == other.constraintOrigins ) );
|
||||
}
|
||||
|
||||
//! Name
|
||||
@ -114,6 +120,15 @@ class QgsFieldPrivate : public QSharedData
|
||||
//! Constraints
|
||||
QgsField::Constraints constraints;
|
||||
|
||||
//! Origin of field constraints
|
||||
QHash< QgsField::Constraint, QgsField::ConstraintOrigin > constraintOrigins;
|
||||
|
||||
//! Expression constraint
|
||||
QString expressionConstraint;
|
||||
|
||||
//! Expression constraint descriptive name
|
||||
QString expressionConstraintDescription;
|
||||
|
||||
QgsEditorWidgetSetup editorWidgetSetup;
|
||||
};
|
||||
|
||||
|
@ -100,8 +100,11 @@ QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const
|
||||
|
||||
QgsField::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const
|
||||
{
|
||||
Q_UNUSED( fieldIndex );
|
||||
return 0;
|
||||
QgsFields f = fields();
|
||||
if ( fieldIndex < 0 || fieldIndex >= f.count() )
|
||||
return 0;
|
||||
|
||||
return f.at( fieldIndex ).constraints();
|
||||
}
|
||||
|
||||
bool QgsVectorDataProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
|
||||
|
@ -286,7 +286,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
* field index.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
virtual QgsField::Constraints fieldConstraints( int fieldIndex ) const;
|
||||
QgsField::Constraints fieldConstraints( int fieldIndex ) const;
|
||||
|
||||
/**
|
||||
* Changes geometries of existing features
|
||||
|
@ -2940,7 +2940,12 @@ void QgsVectorLayer::updateFields()
|
||||
continue;
|
||||
|
||||
// always keep provider constraints intact
|
||||
mFields[ index ].setConstraints( mFields.at( index ).constraints() | constraintIt.value() );
|
||||
if ( !( mFields.at( index ).constraints() & QgsField::ConstraintNotNull ) && ( constraintIt.value() & QgsField::ConstraintNotNull ) )
|
||||
mFields[ index ].setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginLayer );
|
||||
if ( !( mFields.at( index ).constraints() & QgsField::ConstraintUnique ) && ( constraintIt.value() & QgsField::ConstraintUnique ) )
|
||||
mFields[ index ].setConstraint( QgsField::ConstraintUnique, QgsField::ConstraintOriginLayer );
|
||||
if ( !( mFields.at( index ).constraints() & QgsField::ConstraintExpression ) && ( constraintIt.value() & QgsField::ConstraintExpression ) )
|
||||
mFields[ index ].setConstraint( QgsField::ConstraintExpression, QgsField::ConstraintOriginLayer );
|
||||
}
|
||||
|
||||
if ( oldFields != mFields )
|
||||
|
@ -148,7 +148,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
else
|
||||
mValidConstraint = true;
|
||||
|
||||
if ( layer()->fieldConstraints( mFieldIdx ) & QgsField::ConstraintNotNull )
|
||||
if ( layer()->fields().at( mFieldIdx ).constraints() & QgsField::ConstraintNotNull )
|
||||
{
|
||||
descriptions << QStringLiteral( "NotNull" );
|
||||
if ( !expression.isEmpty() )
|
||||
@ -170,7 +170,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
toEmit = true;
|
||||
}
|
||||
|
||||
if ( layer()->fieldConstraints( mFieldIdx ) & QgsField::ConstraintUnique )
|
||||
if ( layer()->fields().at( mFieldIdx ).constraints() & QgsField::ConstraintUnique )
|
||||
{
|
||||
descriptions << QStringLiteral( "Unique" );
|
||||
if ( !expression.isEmpty() )
|
||||
|
@ -674,7 +674,7 @@ void QgsAttributeForm::onAttributeChanged( const QVariant& value )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( eww->layer()->fieldConstraints( eww->fieldIdx() ) & QgsField::ConstraintNotNull )
|
||||
if ( eww->layer()->fields().at( eww->fieldIdx() ).constraints() & QgsField::ConstraintNotNull )
|
||||
{
|
||||
QLabel* buddy = mBuddyMap.value( eww->widget() );
|
||||
|
||||
|
@ -1000,12 +1000,10 @@ bool QgsPostgresProvider::loadFields()
|
||||
|
||||
QgsField newField = QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType );
|
||||
|
||||
QgsField::Constraints constraints = 0;
|
||||
if ( notNullMap[tableoid][attnum] )
|
||||
constraints |= QgsField::ConstraintNotNull;
|
||||
newField.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
if ( uniqueMap[tableoid][attnum] )
|
||||
constraints |= QgsField::ConstraintUnique;
|
||||
newField.setConstraints( constraints );
|
||||
newField.setConstraint( QgsField::ConstraintUnique, QgsField::ConstraintOriginProvider );
|
||||
|
||||
mAttributeFields.append( newField );
|
||||
}
|
||||
@ -1738,14 +1736,6 @@ QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
|
||||
return defVal;
|
||||
}
|
||||
|
||||
QgsField::Constraints QgsPostgresProvider::fieldConstraints( int fieldIndex ) const
|
||||
{
|
||||
if ( fieldIndex < 0 || fieldIndex >= mAttributeFields.count() )
|
||||
return 0;
|
||||
|
||||
return mAttributeFields.at( fieldIndex ).constraints();
|
||||
}
|
||||
|
||||
QString QgsPostgresProvider::paramValue( const QString& fieldValue, const QString &defaultValue ) const
|
||||
{
|
||||
if ( fieldValue.isNull() )
|
||||
|
@ -161,7 +161,6 @@ class QgsPostgresProvider : public QgsVectorDataProvider
|
||||
QgsAttributeList attributeIndexes() const override;
|
||||
QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; }
|
||||
QVariant defaultValue( int fieldId ) const override;
|
||||
QgsField::Constraints fieldConstraints( int fieldIndex ) const override;
|
||||
|
||||
/** Adds a list of features
|
||||
@return true in case of success and false in case of failure*/
|
||||
|
@ -842,16 +842,13 @@ void QgsSpatiaLiteProvider::fetchConstraints()
|
||||
field = field.trimmed();
|
||||
QString fieldName = field.left( field.indexOf( ' ' ) );
|
||||
QString definition = field.mid( field.indexOf( ' ' ) + 1 );
|
||||
QgsField::Constraints constraints = 0;
|
||||
if ( definition.contains( "unique", Qt::CaseInsensitive ) || definition.contains( "primary key", Qt::CaseInsensitive ) )
|
||||
constraints |= QgsField::ConstraintUnique;
|
||||
if ( definition.contains( "not null", Qt::CaseInsensitive ) || definition.contains( "primary key", Qt::CaseInsensitive ) )
|
||||
constraints |= QgsField::ConstraintNotNull;
|
||||
|
||||
int fieldIdx = mAttributeFields.lookupField( fieldName );
|
||||
if ( fieldIdx >= 0 )
|
||||
{
|
||||
mAttributeFields[ fieldIdx ].setConstraints( constraints );
|
||||
if ( definition.contains( "unique", Qt::CaseInsensitive ) || definition.contains( "primary key", Qt::CaseInsensitive ) )
|
||||
mAttributeFields[ fieldIdx ].setConstraint( QgsField::ConstraintUnique, QgsField::ConstraintOriginProvider );
|
||||
if ( definition.contains( "not null", Qt::CaseInsensitive ) || definition.contains( "primary key", Qt::CaseInsensitive ) )
|
||||
mAttributeFields[ fieldIdx ].setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3666,14 +3663,6 @@ void QgsSpatiaLiteProvider::uniqueValues( int index, QList < QVariant > &uniqueV
|
||||
return;
|
||||
}
|
||||
|
||||
QgsField::Constraints QgsSpatiaLiteProvider::fieldConstraints( int fieldIndex ) const
|
||||
{
|
||||
if ( fieldIndex < 0 || fieldIndex >= mAttributeFields.count() )
|
||||
return 0;
|
||||
|
||||
return mAttributeFields.at( fieldIndex ).constraints();
|
||||
}
|
||||
|
||||
QString QgsSpatiaLiteProvider::geomParam() const
|
||||
{
|
||||
QString geometry;
|
||||
|
@ -130,7 +130,6 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
|
||||
QVariant minimumValue( int index ) const override;
|
||||
QVariant maximumValue( int index ) const override;
|
||||
virtual void uniqueValues( int index, QList < QVariant > &uniqueValues, int limit = -1 ) const override;
|
||||
QgsField::Constraints fieldConstraints( int fieldIndex ) const override;
|
||||
|
||||
bool isValid() const override;
|
||||
virtual bool isSaveAndLoadStyleToDBSupported() const override { return true; }
|
||||
|
@ -84,7 +84,8 @@ void TestQgsField::create()
|
||||
void TestQgsField::copy()
|
||||
{
|
||||
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
|
||||
original.setConstraints( QgsField::ConstraintNotNull );
|
||||
original.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
original.setConstraintExpression( QStringLiteral( "constraint expression" ), QStringLiteral( "description" ) );
|
||||
QgsField copy( original );
|
||||
QVERIFY( copy == original );
|
||||
|
||||
@ -96,7 +97,8 @@ void TestQgsField::copy()
|
||||
void TestQgsField::assignment()
|
||||
{
|
||||
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
|
||||
original.setConstraints( QgsField::ConstraintNotNull );
|
||||
original.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
original.setConstraintExpression( QStringLiteral( "constraint expression" ), QStringLiteral( "description" ) );
|
||||
QgsField copy;
|
||||
copy = original;
|
||||
QVERIFY( copy == original );
|
||||
@ -125,8 +127,22 @@ void TestQgsField::gettersSetters()
|
||||
QCOMPARE( field.alias(), QString( "alias" ) );
|
||||
field.setDefaultValueExpression( QStringLiteral( "1+2" ) );
|
||||
QCOMPARE( field.defaultValueExpression(), QString( "1+2" ) );
|
||||
field.setConstraints( QgsField::ConstraintNotNull );
|
||||
field.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
QCOMPARE( field.constraints(), QgsField::ConstraintNotNull );
|
||||
QCOMPARE( field.constraintOrigin( QgsField::ConstraintNotNull ), QgsField::ConstraintOriginProvider );
|
||||
QCOMPARE( field.constraintOrigin( QgsField::ConstraintUnique ), QgsField::ConstraintOriginNotSet );
|
||||
field.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginNotSet );
|
||||
QCOMPARE( field.constraints(), 0 );
|
||||
field.setConstraint( QgsField::ConstraintUnique );
|
||||
field.setConstraint( QgsField::ConstraintNotNull );
|
||||
QCOMPARE( field.constraints(), QgsField::ConstraintUnique | QgsField::ConstraintNotNull );
|
||||
field.removeConstraint( QgsField::ConstraintNotNull );
|
||||
QCOMPARE( field.constraints(), QgsField::ConstraintUnique );
|
||||
|
||||
field.setConstraintExpression( QStringLiteral( "constraint expression" ), QStringLiteral( "description" ) );
|
||||
QCOMPARE( field.constraintExpression(), QStringLiteral( "constraint expression" ) );
|
||||
QCOMPARE( field.constraintDescription(), QStringLiteral( "description" ) );
|
||||
QCOMPARE( field.constraints(), QgsField::ConstraintUnique | QgsField::ConstraintExpression ); //setting constraint expression should add constraint
|
||||
}
|
||||
|
||||
void TestQgsField::isNumeric()
|
||||
@ -161,7 +177,7 @@ void TestQgsField::equality()
|
||||
field1.setPrecision( 2 );
|
||||
field1.setTypeName( QStringLiteral( "typename1" ) ); //typename is NOT required for equality
|
||||
field1.setComment( QStringLiteral( "comment1" ) ); //comment is NOT required for equality
|
||||
field1.setConstraints( QgsField::ConstraintNotNull );
|
||||
field1.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
QgsField field2;
|
||||
field2.setName( QStringLiteral( "name" ) );
|
||||
field2.setType( QVariant::Int );
|
||||
@ -169,7 +185,7 @@ void TestQgsField::equality()
|
||||
field2.setPrecision( 2 );
|
||||
field2.setTypeName( QStringLiteral( "typename2" ) ); //typename is NOT required for equality
|
||||
field2.setComment( QStringLiteral( "comment2" ) ); //comment is NOT required for equality
|
||||
field2.setConstraints( QgsField::ConstraintNotNull );
|
||||
field2.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
QVERIFY( field1 == field2 );
|
||||
QVERIFY( !( field1 != field2 ) );
|
||||
|
||||
@ -198,16 +214,26 @@ void TestQgsField::equality()
|
||||
QVERIFY( !( field1 == field2 ) );
|
||||
QVERIFY( field1 != field2 );
|
||||
field2.setDefaultValueExpression( QString() );
|
||||
field2.setConstraints( QgsField::ConstraintUnique );
|
||||
field2.removeConstraint( QgsField::ConstraintNotNull );
|
||||
QVERIFY( !( field1 == field2 ) );
|
||||
QVERIFY( field1 != field2 );
|
||||
field2.setConstraints( QgsField::ConstraintNotNull );
|
||||
field2.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginLayer );
|
||||
QVERIFY( !( field1 == field2 ) );
|
||||
QVERIFY( field1 != field2 );
|
||||
field2.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
field2.setConstraintExpression( QStringLiteral( "exp" ) );
|
||||
QVERIFY( !( field1 == field2 ) );
|
||||
QVERIFY( field1 != field2 );
|
||||
field2.setConstraintExpression( QStringLiteral( "exp" ), QStringLiteral( "desc" ) );
|
||||
QVERIFY( !( field1 == field2 ) );
|
||||
QVERIFY( field1 != field2 );
|
||||
field2.setConstraintExpression( QString(), QString() );
|
||||
}
|
||||
|
||||
void TestQgsField::asVariant()
|
||||
{
|
||||
QgsField original( QStringLiteral( "original" ), QVariant::Double, QStringLiteral( "double" ), 5, 2, QStringLiteral( "comment" ) );
|
||||
original.setConstraints( QgsField::ConstraintNotNull );
|
||||
original.setConstraint( QgsField::ConstraintNotNull );
|
||||
|
||||
//convert to and from a QVariant
|
||||
QVariant var = QVariant::fromValue( original );
|
||||
@ -386,7 +412,9 @@ void TestQgsField::dataStream()
|
||||
original.setComment( QStringLiteral( "comment1" ) );
|
||||
original.setAlias( QStringLiteral( "alias" ) );
|
||||
original.setDefaultValueExpression( QStringLiteral( "default" ) );
|
||||
original.setConstraints( QgsField::ConstraintNotNull );
|
||||
original.setConstraint( QgsField::ConstraintNotNull, QgsField::ConstraintOriginProvider );
|
||||
original.setConstraint( QgsField::ConstraintUnique, QgsField::ConstraintOriginLayer );
|
||||
original.setConstraintExpression( QStringLiteral( "constraint expression" ), QStringLiteral( "description" ) );
|
||||
|
||||
QByteArray ba;
|
||||
QDataStream ds( &ba, QIODevice::ReadWrite );
|
||||
|
@ -455,8 +455,10 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
|
||||
# test that constraints have been saved to fields correctly
|
||||
fields = vl.fields()
|
||||
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertEqual(fields.at(0).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)
|
||||
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)
|
||||
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintNotNull)
|
||||
|
||||
def testUniqueConstraint(self):
|
||||
@ -476,8 +478,11 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
|
||||
# test that constraints have been saved to fields correctly
|
||||
fields = vl.fields()
|
||||
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(0).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
self.assertTrue(fields.at(1).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(1).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(2).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintUnique)
|
||||
|
||||
def testConstraintOverwrite(self):
|
||||
|
@ -388,7 +388,7 @@ class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase):
|
||||
|
||||
def testNotNullConstraint(self):
|
||||
vl = QgsVectorLayer("dbname=%s table=test_constraints key='id'" % self.dbname, "test_constraints",
|
||||
"spatialite")
|
||||
"spatialite")
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(len(vl.fields()), 5)
|
||||
|
||||
@ -405,14 +405,17 @@ class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase):
|
||||
# test that constraints have been saved to fields correctly
|
||||
fields = vl.fields()
|
||||
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertEqual(fields.at(0).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)
|
||||
self.assertTrue(fields.at(1).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertEqual(fields.at(1).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)
|
||||
self.assertFalse(fields.at(2).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertTrue(fields.at(4).constraints() & QgsField.ConstraintNotNull)
|
||||
self.assertEqual(fields.at(4).constraintOrigin(QgsField.ConstraintNotNull), QgsField.ConstraintOriginProvider)
|
||||
|
||||
def testUniqueConstraint(self):
|
||||
vl = QgsVectorLayer("dbname=%s table=test_constraints key='id'" % self.dbname, "test_constraints",
|
||||
"spatialite")
|
||||
"spatialite")
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(len(vl.fields()), 5)
|
||||
|
||||
@ -429,10 +432,13 @@ class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase):
|
||||
# test that constraints have been saved to fields correctly
|
||||
fields = vl.fields()
|
||||
self.assertTrue(fields.at(0).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(0).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
self.assertFalse(fields.at(1).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertTrue(fields.at(2).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(2).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
self.assertFalse(fields.at(3).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertTrue(fields.at(4).constraints() & QgsField.ConstraintUnique)
|
||||
self.assertEqual(fields.at(4).constraintOrigin(QgsField.ConstraintUnique), QgsField.ConstraintOriginProvider)
|
||||
|
||||
# This test would fail. It would require turning on WAL
|
||||
def XXXXXtestLocking(self):
|
||||
|
@ -1786,20 +1786,32 @@ class TestQgsVectorLayer(unittest.TestCase):
|
||||
self.assertFalse(layer.fieldConstraints(1))
|
||||
self.assertFalse(layer.fieldConstraints(2))
|
||||
self.assertEqual(layer.fields().at(0).constraints(), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
|
||||
layer.setFieldConstraints(1, QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer.fieldConstraints(0), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fieldConstraints(1), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertFalse(layer.fieldConstraints(2))
|
||||
self.assertEqual(layer.fields().at(0).constraints(), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer.fields().at(1).constraints(), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintUnique),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
|
||||
layer.setFieldConstraints(1, QgsField.Constraints())
|
||||
self.assertEqual(layer.fieldConstraints(0), QgsField.ConstraintNotNull)
|
||||
self.assertFalse(layer.fieldConstraints(1))
|
||||
self.assertFalse(layer.fieldConstraints(2))
|
||||
self.assertEqual(layer.fields().at(0).constraints(), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertFalse(layer.fields().at(1).constraints())
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginNotSet)
|
||||
|
||||
def testSaveRestoreConstraints(self):
|
||||
""" test saving and restoring constraints from xml"""
|
||||
@ -1828,7 +1840,13 @@ class TestQgsVectorLayer(unittest.TestCase):
|
||||
self.assertEqual(layer3.fieldConstraints(0), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer3.fieldConstraints(1), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer3.fields().at(0).constraints(), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer3.fields().at(1).constraints(), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintUnique),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
|
||||
def testGetFeatureLimitWithEdits(self):
|
||||
""" test getting features with a limit, when edits are present """
|
||||
|
Loading…
x
Reference in New Issue
Block a user