Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/filter/filtercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ QString FilterController::buildFieldExpression( const FieldFilter &filter ) cons
QString textValue = QgsExpression::quotedString( filter.value.toList().at( 0 ).toString() );
// remove single quotes from the beginning and end of returned string
textValue = textValue.slice( 1, textValue.size() - 2 );
textValue.replace( QStringLiteral( "!" ), QStringLiteral( "!!" ) );
textValue.replace( QStringLiteral( "%" ), QStringLiteral( "!%" ) );
textValue.replace( QStringLiteral( "_" ), QStringLiteral( "!_" ) );
expressionCopy.replace( QStringLiteral( "@@value@@" ), textValue );
expressionCopy.append( QStringLiteral( " ESCAPE '!'" ) );
break;
}
case FieldFilter::CheckboxFilter:
Expand Down
66 changes: 65 additions & 1 deletion app/test/testfiltercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <QtTest/QtTest>
#include <QDateTime>
#include <QFile>
#include <QTemporaryDir>

#include <qgsproject.h>
#include <qgsvectorlayer.h>
Expand Down Expand Up @@ -554,11 +556,73 @@ void TestFilterController::testTextFilter()
filterValues[filterId] = QVariantList{ QStringLiteral( "great" ) };
mController->processFilters( filterValues );

const QString expected = QStringLiteral( "(\"Condition\" LIKE '%great%')" );
const QString expected = QStringLiteral( "(\"Condition\" LIKE '%great%' ESCAPE '!')" );
QCOMPARE( layer->subsetString(), expected );
QCOMPARE( layer->featureCount(), ( long long ) 14 );
}

void TestFilterController::testTextFilterWildcards_data()
{
QTest::addColumn<QString>( "searchValue" );
QTest::addColumn<QString>( "expectedPattern" );
QTest::addColumn<qlonglong>( "expectedCount" );

QTest::newRow( "percent" ) << QStringLiteral( "%" ) << QStringLiteral( "%!%%" ) << 2LL;
QTest::newRow( "underscore" ) << QStringLiteral( "_" ) << QStringLiteral( "%!_%" ) << 2LL;
QTest::newRow( "escape-character" ) << QStringLiteral( "!" ) << QStringLiteral( "%!!%" ) << 1LL;
QTest::newRow( "combined-wildcards" ) << QStringLiteral( "%_" ) << QStringLiteral( "%!%!_%" ) << 1LL;
}

void TestFilterController::testTextFilterWildcards()
{
QFETCH( QString, searchValue );
QFETCH( QString, expectedPattern );
QFETCH( qlonglong, expectedCount );

QTemporaryDir tempDir;
QVERIFY( tempDir.isValid() );
const QString layerPath = tempDir.filePath( QStringLiteral( "roads.gpkg" ) );
QVERIFY( QFile::copy( TestUtils::testDataDir() + QStringLiteral( "/filtering/roads.gpkg" ), layerPath ) );

const QString fieldName = QStringLiteral( "Condition" );
QgsVectorLayer *layer = new QgsVectorLayer(
layerPath + QStringLiteral( "|layername=roads" ),
QStringLiteral( "text-filter-wildcards" ),
QStringLiteral( "ogr" )
);
QVERIFY( layer );
QVERIFY( layer->isValid() );
QgsProject::instance()->addMapLayer( layer );

const QStringList values =
{
QStringLiteral( "plain" ),
QStringLiteral( "percent%only" ),
QStringLiteral( "under_score" ),
QStringLiteral( "bang!mark" ),
QStringLiteral( "both%_chars" )
};
for ( const QString &value : values )
{
QVERIFY( TestUtils::addFeatureToLayer( layer, fieldName, value ) );
}

const QString sql = QStringLiteral( "\"Condition\" LIKE '%@@value@@%'" );
const QString filterId = TestUtils::setupControllerWithFilter(
mController.get(), FieldFilter::TextFilter, layer->id(), fieldName, sql );
QVERIFY( !filterId.isEmpty() );

QVariantMap filterValues;
filterValues[filterId] = QVariantList{ searchValue };
mController->processFilters( filterValues );

const QString expected = QStringLiteral( "(\"Condition\" LIKE '%1' ESCAPE '!')" ).arg( expectedPattern );
QCOMPARE( layer->subsetString(), expected );
QCOMPARE( layer->featureCount(), expectedCount );

QgsProject::instance()->removeMapLayer( layer );
}

// Checkbox filter
void TestFilterController::testCheckboxFilter()
{
Expand Down
2 changes: 2 additions & 0 deletions app/test/testfiltercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class TestFilterController : public QObject

// Text filter
void testTextFilter();
void testTextFilterWildcards_data();
void testTextFilterWildcards();

// Checkbox filter
void testCheckboxFilter();
Expand Down