QGIS API Documentation 3.39.0-Master (52f98f8c831)
Loading...
Searching...
No Matches
qgsvirtuallayerdefinitionutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvirtuallayerdefinitionutils.cpp
3begin : Jan 2016
4copyright : (C) 2016 Hugo Mercier, Oslandia
5email : hugo dot mercier at oslandia dot com
6 ***************************************************************************/
7
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18#include "qgsvectorlayer.h"
21#include "qgsproject.h"
23
25{
27
28 QStringList leftJoins;
29 QStringList columns;
30
31 // add the geometry column if the layer is spatial
32 if ( layer->isSpatial() )
33 columns << "t.geometry";
34
35 // look for the uid
36 const QgsFields fields = layer->dataProvider()->fields();
37 {
39 if ( pk.size() == 1 )
40 {
41 def.setUid( fields.field( pk[0] ).name() );
42 }
43 else
44 {
45 // find an uid name
46 QString uid = QStringLiteral( "uid" );
47 while ( fields.lookupField( uid ) != -1 )
48 uid += QLatin1Char( '_' ); // add "_" each time this name already exists
49
50 // add a column
51 columns << "t.rowid AS " + uid;
52 def.setUid( uid );
53 }
54 }
55 const QgsFields providerFields = layer->dataProvider()->fields();
56 for ( const auto &f : providerFields )
57 {
58 columns << "t.\"" + f.name() + "\"";
59 }
60
61 int joinIdx = 0;
62 const auto constVectorJoins = layer->vectorJoins();
63 for ( const QgsVectorLayerJoinInfo &join : constVectorJoins )
64 {
65 const QString joinName = QStringLiteral( "j%1" ).arg( ++joinIdx );
66 QgsVectorLayer *joinedLayer = join.joinLayer();
67 if ( !joinedLayer )
68 continue;
69 const QString prefix = join.prefix().isEmpty() ? joinedLayer->name() + "_" : join.prefix();
70
71 leftJoins << QStringLiteral( "LEFT JOIN \"%1\" AS %2 ON t.\"%5\"=%2.\"%3\"" ).arg( joinedLayer->id(), joinName, join.joinFieldName(), join.targetFieldName() );
72 if ( auto *lJoinFieldNamesSubset = join.joinFieldNamesSubset() )
73 {
74 const QStringList joinFieldNamesSubset { *lJoinFieldNamesSubset };
75 for ( const QString &f : joinFieldNamesSubset )
76 {
77 columns << joinName + ".\"" + f + "\" AS \"" + prefix + f + "\"";
78 }
79 }
80 else
81 {
82 const QgsFields joinFields = joinedLayer->fields();
83 for ( const QgsField &f : joinFields )
84 {
85 if ( f.name() == join.joinFieldName() )
86 continue;
87 columns << joinName + ".\"" + f.name() + "\" AS \"" + prefix + f.name() + "\"";
88 }
89 }
90 }
91
92 const QString query = "SELECT " + columns.join( QLatin1String( ", " ) ) + " FROM \"" + layer->id() + "\" AS t " + leftJoins.join( QLatin1Char( ' ' ) );
93 def.setQuery( query );
94
95 return def;
96}
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
QString name
Definition qgsfield.h:62
Container of fields for a vector layer.
Definition qgsfields.h:46
QgsField field(int fieldIdx) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QString name
Definition qgsmaplayer.h:79
QString id
Definition qgsmaplayer.h:78
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
Defines left outer join from our vector layer to some other vector layer.
Represents a vector layer which manages a vector based data sets.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
const QList< QgsVectorLayerJoinInfo > vectorJoins() const
static QgsVirtualLayerDefinition fromJoinedLayer(QgsVectorLayer *joinedLayer)
Gets a virtual layer definition from a vector layer where vector joins are replaced by SQL LEFT JOINs...
Class to manipulate the definition of a virtual layer.
void setUid(const QString &uid)
Sets the name of the field with unique identifiers.
void setQuery(const QString &query)
Sets the SQL query.
QList< int > QgsAttributeList
Definition qgsfield.h:27