Skip to content

Commit 5c028f8

Browse files
committed
Merge pull request #452 from minorua/tablejoin
Some fixes for table join. Merged for wider testing.
2 parents 9247262 + 30c343c commit 5c028f8

File tree

6 files changed

+72
-25
lines changed

6 files changed

+72
-25
lines changed

src/app/qgsvectorlayerproperties.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ void QgsVectorLayerProperties::apply()
451451
{
452452
if ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SetEncoding )
453453
{
454-
layer->dataProvider()->setEncoding( cboProviderEncoding->currentText() );
454+
layer->setProviderEncoding( cboProviderEncoding->currentText() );
455455
}
456456
}
457457

@@ -844,15 +844,23 @@ void QgsVectorLayerProperties::addJoinToTreeWidget( const QgsVectorJoinInfo& joi
844844
QTreeWidgetItem* joinItem = new QTreeWidgetItem();
845845

846846
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join.joinLayerId ) );
847-
if ( !joinLayer )
847+
if ( !layer || !joinLayer )
848848
{
849849
return;
850850
}
851851

852852
joinItem->setText( 0, joinLayer->name() );
853853
joinItem->setData( 0, Qt::UserRole, join.joinLayerId );
854-
joinItem->setText( 1, join.joinFieldName );
855-
joinItem->setText( 2, join.targetFieldName );
854+
855+
if ( join.joinFieldName.isEmpty() && join.joinFieldIndex >= 0 && join.joinFieldIndex < joinLayer->pendingFields().count() )
856+
joinItem->setText( 1, joinLayer->pendingFields().field( join.joinFieldIndex ).name() ); //for compatibility with 1.x
857+
else
858+
joinItem->setText( 1, join.joinFieldName );
859+
860+
if ( join.targetFieldName.isEmpty() && join.targetFieldIndex >= 0 && join.targetFieldIndex < layer->pendingFields().count() )
861+
joinItem->setText( 2, layer->pendingFields().field( join.targetFieldIndex ).name() ); //for compatibility with 1.x
862+
else
863+
joinItem->setText( 2, join.targetFieldName );
856864

857865
mJoinTreeWidget->addTopLevelItem( joinItem );
858866
}

src/core/qgsproject.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
707707
for ( ; vIt != vLayerList.end(); ++vIt )
708708
{
709709
vIt->first->createJoinCaches();
710+
vIt->first->updateFields();
710711
//for old symbology, it is necessary to read the symbology again after having the complete field map
711712
if ( !vIt->first->isUsingRendererV2() )
712713
{

src/core/qgsvectorlayer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ void QgsVectorLayer::setProviderEncoding( const QString& encoding )
13201320
if ( mDataProvider )
13211321
{
13221322
mDataProvider->setEncoding( encoding );
1323+
updateFields();
13231324
}
13241325
}
13251326

@@ -3855,7 +3856,7 @@ void QgsVectorLayer::updateFields()
38553856
mEditBuffer->updateFields( mUpdatedFields );
38563857

38573858
// joined fields
3858-
if ( mJoinBuffer->containsJoins() )
3859+
if ( mJoinBuffer && mJoinBuffer->containsJoins() )
38593860
mJoinBuffer->updateFields( mUpdatedFields );
38603861
}
38613862

src/core/qgsvectorlayer.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ struct CORE_EXPORT QgsVectorJoinInfo
135135
*/
136136
QHash< QString, QgsAttributes> cachedAttributes;
137137

138-
// the following are temporaries, assigned by QgsVectorLayerJoinBuffer::updateFields()
139-
mutable int tmpTargetField;
140-
mutable int tmpJoinField;
138+
/**Join field index in the target layer. For backward compatibility with 1.x (x>=7)*/
139+
int targetFieldIndex;
140+
/**Join field index in the source layer. For backward compatibility with 1.x (x>=7)*/
141+
int joinFieldIndex;
141142
};
142143

143144

@@ -829,6 +830,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
829830
@note public and static from version 1.4 */
830831
static void drawVertexMarker( double x, double y, QPainter& p, QgsVectorLayer::VertexMarkerType type, int vertexSize );
831832

833+
/** Assembles mUpdatedFields considering provider fields, joined fields and added fields
834+
@note added in 1.7 */
835+
void updateFields();
836+
832837
/** Caches joined attributes if required (and not already done)
833838
@note added in 1.7 */
834839
void createJoinCaches();
@@ -971,10 +976,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
971976
/** Stop version 2 renderer and selected renderer (if required) */
972977
void stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer );
973978

974-
/** Assembles mUpdatedFields considering provider fields, joined fields and added fields
975-
@note added in 1.7 */
976-
void updateFields();
977-
978979
/**Registers label and diagram layer
979980
@param rendererContext render context
980981
@param attributes attributes needed for labeling and diagrams will be added to the list

src/core/qgsvectorlayerfeatureiterator.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,21 @@ void QgsVectorLayerFeatureIterator::prepareJoins()
310310
{
311311
FetchJoinInfo info;
312312
info.joinInfo = joinInfo;
313-
info.indexOffset = *attIt - sourceLayerIndex;
314313
info.joinLayer = joinLayer;
315-
info.targetField = fields.indexFromName( joinInfo->targetFieldName );
316-
info.joinField = joinLayer->pendingFields().indexFromName( joinInfo->joinFieldName );
314+
315+
if ( joinInfo->targetFieldName.isEmpty() )
316+
info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
317+
else
318+
info.targetField = fields.indexFromName( joinInfo->targetFieldName );
319+
320+
if ( joinInfo->joinFieldName.isEmpty() )
321+
info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
322+
else
323+
info.joinField = joinLayer->pendingFields().indexFromName( joinInfo->joinFieldName );
324+
325+
info.indexOffset = *attIt - sourceLayerIndex;
326+
if ( info.joinField < sourceLayerIndex )
327+
info.indexOffset++;
317328

318329
// for joined fields, we always need to request the targetField from the provider too
319330
if ( !fetchAttributes.contains( info.targetField ) )
@@ -389,7 +400,13 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg
389400
subsetString.append( " AND " );
390401
}
391402

392-
subsetString.append( "\"" + joinInfo->joinFieldName + "\"" + " = " + "\"" + joinValue.toString() + "\"" );
403+
QString joinFieldName;
404+
if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->pendingFields().count() )
405+
joinFieldName = joinLayer->pendingFields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
406+
else
407+
joinFieldName = joinInfo->joinFieldName;
408+
409+
subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + joinValue.toString() + "\"" );
393410
joinLayer->dataProvider()->setSubsetString( subsetString, false );
394411

395412
// select (no geometry)

src/core/qgsvectorlayerjoinbuffer.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ void QgsVectorLayerJoinBuffer::cacheJoinLayer( QgsVectorJoinInfo& joinInfo )
6363
QgsVectorLayer* cacheLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
6464
if ( cacheLayer )
6565
{
66-
int joinFieldIndex = cacheLayer->pendingFields().indexFromName( joinInfo.joinFieldName );
66+
int joinFieldIndex;
67+
if ( joinInfo.joinFieldName.isEmpty() )
68+
joinFieldIndex = joinInfo.joinFieldIndex; //for compatibility with 1.x
69+
else
70+
joinFieldIndex = cacheLayer->pendingFields().indexFromName( joinInfo.joinFieldName );
6771

6872
joinInfo.cachedAttributes.clear();
6973

@@ -88,15 +92,17 @@ void QgsVectorLayerJoinBuffer::updateFields( QgsFields& fields )
8892
continue;
8993
}
9094

91-
joinIt->tmpTargetField = fields.indexFromName( joinIt->targetFieldName );
92-
9395
const QgsFields& joinFields = joinLayer->pendingFields();
94-
joinIt->tmpJoinField = joinFields.indexFromName( joinIt->joinFieldName );
96+
QString joinFieldName;
97+
if ( joinIt->joinFieldName.isEmpty() && joinIt->joinFieldIndex >= 0 && joinIt->joinFieldIndex < joinFields.count() )
98+
joinFieldName = joinFields.field( joinIt->joinFieldIndex ).name(); //for compatibility with 1.x
99+
else
100+
joinFieldName = joinIt->joinFieldName;
95101

96102
for ( int idx = 0; idx < joinFields.count(); ++idx )
97103
{
98104
//skip the join field to avoid double field names (fields often have the same name)
99-
if ( joinFields[idx].name() != joinIt->joinFieldName )
105+
if ( joinFields[idx].name() != joinFieldName )
100106
{
101107
QgsField f = joinFields[idx];
102108
f.setName( joinLayer->name() + "_" + f.name() );
@@ -124,9 +130,18 @@ void QgsVectorLayerJoinBuffer::writeXml( QDomNode& layer_node, QDomDocument& doc
124130
for ( ; joinIt != mVectorJoins.constEnd(); ++joinIt )
125131
{
126132
QDomElement joinElem = document.createElement( "join" );
127-
joinElem.setAttribute( "targetFieldName", joinIt->targetFieldName );
133+
134+
if ( joinIt->targetFieldName.isEmpty() )
135+
joinElem.setAttribute( "targetField", joinIt->targetFieldIndex ); //for compatibility with 1.x
136+
else
137+
joinElem.setAttribute( "targetFieldName", joinIt->targetFieldName );
138+
128139
joinElem.setAttribute( "joinLayerId", joinIt->joinLayerId );
129-
joinElem.setAttribute( "joinFieldName", joinIt->joinFieldName );
140+
if ( joinIt->joinFieldName.isEmpty() )
141+
joinElem.setAttribute( "joinField", joinIt->joinFieldIndex ); //for compatibility with 1.x
142+
else
143+
joinElem.setAttribute( "joinFieldName", joinIt->joinFieldName );
144+
130145
joinElem.setAttribute( "memoryCache", !joinIt->cachedAttributes.isEmpty() );
131146
vectorJoinsElem.appendChild( joinElem );
132147
}
@@ -143,10 +158,14 @@ void QgsVectorLayerJoinBuffer::readXml( const QDomNode& layer_node )
143158
{
144159
QDomElement infoElem = joinList.at( i ).toElement();
145160
QgsVectorJoinInfo info;
146-
info.joinFieldName = infoElem.attribute( "joinFieldName" ); // TODO[MD]: compatibility with 1.x?
161+
info.joinFieldName = infoElem.attribute( "joinFieldName" );
147162
info.joinLayerId = infoElem.attribute( "joinLayerId" );
148-
info.targetFieldName = infoElem.attribute( "targetFieldName" ); // TODO[MD]: compatibility with 1.x?
163+
info.targetFieldName = infoElem.attribute( "targetFieldName" );
149164
info.memoryCache = infoElem.attribute( "memoryCache" ).toInt();
165+
166+
info.joinFieldIndex = infoElem.attribute( "joinField" ).toInt(); //for compatibility with 1.x
167+
info.targetFieldIndex = infoElem.attribute( "targetField" ).toInt(); //for compatibility with 1.x
168+
150169
addJoin( info );
151170
}
152171
}

0 commit comments

Comments
 (0)