Skip to content

Commit 945187c

Browse files
committedNov 26, 2015
case-sensitivity of vector layer field (fixes #13032)
* fieldNameIndex: resort to case-insensitive lookup only if case-sensitive lookup has no match * file writer: fix handling of fields that only differ by case (backported from commit 8e2b791)
1 parent a76c5f6 commit 945187c

File tree

4 files changed

+28
-10
lines changed

4 files changed

+28
-10
lines changed
 

‎python/core/qgsfield.sip

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class QgsField
1414
#include <qgsfield.h>
1515
%End
1616

17-
public:
17+
public:
1818
/** Constructor. Constructs a new QgsField object.
1919
* @param name Field name
2020
* @param type Field variant type, currently supported: String / Int / Double
@@ -171,6 +171,14 @@ public:
171171
}; // class QgsField
172172

173173

174+
/**
175+
\ingroup core
176+
Container of fields for a vector layer.
177+
178+
In addition to storing a list of QgsField instances, it also:
179+
- allows quick lookups of field names to index in the list
180+
- keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
181+
*/
174182

175183
class QgsFields
176184
{
@@ -192,6 +200,8 @@ class QgsFields
192200
void clear();
193201
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
194202
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
203+
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
204+
bool appendExpressionField( const QgsField& field, int originIndex );
195205
//! Remove a field with the given index
196206
void remove( int fieldIdx );
197207
//! Extend with fields from another QgsFields container
@@ -240,8 +250,8 @@ class QgsFields
240250
//! Look up field's index from name. Returns -1 on error
241251
int indexFromName( const QString& name ) const;
242252

243-
//! Look up field's index from name - case insensitive
244-
//! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
253+
//! Look up field's index from name
254+
//! also looks up case-insensitive if there is no match otherwise
245255
//! @note added in 2.4
246256
int fieldNameIndex( const QString& fieldName ) const;
247257

‎src/core/qgsfield.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,18 @@ QList<QgsField> QgsFields::toList() const
262262

263263
int QgsFields::fieldNameIndex( const QString& fieldName ) const
264264
{
265+
for ( int idx = 0; idx < count(); ++idx )
266+
{
267+
if ( mFields[idx].field.name() == fieldName )
268+
return idx;
269+
}
270+
265271
for ( int idx = 0; idx < count(); ++idx )
266272
{
267273
if ( QString::compare( mFields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
268-
{
269274
return idx;
270-
}
271275
}
276+
272277
return -1;
273278
}
274279

‎src/core/qgsfield.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ class CORE_EXPORT QgsFields
238238
//! Look up field's index from name. Returns -1 on error
239239
int indexFromName( const QString& name ) const { return mNameToIndex.value( name, -1 ); }
240240

241-
//! Look up field's index from name - case insensitive
242-
//! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
241+
//! Look up field's index from name
242+
//! also looks up case-insensitive if there is no match otherwise
243243
//! @note added in 2.4
244244
int fieldNameIndex( const QString& fieldName ) const;
245245

‎src/core/qgsvectorfilewriter.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
337337

338338
mFields = fields;
339339
mAttrIdxToOgrIdx.clear();
340+
QSet<int> existingIdxs;
340341

341342
for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
342343
{
@@ -445,7 +446,8 @@ QgsVectorFileWriter::QgsVectorFileWriter(
445446
OGR_Fld_Destroy( fld );
446447

447448
int ogrIdx = OGR_FD_GetFieldIndex( defn, mCodec->fromUnicode( name ) );
448-
if ( ogrIdx < 0 )
449+
QgsDebugMsg( QString( "returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
450+
if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
449451
{
450452
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
451453
// if we didn't find our new column, assume it's name was truncated and
@@ -478,6 +480,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
478480
}
479481
}
480482

483+
existingIdxs.insert( ogrIdx );
481484
mAttrIdxToOgrIdx.insert( fldIdx, ogrIdx );
482485
}
483486

@@ -1386,7 +1389,7 @@ QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()
13861389

13871390
layerOptions.insert( "LAUNDER", new BoolOption(
13881391
QObject::tr( "Controls whether layer and field names will be laundered for easier use "
1389-
"in SQLite. Laundered names will be convered to lower case and some special "
1392+
"in SQLite. Laundered names will be converted to lower case and some special "
13901393
"characters(' - #) will be changed to underscores." ),
13911394
true // Default value
13921395
) );
@@ -2594,7 +2597,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
25942597
if ( !styleString.isEmpty() )
25952598
{
25962599
OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
2597-
if ( ! writeFeature( mLayer, ogrFeature ) )
2600+
if ( !writeFeature( mLayer, ogrFeature ) )
25982601
{
25992602
++nErrors;
26002603
}

0 commit comments

Comments
 (0)
Please sign in to comment.