28 : d( new QgsRelationPrivate() )
33 : d( new QgsRelationPrivate() )
42 , mContext( other.mContext )
49 mContext = other.mContext;
55 QDomElement elem = node.toElement();
57 if ( elem.tagName() != QLatin1String(
"relation" ) )
59 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
65 QString
referencedLayerId = elem.attribute( QStringLiteral(
"referencedLayer" ) );
66 QString
id = elem.attribute( QStringLiteral(
"id" ) );
68 QString
strength = elem.attribute( QStringLiteral(
"strength" ) );
70 QMap<QString, QgsMapLayer *> mapLayers = relationContext.
project()->
mapLayers();
94 relation.d->mReferencingLayer = qobject_cast<QgsVectorLayer *>(
referencingLayer );
96 relation.d->mReferencedLayer = qobject_cast<QgsVectorLayer *>(
referencedLayer );
97 relation.d->mRelationId =
id;
98 relation.d->mRelationName =
name;
99 relation.d->mRelationStrength = qgsEnumKeyToValue<QgsRelation::RelationStrength>(
strength, RelationStrength::Association );
101 QDomNodeList references = elem.elementsByTagName( QStringLiteral(
"fieldRef" ) );
102 for (
int i = 0; i < references.size(); ++i )
104 QDomElement refEl = references.at( i ).toElement();
106 QString referencingField = refEl.attribute( QStringLiteral(
"referencingField" ) );
107 QString referencedField = refEl.attribute( QStringLiteral(
"referencedField" ) );
109 relation.
addFieldPair( referencingField, referencedField );
119 QDomElement elem = doc.createElement( QStringLiteral(
"relation" ) );
120 elem.setAttribute( QStringLiteral(
"id" ), d->mRelationId );
121 elem.setAttribute( QStringLiteral(
"name" ), d->mRelationName );
122 elem.setAttribute( QStringLiteral(
"referencingLayer" ), d->mReferencingLayerId );
123 elem.setAttribute( QStringLiteral(
"referencedLayer" ), d->mReferencedLayerId );
124 elem.setAttribute( QStringLiteral(
"strength" ), qgsEnumValueToKey<RelationStrength>( d->mRelationStrength ) );
126 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
128 QDomElement referenceElem = doc.createElement( QStringLiteral(
"fieldRef" ) );
129 referenceElem.setAttribute( QStringLiteral(
"referencingField" ), pair.first );
130 referenceElem.setAttribute( QStringLiteral(
"referencedField" ), pair.second );
131 elem.appendChild( referenceElem );
134 node.appendChild( elem );
148 d->mRelationName =
name;
161 d->mReferencingLayerId =
id;
169 d->mReferencedLayerId =
id;
177 d->mFieldPairs <<
FieldPair( referencingField, referencedField );
184 d->mFieldPairs << fieldPair;
196 QgsDebugMsgLevel( QStringLiteral(
"Filter conditions: '%1'" ).arg( filter ), 2 );
205 QStringList conditions;
207 if ( ! d->mPolymorphicRelationId.isEmpty() )
216 QgsDebugMsg(
"The polymorphic relation is invalid" );
217 conditions << QStringLiteral(
" FALSE " );
221 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
223 QVariant val( feature.
attribute( pair.referencedField() ) );
227 return conditions.join( QLatin1String(
" AND " ) );
232 QStringList conditions;
234 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
242 QgsDebugMsgLevel( QStringLiteral(
"Filter conditions: '%1'" ).arg( conditions.join(
" AND " ) ), 2 );
259 d->mReferencedLayer->getFeatures( request ).nextFeature( f );
265 return d->mRelationName;
270 return d->mRelationStrength;
275 return d->mRelationId;
280 if ( !d->mFieldPairs.isEmpty() )
283 d->mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
294 return d->mReferencingLayerId;
299 return d->mReferencingLayer;
304 return d->mReferencedLayerId;
309 return d->mReferencedLayer;
314 return d->mFieldPairs;
320 attrs.reserve( d->mFieldPairs.size() );
321 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
323 attrs << d->mReferencedLayer->fields().lookupField( pair.second );
332 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
334 attrs << d->mReferencingLayer->fields().lookupField( pair.first );
342 return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayer.isNull() && d->mReferencingLayer.data()->isValid() && d->mReferencedLayer.data()->isValid();
347 return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
352 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
354 if ( pair.first == referencingField )
362 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
364 if ( pair.second == referencedField )
372 const QMap<QString, QgsMapLayer *> &mapLayers = mContext.
project()->
mapLayers();
374 d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
375 d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );
379 if ( d->mRelationId.isEmpty() )
381 QgsDebugMsg( QStringLiteral(
"Invalid relation: no ID" ) );
386 if ( !d->mReferencedLayer )
388 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
391 else if ( !d->mReferencingLayer )
393 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
398 if ( d->mFieldPairs.count() < 1 )
400 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: no pair of field is specified." ), 4 );
404 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
406 if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) )
408 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
412 else if ( -1 == d->mReferencedLayer->fields().lookupField( pair.second ) )
414 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referenced layer %2" ).arg( pair.second, d->mReferencedLayer->name() ) );
432 return d->mPolymorphicRelationId;
445 if ( d->mPolymorphicRelationId.isNull() )
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
Wrapper for iterator of features from vector data provider or vector layer.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
static void warning(const QString &msg)
Goes to qWarning.
Base class for all map layer types.
A polymorphic relation consists of the same properties like a normal relation except for the referenc...
QString layerRepresentation(const QgsVectorLayer *layer) const
Returns layer representation as evaluated string.
QString referencedLayerField
virtual QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const =0
The derived translate() translates with QTranslator and qm file the sourceText.
QgsRelationManager * relationManager
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
The class is used as a container of context for various read/write operations on other objects.
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
const QgsProject * project() const
Gets the associated project.
QgsPolymorphicRelation polymorphicRelation(const QString &polymorphicRelationId) const
Returns the list of relations associated with a polymorphic relation.
Defines a relation between matching fields of the two involved tables of a relation.
QString referencingField() const
Gets the name of the referencing (child) field.
QString referencedField() const
Gets the name of the referenced (parent) field.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing (ch...
QgsFeature getReferencedFeature(const QgsFeature &feature) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
void setId(const QString &id)
Set an id for this relation.
QgsFeatureIterator getRelatedFeatures(const QgsFeature &feature) const
Creates an iterator which returns all the features on the referencing (child) layer which have a fore...
QgsRelation()
Default constructor.
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
void setPolymorphicRelationId(const QString &polymorphicRelationId)
Sets the parent polymorphic relation id.
QgsRelation & operator=(const QgsRelation &other)
Copies a relation.
void generateId()
Generate a (project-wide) unique id for this relation.
Q_INVOKABLE QString resolveReferencingField(const QString &referencedField) const
Gets the referencing field counterpart given a referenced field.
bool hasEqualDefinition(const QgsRelation &other) const
Compares the two QgsRelation, ignoring the name and the ID.
static QgsRelation createFromXml(const QDomNode &node, QgsReadWriteContext &context, const QgsRelationContext &relationContext=QgsRelationContext())
Creates a relation from an XML structure.
Q_INVOKABLE QString resolveReferencedField(const QString &referencingField) const
Gets the referenced field counterpart given a referencing field.
QString polymorphicRelationId
QgsVectorLayer * referencedLayer
void addFieldPair(const QString &referencingField, const QString &referencedField)
Add a field pair which is part of this relation The first element of each pair are the field names of...
RelationType
Enum holding the relations type.
@ Generated
A generated relation is a child of a polymorphic relation.
@ Normal
A normal relation.
void setReferencingLayer(const QString &id)
Set the referencing (child) 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...
RelationStrength
enum for the relation strength Association, Composition
RelationType type() const
Returns the type of the relation.
QgsPolymorphicRelation polymorphicRelation
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
QgsVectorLayer * referencingLayer
void setStrength(RelationStrength strength)
Set a strength for this relation.
QString referencedLayerId() const
Access the referenced (parent) layer's id.
void setName(const QString &name)
Set a name for this relation.
RelationStrength strength() const
Returns the relation strength as a string.
QString referencingLayerId() const
Access the referencing (child) layer's id This is the layer which has the field(s) which point to ano...
void writeXml(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
void updateRelationStatus()
Updates the validity status of this relation.
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)