Skip to content

Commit

Permalink
Add QgsAttributes::operator== that takes care of NULL variants
Browse files Browse the repository at this point in the history
Fixes an issue that the postgres provider would return multiple subsequent
features whose attributes only differ only in 0 vs. NULL.
  • Loading branch information
m-kuhn committed Jul 13, 2015
1 parent 6d2e112 commit b180dec
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
8 changes: 3 additions & 5 deletions python/core/qgsfeature.sip
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@

typedef qint64 QgsFeatureId;

// key = field index, value = field value
typedef QMap<int, QVariant> QgsAttributeMap;

typedef QVector<QVariant> QgsAttributes;

// QgsAttributes is implemented as a Python list of Python objects.
%MappedType QgsAttributes /DocType="list-of-attributes"/
{
%TypeHeaderCode
#include <qvector.h>
#include <qgsfeature.h>
%End

%ConvertFromTypeCode
Expand Down Expand Up @@ -53,7 +51,7 @@ typedef QVector<QVariant> QgsAttributes;
return 1;
}

QVector<QVariant> *qv = new QVector<QVariant>;
QgsAttributes* qv = new QgsAttributes;

for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i)
{
Expand Down
45 changes: 44 additions & 1 deletion src/core/qgsfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,50 @@ typedef int QgsFeatureId;
// key = field index, value = field value
typedef QMap<int, QVariant> QgsAttributeMap;

typedef QVector<QVariant> QgsAttributes;
/**
* A vector of attributes. Mostly equal to QVector<QVariant>.
*/
class CORE_EXPORT QgsAttributes : public QVector<QVariant>
{
public:
QgsAttributes()
: QVector<QVariant>()
{}
QgsAttributes( int size )
: QVector<QVariant>( size )
{}
QgsAttributes( int size, const QVariant& v )
: QVector<QVariant>( size, v )
{}

QgsAttributes( const QVector<QVariant>& v )
: QVector<QVariant>( v )
{}

/**
* @brief Compares two vectors of attributes.
* They are considered equal if all their members contain the same value and NULL flag.
* This was introduced because the default Qt implementation of QVariant comparison does not
* handle NULL values for certain types (like int).
*
* @param v The attributes to compare
* @return True if v is equal
*/
bool operator==( const QgsAttributes &v ) const
{
if ( size() != v.size() )
return false;
const QVariant* b = constData();
const QVariant* i = b + size();
const QVariant* j = v.constData() + size();
while ( i != b )
if ( !( *--i == *--j && i->isNull() == j->isNull() ) )
return false;
return true;
}

inline bool operator!=( const QgsAttributes &v ) const { return !( *this == v ); }
};

class QgsField;

Expand Down
1 change: 0 additions & 1 deletion tests/src/python/test_qgsfeature.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ def test_Attributes(self):

assert myAttributes == myExpectedAttributes, myMessage

@expectedFailure
def test_SetAttribute(self):
feat = QgsFeature()
feat.initAttributes(1)
Expand Down

0 comments on commit b180dec

Please sign in to comment.