Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Address PR comments - part 2
  • Loading branch information
elpaso committed Jul 7, 2021
1 parent 78a42cf commit 878b243
Show file tree
Hide file tree
Showing 18 changed files with 141 additions and 70 deletions.
6 changes: 3 additions & 3 deletions python/core/auto_additions/qgis.py
Expand Up @@ -315,11 +315,11 @@
# --
Qgis.VectorExportResult.baseClass = Qgis
# monkey patching scoped based enum
Qgis.SqlLayerDefinitionCapability.Filter.__doc__ = "SQL layer definition supports filter"
Qgis.SqlLayerDefinitionCapability.SubsetStringFilter.__doc__ = "SQL layer definition supports subset string filter"
Qgis.SqlLayerDefinitionCapability.GeometryColumn.__doc__ = "SQL layer definition supports geometry column"
Qgis.SqlLayerDefinitionCapability.PrimaryKeys.__doc__ = "SQL layer definition supports primary keys"
Qgis.SqlLayerDefinitionCapability.SelectAtId.__doc__ = "SQL layer definition supports disabling select at id"
Qgis.SqlLayerDefinitionCapability.__doc__ = 'SqlLayerDefinitionCapability enum lists the arguments supported by the provider when creating SQL query layers.\n\n.. versionadded:: 3.22\n\n' + '* ``Filter``: ' + Qgis.SqlLayerDefinitionCapability.Filter.__doc__ + '\n' + '* ``GeometryColumn``: ' + Qgis.SqlLayerDefinitionCapability.GeometryColumn.__doc__ + '\n' + '* ``PrimaryKeys``: ' + Qgis.SqlLayerDefinitionCapability.PrimaryKeys.__doc__ + '\n' + '* ``SelectAtId``: ' + Qgis.SqlLayerDefinitionCapability.SelectAtId.__doc__
Qgis.SqlLayerDefinitionCapability.UnstableFeatureIds.__doc__ = "SQL layer definition supports disabling select at id"
Qgis.SqlLayerDefinitionCapability.__doc__ = 'SqlLayerDefinitionCapability enum lists the arguments supported by the provider when creating SQL query layers.\n\n.. versionadded:: 3.22\n\n' + '* ``SubsetStringFilter``: ' + Qgis.SqlLayerDefinitionCapability.SubsetStringFilter.__doc__ + '\n' + '* ``GeometryColumn``: ' + Qgis.SqlLayerDefinitionCapability.GeometryColumn.__doc__ + '\n' + '* ``PrimaryKeys``: ' + Qgis.SqlLayerDefinitionCapability.PrimaryKeys.__doc__ + '\n' + '* ``UnstableFeatureIds``: ' + Qgis.SqlLayerDefinitionCapability.UnstableFeatureIds.__doc__
# --
Qgis.SqlLayerDefinitionCapability.baseClass = Qgis
# monkey patching scoped based enum
Expand Down
Expand Up @@ -91,7 +91,7 @@ Returns the number of fetched rows.

long long rowCount( ) const;
%Docstring
Returns the number of rows returned by a SELECT query or -1 if unknown
Returns the number of rows returned by a SELECT query or Qgis.FeatureCountState.UnknownCount if unknown.

.. seealso:: :py:func:`fetchedRowCount`
%End
Expand Down Expand Up @@ -125,6 +125,16 @@ Returns the number of rows returned by a SELECT query or -1 if unknown



double queryExecutionTime( );
%Docstring
Returns the query execution time in milliseconds.
%End

void setQueryExecutionTime( double queryExecutionTime );
%Docstring
Sets the query execution time to ``queryExecutionTime`` milliseconds.
%End


};

Expand All @@ -135,7 +145,7 @@ Returns the number of rows returned by a SELECT query or -1 if unknown
QString layerName; //!< Optional name for the new layer
QStringList primaryKeyColumns; //!< List of primary key column names
QString geometryColumn; //!< Name of the geometry column
bool disableSelectAtId; //!< If SelectAtId is disabled (default is false), not all data providers support this feature: check support with SqlLayerDefinitionCapability::SelectAtId capability
bool disableSelectAtId;
};

struct TableProperty
Expand Down Expand Up @@ -462,7 +472,7 @@ Renames a raster table with given ``schema`` (schema is ignored if not supported
%Docstring
Creates a new schema with the specified ``name``.

:raises QgsProviderConnectionException:
:raises QgsProviderConnectionException: if any errors are encountered.
%End

virtual void dropSchema( const QString &name, bool force = false ) const throw( QgsProviderConnectionException );
Expand Down Expand Up @@ -523,7 +533,7 @@ Raises a :py:class:`QgsProviderConnectionException` if any errors are encountere

it is responsibility of the caller to handle open layers and registry entries.

:raises QgsProviderConnectionException:
:raises QgsProviderConnectionException: if any errors are encountered.
%End

virtual QList<QList<QVariant>> executeSql( const QString &sql, QgsFeedback *feedback = 0 ) const throw( QgsProviderConnectionException );
Expand All @@ -538,9 +548,8 @@ Executes raw ``sql`` and returns the (possibly empty) list of results in a multi
virtual QgsVectorLayer *createSqlVectorLayer( const SqlVectorLayerOptions &options ) const throw( QgsProviderConnectionException ) /Factory/;
%Docstring
Creates and returns a (possibly invalid) vector layer based on the ``sql`` statement and optional ``options``.
Raises a :py:class:`QgsProviderConnectionException` if any errors are encountered or if SQL layer creation is not supported.

:raises QgsProviderConnectionException:
:raises QgsProviderConnectionException: if any errors are encountered or if SQL layer creation is not supported.

.. versionadded:: 3.22
%End
Expand Down Expand Up @@ -638,7 +647,7 @@ Returns the fields of a ``table`` and ``schema``.
behavior when the layer does not expose all fields (GPKG for example hides geometry
and primary key column).

:raises QgsProviderConnectionException:
:raises QgsProviderConnectionException: if any errors are encountered.

.. versionadded:: 3.16
%End
Expand All @@ -647,7 +656,7 @@ Returns the fields of a ``table`` and ``schema``.
%Docstring
Returns a list of native types supported by the connection.

:raises QgsProviderConnectionException:
:raises QgsProviderConnectionException: if any errors are encountered.

.. versionadded:: 3.16
%End
Expand Down
8 changes: 4 additions & 4 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -228,12 +228,11 @@ The development version

enum class SqlLayerDefinitionCapability
{
Filter,
SubsetStringFilter,
GeometryColumn,
PrimaryKeys,
SelectAtId
UnstableFeatureIds
};

typedef QFlags<Qgis::SqlLayerDefinitionCapability> SqlLayerDefinitionCapabilities;


Expand All @@ -250,7 +249,6 @@ The development version
Identifier
};


enum class DriveType
{
Unknown,
Expand Down Expand Up @@ -387,6 +385,8 @@ QFlags<Qgis::BrowserItemCapability> operator|(Qgis::BrowserItemCapability f1, QF

QFlags<Qgis::SublayerQueryFlag> operator|(Qgis::SublayerQueryFlag f1, QFlags<Qgis::SublayerQueryFlag> f2);

QFlags<Qgis::SqlLayerDefinitionCapability> operator|(Qgis::SqlLayerDefinitionCapability f1, QFlags<Qgis::SqlLayerDefinitionCapability> f2);




Expand Down
11 changes: 7 additions & 4 deletions python/core/auto_generated/qgsqueryresultmodel.sip.in
Expand Up @@ -65,7 +65,7 @@ Returns the query result

void rowsReady( const QList<QList<QVariant> > &rows );
%Docstring
Triggered when ``newRows`` have been fetched and can be added to the model
Triggered when ``newRows`` have been fetched and can be added to the model.
%End

void cancel();
Expand All @@ -78,14 +78,17 @@ Cancels the row fetching.

void fetchingComplete();
%Docstring
Emitted when all rows have been fetched or when the fetching has been stopped (canceled)
Emitted when rows have been fetched (all of them or a batch if `maxRows` was passed to :py:func:`~QgsQueryResultModel.fetchMoreRows` )
or when the fetching has been stopped (canceled).

.. seealso:: :py:func:`fetchMoreRows`
%End

void fetchMoreRows( qlonglong maxRows );
%Docstring
Emitted when more rows are requested
Emitted when more rows are requested.

:param maxRows: the number of rows that will be fetched
:param maxRows: the number of rows that will be fetched.
%End

void fetchingStarted();
Expand Down
4 changes: 2 additions & 2 deletions src/app/browser/qgsinbuiltdataitemproviders.cpp
Expand Up @@ -1065,7 +1065,7 @@ void QgsDatabaseItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *
// SQL dialog
if ( std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn( item->databaseConnection() ); conn && conn->capabilities().testFlag( QgsAbstractDatabaseProviderConnection::Capability::ExecuteSql ) )
{
QAction *sqlAction = new QAction( QObject::tr( "Run SQL command" ), menu );
QAction *sqlAction = new QAction( QObject::tr( "Execute SQL …" ), menu );

QObject::connect( sqlAction, &QAction::triggered, item, [ item, context ]
{
Expand All @@ -1082,7 +1082,7 @@ void QgsDatabaseItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *

QgsDialog dialog;
dialog.setObjectName( QStringLiteral( "SQLCommandsDialog" ) );
dialog.setWindowTitle( tr( "%1 — Run SQL Commands" ).arg( item->name() ) );
dialog.setWindowTitle( tr( "%1 — Execute SQL" ).arg( item->name() ) );

// If this is a layer item (or below the hierarchy) we can pre-set the query to something
// meaningful
Expand Down
14 changes: 12 additions & 2 deletions src/core/providers/ogr/qgsgeopackageproviderconnection.cpp
Expand Up @@ -22,13 +22,16 @@
#include "qgsogrprovider.h"
#include "qgsmessagelog.h"
#include "qgsproviderregistry.h"
#include "qgsprovidermetadata.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"
#include "qgsfeedback.h"

#include <QTextCodec>
#include <QRegularExpression>

#include <chrono>

///@cond PRIVATE

QgsGeoPackageProviderConnection::QgsGeoPackageProviderConnection( const QString &name )
Expand Down Expand Up @@ -176,7 +179,11 @@ void QgsGeoPackageProviderConnection::renameVectorTable( const QString &schema,

QgsVectorLayer *QgsGeoPackageProviderConnection::createSqlVectorLayer( const QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions &options ) const
{
return new QgsVectorLayer( QStringLiteral( "%1|subset=%2" ).arg( uri(), options.sql ), options.layerName.isEmpty() ? QStringLiteral( "QueryLayer" ) : options.layerName, providerKey() );
QgsProviderMetadata *providerMetadata { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
Q_ASSERT( providerMetadata );
QMap<QString, QVariant> decoded = providerMetadata->decodeUri( uri() );
decoded[ QStringLiteral( "subset" ) ] = options.sql;
return new QgsVectorLayer( providerMetadata->encodeUri( decoded ), options.layerName.isEmpty() ? QStringLiteral( "QueryLayer" ) : options.layerName, providerKey() );
}

QgsAbstractDatabaseProviderConnection::QueryResult QgsGeoPackageProviderConnection::execSql( const QString &sql, QgsFeedback *feedback ) const
Expand Down Expand Up @@ -381,7 +388,7 @@ void QgsGeoPackageProviderConnection::setDefaultCapabilities()
};
mSqlLayerDefinitionCapabilities =
{
Qgis::SqlLayerDefinitionCapability::Filter,
Qgis::SqlLayerDefinitionCapability::SubsetStringFilter,
Qgis::SqlLayerDefinitionCapability::PrimaryKeys,
Qgis::SqlLayerDefinitionCapability::GeometryColumn,
};
Expand All @@ -405,14 +412,17 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsGeoPackageProviderConnecti
return QgsAbstractDatabaseProviderConnection::QueryResult();
}

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
OGRLayerH ogrLayer( GDALDatasetExecuteSQL( hDS.get(), sql.toUtf8().constData(), nullptr, nullptr ) );
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

// Read fields
if ( ogrLayer )
{

auto iterator = std::make_shared<QgsGeoPackageProviderResultIterator>( std::move( hDS ), ogrLayer );
QgsAbstractDatabaseProviderConnection::QueryResult results( iterator );
results.setQueryExecutionTime( std::chrono::duration_cast<std::chrono::milliseconds>( end - begin ).count() );

gdal::ogr_feature_unique_ptr fet;
if ( fet.reset( OGR_L_GetNextFeature( ogrLayer ) ), fet )
Expand Down
10 changes: 10 additions & 0 deletions src/core/providers/qgsabstractdatabaseproviderconnection.cpp
Expand Up @@ -1467,6 +1467,16 @@ QgsAbstractDatabaseProviderConnection::QueryResult::QueryResult( std::shared_ptr
: mResultIterator( iterator )
{}

double QgsAbstractDatabaseProviderConnection::QueryResult::queryExecutionTime()
{
return mQueryExecutionTime;
}

void QgsAbstractDatabaseProviderConnection::QueryResult::setQueryExecutionTime( double queryExecutionTime )
{
mQueryExecutionTime = queryExecutionTime;
}


QVariantList QgsAbstractDatabaseProviderConnection::QueryResult::QueryResultIterator::nextRow()
{
Expand Down
27 changes: 19 additions & 8 deletions src/core/providers/qgsabstractdatabaseproviderconnection.h
Expand Up @@ -120,7 +120,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
long long fetchedRowCount( ) const;

/**
* Returns the number of rows returned by a SELECT query or -1 if unknown
* Returns the number of rows returned by a SELECT query or Qgis::FeatureCountState::UnknownCount if unknown.
*
* \see fetchedRowCount()
*/
Expand Down Expand Up @@ -206,12 +206,24 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
*/
QueryResult( ) = default SIP_SKIP;

/**
* Returns the query execution time in milliseconds.
*/
double queryExecutionTime( );

/**
* Sets the query execution time to \a queryExecutionTime milliseconds.
*/
void setQueryExecutionTime( double queryExecutionTime );

///@endcond private

private:

mutable std::shared_ptr<QueryResultIterator> mResultIterator;
QStringList mColumns;
//! Query execution time in milliseconds
double mQueryExecutionTime = 0;

};

Expand All @@ -228,7 +240,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
QString layerName; //!< Optional name for the new layer
QStringList primaryKeyColumns; //!< List of primary key column names
QString geometryColumn; //!< Name of the geometry column
bool disableSelectAtId; //!< If SelectAtId is disabled (default is false), not all data providers support this feature: check support with SqlLayerDefinitionCapability::SelectAtId capability
bool disableSelectAtId = false; //!< If SelectAtId is disabled (default is false), not all data providers support this feature: check support with SqlLayerDefinitionCapability::SelectAtId capability
};

/**
Expand Down Expand Up @@ -596,7 +608,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
/**
* Creates a new schema with the specified \a name.
*
* \throws QgsProviderConnectionException
* \throws QgsProviderConnectionException if any errors are encountered.
*/
virtual void createSchema( const QString &name ) const SIP_THROW( QgsProviderConnectionException );

Expand Down Expand Up @@ -639,7 +651,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
* Renames a schema with the specified \a name.
* Raises a QgsProviderConnectionException if any errors are encountered.
* \note it is responsibility of the caller to handle open layers and registry entries.
* \throws QgsProviderConnectionException
* \throws QgsProviderConnectionException if any errors are encountered.
*/
virtual void renameSchema( const QString &name, const QString &newName ) const SIP_THROW( QgsProviderConnectionException );

Expand All @@ -653,8 +665,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv

/**
* Creates and returns a (possibly invalid) vector layer based on the \a sql statement and optional \a options.
* Raises a QgsProviderConnectionException if any errors are encountered or if SQL layer creation is not supported.
* \throws QgsProviderConnectionException
* \throws QgsProviderConnectionException if any errors are encountered or if SQL layer creation is not supported.
* \since QGIS 3.22
*/
virtual QgsVectorLayer *createSqlVectorLayer( const SqlVectorLayerOptions &options ) const SIP_THROW( QgsProviderConnectionException ) SIP_FACTORY;
Expand Down Expand Up @@ -748,15 +759,15 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
* choose to override this method for a greater efficiency of to overcome provider's
* behavior when the layer does not expose all fields (GPKG for example hides geometry
* and primary key column).
* \throws QgsProviderConnectionException
* \throws QgsProviderConnectionException if any errors are encountered.
* \since QGIS 3.16
*/
virtual QgsFields fields( const QString &schema, const QString &table ) const SIP_THROW( QgsProviderConnectionException );

/**
* Returns a list of native types supported by the connection.
*
* \throws QgsProviderConnectionException
* \throws QgsProviderConnectionException if any errors are encountered.
* \since QGIS 3.16
*/
virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const SIP_THROW( QgsProviderConnectionException ) = 0;
Expand Down
11 changes: 5 additions & 6 deletions src/core/qgis.h
Expand Up @@ -336,12 +336,11 @@ class CORE_EXPORT Qgis
*/
enum class SqlLayerDefinitionCapability : int
{
Filter = 1 << 1, //!< SQL layer definition supports filter
GeometryColumn = 1 << 2, //!< SQL layer definition supports geometry column
PrimaryKeys = 1 << 3, //!< SQL layer definition supports primary keys
SelectAtId = 1 << 4 //!< SQL layer definition supports disabling select at id
SubsetStringFilter = 1 << 1, //!< SQL layer definition supports subset string filter
GeometryColumn = 1 << 2, //!< SQL layer definition supports geometry column
PrimaryKeys = 1 << 3, //!< SQL layer definition supports primary keys
UnstableFeatureIds = 1 << 4 //!< SQL layer definition supports disabling select at id
};

Q_ENUM( SqlLayerDefinitionCapability )
Q_DECLARE_FLAGS( SqlLayerDefinitionCapabilities, SqlLayerDefinitionCapability )

Expand All @@ -364,7 +363,6 @@ class CORE_EXPORT Qgis
};
Q_ENUM( SqlKeywordCategory )


/**
* Drive types
* \since QGIS 3.20
Expand Down Expand Up @@ -583,6 +581,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SymbolFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SymbolPreviewFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::BrowserItemCapabilities )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SublayerQueryFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::SqlLayerDefinitionCapabilities )

// hack to workaround warnings when casting void pointers
// retrieved from QLibrary::resolve to function pointers.
Expand Down

0 comments on commit 878b243

Please sign in to comment.