242
if (!getValue(value1, mLeft, attributes) || !getValue(value2, mRight, attributes))
268
if ( !getValue( value1, mLeft, fields, attributes ) ||
269
!getValue( value2, mRight, fields, attributes ) )
245
272
// value1 is string to be matched
246
273
// value2 is regular expression
248
275
// XXX does it make sense to use regexp on numbers?
249
276
// in what format should they be?
250
if (value1.isNumeric() || value2.isNumeric())
277
if ( value1.isNumeric() || value2.isNumeric() )
252
mError = QObject::tr("Regular expressions on numeric values don't make sense. Use comparison insted.");
279
mError = QObject::tr( "Regular expressions on numeric values don't make sense. Use comparison instead." );
256
283
QString str = value2.string();
257
if (mOp == opLike) // change from LIKE syntax to regexp
284
if ( mOp == opLike ) // change from LIKE syntax to regexp
259
286
// XXX escape % and _ ???
260
str.replace("%", ".*");
261
str.replace("_", ".");
287
str.replace( "%", ".*" );
288
str.replace( "_", "." );
265
res = re.search(value1.string());
266
QgsDebugMsgLevel("REGEXP: " + str + " ~ " + value2.string(), 2);
267
QgsDebugMsgLevel(" res: " + res, 2);
291
return QRegExp( str ).exactMatch( value1.string() );
272
295
mError = "Unknown operator: ";
273
mError += QString::number(mOp);
296
mError += QString::number( mOp );
277
return false; // will never get there
280
bool QgsSearchTreeNode::getValue(QgsSearchTreeValue& value, QgsSearchTreeNode* node, const std::vector<QgsFeatureAttribute>& attributes)
301
bool QgsSearchTreeNode::getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node, const QgsFieldMap& fields, const QgsAttributeMap& attributes, QgsGeometry* geom )
282
value = node->valueAgainst(attributes);
303
value = node->valueAgainst( fields, attributes, geom );
304
if ( value.isError() )
285
switch ((int)value.number())
306
switch (( int )value.number() )
288
mError = QObject::tr("Referenced column wasn't found: ");
289
mError += value.string();
309
mError = QObject::tr( "Referenced column wasn't found: %1" ).arg( value.string() );
292
mError = QObject::tr("Division by zero.");
312
mError = QObject::tr( "Division by zero." );
295
// these should never happen (no need to translate)
315
// these should never happen (no need to translate)
297
317
mError = "Unknown operator: ";
298
318
mError += value.string();
305
325
mError = "Unknown error!";
313
QgsSearchTreeValue QgsSearchTreeNode::valueAgainst(const std::vector<QgsFeatureAttribute>& attributes)
333
QgsSearchTreeValue QgsSearchTreeNode::valueAgainst( const QgsFieldMap& fields, const QgsAttributeMap& attributes, QgsGeometry* geom )
315
QgsDebugMsgLevel("valueAgainst: " + makeSearchString(), 2);
335
QgsDebugMsgLevel( "valueAgainst: " + makeSearchString(), 2 );
321
QgsDebugMsgLevel("number: " + QString::number(mNumber), 2);
322
return QgsSearchTreeValue(mNumber);
341
QgsDebugMsgLevel( "number: " + QString::number( mNumber ), 2 );
342
return QgsSearchTreeValue( mNumber );
325
QgsDebugMsgLevel("text: " + EVAL_STR(mText), 2);
326
return QgsSearchTreeValue(mText);
345
QgsDebugMsgLevel( "text: " + EVAL_STR( mText ), 2 );
346
return QgsSearchTreeValue( mText );
330
QgsDebugMsgLevel("column (" + mText.lower() + "): ", 2);
331
// find value for the column
332
std::vector<QgsFeatureAttribute>::const_iterator it;
333
for (it = attributes.begin(); it != attributes.end(); it++)
335
if ( (*it).fieldName().lower() == mText.lower()) // TODO: optimize
337
QString value = (*it).fieldValue();
338
if ((*it).isNumeric())
340
QgsDebugMsgLevel(" number: " + QString::number(value.toDouble()), 2);
341
return QgsSearchTreeValue(value.toDouble());
345
QgsDebugMsgLevel(" text: " + EVAL_STR(value), 2);
346
return QgsSearchTreeValue(value);
351
// else report missing column
352
QgsDebugMsgLevel("ERROR!", 2);
353
return QgsSearchTreeValue(1, mText);
350
QgsDebugMsgLevel( "column (" + mText.toLower() + "): ", 2 );
351
// find field index for the column
352
QgsFieldMap::const_iterator it;
353
for ( it = fields.begin(); it != fields.end(); it++ )
355
if ( it->name().toLower() == mText.toLower() ) // TODO: optimize
359
if ( it == fields.end() )
361
// report missing column if not found
362
QgsDebugMsgLevel( "ERROR!", 2 );
363
return QgsSearchTreeValue( 1, mText );
367
QVariant val = attributes[it.key()];
368
if ( val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double )
370
QgsDebugMsgLevel( " number: " + QString::number( val.toDouble() ), 2 );
371
return QgsSearchTreeValue( val.toDouble() );
375
QgsDebugMsgLevel( " text: " + EVAL_STR( val.toString() ), 2 );
376
return QgsSearchTreeValue( val.toString() );
356
381
// arithmetic operators
359
QgsSearchTreeValue value1, value2;
360
if (!getValue(value1, mLeft, attributes)) return value1;
361
if (!getValue(value2, mRight, attributes)) return value2;
363
// convert to numbers if needed
365
if (value1.isNumeric())
366
val1 = value1.number();
368
val1 = value1.string().toDouble();
369
if (value2.isNumeric())
370
val2 = value2.number();
372
val2 = value2.string().toDouble();
377
return QgsSearchTreeValue(val1 + val2);
379
return QgsSearchTreeValue(val1 - val2);
381
return QgsSearchTreeValue(val1 * val2);
384
return QgsSearchTreeValue(2, ""); // division by zero
386
return QgsSearchTreeValue(val1 / val2);
388
return QgsSearchTreeValue(3, QString::number(mOp)); // unknown operator
384
QgsSearchTreeValue value1, value2;
387
if ( !getValue( value1, mLeft, fields, attributes, geom ) ) return value1;
391
if ( !getValue( value2, mRight, fields, attributes, geom ) ) return value2;
394
if ( mOp == opLENGTH || mOp == opAREA )
398
return QgsSearchTreeValue( 2, "Geometry is 0" );
401
//check that we don't use area for lines or length for polygons
402
if ( mOp == opLENGTH && geom->type() != QGis::Line )
404
return QgsSearchTreeValue( 0 );
406
if ( mOp == opAREA && geom->type() != QGis::Polygon )
408
return QgsSearchTreeValue( 0 );
410
return QgsSearchTreeValue( mCalc.measure( geom ) );
413
//string operations with one argument
414
if ( !mRight && !value1.isNumeric() )
416
if ( mOp == opTOINT )
418
return QgsSearchTreeValue( value1.string().toInt() );
420
else if ( mOp == opTOREAL )
422
return QgsSearchTreeValue( value1.string().toDouble() );
426
//don't convert to numbers in case of string concatenation
427
if ( mLeft && mRight && !value1.isNumeric() && !value2.isNumeric() )
431
return QgsSearchTreeValue( value1.string() + value2.string() );
435
// for other operators, convert strings to numbers if needed
437
if ( value1.isNumeric() )
438
val1 = value1.number();
440
val1 = value1.string().toDouble();
441
if ( value2.isNumeric() )
442
val2 = value2.number();
444
val2 = value2.string().toDouble();
449
return QgsSearchTreeValue( val1 + val2 );
451
return QgsSearchTreeValue( val1 - val2 );
453
return QgsSearchTreeValue( val1 * val2 );
456
return QgsSearchTreeValue( 2, "" ); // division by zero
458
return QgsSearchTreeValue( val1 / val2 );
460
return QgsSearchTreeValue( 3, QString::number( mOp ) ); // unknown operator
462
if (( val1 == 0 && val2 < 0 ) || ( val2 < 0 && ( val2 - floor( val2 ) ) > 0 ) )
464
return QgsSearchTreeValue( 4, "Error in power function" );
466
return QgsSearchTreeValue( pow( val1, val2 ) );
468
return QgsSearchTreeValue( sqrt( val1 ) );
470
return QgsSearchTreeValue( sin( val1 ) );
472
return QgsSearchTreeValue( cos( val1 ) );
474
return QgsSearchTreeValue( tan( val1 ) );
476
return QgsSearchTreeValue( asin( val1 ) );
478
return QgsSearchTreeValue( acos( val1 ) );
480
return QgsSearchTreeValue( atan( val1 ) );
482
return QgsSearchTreeValue( int( val1 ) );
484
return QgsSearchTreeValue( val1 );
486
return QgsSearchTreeValue( QString::number( val1 ) );
393
return QgsSearchTreeValue(4, QString::number(mType)); // unknown token
491
return QgsSearchTreeValue( 4, QString::number( mType ) ); // unknown token
398
int QgsSearchTreeValue::compare(QgsSearchTreeValue& value1, QgsSearchTreeValue& value2)
496
int QgsSearchTreeValue::compare( QgsSearchTreeValue& value1, QgsSearchTreeValue& value2, Qt::CaseSensitivity cs )
400
if (value1.isNumeric() || value2.isNumeric())
498
if ( value1.isNumeric() || value2.isNumeric() )
402
500
// numeric comparison
404
502
// convert to numbers if needed
405
503
double val1, val2;
406
if (value1.isNumeric())
504
if ( value1.isNumeric() )
407
505
val1 = value1.number();
409
507
val1 = value1.string().toDouble();
410
if (value2.isNumeric())
508
if ( value2.isNumeric() )
411
509
val2 = value2.number();
413
511
val2 = value2.string().toDouble();
415
QgsDebugMsgLevel("NUM_COMP: " + QString::number(val1) + " ~ " + QString::number(val2), 2);
513
QgsDebugMsgLevel( "NUM_COMP: " + QString::number( val1 ) + " ~ " + QString::number( val2 ), 2 );
419
else if (val1 > val2)
517
else if ( val1 > val2 )