Skip to content

Commit 3cd6899

Browse files
authored
Merge pull request #7698 from m-kuhn/wfsDateTimeNow
Support for now() in WFS filters
2 parents 504cd61 + 7a91b80 commit 3cd6899

File tree

4 files changed

+71
-35
lines changed

4 files changed

+71
-35
lines changed

resources/function_help/json/now

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "now",
33
"type": "function",
4-
"description": "Returns the current date and time.",
4+
"description": "Returns the current date and time. The function is static and will return consistent results while evaluating. The time returned is the time when the expression is prepared.",
55
"examples": [ { "expression":"now()", "returns":"2012-07-22T13:24:57"}]
66
}

src/core/qgsogcutils.cpp

+51-27
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp, QD
21452145
QStringLiteral( "geometry" ), QString(), false, false, errorMessage );
21462146
}
21472147

2148-
QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
2148+
QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &expression,
21492149
QDomDocument &doc,
21502150
GMLVersion gmlVersion,
21512151
FilterVersion filterVersion,
@@ -2155,11 +2155,15 @@ QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
21552155
bool invertAxisOrientation,
21562156
QString *errorMessage )
21572157
{
2158-
if ( !exp.rootNode() )
2158+
if ( !expression.rootNode() )
21592159
return QDomElement();
21602160

2161+
QgsExpression exp = expression;
2162+
2163+
QgsExpressionContext context;
2164+
context << QgsExpressionContextUtils::globalScope();
21612165
QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2162-
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( exp.rootNode() );
2166+
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( exp.rootNode(), &exp, &context );
21632167
if ( errorMessage )
21642168
*errorMessage = utils.errorMessage();
21652169
if ( exprRootElem.isNull() )
@@ -2182,7 +2186,7 @@ QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
21822186
return filterElem;
21832187
}
21842188

2185-
QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
2189+
QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &expression,
21862190
QDomDocument &doc,
21872191
GMLVersion gmlVersion,
21882192
FilterVersion filterVersion,
@@ -2192,6 +2196,11 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
21922196
bool invertAxisOrientation,
21932197
QString *errorMessage )
21942198
{
2199+
QgsExpressionContext context;
2200+
context << QgsExpressionContextUtils::globalScope();
2201+
2202+
QgsExpression exp = expression;
2203+
21952204
const QgsExpressionNode *node = exp.rootNode();
21962205
if ( !node )
21972206
return QDomElement();
@@ -2203,7 +2212,7 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
22032212
case QgsExpressionNode::ntColumnRef:
22042213
{
22052214
QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2206-
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( node );
2215+
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( node, &exp, &context );
22072216

22082217
if ( errorMessage )
22092218
*errorMessage = utils.errorMessage();
@@ -2266,34 +2275,32 @@ QDomElement QgsOgcUtils::SQLStatementToOgcFilter( const QgsSQLStatement &stateme
22662275
//
22672276

22682277

2269-
QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpressionNode *node )
2278+
QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpressionNode *node, QgsExpression *expression, const QgsExpressionContext *context )
22702279
{
22712280
switch ( node->nodeType() )
22722281
{
22732282
case QgsExpressionNode::ntUnaryOperator:
2274-
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ) );
2283+
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ), expression, context );
22752284
case QgsExpressionNode::ntBinaryOperator:
2276-
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
2285+
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ), expression, context );
22772286
case QgsExpressionNode::ntInOperator:
2278-
return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ) );
2287+
return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ), expression, context );
22792288
case QgsExpressionNode::ntFunction:
2280-
return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ) );
2289+
return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ), expression, context );
22812290
case QgsExpressionNode::ntLiteral:
2282-
return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ) );
2291+
return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ), expression, context );
22832292
case QgsExpressionNode::ntColumnRef:
2284-
return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ) );
2293+
return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ), expression, context );
22852294

22862295
default:
22872296
mErrorMessage = QObject::tr( "Node type not supported: %1" ).arg( node->nodeType() );
22882297
return QDomElement();
22892298
}
22902299
}
22912300

2292-
2293-
QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node )
2301+
QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
22942302
{
2295-
2296-
QDomElement operandElem = expressionNodeToOgcFilter( node->operand() );
2303+
QDomElement operandElem = expressionNodeToOgcFilter( node->operand(), expression, context );
22972304
if ( !mErrorMessage.isEmpty() )
22982305
return QDomElement();
22992306

@@ -2329,9 +2336,9 @@ QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const Q
23292336
}
23302337

23312338

2332-
QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node )
2339+
QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
23332340
{
2334-
QDomElement leftElem = expressionNodeToOgcFilter( node->opLeft() );
2341+
QDomElement leftElem = expressionNodeToOgcFilter( node->opLeft(), expression, context );
23352342
if ( !mErrorMessage.isEmpty() )
23362343
return QDomElement();
23372344

@@ -2365,7 +2372,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
23652372

23662373
}
23672374

2368-
QDomElement rightElem = expressionNodeToOgcFilter( node->opRight() );
2375+
QDomElement rightElem = expressionNodeToOgcFilter( node->opRight(), expression, context );
23692376
if ( !mErrorMessage.isEmpty() )
23702377
return QDomElement();
23712378

@@ -2401,8 +2408,10 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
24012408
}
24022409

24032410

2404-
QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node )
2411+
QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node, QgsExpression *expression, const QgsExpressionContext *context )
24052412
{
2413+
Q_UNUSED( expression )
2414+
Q_UNUSED( context )
24062415
QString value;
24072416
switch ( node->value().type() )
24082417
{
@@ -2415,6 +2424,12 @@ QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpr
24152424
case QVariant::String:
24162425
value = node->value().toString();
24172426
break;
2427+
case QVariant::Date:
2428+
value = node->value().toDate().toString( Qt::ISODate );
2429+
break;
2430+
case QVariant::DateTime:
2431+
value = node->value().toDateTime().toString( Qt::ISODate );
2432+
break;
24182433

24192434
default:
24202435
mErrorMessage = QObject::tr( "Literal type not supported: %1" ).arg( node->value().type() );
@@ -2427,26 +2442,28 @@ QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpr
24272442
}
24282443

24292444

2430-
QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node )
2445+
QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node, QgsExpression *expression, const QgsExpressionContext *context )
24312446
{
2447+
Q_UNUSED( expression )
2448+
Q_UNUSED( context )
24322449
QDomElement propElem = mDoc.createElement( mFilterPrefix + ":" + mPropertyName );
24332450
propElem.appendChild( mDoc.createTextNode( node->name() ) );
24342451
return propElem;
24352452
}
24362453

24372454

24382455

2439-
QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node )
2456+
QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
24402457
{
24412458
if ( node->list()->list().size() == 1 )
2442-
return expressionNodeToOgcFilter( node->list()->list()[0] );
2459+
return expressionNodeToOgcFilter( node->list()->list()[0], expression, context );
24432460

24442461
QDomElement orElem = mDoc.createElement( mFilterPrefix + ":Or" );
2445-
QDomElement leftNode = expressionNodeToOgcFilter( node->node() );
2462+
QDomElement leftNode = expressionNodeToOgcFilter( node->node(), expression, context );
24462463

24472464
Q_FOREACH ( QgsExpressionNode *n, node->list()->list() )
24482465
{
2449-
QDomElement listNode = expressionNodeToOgcFilter( n );
2466+
QDomElement listNode = expressionNodeToOgcFilter( n, expression, context );
24502467
if ( !mErrorMessage.isEmpty() )
24512468
return QDomElement();
24522469

@@ -2521,7 +2538,7 @@ static QgsGeometry geometryFromConstExpr( const QgsExpressionNode *node )
25212538
}
25222539

25232540

2524-
QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node )
2541+
QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node, QgsExpression *expression, const QgsExpressionContext *context )
25252542
{
25262543
QgsExpressionFunction *fd = QgsExpression::Functions()[node->fnIndex()];
25272544

@@ -2633,6 +2650,13 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
26332650
return funcElem;
26342651
}
26352652

2653+
if ( fd->isStatic( node, expression, context ) )
2654+
{
2655+
QVariant result = fd->run( node->args(), context, expression, node );
2656+
QgsExpressionNodeLiteral literal( result );
2657+
return expressionLiteralToOgcFilter( &literal, expression, context );
2658+
}
2659+
26362660
if ( fd->params() == 0 )
26372661
{
26382662
mErrorMessage = QObject::tr( "Special columns/constants are not supported." );
@@ -2644,7 +2668,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
26442668
funcElem.setAttribute( QStringLiteral( "name" ), fd->name() );
26452669
Q_FOREACH ( QgsExpressionNode *n, node->args()->list() )
26462670
{
2647-
QDomElement childElem = expressionNodeToOgcFilter( n );
2671+
QDomElement childElem = expressionNodeToOgcFilter( n, expression, context );
26482672
if ( !mErrorMessage.isEmpty() )
26492673
return QDomElement();
26502674

src/core/qgsogcutils.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ class QgsOgcUtilsExprToFilter
338338
bool invertAxisOrientation );
339339

340340
//! Convert an expression to a OGC filter
341-
QDomElement expressionNodeToOgcFilter( const QgsExpressionNode *node );
341+
QDomElement expressionNodeToOgcFilter( const QgsExpressionNode *node, QgsExpression *expression, const QgsExpressionContext *context );
342342

343343
//! Returns whether the gml: namespace is used
344344
bool GMLNamespaceUsed() const { return mGMLUsed; }
@@ -359,12 +359,12 @@ class QgsOgcUtilsExprToFilter
359359
QString mPropertyName;
360360
int mGeomId;
361361

362-
QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node );
363-
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node );
364-
QDomElement expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node );
365-
QDomElement expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node );
366-
QDomElement expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node );
367-
QDomElement expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node );
362+
QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
363+
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
364+
QDomElement expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node, QgsExpression *expression, const QgsExpressionContext *context );
365+
QDomElement expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node, QgsExpression *expression, const QgsExpressionContext *context );
366+
QDomElement expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
367+
QDomElement expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node, QgsExpression *expression, const QgsExpressionContext *context );
368368
};
369369

370370
/**

tests/src/core/testqgsexpression.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -3133,6 +3133,18 @@ class TestQgsExpression: public QObject
31333133
QCOMPARE( QgsExpression::formatPreviewString( QVariant( stringList ) ),
31343134
QStringLiteral( "[ 'One', 'Two', 'A very long string that is going to be tr… ]" ) );
31353135
}
3136+
3137+
void test_nowStatic()
3138+
{
3139+
QgsExpression e( QStringLiteral( "now()" ) );
3140+
QgsExpressionContext ctx;
3141+
e.prepare( &ctx );
3142+
QVariant v = e.evaluate();
3143+
QTest::qSleep( 1000 );
3144+
QVariant v2 = e.evaluate();
3145+
3146+
QCOMPARE( v.toDateTime().toMSecsSinceEpoch(), v2.toDateTime().toMSecsSinceEpoch() );
3147+
}
31363148
};
31373149

31383150
QGSTEST_MAIN( TestQgsExpression )

0 commit comments

Comments
 (0)