Skip to content

Commit 1cbad87

Browse files
author
jef
committed
add ilike, in and not in to search string
git-svn-id: http://svn.osgeo.org/qgis/trunk@14156 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent d2cb8b2 commit 1cbad87

7 files changed

+131
-25
lines changed

src/app/qgsquerybuilder.h

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class QgsQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
112112
*/
113113
void on_btnSampleValues_clicked();
114114
void setDatasourceDescription( QString uri );
115+
115116
private:
116117
/*!
117118
* Populate the field list for the selected table

src/app/qgssearchquerybuilder.cpp

+16-10
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,6 @@ QgsSearchQueryBuilder::QgsSearchQueryBuilder( QgsVectorLayer* layer,
6060
pbn->setToolTip( tr( "Load query from xml file" ) );
6161
connect( pbn, SIGNAL( clicked() ), this, SLOT( loadQuery() ) );
6262

63-
// disable unsupported operators
64-
btnIn->setHidden( true );
65-
btnNotIn->setHidden( true );
66-
btnPct->setHidden( true );
67-
68-
// change to ~
69-
btnILike->setText( "~" );
70-
7163
lblDataUri->setText( layer->name() );
7264
populateFields();
7365
}
@@ -281,6 +273,21 @@ void QgsSearchQueryBuilder::on_btnGreaterThan_clicked()
281273
txtSQL->insertPlainText( " > " );
282274
}
283275

276+
void QgsSearchQueryBuilder::on_btnPct_clicked()
277+
{
278+
txtSQL->insertPlainText( "%" );
279+
}
280+
281+
void QgsSearchQueryBuilder::on_btnIn_clicked()
282+
{
283+
txtSQL->insertPlainText( " IN " );
284+
}
285+
286+
void QgsSearchQueryBuilder::on_btnNotIn_clicked()
287+
{
288+
txtSQL->insertPlainText( " NOT IN " );
289+
}
290+
284291
void QgsSearchQueryBuilder::on_btnLike_clicked()
285292
{
286293
txtSQL->insertPlainText( " LIKE " );
@@ -343,8 +350,7 @@ void QgsSearchQueryBuilder::on_btnClear_clicked()
343350

344351
void QgsSearchQueryBuilder::on_btnILike_clicked()
345352
{
346-
//txtSQL->insertPlainText(" ILIKE ");
347-
txtSQL->insertPlainText( " ~ " );
353+
txtSQL->insertPlainText( " ILIKE " );
348354
}
349355

350356
void QgsSearchQueryBuilder::saveQuery()

src/app/qgssearchquerybuilder.h

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class QgsSearchQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
5757
void on_btnGreaterThan_clicked();
5858
void on_btnLike_clicked();
5959
void on_btnILike_clicked();
60+
void on_btnPct_clicked();
61+
void on_btnIn_clicked();
62+
void on_btnNotIn_clicked();
6063

6164
void on_lstFields_doubleClicked( const QModelIndex &index );
6265
void on_lstValues_doubleClicked( const QModelIndex &index );

src/core/qgssearchstringlexer.ll

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ string "'"{str_char}*"'"
7070
"NULL" { return NULLVALUE; }
7171
7272
"IS" { return IS; }
73+
"IN" { return IN; }
7374
7475
"=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; }
7576
"!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; }
@@ -80,6 +81,7 @@ string "'"{str_char}*"'"
8081
">" { yylval.op = QgsSearchTreeNode::opGT; return COMPARISON; }
8182
"~" { yylval.op = QgsSearchTreeNode::opRegexp; return COMPARISON; }
8283
"LIKE" { yylval.op = QgsSearchTreeNode::opLike; return COMPARISON; }
84+
"ILIKE" { yylval.op = QgsSearchTreeNode::opILike; return COMPARISON; }
8385
8486
"sqrt" { yylval.op = QgsSearchTreeNode::opSQRT; return FUNCTION;}
8587
"sin" { yylval.op = QgsSearchTreeNode::opSIN; return FUNCTION;}

src/core/qgssearchstringparser.yy

+10-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
6464
%token <op> FUNCTION
6565
%token CONCAT
6666
%token IS
67+
%token IN
6768
%token ROWNUM
6869
%token AREA
6970
%token LENGTH
@@ -83,6 +84,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
8384
%type <node> predicate
8485
%type <node> comp_predicate
8586
%type <node> scalar_exp
87+
%type <node> scalar_exp_list
8688

8789
// debugging
8890
//%error-verbose
@@ -130,9 +132,14 @@ comp_predicate:
130132
| scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
131133
;
132134

135+
scalar_exp_list:
136+
| scalar_exp_list ',' scalar_exp { $$ = $1; $1->append($3); joinTmpNodes($1,$1,$3); }
137+
| scalar_exp { $$ = new QgsSearchTreeNode( QgsSearchTreeNode::tNodeList ); $$->append($1); joinTmpNodes($$,$$,$1); }
138+
;
139+
133140
scalar_exp:
134141
FUNCTION '(' scalar_exp ')' { $$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
135-
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
142+
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$,$1,$3); }
136143
| scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
137144
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
138145
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
@@ -147,6 +154,8 @@ scalar_exp:
147154
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
148155
| STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); }
149156
| COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); }
157+
| scalar_exp IN '(' scalar_exp_list ')' { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opIN, $1, $4); joinTmpNodes($$,$1,$4); }
158+
| scalar_exp NOT IN '(' scalar_exp_list ')' { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opNOTIN, $1, $5); joinTmpNodes($$,$1,$5); }
150159
;
151160

152161
%%

src/core/qgssearchtreenode.cpp

+74-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@
3838

3939
#define EVAL_STR(x) (x.length() ? x : "(empty)")
4040

41+
QgsSearchTreeNode::QgsSearchTreeNode( QgsSearchTreeNode::Type t )
42+
{
43+
Q_ASSERT( t == tNodeList );
44+
mType = t;
45+
mLeft = NULL;
46+
mRight = NULL;
47+
48+
init();
49+
}
50+
4151
QgsSearchTreeNode::QgsSearchTreeNode( double number )
4252
{
4353
mType = tNumber;
@@ -49,7 +59,8 @@ QgsSearchTreeNode::QgsSearchTreeNode( double number )
4959
}
5060

5161

52-
QgsSearchTreeNode::QgsSearchTreeNode( Operator op, QgsSearchTreeNode* left,
62+
QgsSearchTreeNode::QgsSearchTreeNode( Operator op,
63+
QgsSearchTreeNode* left,
5364
QgsSearchTreeNode* right )
5465
{
5566
mType = tOperator;
@@ -86,7 +97,6 @@ QgsSearchTreeNode::QgsSearchTreeNode( QString text, bool isColumnRef )
8697
init();
8798
}
8899

89-
90100
QgsSearchTreeNode::QgsSearchTreeNode( const QgsSearchTreeNode& node )
91101
{
92102
mType = node.mType;
@@ -105,6 +115,9 @@ QgsSearchTreeNode::QgsSearchTreeNode( const QgsSearchTreeNode& node )
105115
else
106116
mRight = NULL;
107117

118+
foreach( QgsSearchTreeNode *lnode, node.mNodeList )
119+
mNodeList.append( new QgsSearchTreeNode( *lnode ) );
120+
108121
init();
109122
}
110123

@@ -119,6 +132,9 @@ QgsSearchTreeNode::~QgsSearchTreeNode()
119132
if ( mRight )
120133
delete mRight;
121134

135+
while ( !mNodeList.isEmpty() )
136+
delete mNodeList.takeFirst();
137+
122138
delete mCalc;
123139
}
124140

@@ -262,6 +278,9 @@ QString QgsSearchTreeNode::makeSearchString()
262278

263279
case opRegexp: str += " ~ "; break;
264280
case opLike: str += " LIKE "; break;
281+
case opILike: str += " ILIKE "; break;
282+
case opIN: str += " IN "; break;
283+
case opNOTIN: str += " NOT IN "; break;
265284

266285
case opCONCAT: str += " || "; break;
267286

@@ -283,6 +302,16 @@ QString QgsSearchTreeNode::makeSearchString()
283302
{
284303
str += mText;
285304
}
305+
else if ( mType == tNodeList )
306+
{
307+
QStringList items;
308+
foreach( QgsSearchTreeNode *node, mNodeList )
309+
{
310+
items << node->makeSearchString();
311+
}
312+
313+
str += "(" + items.join( "," ) + ")";
314+
}
286315
else // unknown type
287316
{
288317
str += "unknown_node_type:";
@@ -422,8 +451,39 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
422451
return false;
423452
}
424453

454+
case opIN:
455+
case opNOTIN:
456+
{
457+
if ( !getValue( value1, mLeft, fields, attributes, geom ) ||
458+
!mRight || mRight->type() != tNodeList )
459+
{
460+
return false;
461+
}
462+
463+
foreach( QgsSearchTreeNode *node, mRight->mNodeList )
464+
{
465+
if ( !getValue( value2, node, fields, attributes, geom ) )
466+
{
467+
mError = QObject::tr( "Could not retrieve value of list value" );
468+
return false;
469+
}
470+
471+
res = QgsSearchTreeValue::compare( value1, value2 );
472+
473+
if ( res == 0 )
474+
{
475+
// found
476+
return mOp == opIN;
477+
}
478+
}
479+
480+
return mOp == opNOTIN;
481+
}
482+
break;
483+
425484
case opRegexp:
426485
case opLike:
486+
case opILike:
427487
{
428488
if ( !getValue( value1, mLeft, fields, attributes, geom ) ||
429489
!getValue( value2, mRight, fields, attributes, geom ) )
@@ -443,12 +503,12 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
443503
// TODO: reuse QRegExp
444504

445505
QString str = value2.string();
446-
if ( mOp == opLike ) // change from LIKE syntax to regexp
506+
if ( mOp == opLike || mOp == opILike ) // change from LIKE syntax to regexp
447507
{
448508
// XXX escape % and _ ???
449509
str.replace( "%", ".*" );
450510
str.replace( "_", "." );
451-
return QRegExp( str ).exactMatch( value1.string() );
511+
return QRegExp( str, mOp == opLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( value1.string() );
452512
}
453513
else
454514
{
@@ -705,7 +765,17 @@ void QgsSearchTreeNode::setCurrentRowNumber( int rownum )
705765
}
706766
}
707767

768+
void QgsSearchTreeNode::append( QgsSearchTreeNode *node )
769+
{
770+
Q_ASSERT( mType == tNodeList );
771+
mNodeList.append( node );
772+
}
708773

774+
void QgsSearchTreeNode::append( QList<QgsSearchTreeNode *> nodes )
775+
{
776+
foreach( QgsSearchTreeNode *node, nodes )
777+
mNodeList.append( node );
778+
}
709779

710780
int QgsSearchTreeValue::compare( QgsSearchTreeValue& value1, QgsSearchTreeValue& value2, Qt::CaseSensitivity cs )
711781
{

src/core/qgssearchtreenode.h

+25-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <QString>
2525
#include <QStringList>
2626
#include <QVariant>
27+
#include <QList>
2728

2829
#include <qgsfield.h>
2930
#include <qgsfeature.h>
@@ -48,7 +49,8 @@ class CORE_EXPORT QgsSearchTreeNode
4849
tOperator = 1,
4950
tNumber,
5051
tColumnRef,
51-
tString
52+
tString,
53+
tNodeList,
5254
};
5355

5456
//! possible operators
@@ -83,16 +85,19 @@ class CORE_EXPORT QgsSearchTreeNode
8385
opAREA,
8486

8587
// comparison
86-
opISNULL, // IS NULL
88+
opISNULL, // IS NULL
8789
opISNOTNULL, // IS NOT NULL
88-
opEQ, // =
89-
opNE, // != resp. <>
90-
opGT, // >
91-
opLT, // <
92-
opGE, // >=
93-
opLE, // <=
94-
opRegexp, // ~
95-
opLike, // LIKE
90+
opEQ, // =
91+
opNE, // != resp. <>
92+
opGT, // >
93+
opLT, // <
94+
opGE, // >=
95+
opLE, // <=
96+
opRegexp, // ~
97+
opLike, // LIKE
98+
opILike, // ILIKE
99+
opIN, // IN
100+
opNOTIN, // NOT IN
96101

97102
// string handling
98103
opCONCAT,
@@ -103,6 +108,7 @@ class CORE_EXPORT QgsSearchTreeNode
103108
};
104109

105110
//! constructors
111+
QgsSearchTreeNode( Type type );
106112
QgsSearchTreeNode( double number );
107113
QgsSearchTreeNode( Operator op, QgsSearchTreeNode* left, QgsSearchTreeNode* right );
108114
QgsSearchTreeNode( QString text, bool isColumnRef );
@@ -173,6 +179,14 @@ class CORE_EXPORT QgsSearchTreeNode
173179
//! @note added in 1.6
174180
void setCurrentRowNumber( int rownum );
175181

182+
//! append a node to the list
183+
//! @note added in 1.6
184+
void append( QgsSearchTreeNode * );
185+
186+
//! append nodelist to the list
187+
//! @note added in 1.6
188+
void append( QList<QgsSearchTreeNode*> );
189+
176190
protected:
177191

178192

@@ -197,6 +211,7 @@ class CORE_EXPORT QgsSearchTreeNode
197211
Operator mOp;
198212
double mNumber;
199213
QString mText;
214+
QList<QgsSearchTreeNode *> mNodeList;
200215

201216
QString mError;
202217

0 commit comments

Comments
 (0)