QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsexpressionfunction.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressionfunction.h
3  -------------------
4  begin : May 2017
5  copyright : (C) 2017 Matthias Kuhn
6  email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSEXPRESSIONFUNCTION_H
17 #define QGSEXPRESSIONFUNCTION_H
18 
19 #include <functional>
20 
21 #include <QString>
22 #include <QVariant>
23 #include <QSet>
24 #include <QJsonDocument>
25 #include <QJsonObject>
26 
27 #include "qgis.h"
28 #include "qgis_core.h"
29 #include "qgsexpressionnode.h"
30 
32 class QgsExpression;
35 
40 class CORE_EXPORT QgsExpressionFunction
41 {
42  public:
43 
47  typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) SIP_SKIP;
48 
54  class CORE_EXPORT Parameter
55  {
56  public:
57 
65  Parameter( const QString &name,
66  bool optional = false,
67  const QVariant &defaultValue = QVariant(),
68  bool isSubExpression = false )
69  : mName( name )
70  , mOptional( optional )
71  , mDefaultValue( defaultValue )
72  , mIsSubExpression( isSubExpression )
73  {}
74 
76  QString name() const { return mName; }
77 
79  bool optional() const { return mOptional; }
80 
82  QVariant defaultValue() const { return mDefaultValue; }
83 
89  bool isSubExpression() const { return mIsSubExpression; }
90 
91  bool operator==( const QgsExpressionFunction::Parameter &other ) const
92  {
93  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
94  }
95 
96  private:
97  QString mName;
98  bool mOptional = false;
99  QVariant mDefaultValue;
100  bool mIsSubExpression = false;
101  };
102 
104  typedef QList< QgsExpressionFunction::Parameter > ParameterList;
105 
107  QgsExpressionFunction( const QString &fnname,
108  int params,
109  const QString &group,
110  const QString &helpText = QString(),
111  bool lazyEval = false,
112  bool handlesNull = false,
113  bool isContextual = false )
114  : mName( fnname )
115  , mParams( params )
116  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
117  , mHelpText( helpText )
118  , mLazyEval( lazyEval )
119  , mHandlesNull( handlesNull )
120  , mIsContextual( isContextual )
121  {
122  }
123 
128  QgsExpressionFunction( const QString &fnname,
129  int params,
130  const QStringList &groups,
131  const QString &helpText = QString(),
132  bool lazyEval = false,
133  bool handlesNull = false,
134  bool isContextual = false )
135  : mName( fnname )
136  , mParams( params )
137  , mGroups( groups )
138  , mHelpText( helpText )
139  , mLazyEval( lazyEval )
140  , mHandlesNull( handlesNull )
141  , mIsContextual( isContextual )
142  {
143  }
144 
149  QgsExpressionFunction( const QString &fnname,
151  const QString &group,
152  const QString &helpText = QString(),
153  bool lazyEval = false,
154  bool handlesNull = false,
155  bool isContextual = false )
156  : mName( fnname )
157  , mParams( 0 )
158  , mParameterList( params )
159  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
160  , mHelpText( helpText )
161  , mLazyEval( lazyEval )
162  , mHandlesNull( handlesNull )
163  , mIsContextual( isContextual )
164  {}
165 
170  QgsExpressionFunction( const QString &fnname,
172  const QStringList &groups,
173  const QString &helpText = QString(),
174  bool lazyEval = false,
175  bool handlesNull = false,
176  bool isContextual = false )
177  : mName( fnname )
178  , mParams( 0 )
179  , mParameterList( params )
180  , mGroups( groups )
181  , mHelpText( helpText )
182  , mLazyEval( lazyEval )
183  , mHandlesNull( handlesNull )
184  , mIsContextual( isContextual )
185  {}
186 
187  virtual ~QgsExpressionFunction() = default;
188 
190  QString name() const { return mName; }
191 
193  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
194 
196  int minParams() const
197  {
198  if ( mParameterList.isEmpty() )
199  return mParams;
200 
201  int min = 0;
202  for ( const Parameter &param : mParameterList )
203  {
204  if ( !param.optional() )
205  min++;
206  }
207  return min;
208  }
209 
214  const QgsExpressionFunction::ParameterList &parameters() const { return mParameterList; }
215 
217  virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
218 
225  virtual QStringList aliases() const;
226 
232  bool lazyEval() const { return mLazyEval; }
233 
244  virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
245 
254  virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
255 
264  virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
265 
270  bool isContextual() const { return mIsContextual; }
271 
277  virtual bool isDeprecated() const;
278 
283  QString group() const { return mGroups.isEmpty() ? QString() : mGroups.at( 0 ); }
284 
290  QStringList groups() const { return mGroups; }
291 
293  const QString helpText() const;
294 
303  virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;
304 
309  virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );
310 
311  bool operator==( const QgsExpressionFunction &other ) const;
312 
317  virtual bool handlesNull() const;
318 
319  protected:
320 
330  static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
331 
332  private:
333  QString mName;
334  int mParams;
336  QStringList mGroups;
337  QString mHelpText;
338  bool mLazyEval;
339  bool mHandlesNull;
340  bool mIsContextual; //if true function is only available through an expression context
341 };
342 
348 #ifndef SIP_RUN
350 {
351  public:
352 
356  QgsStaticExpressionFunction( const QString &fnname,
357  int params,
358  FcnEval fcn,
359  const QString &group,
360  const QString &helpText = QString(),
361  bool usesGeometry = false,
362  const QSet<QString> &referencedColumns = QSet<QString>(),
363  bool lazyEval = false,
364  const QStringList &aliases = QStringList(),
365  bool handlesNull = false )
366  : QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
367  , mFnc( fcn )
368  , mAliases( aliases )
369  , mUsesGeometry( usesGeometry )
370  , mReferencedColumns( referencedColumns )
371  {
372  }
373 
377  QgsStaticExpressionFunction( const QString &fnname,
379  FcnEval fcn,
380  const QString &group,
381  const QString &helpText = QString(),
382  bool usesGeometry = false,
383  const QSet<QString> &referencedColumns = QSet<QString>(),
384  bool lazyEval = false,
385  const QStringList &aliases = QStringList(),
386  bool handlesNull = false )
387  : QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
388  , mFnc( fcn )
389  , mAliases( aliases )
390  , mUsesGeometry( usesGeometry )
391  , mReferencedColumns( referencedColumns )
392  {}
393 
405  QgsStaticExpressionFunction( const QString &fnname,
407  FcnEval fcn,
408  const QString &group,
409  const QString &helpText,
410  const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry,
411  const std::function< QSet<QString>( const QgsExpressionNodeFunction *node )> &referencedColumns,
412  bool lazyEval = false,
413  const QStringList &aliases = QStringList(),
414  bool handlesNull = false );
415 
416 
421  QgsStaticExpressionFunction( const QString &fnname,
423  FcnEval fcn,
424  const QStringList &groups,
425  const QString &helpText = QString(),
426  bool usesGeometry = false,
427  const QSet<QString> &referencedColumns = QSet<QString>(),
428  bool lazyEval = false,
429  const QStringList &aliases = QStringList(),
430  bool handlesNull = false )
431  : QgsExpressionFunction( fnname, params, groups, helpText, lazyEval, handlesNull )
432  , mFnc( fcn )
433  , mAliases( aliases )
434  , mUsesGeometry( usesGeometry )
435  , mReferencedColumns( referencedColumns )
436  {}
437 
446  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
447  {
448  return mFnc ? mFnc( values, context, parent, node ) : QVariant();
449  }
450 
451  QStringList aliases() const override;
452 
453  bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
454 
455  QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
456 
457  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
458 
459  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
460 
467  void setIsStaticFunction( const std::function< bool ( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) > &isStatic );
468 
476  void setIsStatic( bool isStatic );
477 
484  void setPrepareFunction( const std::function< bool( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * )> &prepareFunc );
485 
489  static const QList<QgsExpressionFunction *> &functions();
490 
491  private:
492  FcnEval mFnc;
493  QStringList mAliases;
494  bool mUsesGeometry;
495  std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
496  std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
497  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
498  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
499  QSet<QString> mReferencedColumns;
500  bool mIsStatic = false;
501 };
502 
512 {
513  public:
515 
516  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
517 
518  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
519 
520  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
521 
522  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
523 
524 };
525 
535 {
536  public:
538 
539  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
540 
541  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
542 
543  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
544 
545  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
546 
547 };
548 
559 {
560  public:
562 
563  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
564 
565  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
566 
567  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
568 
569  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
570 
571  private:
572 
576  void appendTemporaryVariable( const QgsExpressionContext *context, const QString &name, const QVariant &value ) const;
577 
581  void popTemporaryVariable( const QgsExpressionContext *context ) const;
582 };
583 
584 #endif
585 
586 #endif // QGSEXPRESSIONFUNCTION_H
Class for parsing and evaluation of expressions (formerly called "search strings").
bool optional() const
Returns true if the parameter is optional.
int params() const
The number of parameters this function takes.
QStringList groups() const
Returns a list of the groups the function belongs to.
QgsExpressionFunction(const QString &fnname, int params, const QStringList &groups, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters and group list.
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
Handles the with_variable(name, value, node) expression function.
QVariant defaultValue() const
Returns the default value for the parameter.
Handles the array_foreach(array, expression) expression function.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
QgsExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses named parameter list.
QgsStaticExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, FcnEval fcn, const QStringList &groups, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
Parameter(const QString &name, bool optional=false, const QVariant &defaultValue=QVariant(), bool isSubExpression=false)
Constructor for Parameter.
#define SIP_SKIP
Definition: qgis_sip.h:126
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
int minParams() const
The minimum number of parameters this function takes.
QgsStaticExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
Single scope for storing variables and functions for use within a QgsExpressionContext.
An expression node for expression functions.
QString name() const
Returns the name of the parameter.
bool lazyEval() const
true if this function should use lazy evaluation.
QString group() const
Returns the first group which the function belongs to.
bool isSubExpression() const
Returns true if parameter argument is a separate sub-expression, and should not be checked while dete...
QgsExpressionFunction(const QString &fnname, int params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters.
QString name() const
The name of the function.
Handles the array_filter(array, expression) expression function.
A abstract base class for defining QgsExpression functions.
A list of expression nodes.
c++ helper class for defining QgsExpression functions.
bool operator==(const QgsExpressionFunction::Parameter &other) const
Represents a single parameter passed to a function.
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object...
QgsExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, const QStringList &groups, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses named parameter list and group list.