Skip to content
Permalink
Browse files

[feature][processing] Add dedicated parameter type for database conne…

…ctions

Allows selection from the registered database connections for a specific
database provider type (the provider must implement the connections API)
  • Loading branch information
nyalldawson committed Mar 10, 2020
1 parent 6969db1 commit 4f66115b9cd5789d8deed266e2f22a72503a5794
@@ -866,6 +866,13 @@ Evaluates the parameter with matching ``name`` to a print layout item, taken fro
Evaluates the parameter with matching ``name`` to a color, or returns an invalid color if the parameter was not set.

.. versionadded:: 3.10
%End

QString parameterAsConnectionName( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context );
%Docstring
Evaluates the parameter with matching ``name`` to a connection name string.

.. versionadded:: 3.14
%End

static QString invalidSourceError( const QVariantMap &parameters, const QString &name );
@@ -197,6 +197,8 @@ their acceptable ranges, defaults, etc.
sipType = sipType_QgsProcessingParameterMapTheme;
else if ( sipCpp->type() == QgsProcessingParameterDateTime::typeName() )
sipType = sipType_QgsProcessingParameterDateTime;
else if ( sipCpp->type() == QgsProcessingParameterProviderConnection::typeName() )
sipType = sipType_QgsProcessingParameterProviderConnection;
else
sipType = nullptr;
%End
@@ -1186,6 +1188,20 @@ Returns the color associated with an point parameter value, or an invalid color
Returns the color associated with an color parameter value, or an invalid color if the parameter was not set.

.. versionadded:: 3.10
%End

static QString parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context );
%Docstring
Evaluates the parameter with matching ``definition`` to a connection name string.

.. versionadded:: 3.14
%End

static QString parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context );
%Docstring
Evaluates the parameter with matching ``definition`` and ``value`` to a connection name string.

.. versionadded:: 3.14
%End

static QgsProcessingParameterDefinition *parameterFromVariantMap( const QVariantMap &map ) /Factory/;
@@ -3599,6 +3615,75 @@ Creates a new parameter using the definition from a script code.
};


class QgsProcessingParameterProviderConnection : QgsProcessingParameterDefinition
{
%Docstring
A data provider connection parameter for processing algorithms, allowing users to select from available registered
connections for a particular data provider.

QgsProcessingParameterProviderConnection should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsConnectionName()`

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsprocessingparameters.h"
%End
public:

QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue = QVariant(),
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterProviderConnection, for the specified ``provider`` type.

.. warning::

The provider must support the connection API methods in its QgsProviderMetadata implementation
in order for the model to work correctly. This is only implemented for a subset of current data providers.
%End

static QString typeName();
%Docstring
Returns the type name for the parameter class.
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;

virtual QString asScriptCode() const;

virtual QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const;

virtual QVariantMap toVariantMap() const;

virtual bool fromVariantMap( const QVariantMap &map );


QString providerId() const;
%Docstring
Returns the ID of the provider associated with the connections.

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

void setProviderId( const QString &provider );
%Docstring
Sets the ID of the ``provider`` associated with the connections.

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

static QgsProcessingParameterProviderConnection *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
%Docstring
Creates a new parameter using the definition from a script code.
%End

};





@@ -722,6 +722,11 @@ QColor QgsProcessingAlgorithm::parameterAsColor( const QVariantMap &parameters,
return QgsProcessingParameters::parameterAsColor( parameterDefinition( name ), parameters, context );
}

QString QgsProcessingAlgorithm::parameterAsConnectionName( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context )
{
return QgsProcessingParameters::parameterAsConnectionName( parameterDefinition( name ), parameters, context );
}

QString QgsProcessingAlgorithm::invalidSourceError( const QVariantMap &parameters, const QString &name )
{
if ( !parameters.contains( name ) )
@@ -855,6 +855,13 @@ class CORE_EXPORT QgsProcessingAlgorithm
*/
QColor parameterAsColor( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a name to a connection name string.
*
* \since QGIS 3.14
*/
QString parameterAsConnectionName( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context );

/**
* Returns a user-friendly string to use as an error when a source parameter could
* not be loaded.
@@ -1770,6 +1770,21 @@ QColor QgsProcessingParameters::parameterAsColor( const QgsProcessingParameterDe
return c;
}

QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return QString();

return parameterAsConnectionName( definition, parameters.value( definition->name() ), context );
}

QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
// for now it's just treated identical to strings, but in future we may want flexibility to amend this
// (hence the new method)
return parameterAsString( definition, value, context );
}

QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromVariantMap( const QVariantMap &map )
{
QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
@@ -1936,6 +1951,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCo
return QgsProcessingParameterMapTheme::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "datetime" ) )
return QgsProcessingParameterDateTime::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "providerconnection" ) )
return QgsProcessingParameterProviderConnection::fromScriptCode( name, description, isOptional, definition );

return nullptr;
}
@@ -6489,3 +6506,121 @@ QgsProcessingParameterDateTime *QgsProcessingParameterDateTime::fromScriptCode(
return new QgsProcessingParameterDateTime( name, description, DateTime, definition.isEmpty() ? QVariant()
: ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
}



//
// QgsProcessingParameterProviderConnection
//

QgsProcessingParameterProviderConnection::QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mProviderId( provider )
{

}


QgsProcessingParameterDefinition *QgsProcessingParameterProviderConnection::clone() const
{
return new QgsProcessingParameterProviderConnection( *this );
}

bool QgsProcessingParameterProviderConnection::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() && !mDefault.isValid() )
return mFlags & FlagOptional;

if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
|| ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
return mFlags & FlagOptional;

return true;
}

QString QgsProcessingParameterProviderConnection::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );

if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );

return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}

QString QgsProcessingParameterProviderConnection::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "providerconnection " );
code += mProviderId + ' ';

code += mDefault.toString();
return code.trimmed();
}

QString QgsProcessingParameterProviderConnection::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
{
switch ( outputType )
{
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
{
QString code = QStringLiteral( "QgsProcessingParameterProviderConnection('%1', '%2', '%3'" ).arg( name(), description(), mProviderId );
if ( mFlags & FlagOptional )
code += QStringLiteral( ", optional=True" );

QgsProcessingContext c;
code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );

return code;
}
}
return QString();
}

QVariantMap QgsProcessingParameterProviderConnection::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "provider" ), mProviderId );
return map;
}

bool QgsProcessingParameterProviderConnection::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mProviderId = map.value( QStringLiteral( "provider" ) ).toString();
return true;
}

QgsProcessingParameterProviderConnection *QgsProcessingParameterProviderConnection::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString parent;

QString def = definition;
QString provider;
if ( def.contains( ' ' ) )
{
provider = def.left( def.indexOf( ' ' ) );
def = def.mid( def.indexOf( ' ' ) + 1 );
}
else
{
provider = def;
def.clear();
}

if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
def = def.mid( 1 );
if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
def.chop( 1 );

QVariant defaultValue = def;

if ( defaultValue == QStringLiteral( "None" ) || defaultValue.toString().isEmpty() )
defaultValue = QVariant();

return new QgsProcessingParameterProviderConnection( name, description, provider, defaultValue, isOptional );
}

@@ -274,6 +274,8 @@ class CORE_EXPORT QgsProcessingParameterDefinition
sipType = sipType_QgsProcessingParameterMapTheme;
else if ( sipCpp->type() == QgsProcessingParameterDateTime::typeName() )
sipType = sipType_QgsProcessingParameterDateTime;
else if ( sipCpp->type() == QgsProcessingParameterProviderConnection::typeName() )
sipType = sipType_QgsProcessingParameterProviderConnection;
else
sipType = nullptr;
SIP_END
@@ -1222,6 +1224,20 @@ class CORE_EXPORT QgsProcessingParameters
*/
static QColor parameterAsColor( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a definition to a connection name string.
*
* \since QGIS 3.14
*/
static QString parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a definition and \a value to a connection name string.
*
* \since QGIS 3.14
*/
static QString parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context );

/**
* Creates a new QgsProcessingParameterDefinition using the configuration from a
* supplied variant \a map.
@@ -3353,6 +3369,65 @@ class CORE_EXPORT QgsProcessingParameterDateTime : public QgsProcessingParameter
};


/**
* \class QgsProcessingParameterProviderConnection
* \ingroup core
* A data provider connection parameter for processing algorithms, allowing users to select from available registered
* connections for a particular data provider.
*
* QgsProcessingParameterProviderConnection should be evaluated by calling QgsProcessingAlgorithm::parameterAsConnectionName().
*
* \since QGIS 3.14
*/
class CORE_EXPORT QgsProcessingParameterProviderConnection : public QgsProcessingParameterDefinition
{
public:

/**
* Constructor for QgsProcessingParameterProviderConnection, for the specified \a provider type.
*
* \warning The provider must support the connection API methods in its QgsProviderMetadata implementation
* in order for the model to work correctly. This is only implemented for a subset of current data providers.
*/
QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue = QVariant(),
bool optional = false );

/**
* Returns the type name for the parameter class.
*/
static QString typeName() { return QStringLiteral( "providerconnection" ); }
QgsProcessingParameterDefinition *clone() const override SIP_FACTORY;
QString type() const override { return typeName(); }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
QString asScriptCode() const override;
QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const override;
QVariantMap toVariantMap() const override;
bool fromVariantMap( const QVariantMap &map ) override;

/**
* Returns the ID of the provider associated with the connections.
* \see setProvider()
*/
QString providerId() const { return mProviderId; }

/**
* Sets the ID of the \a provider associated with the connections.
* \see provider()
*/
void setProviderId( const QString &provider ) { mProviderId = provider; }

/**
* Creates a new parameter using the definition from a script code.
*/
static QgsProcessingParameterProviderConnection *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;

private:

QString mProviderId;
};


// clazy:excludeall=qstring-allocations

#endif // QGSPROCESSINGPARAMETERS_H

1 comment on commit 4f66115

@havatv

This comment has been minimized.

Copy link
Contributor

@havatv havatv commented on 4f66115 Mar 14, 2020

Great addition!
It would be nice to have an ALG decorator for it. Could it be added to python/processing/algfactory.py (and python/plugins/processing/core/parameters.py)?

Please sign in to comment.
You can’t perform that action at this time.