QGIS API Documentation  2.14.0-Essen
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 
22 {
24 
25  QStringList leftJoins;
26  QStringList columns;
27 
28  columns << "t.*"; // columns from the main layer
29 
30  // look for the uid
31  const QgsFields& fields = layer->dataProvider()->fields();
32  {
34  if ( pk.size() == 1 )
35  {
36  def.setUid( fields.field( pk[0] ).name() );
37  }
38  else
39  {
40  // find an uid name
41  QString uid = "uid";
42  while ( fields.fieldNameIndex( uid ) != -1 )
43  uid += "_"; // add "_" each time this name already exists
44 
45  // add a column
46  columns << "t.rowid AS " + uid;
47  def.setUid( uid );
48  }
49  }
50 
51  int joinIdx = 0;
52  Q_FOREACH ( const QgsVectorJoinInfo& join, layer->vectorJoins() )
53  {
54  QString joinName = QString( "j%1" ).arg( ++joinIdx );
55  QString prefix = join.prefix.isEmpty() ? layer->name() + "_" : join.prefix;
56 
57  leftJoins << QString( "LEFT JOIN %1 AS %2 ON t.\"%3\"=%2.\"%5\"" ).arg( join.joinLayerId, joinName, join.joinFieldName, join.targetFieldName );
58  if ( join.joinFieldNamesSubset() )
59  {
60  Q_FOREACH ( const QString& f, *join.joinFieldNamesSubset() )
61  {
62  columns << joinName + "." + f + " AS " + prefix + f;
63  }
64  }
65  else
66  {
67  const QgsFields& joinedFields = layer->dataProvider()->fields();
68  for ( int i = 0; i < joinedFields.count(); i++ )
69  {
70  const QgsField& f = joinedFields.field( i );
71  columns << joinName + "." + f.name() + " AS " + prefix + f.name();
72  }
73  }
74  }
75 
76  QString query = "SELECT " + columns.join( ", " ) + " FROM " + layer->id() + " AS t " + leftJoins.join( " " );
77  def.setQuery( query );
78 
79  return def;
80 }
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:390
const QList< QgsVectorJoinInfo > vectorJoins() const
QString joinFieldName
Join field in the source layer.
QString targetFieldName
Join field in the target layer.
QString name() const
Get the display name of the layer.
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:503
Container of fields for a vector layer.
Definition: qgsfield.h:187
QString join(const QString &separator) const
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
int size() const
QString prefix
An optional prefix.
void setQuery(const QString &query)
Set the SQL query.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
bool isEmpty() const
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
static QgsVirtualLayerDefinition fromJoinedLayer(QgsVectorLayer *joinedLayer)
Get a virtual layer definition from a vector layer where vector joins are replaced by SQL LEFT JOINs...
int count() const
Return number of items.
Definition: qgsfield.cpp:365
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
void setUid(const QString &uid)
Set the name of the field with unique identifiers.
QStringList * joinFieldNamesSubset() const
Get subset of fields to be used from joined layer.
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.
Class to manipulate the definition of a virtual layer.