26 QDomElement elem = node.toElement();
28 if ( elem.tagName() != QLatin1String(
"relation" ) )
30 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
36 QString
referencedLayerId = elem.attribute( QStringLiteral(
"referencedLayer" ) );
37 QString
id = elem.attribute( QStringLiteral(
"id" ) );
38 QString
name = elem.attribute( QStringLiteral(
"name" ) );
39 QString
strength = elem.attribute( QStringLiteral(
"strength" ) );
46 if ( !referencingLayer )
48 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) );
52 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) );
55 if ( !referencedLayer )
57 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) );
61 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
68 relation.mRelationId =
id;
69 relation.mRelationName =
name;
70 if ( strength ==
"Composition" )
72 relation.mRelationStrength = RelationStrength::Composition;
76 relation.mRelationStrength = RelationStrength::Association;
79 QDomNodeList references = elem.elementsByTagName( QStringLiteral(
"fieldRef" ) );
80 for (
int i = 0; i < references.size(); ++i )
82 QDomElement refEl = references.at( i ).toElement();
84 QString referencingField = refEl.attribute( QStringLiteral(
"referencingField" ) );
85 QString referencedField = refEl.attribute( QStringLiteral(
"referencedField" ) );
87 relation.
addFieldPair( referencingField, referencedField );
90 relation.updateRelationStatus();
97 QDomElement elem = doc.createElement( QStringLiteral(
"relation" ) );
98 elem.setAttribute( QStringLiteral(
"id" ), mRelationId );
99 elem.setAttribute( QStringLiteral(
"name" ), mRelationName );
100 elem.setAttribute( QStringLiteral(
"referencingLayer" ), mReferencingLayerId );
101 elem.setAttribute( QStringLiteral(
"referencedLayer" ), mReferencedLayerId );
102 if ( mRelationStrength == RelationStrength::Composition )
104 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Composition" ) );
108 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Association" ) );
111 Q_FOREACH (
const FieldPair &fields, mFieldPairs )
113 QDomElement referenceElem = doc.createElement( QStringLiteral(
"fieldRef" ) );
114 referenceElem.setAttribute( QStringLiteral(
"referencingField" ), fields.first );
115 referenceElem.setAttribute( QStringLiteral(
"referencedField" ), fields.second );
116 elem.appendChild( referenceElem );
119 node.appendChild( elem );
126 updateRelationStatus();
131 mRelationName =
name;
142 mReferencingLayerId =
id;
144 updateRelationStatus();
149 mReferencedLayerId =
id;
151 updateRelationStatus();
156 mFieldPairs <<
FieldPair( referencingField, referencedField );
157 updateRelationStatus();
162 mFieldPairs << fieldPair;
163 updateRelationStatus();
174 QgsDebugMsg( QString(
"Filter conditions: '%1'" ).arg( filter ) );
183 QStringList conditions;
188 conditions << QgsExpression::createFieldEqualityExpression( fieldPair.
referencingField(), val );
191 return conditions.join( QStringLiteral(
" AND " ) );
196 QStringList conditions;
201 conditions << QgsExpression::createFieldEqualityExpression( fieldPair.
referencedField(), attributes.at( referencingIdx ) );
206 QgsDebugMsg( QString(
"Filter conditions: '%1'" ).arg( conditions.join(
" AND " ) ) );
208 myRequest.setFilterExpression( conditions.join( QStringLiteral(
" AND " ) ) );
229 return mRelationName;
234 return mRelationStrength;
244 mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
246 mFieldPairs.at( 0 ).referencingField(),
248 mFieldPairs.at( 0 ).referencedField() );
249 updateRelationStatus();
254 return mReferencingLayerId;
259 return mReferencingLayer;
264 return mReferencedLayerId;
269 return mReferencedLayer;
281 Q_FOREACH (
const FieldPair &pair, mFieldPairs )
292 Q_FOREACH (
const FieldPair &pair, mFieldPairs )
307 return mReferencedLayerId == other.mReferencedLayerId && mReferencingLayerId == other.mReferencingLayerId && mFieldPairs == other.mFieldPairs;
312 Q_FOREACH (
const FieldPair &pair, mFieldPairs )
314 if ( pair.first == referencingField )
322 Q_FOREACH (
const FieldPair &pair, mFieldPairs )
324 if ( pair.second == referencedField )
330 void QgsRelation::updateRelationStatus()
334 mReferencingLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[mReferencingLayerId] );
335 mReferencedLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[mReferencedLayerId] );
339 if ( mRelationId.isEmpty() )
346 if ( !mReferencedLayer )
348 QgsDebugMsg( QString(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( mReferencedLayerId ) );
351 else if ( !mReferencingLayer )
353 QgsDebugMsg( QString(
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( mReferencingLayerId ) );
358 if ( mFieldPairs.count() < 1 )
360 QgsDebugMsg(
"Invalid relation: no pair of field is specified." );
364 Q_FOREACH (
const FieldPair &fieldPair, mFieldPairs )
368 QgsDebugMsg( QString(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( fieldPair.first, mReferencingLayer->
name() ) );
372 else if ( -1 == mReferencedLayer->fields().lookupField( fieldPair.second ) )
374 QgsDebugMsg( QString(
"Invalid relation: field %1 does not exist in referencedg layer %2" ).arg( fieldPair.second, mReferencedLayer->name() ) );
int lookupField(const QString &fieldName) const
Look up field's index from the field name.
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
Base class for all map layer types.
void generateId()
Generate a (project-wide) unique id for this relation.
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing (ch...
static void warning(const QString &msg)
Goes to qWarning.
void setReferencingLayer(const QString &id)
Set the referencing (child) layer id.
void addFieldPair(const QString &referencingField, const QString &referencedField)
Add a field pairs which is part of this relation The first element of each pair are the field names o...
void setName(const QString &name)
Set a name for this relation.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsMapLayer::LayerType type() const
Returns the type of the layer.
QString id() const
A (project-wide) unique id for this relation.
void setId(const QString &id)
Set an id for this relation.
void setStrength(RelationStrength strength)
Set a strength for this relation.
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
int indexFromName(const QString &fieldName) const
Get the field index from the field name.
RelationStrength strength() const
Returns the relation strength as a string.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
Defines a relation between matching fields of the two involved tables of a relation.
QgsFields fields() const override
Returns the list of fields of this layer.
Q_INVOKABLE QString resolveReferencedField(const QString &referencingField) const
Get the referenced field counterpart given a referencing field.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
static QgsRelation createFromXml(const QDomNode &node)
Creates a relation from an XML structure.
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
Q_INVOKABLE QString resolveReferencingField(const QString &referencedField) const
Get the referencing field counterpart given a referenced field.
bool hasEqualDefinition(const QgsRelation &other) const
Compares the two QgsRelation, ignoring the name and the ID.
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
QgsFeatureIterator getRelatedFeatures(const QgsFeature &feature) const
Creates an iterator which returns all the features on the referencing (child) layer which have a fore...
QString referencingLayerId() const
Access the referencing (child) layer's id This is the layer which has the field(s) which point to ano...
RelationStrength
enum for the relation strength Association, Composition
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
static QgsProject * instance()
Returns the QgsProject singleton instance.
QString referencedField() const
Get the name of the referenced (parent) field.
QList< int > QgsAttributeList
bool nextFeature(QgsFeature &f)
QgsFeature getReferencedFeature(const QgsFeature &feature) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QString referencedLayerId() const
Access the referenced (parent) layer's id.
QString referencingField() const
Get the name of the referencing (child) field.
void writeXml(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
QString name() const
Returns a human readable name for this relation.