Skip to content

Commit 116ffc1

Browse files
committedJul 13, 2015
Add QgsAttributes::operator== that takes care of NULL variants
Fixes an issue that the postgres provider would return multiple subsequent features whose attributes only differ only in 0 vs. NULL.
1 parent b6194aa commit 116ffc1

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed
 

‎python/core/qgsfeature.sip

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11

22
typedef qint64 QgsFeatureId;
3-
4-
// key = field index, value = field value
53
typedef QMap<int, QVariant> QgsAttributeMap;
6-
74
typedef QVector<QVariant> QgsAttributes;
5+
86
// QgsAttributes is implemented as a Python list of Python objects.
97
%MappedType QgsAttributes /DocType="list-of-attributes"/
108
{
119
%TypeHeaderCode
12-
#include <qvector.h>
10+
#include <qgsfeature.h>
1311
%End
1412

1513
%ConvertFromTypeCode
@@ -53,7 +51,7 @@ typedef QVector<QVariant> QgsAttributes;
5351
return 1;
5452
}
5553

56-
QVector<QVariant> *qv = new QVector<QVariant>;
54+
QgsAttributes* qv = new QgsAttributes;
5755

5856
for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i)
5957
{

‎src/core/qgsfeature.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,50 @@ typedef int QgsFeatureId;
103103
// key = field index, value = field value
104104
typedef QMap<int, QVariant> QgsAttributeMap;
105105

106-
typedef QVector<QVariant> QgsAttributes;
106+
/**
107+
* A vector of attributes. Mostly equal to QVector<QVariant>.
108+
*/
109+
class CORE_EXPORT QgsAttributes : public QVector<QVariant>
110+
{
111+
public:
112+
QgsAttributes()
113+
: QVector<QVariant>()
114+
{}
115+
QgsAttributes( int size )
116+
: QVector<QVariant>( size )
117+
{}
118+
QgsAttributes( int size, const QVariant& v )
119+
: QVector<QVariant>( size, v )
120+
{}
121+
122+
QgsAttributes( const QVector<QVariant>& v )
123+
: QVector<QVariant>( v )
124+
{}
125+
126+
/**
127+
* @brief Compares two vectors of attributes.
128+
* They are considered equal if all their members contain the same value and NULL flag.
129+
* This was introduced because the default Qt implementation of QVariant comparison does not
130+
* handle NULL values for certain types (like int).
131+
*
132+
* @param v The attributes to compare
133+
* @return True if v is equal
134+
*/
135+
bool operator==( const QgsAttributes &v ) const
136+
{
137+
if ( size() != v.size() )
138+
return false;
139+
const QVariant* b = constData();
140+
const QVariant* i = b + size();
141+
const QVariant* j = v.constData() + size();
142+
while ( i != b )
143+
if ( !( *--i == *--j && i->isNull() == j->isNull() ) )
144+
return false;
145+
return true;
146+
}
147+
148+
inline bool operator!=( const QgsAttributes &v ) const { return !( *this == v ); }
149+
};
107150

108151
class QgsField;
109152

‎tests/src/python/test_qgsfeature.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def test_Attributes(self):
7070

7171
assert myAttributes == myExpectedAttributes, myMessage
7272

73-
@expectedFailure
7473
def test_SetAttribute(self):
7574
feat = QgsFeature()
7675
feat.initAttributes(1)

0 commit comments

Comments
 (0)
Please sign in to comment.