QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsvirtuallayerdefinitionutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvirtuallayerdefinitionutils.cpp
3 begin : Jan 2016
4 copyright : (C) 2016 Hugo Mercier, Oslandia
5 email : 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"
19 #include "qgsvectorlayerjoininfo.h"
20 #include "qgsvectordataprovider.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  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  QString joinName = QStringLiteral( "j%1" ).arg( ++joinIdx );
66  QgsVectorLayer *joinedLayer = join.joinLayer();
67  if ( !joinedLayer )
68  continue;
69  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  QString query = "SELECT " + columns.join( QLatin1String( ", " ) ) + " FROM \"" + layer->id() + "\" AS t " + leftJoins.join( QLatin1Char( ' ' ) );
93  def.setQuery( query );
94 
95  return def;
96 }
qgsvirtuallayerdefinition.h
QgsVirtualLayerDefinition::setQuery
void setQuery(const QString &query)
Sets the SQL query.
Definition: qgsvirtuallayerdefinition.h:123
QgsVectorDataProvider::pkAttributeIndexes
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
Definition: qgsvectordataprovider.cpp:351
QgsVirtualLayerDefinition::setUid
void setUid(const QString &uid)
Sets the name of the field with unique identifiers.
Definition: qgsvirtuallayerdefinition.h:133
QgsVectorDataProvider::fields
QgsFields fields() const override=0
Returns the fields associated with this data provider.
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsVectorLayer::isSpatial
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Definition: qgsvectorlayer.cpp:3599
QgsAttributeList
QList< int > QgsAttributeList
Definition: qgsfield.h:26
QgsField::name
QString name
Definition: qgsfield.h:59
qgsvectorlayerjoininfo.h
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
QgsVectorLayer::vectorJoins
const QList< QgsVectorLayerJoinInfo > vectorJoins() const
Definition: qgsvectorlayer.cpp:3732
qgsvectordataprovider.h
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsVectorLayerJoinInfo
Defines left outer join from our vector layer to some other vector layer.
Definition: qgsvectorlayerjoininfo.h:34
QgsFields::field
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:168
qgsvectorlayer.h
QgsVirtualLayerDefinitionUtils::fromJoinedLayer
static QgsVirtualLayerDefinition fromJoinedLayer(QgsVectorLayer *joinedLayer)
Gets a virtual layer definition from a vector layer where vector joins are replaced by SQL LEFT JOINs...
Definition: qgsvirtuallayerdefinitionutils.cpp:24
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsVirtualLayerDefinition
Class to manipulate the definition of a virtual layer.
Definition: qgsvirtuallayerdefinition.h:32
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
qgsvirtuallayerdefinitionutils.h
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
qgsproject.h
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50