Skip to content

Commit

Permalink
Rework QgsHanaConnection class
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 dfc08de commit 564420c
Show file tree
Hide file tree
Showing 12 changed files with 536 additions and 439 deletions.
369 changes: 268 additions & 101 deletions src/providers/hana/qgshanaconnection.cpp

Large diffs are not rendered by default.

34 changes: 19 additions & 15 deletions src/providers/hana/qgshanaconnection.h
Expand Up @@ -20,6 +20,7 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsdatasourceuri.h"
#include "qgshanatablemodel.h"
#include "qgshanaresultset.h"
#include "qgslogger.h"

#include "odbc/Forwards.h"
Expand All @@ -33,9 +34,20 @@ class QgsHanaConnection : public QObject
~QgsHanaConnection() override;

QString connInfo();
void disconnect();

bool dropTable( const QString &schemaName, const QString &tableName, QString *errMessage );
void execute( const QString &sql );
bool execute( const QString &sql, QString *errorMessage );
QgsHanaResultSetRef executeQuery( const QString &sql );
QgsHanaResultSetRef executeQuery( const QString &sql, const QVariantList &args );
size_t executeCountQuery( const QString &sql );
size_t executeCountQuery( const QString &sql, const QVariantList &args );
QVariant executeScalar( const QString &sql );
QVariant executeScalar( const QString &sql, const QVariantList &args );

odbc::PreparedStatementRef prepareStatement( const QString &sql );

void commit();
void rollback();

const QString &getDatabaseVersion();
const QString &getUserName();
Expand All @@ -48,35 +60,27 @@ class QgsHanaConnection : public QObject
QVector<QgsHanaSchemaProperty> getSchemas( const QString &ownerName );
QgsWkbTypes::Type getLayerGeometryType( const QgsHanaLayerProperty &layerProperty );
QString getColumnDataType( const QString &schemaName, const QString &tableName, const QString &columnName );

odbc::ConnectionRef &getNativeRef() { return mConnection; }
QgsHanaResultSetRef getColumns( const QString &schemaName, const QString &tableName, const QString &fieldName );

static QgsHanaConnection *createConnection( const QgsDataSourceUri &uri );
static QgsHanaConnection *createConnection( const QgsDataSourceUri &uri, QString *errorMessage );

static void setConnectionAttemptCanceled( bool value ) { sConnectionAttemptCanceled = value; }
static bool isConnectionAttemptCanceled() { return sConnectionAttemptCanceled; }
static QgsHanaConnection *createConnection( const QgsDataSourceUri &uri, bool *cancelled );
static QgsHanaConnection *createConnection( const QgsDataSourceUri &uri, bool *cancelled, QString *errorMessage );

static QStringList connectionList();

private:
explicit QgsHanaConnection( const QgsDataSourceUri &uri );
QgsHanaConnection( odbc::ConnectionRef connection, const QgsDataSourceUri &uri );

int getLayerSRID( const QgsHanaLayerProperty &layerProperty );
QStringList getLayerPrimaryeKeys( const QgsHanaLayerProperty &layerProperty );

static bool connect(
odbc::ConnectionRef &conn,
const QgsDataSourceUri &uri,
QString &errorMessage );
PreparedStatementRef createPreparedStatement( const QString &sql, const QVariantList &args );

private:
odbc::ConnectionRef mConnection;
QgsDataSourceUri mUri;
QString mDatabaseVersion;
QString mUserName;

static bool sConnectionAttemptCanceled;
};

class QgsHanaConnectionRef
Expand Down
6 changes: 5 additions & 1 deletion src/providers/hana/qgshanadataitemguiprovider.cpp
Expand Up @@ -19,6 +19,7 @@
#include "qgshanadataitemguiprovider.h"
#include "qgshananewconnection.h"
#include "qgshanaprovider.h"
#include "qgshanautils.h"
#include "qgsnewnamedialog.h"

#include <QInputDialog>
Expand Down Expand Up @@ -77,8 +78,11 @@ bool QgsHanaDataItemGuiProvider::deleteLayer( QgsLayerItem *item, QgsDataItemGui
if ( conn.isNull() )
return false;

QString sql = QStringLiteral( "DROP TABLE %1.%2" )
.arg( QgsHanaUtils::quotedIdentifier( layerInfo.schemaName ), QgsHanaUtils::quotedIdentifier( layerInfo.tableName ) );

QString errMessage;
bool res = conn->dropTable( layerInfo.schemaName, layerInfo.tableName, &errMessage );
bool res = conn->execute( sql, &errMessage );
if ( !res )
{
QMessageBox::warning( nullptr, tr( "Delete %1" ).arg( typeName ), errMessage );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/hana/qgshanaexception.h
Expand Up @@ -18,6 +18,7 @@
#define QGSHANAEXCEPTION_H

#include "qexception.h"
#include "qgslogger.h"
#include "qgshanautils.h"

class QgsHanaException final : public QException
Expand All @@ -26,6 +27,7 @@ class QgsHanaException final : public QException
explicit QgsHanaException( const char *what ) noexcept
: mMessage( QgsHanaUtils::formatErrorMessage( what ).toStdString() )
{
QgsDebugMsg( what );
}

void raise() const override { throw *this; }
Expand Down
99 changes: 42 additions & 57 deletions src/providers/hana/qgshanafeatureiterator.cpp
Expand Up @@ -26,11 +26,6 @@
#include "qgsmessagelog.h"
#include "qgssettings.h"

#include "odbc/Connection.h"
#include "odbc/Exception.h"
#include "odbc/PreparedStatement.h"
#include "odbc/ResultSet.h"

using namespace odbc;

static QString andWhereClauses( const QString &c1, const QString &c2 )
Expand All @@ -48,13 +43,13 @@ QgsHanaFeatureIterator::QgsHanaFeatureIterator(
bool ownSource,
const QgsFeatureRequest &request )
: QgsAbstractFeatureIteratorFromSource<QgsHanaFeatureSource>( source, ownSource, request )
, mConnRef( source->mUri )
, mConnection( source->mUri )
, mSrsExtent( source->mSrsExtent )
, mFidColumn( source->mFidColumn )
{
mClosed = true;

if ( mConnRef.isNull() )
if ( mConnection.isNull() )
{
iteratorClosed();
return;
Expand All @@ -75,16 +70,13 @@ QgsHanaFeatureIterator::QgsHanaFeatureIterator(

try
{
QString sql = buildSqlQuery( request );
PreparedStatementRef stmt = mConnRef->getNativeRef()->prepareStatement( QgsHanaUtils::toQueryString( sql ) );
mSqlQuery = sql;
mSqlQuery = buildSqlQuery( request );
mClosed = false;

rewind();
}
catch ( const odbc::Exception &ex )
catch ( const QgsHanaException & )
{
QgsDebugMsg( ex.what() );
iteratorClosed();
}
}
Expand All @@ -101,8 +93,7 @@ bool QgsHanaFeatureIterator::rewind()
return false;

mResultSet.reset();
PreparedStatementRef stmt = mConnRef->getNativeRef()->prepareStatement( QgsHanaUtils::toQueryString( mSqlQuery ) );
mResultSet = QgsHanaResultSet::create( stmt );
mResultSet = mConnection->executeQuery( mSqlQuery );
return true;
}

Expand All @@ -125,60 +116,54 @@ bool QgsHanaFeatureIterator::fetchFeature( QgsFeature &feature )
if ( mClosed )
return false;

try
{
if ( !mResultSet->next() )
return false;
if ( !mResultSet->next() )
return false;

feature.initAttributes( mSource->mFields.count() );
unsigned short paramIndex = 1;
feature.initAttributes( mSource->mFields.count() );
unsigned short paramIndex = 1;

// Read feature id
if ( !mFidColumn.isEmpty() )
{
QVariant id = mResultSet->getValue( paramIndex );
feature.setId( id.toLongLong() );
feature.setAttribute( 0, id );
++paramIndex;
}
else
{
feature.setId( 0u );
}
// Read feature id
if ( !mFidColumn.isEmpty() )
{
QVariant id = mResultSet->getValue( paramIndex );
feature.setId( id.toLongLong() );
feature.setAttribute( 0, id );
++paramIndex;
}
else
{
feature.setId( 0u );
}

// Read attributes
if ( mHasAttributes )
// Read attributes
if ( mHasAttributes )
{
Q_FOREACH ( int idx, mAttributesToFetch )
{
Q_FOREACH ( int idx, mAttributesToFetch )
{
feature.setAttribute( idx, mResultSet->getValue( paramIndex ) );
++paramIndex;
}
feature.setAttribute( idx, mResultSet->getValue( paramIndex ) );
++paramIndex;
}
}

// Read geometry
if ( mHasGeometryColumn )
{
QgsGeometry geom = mResultSet->getGeometry( paramIndex );
if ( !geom.isNull() )
feature.setGeometry( geom );
else
feature.clearGeometry();
}
// Read geometry
if ( mHasGeometryColumn )
{
QgsGeometry geom = mResultSet->getGeometry( paramIndex );
if ( !geom.isNull() )
feature.setGeometry( geom );
else
{
feature.clearGeometry();
}

feature.setValid( true );
feature.setFields( mSource->mFields ); // allow name-based attribute lookups
geometryToDestinationCrs( feature, mTransform );
}
catch ( const Exception &ex )
else
{
throw QgsHanaException( ex.what() );
feature.clearGeometry();
}

feature.setValid( true );
feature.setFields( mSource->mFields ); // allow name-based attribute lookups
geometryToDestinationCrs( feature, mTransform );


return true;
}

Expand Down Expand Up @@ -339,7 +324,7 @@ QString QgsHanaFeatureIterator::buildSqlQuery( const QgsFeatureRequest &request
QString sqlFilter;
// Set spatial filter
if ( !( filterRect.isNull() || filterRect.isEmpty() ) && mSource->isSpatial() && mHasGeometryColumn )
sqlFilter = getBBOXFilter( filterRect, QgsHanaUtils::toHANAVersion( mConnRef->getDatabaseVersion() ) );
sqlFilter = getBBOXFilter( filterRect, QgsHanaUtils::toHANAVersion( mConnection->getDatabaseVersion() ) );

if ( !mSource->mQueryWhereClause.isEmpty() )
sqlFilter = andWhereClauses( sqlFilter, mSource->mQueryWhereClause );
Expand Down
2 changes: 1 addition & 1 deletion src/providers/hana/qgshanafeatureiterator.h
Expand Up @@ -77,7 +77,7 @@ class QgsHanaFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsHa
QString getBBOXFilter( const QgsRectangle &bbox, const QVersionNumber &dbVersion ) const;

private:
QgsHanaConnectionRef mConnRef;
QgsHanaConnectionRef mConnection;
QgsHanaResultSetRef mResultSet;
QString mSqlQuery = QString( "" );
QgsRectangle mFilterRect;
Expand Down
2 changes: 1 addition & 1 deletion src/providers/hana/qgshananewconnection.cpp
Expand Up @@ -323,7 +323,7 @@ void QgsHanaNewConnection::testConnection()
readSettingsFromControls( settings );

QString errorMsg;
unique_ptr<QgsHanaConnection> conn( QgsHanaConnection::createConnection( settings.toDataSourceUri(), &errorMsg ) );
unique_ptr<QgsHanaConnection> conn( QgsHanaConnection::createConnection( settings.toDataSourceUri(), nullptr, &errorMsg ) );

if ( conn )
bar->pushMessage( tr( "Connection to the server was successful." ), Qgis::Info );
Expand Down

0 comments on commit 564420c

Please sign in to comment.