Skip to content
Permalink
Browse files
Address PR comments
  • Loading branch information
elpaso committed Jul 6, 2021
1 parent af26206 commit 78a42cf7e89b080581e5a7b0433ed00e08ea6319
@@ -315,6 +315,27 @@
# --
Qgis.VectorExportResult.baseClass = Qgis
# monkey patching scoped based enum
Qgis.SqlLayerDefinitionCapability.Filter.__doc__ = "SQL layer definition supports 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.baseClass = Qgis
# monkey patching scoped based enum
Qgis.SqlKeywordCategory.Keyword.__doc__ = "SQL keyword"
Qgis.SqlKeywordCategory.Constant.__doc__ = "SQL constant"
Qgis.SqlKeywordCategory.Function.__doc__ = "SQL generic function"
Qgis.SqlKeywordCategory.Geospatial.__doc__ = "SQL spatial function"
Qgis.SqlKeywordCategory.Operator.__doc__ = "SQL operator"
Qgis.SqlKeywordCategory.Math.__doc__ = "SQL math function"
Qgis.SqlKeywordCategory.Aggregate.__doc__ = "SQL aggregate function"
Qgis.SqlKeywordCategory.String.__doc__ = "SQL string function"
Qgis.SqlKeywordCategory.Identifier.__doc__ = "SQL identifier"
Qgis.SqlKeywordCategory.__doc__ = 'SqlKeywordCategory enum represents the categories of the SQL keywords used by the SQL query editor.\n\n.. note::\n\n The category has currently no usage, but it was planned for future uses.\n\n.. versionadded:: 3.22\n\n' + '* ``Keyword``: ' + Qgis.SqlKeywordCategory.Keyword.__doc__ + '\n' + '* ``Constant``: ' + Qgis.SqlKeywordCategory.Constant.__doc__ + '\n' + '* ``Function``: ' + Qgis.SqlKeywordCategory.Function.__doc__ + '\n' + '* ``Geospatial``: ' + Qgis.SqlKeywordCategory.Geospatial.__doc__ + '\n' + '* ``Operator``: ' + Qgis.SqlKeywordCategory.Operator.__doc__ + '\n' + '* ``Math``: ' + Qgis.SqlKeywordCategory.Math.__doc__ + '\n' + '* ``Aggregate``: ' + Qgis.SqlKeywordCategory.Aggregate.__doc__ + '\n' + '* ``String``: ' + Qgis.SqlKeywordCategory.String.__doc__ + '\n' + '* ``Identifier``: ' + Qgis.SqlKeywordCategory.Identifier.__doc__
# --
Qgis.SqlKeywordCategory.baseClass = Qgis
# monkey patching scoped based enum
Qgis.DriveType.Unknown.__doc__ = "Unknown type"
Qgis.DriveType.Invalid.__doc__ = "Invalid path"
Qgis.DriveType.Removable.__doc__ = "Removable drive"
@@ -8,7 +8,3 @@
QgsAbstractDatabaseProviderConnection.GeometryColumnCapability.baseClass = QgsAbstractDatabaseProviderConnection
QgsAbstractDatabaseProviderConnection.GeometryColumnCapabilities.baseClass = QgsAbstractDatabaseProviderConnection
GeometryColumnCapabilities = QgsAbstractDatabaseProviderConnection # dirty hack since SIP seems to introduce the flags in module
QgsAbstractDatabaseProviderConnection.SqlLayerDefinitionCapability.baseClass = QgsAbstractDatabaseProviderConnection
QgsAbstractDatabaseProviderConnection.SqlLayerDefinitionCapabilities.baseClass = QgsAbstractDatabaseProviderConnection
SqlLayerDefinitionCapabilities = QgsAbstractDatabaseProviderConnection # dirty hack since SIP seems to introduce the flags in module
QgsAbstractDatabaseProviderConnection.SqlKeywordCategory.baseClass = QgsAbstractDatabaseProviderConnection
@@ -82,14 +82,14 @@ Returns the next result row or an empty row if there are no rows left.
.. seealso:: :py:func:`rewind`
%End

qlonglong fetchedRowCount( ) const;
long long fetchedRowCount( ) const;
%Docstring
Returns the number of fetched rows.

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

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

@@ -130,12 +130,12 @@ Returns the number of rows returned by a SELECT query or -1 if unknown

struct SqlVectorLayerOptions
{
QString sql; //! The SQL expression that defines the SQL (query) layer
QString filter; //! Additional subset string (provider-side filter), not all data providers support this feature: check support with SqlLayerDefinitionCapability::Filters capability
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
QString sql; //!< The SQL expression that defines the SQL (query) layer
QString filter; //!< Additional subset string (provider-side filter), not all data providers support this feature: check support with SqlLayerDefinitionCapability::Filters capability
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
};

struct TableProperty
@@ -353,31 +353,6 @@ This information is calculated from the geometry columns types.
typedef QFlags<QgsAbstractDatabaseProviderConnection::GeometryColumnCapability> GeometryColumnCapabilities;


enum SqlLayerDefinitionCapability
{
Filter,
GeometryColumn,
PrimaryKeys,
SelectAtId
};

typedef QFlags<QgsAbstractDatabaseProviderConnection::SqlLayerDefinitionCapability> SqlLayerDefinitionCapabilities;


enum SqlKeywordCategory
{
Keyword,
Constant,
Function,
Geospatial,
Operator,
Math,
Aggregate,
String,
Identifier
};


QgsAbstractDatabaseProviderConnection( const QString &name );
%Docstring
Creates a new connection with ``name`` by reading its configuration from the settings.
@@ -408,7 +383,7 @@ Returns connection geometry column capabilities (Z, M, SinglePart, Curves).
.. versionadded:: 3.16
%End

virtual SqlLayerDefinitionCapabilities sqlLayerDefinitionCapabilities();
virtual Qgis::SqlLayerDefinitionCapabilities sqlLayerDefinitionCapabilities();
%Docstring
Returns SQL layer definition capabilities (Filters, GeometryColumn, PrimaryKeys).

@@ -684,7 +659,7 @@ Returns the provider key.
.. versionadded:: 3.16
%End

virtual QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> sqlDictionary();
virtual QMap<Qgis::SqlKeywordCategory, QStringList> sqlDictionary();
%Docstring
Returns a dictionary of SQL keywords supported by the provider.
The default implementation returns an list of common reserved words under the
@@ -226,6 +226,31 @@ The development version
UserCanceled,
};

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

typedef QFlags<Qgis::SqlLayerDefinitionCapability> SqlLayerDefinitionCapabilities;


enum class SqlKeywordCategory
{
Keyword,
Constant,
Function,
Geospatial,
Operator,
Math,
Aggregate,
String,
Identifier
};


enum class DriveType
{
Unknown,
@@ -1063,75 +1063,70 @@ void QgsDatabaseItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *
}

// SQL dialog
if ( std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn( item->databaseConnection() ); conn )
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 );

if ( conn->capabilities().testFlag( QgsAbstractDatabaseProviderConnection::Capability::ExecuteSql ) )
QObject::connect( sqlAction, &QAction::triggered, item, [ item, context ]
{

QAction *sqlAction = new QAction( QObject::tr( "Run SQL command…" ), menu );

QObject::connect( sqlAction, &QAction::triggered, item, [ item, context ]
std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn2( item->databaseConnection() );
// This should never happen but let's play safe
if ( ! conn2 )
{
std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn2( item->databaseConnection() );
// This should never happen but let's play safe
if ( ! conn2 )
{
QgsMessageLog::logMessage( tr( "Connection to the database (%1) was lost." ).arg( item->name() ) );
return;
}
QgsMessageLog::logMessage( tr( "Connection to the database (%1) was lost." ).arg( item->name() ) );
return;
}

// Create the SQL dialog: this might become an independent class dialog in the future, for now
// we are still prototyping the features that this dialog will have.
// Create the SQL dialog: this might become an independent class dialog in the future, for now
// we are still prototyping the features that this dialog will have.

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

// If this is a layer item (or below the hierarchy) we can pre-set the query to something
// meaningful
QString sql;
// If this is a layer item (or below the hierarchy) we can pre-set the query to something
// meaningful
QString sql;

if ( qobject_cast<QgsLayerItem *>( item ) )
if ( qobject_cast<QgsLayerItem *>( item ) )
{
if ( conn2->capabilities().testFlag( QgsAbstractDatabaseProviderConnection::Capability::Schemas ) )
{
if ( conn2->capabilities().testFlag( QgsAbstractDatabaseProviderConnection::Capability::Schemas ) )
{
// Ok, this is gross: we lack a connection API for quoting properly...
sql = QStringLiteral( "SELECT * FROM %1.%2 LIMIT 10" ).arg( QgsSqliteUtils::quotedIdentifier( item->parent()->name() ), QgsSqliteUtils::quotedIdentifier( item->name() ) );
}
else
{
// Ok, this is gross: we lack a connection API for quoting properly...
sql = QStringLiteral( "SELECT * FROM %1 LIMIT 10" ).arg( QgsSqliteUtils::quotedIdentifier( item->name() ) );
}
// Ok, this is gross: we lack a connection API for quoting properly...
sql = QStringLiteral( "SELECT * FROM %1.%2 LIMIT 10" ).arg( QgsSqliteUtils::quotedIdentifier( item->parent()->name() ), QgsSqliteUtils::quotedIdentifier( item->name() ) );
}
else
{
// Ok, this is gross: we lack a connection API for quoting properly...
sql = QStringLiteral( "SELECT * FROM %1 LIMIT 10" ).arg( QgsSqliteUtils::quotedIdentifier( item->name() ) );
}
}

QgsGui::enableAutoGeometryRestore( &dialog );
QgsQueryResultWidget *widget { new QgsQueryResultWidget( &dialog, conn2.release() ) };
widget->setQuery( sql );
widget->layout()->setMargin( 0 );
dialog.layout()->addWidget( widget );
QgsGui::enableAutoGeometryRestore( &dialog );
QgsQueryResultWidget *widget { new QgsQueryResultWidget( &dialog, conn2.release() ) };
widget->setQuery( sql );
widget->layout()->setMargin( 0 );
dialog.layout()->addWidget( widget );

connect( widget, &QgsQueryResultWidget::createSqlVectorLayer, widget, [ item, context ]( const QString &, const QString &, const QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions & options )
connect( widget, &QgsQueryResultWidget::createSqlVectorLayer, widget, [ item, context ]( const QString &, const QString &, const QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions & options )
{
std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn3( item->databaseConnection() );
try
{
std::unique_ptr<QgsAbstractDatabaseProviderConnection> conn3( item->databaseConnection() );
try
{
QgsMapLayer *sqlLayer { conn3->createSqlVectorLayer( options ) };
QgsProject::instance()->addMapLayers( { sqlLayer } );
}
catch ( QgsProviderConnectionException &ex )
{
notify( QObject::tr( "New SQL Layer Creation Error" ), QObject::tr( "Error creating new SQL layer: %1" ).arg( ex.what() ), context, Qgis::MessageLevel::Critical );
}
QgsMapLayer *sqlLayer { conn3->createSqlVectorLayer( options ) };
QgsProject::instance()->addMapLayers( { sqlLayer } );
}
catch ( QgsProviderConnectionException &ex )
{
notify( QObject::tr( "New SQL Layer Creation Error" ), QObject::tr( "Error creating new SQL layer: %1" ).arg( ex.what() ), context, Qgis::MessageLevel::Critical );
}

} );
dialog.exec();
} );
dialog.exec();


} );
menu->addAction( sqlAction );
}
} );
menu->addAction( sqlAction );
}
}
}
@@ -381,9 +381,9 @@ void QgsGeoPackageProviderConnection::setDefaultCapabilities()
};
mSqlLayerDefinitionCapabilities =
{
SqlLayerDefinitionCapability::Filter,
SqlLayerDefinitionCapability::PrimaryKeys,
SqlLayerDefinitionCapability::GeometryColumn,
Qgis::SqlLayerDefinitionCapability::Filter,
Qgis::SqlLayerDefinitionCapability::PrimaryKeys,
Qgis::SqlLayerDefinitionCapability::GeometryColumn,
};
}

@@ -618,7 +618,7 @@ bool QgsGeoPackageProviderResultIterator::hasNextRowPrivate() const
return ! mNextRow.isEmpty();
}

qlonglong QgsGeoPackageProviderResultIterator::rowCountPrivate() const
long long QgsGeoPackageProviderResultIterator::rowCountPrivate() const
{
return mRowCount;
}
@@ -704,7 +704,7 @@ QgsFields QgsGeoPackageProviderConnection::fields( const QString &schema, const
return fieldList;
}

QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> QgsGeoPackageProviderConnection::sqlDictionary()
QMap<Qgis::SqlKeywordCategory, QStringList> QgsGeoPackageProviderConnection::sqlDictionary()
{
/*
* last_insert_rowid + list from: http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.0.html
@@ -728,7 +728,7 @@ QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> Qgs
return QgsAbstractDatabaseProviderConnection::sqlDictionary().unite(
{
{
QgsAbstractDatabaseProviderConnection::SqlKeywordCategory::Math, {
Qgis::SqlKeywordCategory::Math, {
// SQL math functions
QStringLiteral( "Abs( x [Double precision] )" ),
QStringLiteral( "Acos( x [Double precision] )" ),
@@ -758,7 +758,7 @@ QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> Qgs
}
},
{
QgsAbstractDatabaseProviderConnection::SqlKeywordCategory::Function, {
Qgis::SqlKeywordCategory::Function, {

// Specific
QStringLiteral( "last_insert_rowid" ),
@@ -846,7 +846,7 @@ QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> Qgs
}
},
{
QgsAbstractDatabaseProviderConnection::SqlKeywordCategory::Geospatial, {
Qgis::SqlKeywordCategory::Geospatial, {
// SQL functions reporting GEOS / LWGEOM errors and warnings
QStringLiteral( "GEOS_GetLastWarningMsg( [void] )" ),
QStringLiteral( "GEOS_GetLastErrorMsg( [void] )" ),
@@ -44,11 +44,11 @@ struct QgsGeoPackageProviderResultIterator: public QgsAbstractDatabaseProviderCo
QVariantList mNextRow;
QString mGeometryColumnName;
QString mPrimaryKeyColumnName;
qlonglong mRowCount = -1;
long long mRowCount = -1;

QVariantList nextRowPrivate() override;
bool hasNextRowPrivate() const override;
qlonglong rowCountPrivate() const override;
long long rowCountPrivate() const override;
QVariantList nextRowInternal();

};
@@ -81,7 +81,7 @@ class QgsGeoPackageProviderConnection : public QgsAbstractDatabaseProviderConnec
QIcon icon() const override;
QList<QgsVectorDataProvider::NativeType> nativeTypes() const override;
QgsFields fields( const QString &schema, const QString &table ) const override;
QMap<QgsAbstractDatabaseProviderConnection::SqlKeywordCategory, QStringList> sqlDictionary() override;
QMap<Qgis::SqlKeywordCategory, QStringList> sqlDictionary() override;

private:

0 comments on commit 78a42cf

Please sign in to comment.