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() ) );
225 if ( referencingIdx >= 0 )
236 return conditions.join( QLatin1String(
" AND " ) );
241 QStringList conditions;
243 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
247 if ( referencedIdx >= 0 )
260 QgsDebugMsgLevel( QStringLiteral(
"Filter conditions: '%1'" ).arg( conditions.join(
" AND " ) ), 2 );
277 d->mReferencedLayer->getFeatures( request ).nextFeature( f );
283 return d->mRelationName;
288 return d->mRelationStrength;
293 return d->mRelationId;
298 if ( !d->mFieldPairs.isEmpty() )
301 d->mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
312 return d->mReferencingLayerId;
317 return d->mReferencingLayer;
322 return d->mReferencedLayerId;
327 return d->mReferencedLayer;
332 return d->mFieldPairs;
338 attrs.reserve( d->mFieldPairs.size() );
339 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
341 attrs << d->mReferencedLayer->fields().lookupField( pair.second );
350 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
352 attrs << d->mReferencingLayer->fields().lookupField( pair.first );
360 return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayer.isNull() && d->mReferencingLayer.data()->isValid() && d->mReferencedLayer.data()->isValid();
365 return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
370 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
372 if ( pair.first == referencingField )
380 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
382 if ( pair.second == referencedField )
390 const QMap<QString, QgsMapLayer *> &mapLayers = mContext.
project()->
mapLayers();
392 d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
393 d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );
397 if ( d->mRelationId.isEmpty() )
399 QgsDebugMsg( QStringLiteral(
"Invalid relation: no ID" ) );
404 if ( !d->mReferencedLayer )
406 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
409 else if ( !d->mReferencingLayer )
411 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
416 if ( d->mFieldPairs.count() < 1 )
418 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: no pair of field is specified." ), 4 );
422 for (
const FieldPair &pair : std::as_const( d->mFieldPairs ) )
424 if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) )
426 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
430 else if ( -1 == d->mReferencedLayer->fields().lookupField( pair.second ) )
432 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referenced layer %2" ).arg( pair.second, d->mReferencedLayer->name() ) );
450 return d->mPolymorphicRelationId;
463 if ( d->mPolymorphicRelationId.isNull() )
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QVariant::Type fieldType=QVariant::Type::Invalid)
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.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
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.
@ VectorLayer
Vector layer.
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)