Skip to content
Permalink
Browse files

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)
  • Loading branch information
jef-n committed Oct 11, 2015
1 parent a76c5f6 commit 945187c8f255fd86b5f0d0371650007cd9c47d30
Showing with 28 additions and 10 deletions.
  1. +13 −3 python/core/qgsfield.sip
  2. +7 −2 src/core/qgsfield.cpp
  3. +2 −2 src/core/qgsfield.h
  4. +6 −3 src/core/qgsvectorfilewriter.cpp
@@ -14,7 +14,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
@@ -171,6 +171,14 @@ public:
}; // class QgsField


/**
\ingroup core
Container of fields for a vector layer.

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)
*/

class QgsFields
{
@@ -192,6 +200,8 @@ class QgsFields
void clear();
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
bool appendExpressionField( const QgsField& field, int originIndex );
//! Remove a field with the given index
void remove( int fieldIdx );
//! Extend with fields from another QgsFields container
@@ -240,8 +250,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;

@@ -262,13 +262,18 @@ QList<QgsField> QgsFields::toList() const

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

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

return -1;
}

@@ -238,8 +238,8 @@ class CORE_EXPORT QgsFields
//! Look up field's index from name. Returns -1 on error
int indexFromName( const QString& name ) const { return mNameToIndex.value( name, -1 ); }

//! 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;

@@ -337,6 +337,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(

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

for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
{
@@ -445,7 +446,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
@@ -478,6 +480,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
}
}

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

@@ -1386,7 +1389,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
) );
@@ -2594,7 +2597,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
if ( !styleString.isEmpty() )
{
OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
if ( ! writeFeature( mLayer, ogrFeature ) )
if ( !writeFeature( mLayer, ogrFeature ) )
{
++nErrors;
}

0 comments on commit 945187c

Please sign in to comment.
You can’t perform that action at this time.