Skip to content

Commit

Permalink
Rework HANA data types to QVariant conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
Maksim Rylov authored and mrylov committed Dec 7, 2020
1 parent 48e3536 commit 16eb692
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 99 deletions.
18 changes: 9 additions & 9 deletions src/providers/hana/qgshanaprovider.cpp
Expand Up @@ -190,10 +190,10 @@ namespace
stmt->setDecimal( paramIndex, isNull ? Decimal() :
makeNullable<decimal>( value.toString().toStdString(), field.length(), field.precision() ) );
break;
case SQLDataTypes::Float:
case SQLDataTypes::Real:
stmt->setFloat( paramIndex, isNull ? Float() : Float( value.toFloat() ) );
break;
case SQLDataTypes::Float:
case SQLDataTypes::Double:
stmt->setDouble( paramIndex, isNull ? Double() : Double( value.toDouble() ) );
break;
Expand Down Expand Up @@ -1287,10 +1287,9 @@ void QgsHanaProvider::readAttributeFields()
fieldType = QVariant::Bool;
break;
case SQLDataTypes::TinyInt:
case SQLDataTypes::SmallInt:
// we try to make it more compatible with other providers
fieldType = QVariant::Int;
fieldType = QVariant::UInt;
break;
case SQLDataTypes::SmallInt:
case SQLDataTypes::Integer:
fieldType = isSigned ? QVariant::Int : QVariant::UInt;
break;
Expand All @@ -1310,7 +1309,7 @@ void QgsHanaProvider::readAttributeFields()
break;
case SQLDataTypes::Char:
case SQLDataTypes::WChar:
fieldType = QVariant::Char;
fieldType = ( fieldSize == 1 ) ? QVariant::Char : QVariant::String;
break;
case SQLDataTypes::VarChar:
case SQLDataTypes::WVarChar:
Expand Down Expand Up @@ -1363,11 +1362,12 @@ void QgsHanaProvider::readAttributeFields()
QString schemaName( rsmd->getSchemaName( i ).c_str() );
if ( schemaName.isEmpty() )
schemaName = mSchemaName;
ResultSetRef rsColumns = dmd->getColumns( nullptr, schemaName.toStdString().c_str(),
rsmd->getTableName( i ).c_str(), fieldName.toStdString().c_str() );
QString tableName( rsmd->getTableName( i ).c_str() );
if ( tableName.isEmpty() )
tableName = mTableName;
QgsHanaResultSetRef rsColumns = QgsHanaResultSet::getColumns( dmd, schemaName, tableName, fieldName );
if ( rsColumns->next() )
mDefaultValues.insert( mAttributeFields.size() - 1,
QgsHanaUtils::toVariant( rsColumns->getString( 13/*COLUMN_DEF*/ ), sqlType, isSigned ) );
mDefaultValues.insert( mAttributeFields.size() - 1, rsColumns->getValue( 13/*COLUMN_DEF*/ ) );
rsColumns->close();
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/providers/hana/qgshanaresultset.cpp
Expand Up @@ -14,6 +14,7 @@
* (at your option) any later version.
*
***************************************************************************/
#include "qgshanaexception.h"
#include "qgshanaresultset.h"
#include "qgshanautils.h"
#include "qgslogger.h"
Expand All @@ -37,6 +38,13 @@ QgsHanaResultSetRef QgsHanaResultSet::create( PreparedStatementRef &stmt )
return ret;
}

QgsHanaResultSetRef QgsHanaResultSet::getColumns( DatabaseMetaDataRef &metadata, const QString &schemaName, const QString &tableName, const QString &fieldName )
{
QgsHanaResultSetRef ret( new QgsHanaResultSet( metadata->getColumns( nullptr,
schemaName.toStdString().c_str(), tableName.toStdString().c_str(), fieldName.toStdString().c_str() ) ) );
return ret;
}

void QgsHanaResultSet::close()
{
mResultSet->close();
Expand Down Expand Up @@ -100,8 +108,11 @@ QVariant QgsHanaResultSet::getValue( unsigned short columnIndex )
return QgsHanaUtils::toVariant( mResultSet->getLong( columnIndex ) );
else
return QgsHanaUtils::toVariant( mResultSet->getULong( columnIndex ) );
case SQLDataTypes::Real:
return QgsHanaUtils::toVariant( mResultSet->getFloat( columnIndex ) );
case SQLDataTypes::Double:
case SQLDataTypes::Decimal:
case SQLDataTypes::Float:
case SQLDataTypes::Numeric:
return QgsHanaUtils::toVariant( mResultSet->getDouble( columnIndex ) );
case SQLDataTypes::Date:
Expand Down Expand Up @@ -137,7 +148,7 @@ QgsGeometry QgsHanaResultSet::getGeometry( unsigned short columnIndex )
return QgsGeometry();

if ( size > static_cast<size_t>( std::numeric_limits<int>::max() ) )
throw std::overflow_error( "Geometry size is larger than maximum integer value" );
throw QgsHanaException( "Geometry size is larger than maximum integer value" );

QByteArray wkbBytes( data, static_cast<int>( size ) );
QgsGeometry geom;
Expand Down
2 changes: 2 additions & 0 deletions src/providers/hana/qgshanaresultset.h
Expand Up @@ -25,6 +25,7 @@
#include <QString>
#include <QVariant>

#include "odbc/DatabaseMetaData.h"
#include "odbc/PreparedStatement.h"
#include "odbc/Statement.h"
#include "odbc/ResultSet.h"
Expand All @@ -43,6 +44,7 @@ class QgsHanaResultSet
public:
static QgsHanaResultSetRef create( PreparedStatementRef &stmt );
static QgsHanaResultSetRef create( StatementRef &stmt, const QString &sql );
static QgsHanaResultSetRef getColumns( DatabaseMetaDataRef &metadata, const QString &schemaName, const QString &tableName, const QString &fieldName );

void close();
bool next();
Expand Down
107 changes: 20 additions & 87 deletions src/providers/hana/qgshanautils.cpp
Expand Up @@ -15,6 +15,7 @@
*
***************************************************************************/
#include "qgsdatasourceuri.h"
#include "qgshanaexception.h"
#include "qgshanautils.h"

#include <QDate>
Expand Down Expand Up @@ -144,9 +145,9 @@ QVariant QgsHanaUtils::toVariant( const Byte &value )
QVariant QgsHanaUtils::toVariant( const UByte &value )
{
if ( value.isNull() )
return QVariant( QVariant::Char );
return QVariant( QVariant::UInt );
else
return QVariant( static_cast<int>( *value ) );
return QVariant( static_cast<uint>( *value ) );
}

QVariant QgsHanaUtils::toVariant( const Short &value )
Expand Down Expand Up @@ -197,14 +198,22 @@ QVariant QgsHanaUtils::toVariant( const ULong &value )
return QVariant( static_cast<qulonglong>( *value ) );
}

QVariant QgsHanaUtils::toVariant( const Double &value )
QVariant QgsHanaUtils::toVariant( const Float &value )
{
if ( value.isNull() )
return QVariant( QVariant::Double );
else
return QVariant( static_cast<double>( *value ) );
}

QVariant QgsHanaUtils::toVariant( const Double &value )
{
if ( value.isNull() )
return QVariant( QVariant::Double );
else
return QVariant( *value );
}

QVariant QgsHanaUtils::toVariant( const Date &value )
{
if ( value.isNull() )
Expand Down Expand Up @@ -238,77 +247,6 @@ QVariant QgsHanaUtils::toVariant( const String &value )
return QVariant( QString::fromUtf8( value->c_str() ) );
}

QVariant QgsHanaUtils::toVariant( const String &value, int type, bool isSigned )
{
bool isNull = value.isNull();
switch ( type )
{
case SQLDataTypes::Bit:
case SQLDataTypes::Boolean:
if ( isNull )
return QVariant( QVariant::Bool );
else
return QVariant( ( *value == "true" || *value == "1" ) ? true : false );
case SQLDataTypes::Integer:
case SQLDataTypes::TinyInt:
if ( isNull )
return QVariant( isSigned ? QVariant::Int : QVariant::UInt );
else
return QVariant( atoi( value->c_str() ) );
case SQLDataTypes::BigInt:
if ( isNull )
return QVariant( isSigned ? QVariant::LongLong : QVariant::ULongLong );
else
return QVariant( static_cast< qlonglong >( atoll( value->c_str() ) ) );
case SQLDataTypes::Numeric:
case SQLDataTypes::Double:
case SQLDataTypes::Decimal:
if ( isNull )
return QVariant( QVariant::Double );
else
return QVariant( stod( value->c_str() ) );
case SQLDataTypes::Float:
case SQLDataTypes::Real:
if ( isNull )
return QVariant( QVariant::Double );
else
return QVariant( stof( value->c_str() ) );
case SQLDataTypes::Char:
case SQLDataTypes::WChar:
if ( isNull )
return QVariant( QVariant::Char );
else
{
QString str = QString( value->c_str() );
if ( str.isEmpty() )
return QVariant( QVariant::Char );
return QVariant( str.at( 0 ) );
}
case SQLDataTypes::VarChar:
case SQLDataTypes::WVarChar:
case SQLDataTypes::LongVarChar:
case SQLDataTypes::WLongVarChar:
if ( isNull )
return QVariant( QVariant::String );
else
return QVariant( QString( value->c_str() ) );
case SQLDataTypes::Binary:
case SQLDataTypes::VarBinary:
return QVariant( QByteArray( value->c_str(), static_cast< int >( value->length() ) ) );
case SQLDataTypes::Date:
case SQLDataTypes::TypeDate:
return QVariant( QDate::fromString( QString( value->c_str() ) ) );
case SQLDataTypes::Time:
case SQLDataTypes::TypeTime:
return QVariant( QTime::fromString( QString( value->c_str() ) ) );
case SQLDataTypes::Timestamp:
case SQLDataTypes::TypeTimestamp:
return QVariant( QDateTime::fromString( QString( value->c_str() ) ) );
default:
return QVariant( QVariant::String );
}
}

QVariant QgsHanaUtils::toVariant( const NString &value )
{
if ( value.isNull() )
Expand All @@ -321,16 +259,11 @@ QVariant QgsHanaUtils::toVariant( const Binary &value )
{
if ( value.isNull() )
return QVariant( QVariant::ByteArray );
else
return QVariant( toQByteArray( value ) );
}

QByteArray QgsHanaUtils::toQByteArray( const Binary &value )
{
if ( value.isNull() )
return QByteArray();
else
return QByteArray( value->data(), static_cast<int>( value->size() ) );
if ( value->size() > static_cast<size_t>( std::numeric_limits<int>::max() ) )
throw QgsHanaException( "Binary size is larger than maximum integer value" );

return QByteArray( value->data(), static_cast<int>( value->size() ) );
}

QgsWkbTypes::Type QgsHanaUtils::toWkbType( const QString &hanaType )
Expand Down Expand Up @@ -437,15 +370,15 @@ bool QgsHanaUtils::convertField( QgsField &field )
}
else
{
if ( field.length() > 0 && field.precision() >= 0 )
fieldType = QStringLiteral( "DECIMAL(%1,%2)" ).arg( field.length(), field.precision() );
if ( fieldPrec > 0 )
fieldType = QStringLiteral( "DECIMAL(%1,%2)" ).arg( fieldSize, fieldPrec );
else
fieldType = QStringLiteral( "DECIMAL" );
}
break;
case QVariant::ByteArray:
if ( fieldSize > 0 )
fieldType = QStringLiteral( "BLOB(%1)" ).arg( QString::number( fieldSize ) );
if ( fieldSize > 1 && fieldSize <= 5000 )
fieldType = QStringLiteral( "VARBINARY(%1)" ).arg( QString::number( fieldSize ) );
else
fieldType = QStringLiteral( "BLOB" );
break;
Expand Down
3 changes: 1 addition & 2 deletions src/providers/hana/qgshanautils.h
Expand Up @@ -47,12 +47,12 @@ class QgsHanaUtils
static QVariant toVariant( const odbc::UInt &value );
static QVariant toVariant( const odbc::Long &value );
static QVariant toVariant( const odbc::ULong &value );
static QVariant toVariant( const odbc::Float &value );
static QVariant toVariant( const odbc::Double &value );
static QVariant toVariant( const odbc::Date &value );
static QVariant toVariant( const odbc::Time &value );
static QVariant toVariant( const odbc::Timestamp &value );
static QVariant toVariant( const odbc::String &value );
static QVariant toVariant( const odbc::String &value, int type, bool isSigned );
static QVariant toVariant( const odbc::NString &value );
static QVariant toVariant( const odbc::Binary &value );
template<typename T>
Expand All @@ -63,7 +63,6 @@ class QgsHanaUtils
else
return QVariant( *value );
}
static QByteArray toQByteArray( const odbc::Binary &value );

static QgsWkbTypes::Type toWkbType( const QString &hanaType );
static QVersionNumber toHANAVersion( const QString &dbVersion );
Expand Down

0 comments on commit 16eb692

Please sign in to comment.