QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "qgsvectordataprovider.h"
20 #include "qgsmaplayerregistry.h"
21 
23 {
25 
26  QStringList leftJoins;
27  QStringList columns;
28 
29  // look for the uid
30  const QgsFields& fields = layer->dataProvider()->fields();
31  {
33  if ( pk.size() == 1 )
34  {
35  def.setUid( fields.field( pk[0] ).name() );
36  }
37  else
38  {
39  // find an uid name
40  QString uid = "uid";
41  while ( fields.fieldNameIndex( uid ) != -1 )
42  uid += "_"; // add "_" each time this name already exists
43 
44  // add a column
45  columns << "t.rowid AS " + uid;
46  def.setUid( uid );
47  }
48  }
49  Q_FOREACH ( const QgsField& f, layer->dataProvider()->fields() )
50  {
51  columns << "t." + f.name();
52  }
53 
54  int joinIdx = 0;
55  Q_FOREACH ( const QgsVectorJoinInfo& join, layer->vectorJoins() )
56  {
57  QString joinName = QString( "j%1" ).arg( ++joinIdx );
58  QgsVectorLayer* joinedLayer = static_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join.joinLayerId ) );
59  if ( !joinedLayer )
60  continue;
61  QString prefix = join.prefix.isEmpty() ? joinedLayer->name() + "_" : join.prefix;
62 
63  leftJoins << QString( "LEFT JOIN %1 AS %2 ON t.\"%5\"=%2.\"%3\"" ).arg( join.joinLayerId, joinName, join.joinFieldName, join.targetFieldName );
64  if ( join.joinFieldNamesSubset() )
65  {
66  Q_FOREACH ( const QString& f, *join.joinFieldNamesSubset() )
67  {
68  columns << joinName + "." + f + " AS " + prefix + f;
69  }
70  }
71  else
72  {
73  Q_FOREACH ( const QgsField& f, joinedLayer->fields() )
74  {
75  if ( f.name() == join.joinFieldName )
76  continue;
77  columns << joinName + "." + f.name() + " AS " + prefix + f.name();
78  }
79  }
80  }
81 
82  QString query = "SELECT " + columns.join( ", " ) + " FROM " + layer->id() + " AS t " + leftJoins.join( " " );
83  def.setQuery( query );
84 
85  return def;
86 }
QString joinFieldName
Join field in the source layer.
QString targetFieldName
Join field in the target layer.
QString name
Definition: qgsfield.h:52
QgsMapLayer * mapLayer(const QString &theLayerId) const
Retrieve a pointer to a registered layer by layer ID.
Container of fields for a vector layer.
Definition: qgsfield.h:252
QString join(const QString &separator) const
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
const QList< QgsVectorJoinInfo > vectorJoins() const
int size() const
QgsFields fields() const
Returns the list of fields of this layer.
QString prefix
An optional prefix.
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
void setQuery(const QString &query)
Set the SQL query.
bool isEmpty() const
static QgsVirtualLayerDefinition fromJoinedLayer(QgsVectorLayer *joinedLayer)
Get a virtual layer definition from a vector layer where vector joins are replaced by SQL LEFT JOINs...
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:571
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void setUid(const QString &uid)
Set the name of the field with unique identifiers.
QString name
Read property of QString layerName.
Definition: qgsmaplayer.h:53
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:427
QgsVectorDataProvider * dataProvider()
Returns the data provider.
Represents a vector layer which manages a vector based data sets.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString joinLayerId
Source layer.
QStringList * joinFieldNamesSubset() const
Get subset of fields to be used from joined layer.
Class to manipulate the definition of a virtual layer.