Skip to content

Commit

Permalink
[mssql] Fix conversion of time values
Browse files Browse the repository at this point in the history
At least using the linux sql server driver, time fields are not
correctly automatically converted to QTime variants. Instead
they are returned as a raw byte array containing the value.

Add special handling to ensure that these time values are
read regardless.

(there's already a test in place for this, which was failing
on Linux)
  • Loading branch information
nyalldawson committed Oct 4, 2018
1 parent 0729653 commit f377958
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
22 changes: 20 additions & 2 deletions src/providers/mssql/qgsmssqlfeatureiterator.cpp
Expand Up @@ -321,10 +321,28 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature &feature )

for ( int i = 0; i < mAttributesToFetch.count(); i++ )
{
QVariant v = mQuery->value( i );
const QVariant originalValue = mQuery->value( i );
QgsField fld = mSource->mFields.at( mAttributesToFetch.at( i ) );
QVariant v = originalValue;
if ( v.type() != fld.type() )
v = QgsVectorDataProvider::convertValue( fld.type(), v.toString() );
v = QgsVectorDataProvider::convertValue( fld.type(), originalValue.toString() );

// second chance for time fields -- time fields are not correctly handled by sql server driver on linux (maybe win too?)
if ( v.isNull() && fld.type() == QVariant::Time && originalValue.isValid() && originalValue.type() == QVariant::ByteArray )
{
// time fields can be returned as byte arrays... woot
const QByteArray ba = originalValue.toByteArray();
if ( ba.length() >= 5 )
{
const int hours = ba.at( 0 );
const int mins = ba.at( 2 );
const int seconds = ba.at( 4 );
v = QTime( hours, mins, seconds );
if ( !v.isValid() ) // can't handle it
v = QVariant( QVariant::Time );
}
}

feature.setAttribute( mAttributesToFetch.at( i ), v );
}

Expand Down
6 changes: 3 additions & 3 deletions tests/src/python/test_provider_mssql.py
Expand Up @@ -74,13 +74,13 @@ def testDateTimeTypes(self):
f = next(vl.getFeatures(QgsFeatureRequest()))

date_idx = vl.fields().lookupField('date_field')
assert isinstance(f.attributes()[date_idx], QDate)
self.assertIsInstance(f.attributes()[date_idx], QDate)
self.assertEqual(f.attributes()[date_idx], QDate(2004, 3, 4))
time_idx = vl.fields().lookupField('time_field')
assert isinstance(f.attributes()[time_idx], QTime)
self.assertIsInstance(f.attributes()[time_idx], QTime)
self.assertEqual(f.attributes()[time_idx], QTime(13, 41, 52))
datetime_idx = vl.fields().lookupField('datetime_field')
assert isinstance(f.attributes()[datetime_idx], QDateTime)
self.assertIsInstance(f.attributes()[datetime_idx], QDateTime)
self.assertEqual(f.attributes()[datetime_idx], QDateTime(
QDate(2004, 3, 4), QTime(13, 41, 52)))

Expand Down

0 comments on commit f377958

Please sign in to comment.