Branch data Line data Source code
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 : : 17 : : #include "qgsvirtuallayerdefinitionutils.h" 18 : : #include "qgsvectorlayer.h" 19 : : #include "qgsvectorlayerjoininfo.h" 20 : : #include "qgsvectordataprovider.h" 21 : : #include "qgsproject.h" 22 : : #include "qgsvirtuallayerdefinition.h" 23 : : 24 : 0 : QgsVirtualLayerDefinition QgsVirtualLayerDefinitionUtils::fromJoinedLayer( QgsVectorLayer *layer ) 25 : : { 26 : 0 : QgsVirtualLayerDefinition def; 27 : : 28 : 0 : QStringList leftJoins; 29 : 0 : QStringList columns; 30 : : 31 : : // add the geometry column if the layer is spatial 32 : 0 : if ( layer->isSpatial() ) 33 : 0 : columns << "t.geometry"; 34 : : 35 : : // look for the uid 36 : 0 : QgsFields fields = layer->dataProvider()->fields(); 37 : : { 38 : 0 : QgsAttributeList pk = layer->dataProvider()->pkAttributeIndexes(); 39 : 0 : if ( pk.size() == 1 ) 40 : : { 41 : 0 : def.setUid( fields.field( pk[0] ).name() ); 42 : 0 : } 43 : : else 44 : : { 45 : : // find an uid name 46 : 0 : QString uid = QStringLiteral( "uid" ); 47 : 0 : while ( fields.lookupField( uid ) != -1 ) 48 : 0 : uid += QLatin1Char( '_' ); // add "_" each time this name already exists 49 : : 50 : : // add a column 51 : 0 : columns << "t.rowid AS " + uid; 52 : 0 : def.setUid( uid ); 53 : 0 : } 54 : 0 : } 55 : 0 : const QgsFields providerFields = layer->dataProvider()->fields(); 56 : 0 : for ( const auto &f : providerFields ) 57 : : { 58 : 0 : columns << "t.\"" + f.name() + "\""; 59 : : } 60 : : 61 : 0 : int joinIdx = 0; 62 : 0 : const auto constVectorJoins = layer->vectorJoins(); 63 : 0 : for ( const QgsVectorLayerJoinInfo &join : constVectorJoins ) 64 : : { 65 : 0 : QString joinName = QStringLiteral( "j%1" ).arg( ++joinIdx ); 66 : 0 : QgsVectorLayer *joinedLayer = join.joinLayer(); 67 : 0 : if ( !joinedLayer ) 68 : 0 : continue; 69 : 0 : QString prefix = join.prefix().isEmpty() ? joinedLayer->name() + "_" : join.prefix(); 70 : : 71 : 0 : leftJoins << QStringLiteral( "LEFT JOIN \"%1\" AS %2 ON t.\"%5\"=%2.\"%3\"" ).arg( joinedLayer->id(), joinName, join.joinFieldName(), join.targetFieldName() ); 72 : 0 : if ( auto *lJoinFieldNamesSubset = join.joinFieldNamesSubset() ) 73 : : { 74 : 0 : const QStringList joinFieldNamesSubset { *lJoinFieldNamesSubset }; 75 : 0 : for ( const QString &f : joinFieldNamesSubset ) 76 : : { 77 : 0 : columns << joinName + ".\"" + f + "\" AS \"" + prefix + f + "\""; 78 : : } 79 : 0 : } 80 : : else 81 : : { 82 : 0 : const QgsFields joinFields = joinedLayer->fields(); 83 : 0 : for ( const QgsField &f : joinFields ) 84 : : { 85 : 0 : if ( f.name() == join.joinFieldName() ) 86 : 0 : continue; 87 : 0 : columns << joinName + ".\"" + f.name() + "\" AS \"" + prefix + f.name() + "\""; 88 : : } 89 : 0 : } 90 : 0 : } 91 : : 92 : 0 : QString query = "SELECT " + columns.join( QLatin1String( ", " ) ) + " FROM \"" + layer->id() + "\" AS t " + leftJoins.join( QLatin1Char( ' ' ) ); 93 : 0 : def.setQuery( query ); 94 : : 95 : 0 : return def; 96 : 0 : }