Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch '5605-types' of git://github.com/carolinux/QGIS into car…
…olinux-5605-types
  • Loading branch information
ccrook committed Mar 21, 2015
2 parents 250eb74 + 48591df commit 532599e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 18 deletions.
48 changes: 31 additions & 17 deletions src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
Expand Up @@ -245,7 +245,7 @@ QStringList QgsDelimitedTextProvider::readCsvtFieldTypes( QString filename, QStr
// not allowed in OGR CSVT files. Also doesn't care if int and string fields have

strTypeList = strTypeList.toLower();
QRegExp reTypeList( "^(?:\\s*(\\\"?)(?:integer|real|string|date|datetime|time)(?:\\(\\d+(?:\\.\\d+)?\\))?\\1\\s*(?:,|$))+" );
QRegExp reTypeList( "^(?:\\s*(\\\"?)(?:integer|real|long|longlong|string|date|datetime|time)(?:\\(\\d+(?:\\.\\d+)?\\))?\\1\\s*(?:,|$))+" );
if ( ! reTypeList.exactMatch( strTypeList ) )
{
// Looks like this was supposed to be a CSVT file, so report bad formatted string
Expand Down Expand Up @@ -407,6 +407,7 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )

QList<bool> isEmpty;
QList<bool> couldBeInt;
QList<bool> couldBeLongLong;
QList<bool> couldBeDouble;

while ( true )
Expand Down Expand Up @@ -561,27 +562,28 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
{

QString &value = parts[i];
if ( value.isEmpty() )
continue;

// try to convert attribute values to integer and double

while ( couldBeInt.size() <= i )
{
if ( value.isEmpty() ) {
isEmpty.append( true );
couldBeInt.append( false );
couldBeLongLong.append( false );
couldBeDouble.append( false );
continue;
}
if ( isEmpty[i] )
{
isEmpty[i] = false;
couldBeInt[i] = true;
couldBeDouble[i] = true;
}
// try to convert attribute values to integer, long and double
isEmpty.append( false );
// try all possible formats
couldBeInt.append( true );
couldBeLongLong.append( true );
couldBeDouble.append( true );
if ( couldBeInt[i] )
{
value.toInt( &couldBeInt[i] );
}

if ( couldBeLongLong[i] )
{
value.toLongLong( &couldBeLongLong[i] );
}
if ( couldBeDouble[i] )
{
if ( ! mDecimalPoint.isEmpty() )
Expand Down Expand Up @@ -620,6 +622,11 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
fieldType = QVariant::Int;
typeName = "integer";
}
else if ( csvtTypes[i] == "long" || csvtTypes[i]== "longlong" )
{
fieldType = QVariant::LongLong; //QVariant doesn't support long
typeName = "longlong";
}
else if ( csvtTypes[i] == "real" )
{
fieldType = QVariant::Double;
Expand All @@ -633,6 +640,11 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
fieldType = QVariant::Int;
typeName = "integer";
}
else if ( couldBeLongLong[i] )
{
fieldType = QVariant::LongLong;
typeName = "longlong";
}
else if ( couldBeDouble[i] )
{
fieldType = QVariant::Double;
Expand Down Expand Up @@ -997,12 +1009,14 @@ bool QgsDelimitedTextProvider::setSubsetString( QString subset, bool updateFeatu

if ( valid )
{

if ( mSubsetExpression ) delete mSubsetExpression;
QgsExpression * tmpSubsetExpression = mSubsetExpression;
// using a tmp pointer to avoid the pointer being dereferenced by
// a friend class after it has been freed but before it has been
// reassigned
QString previousSubset = mSubsetString;
mSubsetString = subset;
mSubsetExpression = expression;

if ( tmpSubsetExpression ) delete tmpSubsetExpression;
// Update the feature count and extents if requested

// Usage of updateFeatureCount is a bit painful, basically expect that it
Expand Down
8 changes: 7 additions & 1 deletion tests/src/python/test_qgsdelimitedtextprovider.py
Expand Up @@ -12,7 +12,7 @@
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

# This module provides unit test for the delimtied text provider. It uses data files in
# This module provides unit test for the delimited text provider. It uses data files in
# the testdata/delimitedtext directory.
#
# New tests can be created (or existing ones updated), but incorporating a createTest
Expand Down Expand Up @@ -650,6 +650,12 @@ def test_037_csvt_file_invalid_file(self):
requests=None
runTest(filename,requests,**params)

def test_038_long_type(self):
# Skip lines
filename='testlongs.csv'
params={'yField': 'lat', 'xField': 'lon', 'type': 'csv'}
requests=None
runTest(filename,requests,**params)

if __name__ == '__main__':
unittest.main()
51 changes: 51 additions & 0 deletions tests/src/python/test_qgsdelimitedtextprovider_wanted.py
Expand Up @@ -2165,3 +2165,54 @@ def test_037_csvt_file_invalid_file():
}
wanted['log']=[]
return wanted

def test_038_long_type():
wanted={}
filename="testlongs.csv"
wanted['uri']=u'file://{}?yField={}&xField={}&type={}'.format(filename,"lat","lon","csv")
wanted['fieldTypes']=['longlong', 'text', 'double', 'double', 'integer']
# long is casted as longlong because of QVariant limitation
wanted['data']={
2L: {
'id': u'9189304972279762602',
'a_long': u'9189304972279762602',
'lon': u'1.0',
'lat': u'1.0',
'an_integer': u'40',
'#geometry': 'POINT(1.0 1.0)',
'#fid':2L,
'description': 'line1'
},
3L: {
'id': u'9189304972279762602',
'a_long': u'9189304972279762602',
'lon': u'2.2',
'lat': u'2.5',
'an_integer': u'5',
'#geometry': 'POINT(2.2 2.5)',
'#fid':3L,
'description': 'line2'
},
4L: {
'id': u'-3123724580211819352',
'a_long': u'-3123724580211819352',
'lon': u'1.0',
'lat': u'1.0',
'an_integer': u'7',
'#geometry': 'POINT(1.0 1.0)',
'#fid':4L,
'description': 'line3'
},
5L: {
'id': u'-3',
'a_long': u'-3',
'lon': u'1.0',
'lat': u'1.0',
'an_integer': u'7',
'#geometry': 'POINT(1.0 1.0)',
'#fid':5L,
'description': 'line4'
}
}
wanted['log']=[]
return wanted
5 changes: 5 additions & 0 deletions tests/testdata/delimitedtext/testlongs.csv
@@ -0,0 +1,5 @@
a_long,description,lon,lat,an_integer
9189304972279762602,line1,1.0,1.0,40
9189304972279762602,line2,2.2,2.5,5
-3123724580211819352,line3,1.0,1.0,7
-3,line4,1.0,1.0,7

0 comments on commit 532599e

Please sign in to comment.