Skip to content

Commit

Permalink
Implement QgsHanaProviderConnection::execSql
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanuhrig committed Jan 9, 2021
1 parent a090f63 commit 45ae4c6
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 52 deletions.
91 changes: 42 additions & 49 deletions src/providers/hana/qgshanaproviderconnection.cpp
Expand Up @@ -27,6 +27,23 @@

#include "odbc/PreparedStatement.h"

QgsHanaProviderResultIterator::QgsHanaProviderResultIterator( QgsHanaResultSetRef&& resultSet )
: mResultSet( std::move( resultSet ) )
, mNumColumns( mResultSet->getMetadata().getColumnCount() )
, mNextRow( mResultSet->next() )
{}

QVariantList QgsHanaProviderResultIterator::nextRow()
{
QVariantList ret;
if ( !mNextRow )
return ret;
for ( unsigned short i = 1; i <= mNumColumns; ++i )
ret.push_back( mResultSet->getValue( i ) );
mNextRow = mResultSet->next();
return ret;
}

QgsHanaProviderConnection::QgsHanaProviderConnection( const QString &name )
: QgsAbstractDatabaseProviderConnection( name )
{
Expand Down Expand Up @@ -203,94 +220,70 @@ void QgsHanaProviderConnection::renameSchema( const QString &name, const QString
.arg( QgsHanaUtils::quotedIdentifier( name ), QgsHanaUtils::quotedIdentifier( newName ) ) );
}

QList<QVariantList> QgsHanaProviderConnection::executeSql( const QString &sql, QgsFeedback *feedback ) const
QgsAbstractDatabaseProviderConnection::QueryResult QgsHanaProviderConnection::execSql( const QString &sql, QgsFeedback *feedback ) const
{
checkCapability( Capability::ExecuteSql );

// Check feedback first!
if ( feedback && feedback->isCanceled() )
return QList<QVariantList>();
return QueryResult( std::make_shared<QgsHanaEmptyProviderResultIterator>() );

const QgsDataSourceUri dsUri { uri() };
QgsHanaConnectionRef conn( dsUri );
if ( conn.isNull() )
throw QgsProviderConnectionException( QObject::tr( "Connection failed: %1" ).arg( uri() ) );

if ( feedback && feedback->isCanceled() )
return QList<QVariantList>();
return QueryResult( std::make_shared<QgsHanaEmptyProviderResultIterator>() );

bool isQuery = false;

try
{
odbc::PreparedStatementRef stmt = conn->prepareStatement( sql );
isQuery = stmt->getMetaDataUnicode()->getColumnCount() > 0;
}
catch ( const QgsHanaException &ex )
{
throw QgsProviderConnectionException( ex.what() );
}

if ( isQuery )
return executeSqlQuery( *conn, sql, feedback );
else
{
executeSqlStatement( *conn, sql );
return QList<QVariantList>();
}
}

QList<QVariantList> QgsHanaProviderConnection::executeSqlQuery( QgsHanaConnection &conn, const QString &sql, QgsFeedback *feedback ) const
{
QList<QVariantList> results;

try
{
QgsHanaResultSetRef resultSet = conn.executeQuery( sql );
const unsigned short nColumns = resultSet->getMetadata().getColumnCount();
while ( resultSet->next() )
if ( isQuery )
{
if ( feedback && feedback->isCanceled() )
break;

QVariantList row;
for ( unsigned short i = 1; i <= nColumns; ++i )
row.push_back( resultSet->getValue( i ) );
results.push_back( row );
QgsHanaResultSetRef rs = conn->executeQuery( sql );
odbc::ResultSetMetaDataUnicode &md = rs->getMetadata();
QueryResult ret( std::make_shared<QgsHanaProviderResultIterator>( std::move( rs ) ) );
unsigned short numColumns = md.getColumnCount();
for ( unsigned short i = 1; i <= numColumns; ++i )
ret.appendColumn( QgsHanaUtils::toQString( md.getColumnName( i ) ) );
ret.setRowCount( -1 );
return ret;
}
else
{
conn->execute( sql );
conn->commit();
return QueryResult( std::make_shared<QgsHanaEmptyProviderResultIterator>() );
}
resultSet->close();
}
catch ( const QgsHanaException &ex )
{
throw QgsProviderConnectionException( ex.what() );
}

return results;
}

void QgsHanaProviderConnection::executeSqlStatement( QgsHanaConnection &conn, const QString &sql ) const
void QgsHanaProviderConnection::executeSqlStatement( const QString &sql ) const
{
const QgsDataSourceUri dsUri { uri() };
QgsHanaConnectionRef conn( dsUri );
if ( conn.isNull() )
throw QgsProviderConnectionException( QObject::tr( "Connection failed: %1" ).arg( uri() ) );
try
{
conn.execute( sql );
conn.commit();
conn->execute( sql );
conn->commit();
}
catch ( const QgsHanaException &ex )
{
throw QgsProviderConnectionException( ex.what() );
}
}

void QgsHanaProviderConnection::executeSqlStatement( const QString &sql ) const
{
const QgsDataSourceUri dsUri { uri() };
QgsHanaConnectionRef conn( dsUri );
if ( conn.isNull() )
throw QgsProviderConnectionException( QObject::tr( "Connection failed: %1" ).arg( uri() ) );

executeSqlStatement( *conn, sql );
}

QList<QgsHanaProviderConnection::TableProperty> QgsHanaProviderConnection::tables( const QString &schema, const TableFlags &flags ) const
{
checkCapability( Capability::Tables );
Expand Down
23 changes: 20 additions & 3 deletions src/providers/hana/qgshanaproviderconnection.h
Expand Up @@ -19,6 +19,25 @@

#include "qgsabstractdatabaseproviderconnection.h"
#include "qgshanaconnection.h"
#include "qgshanaresultset.h"

struct QgsHanaEmptyProviderResultIterator: public QgsAbstractDatabaseProviderConnection::QueryResult::QueryResultIterator
{
QVariantList nextRow() override { return QVariantList(); }
bool hasNextRow() const override { return false; }
};

struct QgsHanaProviderResultIterator: public QgsAbstractDatabaseProviderConnection::QueryResult::QueryResultIterator
{
QgsHanaProviderResultIterator( QgsHanaResultSetRef&& resultSet );
QVariantList nextRow() override;
bool hasNextRow() const override { return mNextRow; }

private:
QgsHanaResultSetRef mResultSet;
unsigned short mNumColumns = 0;
bool mNextRow = false;
};

class QgsHanaProviderConnection : public QgsAbstractDatabaseProviderConnection
{
Expand All @@ -40,7 +59,7 @@ class QgsHanaProviderConnection : public QgsAbstractDatabaseProviderConnection
void createSchema( const QString &name ) const override;
void dropSchema( const QString &name, bool force = false ) const override;
void renameSchema( const QString &name, const QString &newName ) const override;
QList<QVariantList> executeSql( const QString &sql, QgsFeedback *feedback = nullptr ) const override;
QueryResult execSql( const QString &sql, QgsFeedback *feedback = nullptr ) const override;
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tables( const QString &schema,
const TableFlags &flags = TableFlags() ) const override;
QStringList schemas( ) const override;
Expand All @@ -50,8 +69,6 @@ class QgsHanaProviderConnection : public QgsAbstractDatabaseProviderConnection
QList<QgsVectorDataProvider::NativeType> nativeTypes() const override;

private:
QList<QVariantList> executeSqlQuery( QgsHanaConnection &conn, const QString &sql, QgsFeedback *feedback = nullptr ) const;
void executeSqlStatement( QgsHanaConnection &conn, const QString &sql ) const;
void executeSqlStatement( const QString &sql ) const;
void setCapabilities();
void dropTable( const QString &schema, const QString &name ) const;
Expand Down

0 comments on commit 45ae4c6

Please sign in to comment.