Skip to content

Commit

Permalink
case-sensitivity of vector layer field (fixes #13032)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jef-n committed Oct 11, 2015
1 parent d277dd6 commit 8e2b791
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 11 deletions.
8 changes: 4 additions & 4 deletions python/core/qgsfield.sip
Expand Up @@ -13,7 +13,7 @@ class QgsField
#include <qgsfield.h>
%End

public:
public:
/** Constructor. Constructs a new QgsField object.
* @param name Field name
* @param type Field variant type, currently supported: String / Int / Double
Expand Down Expand Up @@ -177,7 +177,7 @@ public:
*
* In addition to storing a list of QgsField instances, it also:
* - allows quick lookups of field names to index in the list
*- keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* \note QgsFields objects are implicitly shared.
*/

Expand Down Expand Up @@ -332,8 +332,8 @@ class QgsFields
//! Look up field's index from name. Returns -1 on error
int indexFromName( const QString& name ) const;

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

Expand Down
9 changes: 7 additions & 2 deletions src/core/qgsfield.cpp
Expand Up @@ -356,13 +356,18 @@ bool QgsFields::operator==( const QgsFields &other ) const

int QgsFields::fieldNameIndex( const QString& fieldName ) const
{
for ( int idx = 0; idx < count(); ++idx )
{
if ( d->fields[idx].field.name() == fieldName )
return idx;
}

for ( int idx = 0; idx < count(); ++idx )
{
if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
{
return idx;
}
}

return -1;
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsfield.h
Expand Up @@ -257,8 +257,8 @@ class CORE_EXPORT QgsFields
//! Look up field's index from name. Returns -1 on error
int indexFromName( const QString& name ) const;

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

Expand Down
9 changes: 6 additions & 3 deletions src/core/qgsvectorfilewriter.cpp
Expand Up @@ -339,6 +339,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(

mFields = fields;
mAttrIdxToOgrIdx.clear();
QSet<int> existingIdxs;

for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
{
Expand Down Expand Up @@ -447,7 +448,8 @@ QgsVectorFileWriter::QgsVectorFileWriter(
OGR_Fld_Destroy( fld );

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

existingIdxs.insert( ogrIdx );
mAttrIdxToOgrIdx.insert( fldIdx, ogrIdx );
}

Expand Down Expand Up @@ -1388,7 +1391,7 @@ QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()

layerOptions.insert( "LAUNDER", new BoolOption(
QObject::tr( "Controls whether layer and field names will be laundered for easier use "
"in SQLite. Laundered names will be convered to lower case and some special "
"in SQLite. Laundered names will be converted to lower case and some special "
"characters(' - #) will be changed to underscores." ),
true // Default value
) );
Expand Down Expand Up @@ -2633,7 +2636,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
if ( !styleString.isEmpty() )
{
OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
if ( ! writeFeature( mLayer, ogrFeature ) )
if ( !writeFeature( mLayer, ogrFeature ) )
{
++nErrors;
}
Expand Down

0 comments on commit 8e2b791

Please sign in to comment.