LCOV - code coverage report
Current view: top level - core/expression - qgsexpressionnode.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 24 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                                qgsexpressionnode.h
       3                 :            :                              -------------------
       4                 :            :     begin                : May 2017
       5                 :            :     copyright            : (C) 2017 Matthias Kuhn
       6                 :            :     email                : matthias@opengis.ch
       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                 :            : 
      17                 :            : #ifndef QGSEXPRESSIONNODE_H
      18                 :            : #define QGSEXPRESSIONNODE_H
      19                 :            : 
      20                 :            : #include <QSet>
      21                 :            : #include <QVariant>
      22                 :            : #include <QCoreApplication>
      23                 :            : 
      24                 :            : #include "qgis.h"
      25                 :            : 
      26                 :            : class QgsExpression;
      27                 :            : class QgsExpressionContext;
      28                 :            : 
      29                 :            : /**
      30                 :            :  * \ingroup core
      31                 :            :  *
      32                 :            :  * \brief Abstract base class for all nodes that can appear in an expression.
      33                 :            :  */
      34                 :          0 : class CORE_EXPORT QgsExpressionNode SIP_ABSTRACT
      35                 :            : {
      36                 :            : 
      37                 :            : #ifdef SIP_RUN
      38                 :            :     SIP_CONVERT_TO_SUBCLASS_CODE
      39                 :            :     switch ( sipCpp->nodeType() )
      40                 :            :     {
      41                 :            :       case QgsExpressionNode::ntUnaryOperator:
      42                 :            :         sipType = sipType_QgsExpressionNodeUnaryOperator;
      43                 :            :         break;
      44                 :            :       case QgsExpressionNode::ntBinaryOperator:
      45                 :            :         sipType = sipType_QgsExpressionNodeBinaryOperator;
      46                 :            :         break;
      47                 :            :       case QgsExpressionNode::ntInOperator:
      48                 :            :         sipType = sipType_QgsExpressionNodeInOperator;
      49                 :            :         break;
      50                 :            :       case QgsExpressionNode::ntFunction:
      51                 :            :         sipType = sipType_QgsExpressionNodeFunction;
      52                 :            :         break;
      53                 :            :       case QgsExpressionNode::ntLiteral:
      54                 :            :         sipType = sipType_QgsExpressionNodeLiteral;
      55                 :            :         break;
      56                 :            :       case QgsExpressionNode::ntColumnRef:
      57                 :            :         sipType = sipType_QgsExpressionNodeColumnRef;
      58                 :            :         break;
      59                 :            :       case QgsExpressionNode::ntCondition:
      60                 :            :         sipType = sipType_QgsExpressionNodeCondition;
      61                 :            :         break;
      62                 :            :       default:
      63                 :            :         sipType = 0;
      64                 :            :         break;
      65                 :            :     }
      66                 :            :     SIP_END
      67                 :            : #endif
      68                 :            : 
      69                 :          0 :     Q_DECLARE_TR_FUNCTIONS( QgsExpressionNode )
      70                 :            : 
      71                 :            :   public:
      72                 :            : 
      73                 :            :     //! Known node types.
      74                 :            :     enum NodeType
      75                 :            :     {
      76                 :            :       ntUnaryOperator, //!< \see QgsExpression::Node::NodeUnaryOperator
      77                 :            :       ntBinaryOperator, //!< \see QgsExpression::Node::NodeBinaryOperator
      78                 :            :       ntInOperator, //!< \see QgsExpression::Node::NodeInOperator
      79                 :            :       ntFunction,  //!< \see QgsExpression::Node::NodeFunction
      80                 :            :       ntLiteral, //!< \see QgsExpression::Node::NodeLiteral
      81                 :            :       ntColumnRef, //!< \see QgsExpression::Node::NodeColumnRef
      82                 :            :       ntCondition, //!< \see QgsExpression::Node::NodeCondition
      83                 :            :       ntIndexOperator, //!< Index operator
      84                 :            :     };
      85                 :            : 
      86                 :            : 
      87                 :            :     /**
      88                 :            :      * \brief Named node
      89                 :            :      * \ingroup core
      90                 :            :      * \since QGIS 2.16
      91                 :            :      */
      92                 :          0 :     struct NamedNode
      93                 :            :     {
      94                 :            :       public:
      95                 :            : 
      96                 :            :         /**
      97                 :            :          * Constructor for NamedNode
      98                 :            :          * \param name node name
      99                 :            :          * \param node node
     100                 :            :          */
     101                 :          0 :         NamedNode( const QString &name, QgsExpressionNode *node )
     102                 :          0 :           : name( name )
     103                 :          0 :           , node( node )
     104                 :          0 :         {}
     105                 :            : 
     106                 :            :         //! Node name
     107                 :            :         QString name;
     108                 :            : 
     109                 :            :         //! Node
     110                 :            :         QgsExpressionNode *node = nullptr;
     111                 :            :     };
     112                 :            : 
     113                 :            :     /**
     114                 :            :      * \brief A list of expression nodes.
     115                 :            :      * \ingroup core
     116                 :            :      */
     117                 :          0 :     class CORE_EXPORT NodeList
     118                 :            :     {
     119                 :            :       public:
     120                 :            :         virtual ~NodeList();
     121                 :            :         //! Takes ownership of the provided node
     122                 :          0 :         void append( QgsExpressionNode *node SIP_TRANSFER ) { mList.append( node ); mNameList.append( QString() ); }
     123                 :            : 
     124                 :            :         /**
     125                 :            :          * Adds a named node. Takes ownership of the provided node.
     126                 :            :          * \since QGIS 2.16
     127                 :            :         */
     128                 :            :         void append( QgsExpressionNode::NamedNode *node SIP_TRANSFER );
     129                 :            : 
     130                 :            :         /**
     131                 :            :          * Returns the number of nodes in the list.
     132                 :            :          */
     133                 :          0 :         int count() const { return mList.count(); }
     134                 :            : 
     135                 :            :         /**
     136                 :            :          * Returns TRUE if list contains any named nodes
     137                 :            :          * \since QGIS 2.16
     138                 :            :          */
     139                 :          0 :         bool hasNamedNodes() const { return mHasNamedNodes; }
     140                 :            : 
     141                 :            :         /**
     142                 :            :          * Gets a list of all the nodes.
     143                 :            :          */
     144                 :          0 :         QList<QgsExpressionNode *> list() { return mList; }
     145                 :            : 
     146                 :            :         /**
     147                 :            :          * Gets the node at position i in the list.
     148                 :            :          *
     149                 :            :          * \since QGIS 3.0
     150                 :            :          */
     151                 :          0 :         QgsExpressionNode *at( int i ) { return mList.at( i ); }
     152                 :            : 
     153                 :            :         /**
     154                 :            :          * Returns a list of names for nodes. Unnamed nodes will be indicated by an empty string in the list.
     155                 :            :          * \since QGIS 2.16
     156                 :            :          */
     157                 :          0 :         QStringList names() const { return mNameList; }
     158                 :            : 
     159                 :            :         //! Creates a deep copy of this list. Ownership is transferred to the caller
     160                 :            :         QgsExpressionNode::NodeList *clone() const SIP_FACTORY;
     161                 :            : 
     162                 :            :         /**
     163                 :            :          * Returns a string dump of the expression node.
     164                 :            :          */
     165                 :            :         virtual QString dump() const;
     166                 :            : 
     167                 :            :       private:
     168                 :            :         QList<QgsExpressionNode *> mList;
     169                 :            :         QStringList mNameList;
     170                 :            : 
     171                 :          0 :         bool mHasNamedNodes = false;
     172                 :            : 
     173                 :            :         /**
     174                 :            :          * Cleans up and standardises the name of a named node.
     175                 :            :          */
     176                 :            :         static QString cleanNamedNodeName( const QString &name );
     177                 :            : 
     178                 :            :       public:
     179                 :            :     };
     180                 :            : 
     181                 :          0 :     virtual ~QgsExpressionNode() = default;
     182                 :            : 
     183                 :            :     /**
     184                 :            :      * Gets the type of this node.
     185                 :            :      *
     186                 :            :      * \returns The type of this node
     187                 :            :      */
     188                 :            :     virtual QgsExpressionNode::NodeType nodeType() const = 0;
     189                 :            : 
     190                 :            :     /**
     191                 :            :      * Dump this node into a serialized (part) of an expression.
     192                 :            :      * The returned expression does not necessarily literally match
     193                 :            :      * the original expression, it's just guaranteed to behave the same way.
     194                 :            :      */
     195                 :            :     virtual QString dump() const = 0;
     196                 :            : 
     197                 :            :     /**
     198                 :            :      * Evaluate this node with the given context and parent.
     199                 :            :      * This will return a cached value if it has been determined to be static
     200                 :            :      * during the prepare() execution.
     201                 :            :      *
     202                 :            :      * \since QGIS 2.12
     203                 :            :      */
     204                 :            :     QVariant eval( QgsExpression *parent, const QgsExpressionContext *context );
     205                 :            : 
     206                 :            :     /**
     207                 :            :      * Generate a clone of this node.
     208                 :            :      * Ownership is transferred to the caller.
     209                 :            :      *
     210                 :            :      * \returns a deep copy of this node.
     211                 :            :      */
     212                 :            :     virtual QgsExpressionNode *clone() const = 0;
     213                 :            : 
     214                 :            :     /**
     215                 :            :      * Abstract virtual method which returns a list of columns required to
     216                 :            :      * evaluate this node.
     217                 :            :      *
     218                 :            :      * When reimplementing this, you need to return any column that is required to
     219                 :            :      * evaluate this node and in addition recursively collect all the columns required
     220                 :            :      * to evaluate child nodes.
     221                 :            :      *
     222                 :            :      * \warning If the expression has been prepared via a call to QgsExpression::prepare(),
     223                 :            :      * or a call to QgsExpressionNode::prepare() for a node has been made, then some nodes in
     224                 :            :      * the expression may have been determined to evaluate to a static pre-calculatable value.
     225                 :            :      * In this case the results will omit attribute indices which are used by these
     226                 :            :      * pre-calculated nodes, regardless of their actual referenced columns.
     227                 :            :      * If you are seeking to use these functions to introspect an expression you must
     228                 :            :      * take care to do this with an unprepared expression node.
     229                 :            :      *
     230                 :            :      * \returns A list of columns required to evaluate this expression
     231                 :            :      */
     232                 :            :     virtual QSet<QString> referencedColumns() const = 0;
     233                 :            : 
     234                 :            :     /**
     235                 :            :      * Returns a set of all variables which are used in this expression.
     236                 :            :      *
     237                 :            :      * \note In contrast to the referencedColumns() function this method
     238                 :            :      * is not affected by any previous calls to QgsExpressionNode::prepare().
     239                 :            :      */
     240                 :            :     virtual QSet<QString> referencedVariables() const = 0;
     241                 :            : 
     242                 :            :     /**
     243                 :            :      * Returns a set of all functions which are used in this expression.
     244                 :            :      *
     245                 :            :      * \note In contrast to the referencedColumns() function this method
     246                 :            :      * is not affected by any previous calls to QgsExpressionNode::prepare().
     247                 :            :      */
     248                 :            :     virtual QSet<QString> referencedFunctions() const = 0;
     249                 :            : 
     250                 :            :     /**
     251                 :            :      * Returns a list of all nodes which are used in this expression.
     252                 :            :      *
     253                 :            :      * \note not available in Python bindings
     254                 :            :      * \since QGIS 3.2
     255                 :            :      */
     256                 :            :     virtual QList<const QgsExpressionNode *> nodes( ) const = 0; SIP_SKIP
     257                 :            : 
     258                 :            :     /**
     259                 :            :      * Abstract virtual method which returns if the geometry is required to evaluate
     260                 :            :      * this expression.
     261                 :            :      *
     262                 :            :      * This needs to call `needsGeometry()` recursively on any child nodes.
     263                 :            :      *
     264                 :            :      * \returns TRUE if a geometry is required to evaluate this expression
     265                 :            :      */
     266                 :            :     virtual bool needsGeometry() const = 0;
     267                 :            : 
     268                 :            :     /**
     269                 :            :      * Returns TRUE if this node can be evaluated for a static value. This is used during
     270                 :            :      * the prepare() step and in case it returns TRUE, the value of this node will already
     271                 :            :      * be evaluated and the result cached (and therefore not re-evaluated in subsequent calls
     272                 :            :      * to eval()). In case this returns TRUE, prepareNode() will never be called.
     273                 :            :      *
     274                 :            :      * \since QGIS 3.0
     275                 :            :      */
     276                 :            :     virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const = 0;
     277                 :            : 
     278                 :            :     /**
     279                 :            :      * Prepare this node for evaluation.
     280                 :            :      * This will check if the node content is static and in this case cache the value.
     281                 :            :      * If it's not static it will call prepareNode() to allow the node to do initialization
     282                 :            :      * work like for example resolving a column name to an attribute index.
     283                 :            :      *
     284                 :            :      * \since QGIS 2.12
     285                 :            :      */
     286                 :            :     bool prepare( QgsExpression *parent, const QgsExpressionContext *context );
     287                 :            : 
     288                 :            :     /**
     289                 :            :      * First line in the parser this node was found.
     290                 :            :      * \note This might not be complete for all nodes. Currently
     291                 :            :      * only \see QgsExpressionNode has this complete
     292                 :            :      */
     293                 :          0 :     int parserFirstLine = 0;
     294                 :            : 
     295                 :            :     /**
     296                 :            :      * First column in the parser this node was found.
     297                 :            :      * \note This might not be complete for all nodes. Currently
     298                 :            :      * only \see QgsExpressionNode has this complete
     299                 :            :      */
     300                 :          0 :     int parserFirstColumn = 0;
     301                 :            : 
     302                 :            :     /**
     303                 :            :      * Last line in the parser this node was found.
     304                 :            :      * \note This might not be complete for all nodes. Currently
     305                 :            :      * only \see QgsExpressionNode has this complete
     306                 :            :      */
     307                 :          0 :     int parserLastLine = 0;
     308                 :            : 
     309                 :            :     /**
     310                 :            :      * Last column in the parser this node was found.
     311                 :            :      * \note This might not be complete for all nodes. Currently
     312                 :            :      * only \see QgsExpressionNode has this complete
     313                 :            :      */
     314                 :          0 :     int parserLastColumn = 0;
     315                 :            : 
     316                 :            :     /**
     317                 :            :      * Returns TRUE if the node can be replaced by a static cached value.
     318                 :            :      *
     319                 :            :      * \see cachedStaticValue()
     320                 :            :      * \since QGIS 3.18
     321                 :            :      */
     322                 :          0 :     bool hasCachedStaticValue() const { return mHasCachedValue; }
     323                 :            : 
     324                 :            :     /**
     325                 :            :      * Returns the node's static cached value. Only valid if hasCachedStaticValue() is TRUE.
     326                 :            :      *
     327                 :            :      * \see hasCachedStaticValue()
     328                 :            :      * \since QGIS 3.18
     329                 :            :      */
     330                 :          0 :     QVariant cachedStaticValue() const { return mCachedStaticValue; }
     331                 :            : 
     332                 :            :   protected:
     333                 :            : 
     334                 :            :     /**
     335                 :            :      * Copies the members of this node to the node provided in \a target.
     336                 :            :      * Needs to be called by all subclasses as part of their clone() implementation.
     337                 :            :      *
     338                 :            :      * \note Not available in python bindings, QgsExpression::Node is not
     339                 :            :      * going to be subclassed from python. If that's what you are looking
     340                 :            :      * for, look into writing a custom python expression function.
     341                 :            :      * \since QGIS 3.0
     342                 :            :      */
     343                 :            :     void cloneTo( QgsExpressionNode *target ) const SIP_SKIP;
     344                 :            : 
     345                 :            : #ifndef SIP_RUN
     346                 :            : 
     347                 :            :     /**
     348                 :            :      * TRUE if the node has a static, precalculated value.
     349                 :            :      *
     350                 :            :      * \since QGIS 3.20
     351                 :            :      */
     352                 :          0 :     mutable bool mHasCachedValue = false;
     353                 :            : 
     354                 :            :     /**
     355                 :            :      * Contains the static, precalculated value for the node if mHasCachedValue is TRUE.
     356                 :            :      *
     357                 :            :      * \since QGIS 3.20
     358                 :            :      */
     359                 :            :     mutable QVariant mCachedStaticValue;
     360                 :            : #endif
     361                 :            : 
     362                 :            :   private:
     363                 :            : 
     364                 :            :     /**
     365                 :            :      * Abstract virtual preparation method
     366                 :            :      * Errors are reported to the parent
     367                 :            :      * \since QGIS 3.0
     368                 :            :      */
     369                 :            :     virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) = 0;
     370                 :            : 
     371                 :            :     /**
     372                 :            :      * Abstract virtual eval method
     373                 :            :      * Errors are reported to the parent
     374                 :            :      * \since QGIS 3.0
     375                 :            :      */
     376                 :            :     virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) = 0;
     377                 :            : 
     378                 :            : };
     379                 :            : 
     380                 :          0 : Q_DECLARE_METATYPE( QgsExpressionNode * )
     381                 :            : 
     382                 :            : #endif // QGSEXPRESSIONNODE_H

Generated by: LCOV version 1.14