QGIS API Documentation  3.2.0-Bonn (bc43194)
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 
25 #include "qgis.h"
26 #include "qgis_core.h"
27 #include "qgsexpressionnode.h"
28 
30 class QgsExpression;
33 
38 class CORE_EXPORT QgsExpressionFunction
39 {
40  public:
41 
45  typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) SIP_SKIP;
46 
52  class CORE_EXPORT Parameter
53  {
54  public:
55 
63  Parameter( const QString &name,
64  bool optional = false,
65  const QVariant &defaultValue = QVariant(),
66  bool isSubExpression = false )
67  : mName( name )
68  , mOptional( optional )
69  , mDefaultValue( defaultValue )
70  , mIsSubExpression( isSubExpression )
71  {}
72 
74  QString name() const { return mName; }
75 
77  bool optional() const { return mOptional; }
78 
80  QVariant defaultValue() const { return mDefaultValue; }
81 
87  bool isSubExpression() const { return mIsSubExpression; }
88 
89  bool operator==( const QgsExpressionFunction::Parameter &other ) const
90  {
91  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
92  }
93 
94  private:
95  QString mName;
96  bool mOptional = false;
97  QVariant mDefaultValue;
98  bool mIsSubExpression = false;
99  };
100 
102  typedef QList< QgsExpressionFunction::Parameter > ParameterList;
103 
105  QgsExpressionFunction( const QString &fnname,
106  int params,
107  const QString &group,
108  const QString &helpText = QString(),
109  bool lazyEval = false,
110  bool handlesNull = false,
111  bool isContextual = false )
112  : mName( fnname )
113  , mParams( params )
114  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
115  , mHelpText( helpText )
116  , mLazyEval( lazyEval )
117  , mHandlesNull( handlesNull )
118  , mIsContextual( isContextual )
119  {
120  }
121 
126  QgsExpressionFunction( const QString &fnname,
127  int params,
128  const QStringList &groups,
129  const QString &helpText = QString(),
130  bool lazyEval = false,
131  bool handlesNull = false,
132  bool isContextual = false )
133  : mName( fnname )
134  , mParams( params )
135  , mGroups( groups )
136  , mHelpText( helpText )
137  , mLazyEval( lazyEval )
138  , mHandlesNull( handlesNull )
139  , mIsContextual( isContextual )
140  {
141  }
142 
147  QgsExpressionFunction( const QString &fnname,
149  const QString &group,
150  const QString &helpText = QString(),
151  bool lazyEval = false,
152  bool handlesNull = false,
153  bool isContextual = false )
154  : mName( fnname )
155  , mParams( 0 )
156  , mParameterList( params )
157  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
158  , mHelpText( helpText )
159  , mLazyEval( lazyEval )
160  , mHandlesNull( handlesNull )
161  , mIsContextual( isContextual )
162  {}
163 
168  QgsExpressionFunction( const QString &fnname,
170  const QStringList &groups,
171  const QString &helpText = QString(),
172  bool lazyEval = false,
173  bool handlesNull = false,
174  bool isContextual = false )
175  : mName( fnname )
176  , mParams( 0 )
177  , mParameterList( params )
178  , mGroups( groups )
179  , mHelpText( helpText )
180  , mLazyEval( lazyEval )
181  , mHandlesNull( handlesNull )
182  , mIsContextual( isContextual )
183  {}
184 
185  virtual ~QgsExpressionFunction() = default;
186 
188  QString name() const { return mName; }
189 
191  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
192 
194  int minParams() const
195  {
196  if ( mParameterList.isEmpty() )
197  return mParams;
198 
199  int min = 0;
200  for ( const Parameter &param : mParameterList )
201  {
202  if ( !param.optional() )
203  min++;
204  }
205  return min;
206  }
207 
212  const QgsExpressionFunction::ParameterList &parameters() const { return mParameterList; }
213 
215  virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
216 
223  virtual QStringList aliases() const;
224 
230  bool lazyEval() const { return mLazyEval; }
231 
242  virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
243 
252  virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
253 
262  virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
263 
268  bool isContextual() const { return mIsContextual; }
269 
275  virtual bool isDeprecated() const;
276 
281  QString group() const { return mGroups.isEmpty() ? QString() : mGroups.at( 0 ); }
282 
288  QStringList groups() const { return mGroups; }
289 
291  const QString helpText() const;
292 
301  virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;
302 
307  virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );
308 
309  bool operator==( const QgsExpressionFunction &other ) const;
310 
315  virtual bool handlesNull() const;
316 
317  protected:
318 
328  static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
329 
330  private:
331  QString mName;
332  int mParams;
334  QStringList mGroups;
335  QString mHelpText;
336  bool mLazyEval;
337  bool mHandlesNull;
338  bool mIsContextual; //if true function is only available through an expression context
339 };
340 
346 #ifndef SIP_RUN
348 {
349  public:
350 
354  QgsStaticExpressionFunction( const QString &fnname,
355  int params,
356  FcnEval fcn,
357  const QString &group,
358  const QString &helpText = QString(),
359  bool usesGeometry = false,
360  const QSet<QString> &referencedColumns = QSet<QString>(),
361  bool lazyEval = false,
362  const QStringList &aliases = QStringList(),
363  bool handlesNull = false )
364  : QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
365  , mFnc( fcn )
366  , mAliases( aliases )
367  , mUsesGeometry( usesGeometry )
368  , mReferencedColumns( referencedColumns )
369  {
370  }
371 
375  QgsStaticExpressionFunction( const QString &fnname,
377  FcnEval fcn,
378  const QString &group,
379  const QString &helpText = QString(),
380  bool usesGeometry = false,
381  const QSet<QString> &referencedColumns = QSet<QString>(),
382  bool lazyEval = false,
383  const QStringList &aliases = QStringList(),
384  bool handlesNull = false )
385  : QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
386  , mFnc( fcn )
387  , mAliases( aliases )
388  , mUsesGeometry( usesGeometry )
389  , mReferencedColumns( referencedColumns )
390  {}
391 
403  QgsStaticExpressionFunction( const QString &fnname,
405  FcnEval fcn,
406  const QString &group,
407  const QString &helpText,
408  const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry,
409  const std::function< QSet<QString>( const QgsExpressionNodeFunction *node )> &referencedColumns,
410  bool lazyEval = false,
411  const QStringList &aliases = QStringList(),
412  bool handlesNull = false );
413 
414 
419  QgsStaticExpressionFunction( const QString &fnname,
421  FcnEval fcn,
422  const QStringList &groups,
423  const QString &helpText = QString(),
424  bool usesGeometry = false,
425  const QSet<QString> &referencedColumns = QSet<QString>(),
426  bool lazyEval = false,
427  const QStringList &aliases = QStringList(),
428  bool handlesNull = false )
429  : QgsExpressionFunction( fnname, params, groups, helpText, lazyEval, handlesNull )
430  , mFnc( fcn )
431  , mAliases( aliases )
432  , mUsesGeometry( usesGeometry )
433  , mReferencedColumns( referencedColumns )
434  {}
435 
444  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
445  {
446  return mFnc ? mFnc( values, context, parent, node ) : QVariant();
447  }
448 
449  QStringList aliases() const override;
450 
451  bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
452 
453  QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
454 
455  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
456 
457  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
458 
465  void setIsStaticFunction( const std::function< bool ( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) > &isStatic );
466 
474  void setIsStatic( bool isStatic );
475 
482  void setPrepareFunction( const std::function< bool( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * )> &prepareFunc );
483 
487  static const QList<QgsExpressionFunction *> &functions();
488 
489  private:
490  FcnEval mFnc;
491  QStringList mAliases;
492  bool mUsesGeometry;
493  std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
494  std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
495  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
496  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
497  QSet<QString> mReferencedColumns;
498  bool mIsStatic = false;
499 };
500 
511 {
512  public:
514 
515  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
516 
517  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
518 
519  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
520 
521  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
522 
523  private:
524 
528  void appendTemporaryVariable( const QgsExpressionContext *context, const QString &name, const QVariant &value ) const;
529 
533  void popTemporaryVariable( const QgsExpressionContext *context ) const;
534 };
535 
536 #endif
537 
538 #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.
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:119
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.
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.