Skip to content
Permalink
Browse files

[mssql] Fix conversion of time values

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 f3779589c62e7605d980a36d62b4214411342f92
Showing with 23 additions and 5 deletions.
  1. +20 −2 src/providers/mssql/qgsmssqlfeatureiterator.cpp
  2. +3 −3 tests/src/python/test_provider_mssql.py
@@ -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 );
}

@@ -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)))

0 comments on commit f377958

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