mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
add ilike, in and not in to search string
git-svn-id: http://svn.osgeo.org/qgis/trunk@14156 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
d2cb8b281b
commit
1cbad87895
@ -112,6 +112,7 @@ class QgsQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
|
|||||||
*/
|
*/
|
||||||
void on_btnSampleValues_clicked();
|
void on_btnSampleValues_clicked();
|
||||||
void setDatasourceDescription( QString uri );
|
void setDatasourceDescription( QString uri );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* Populate the field list for the selected table
|
* Populate the field list for the selected table
|
||||||
|
@ -60,14 +60,6 @@ QgsSearchQueryBuilder::QgsSearchQueryBuilder( QgsVectorLayer* layer,
|
|||||||
pbn->setToolTip( tr( "Load query from xml file" ) );
|
pbn->setToolTip( tr( "Load query from xml file" ) );
|
||||||
connect( pbn, SIGNAL( clicked() ), this, SLOT( loadQuery() ) );
|
connect( pbn, SIGNAL( clicked() ), this, SLOT( loadQuery() ) );
|
||||||
|
|
||||||
// disable unsupported operators
|
|
||||||
btnIn->setHidden( true );
|
|
||||||
btnNotIn->setHidden( true );
|
|
||||||
btnPct->setHidden( true );
|
|
||||||
|
|
||||||
// change to ~
|
|
||||||
btnILike->setText( "~" );
|
|
||||||
|
|
||||||
lblDataUri->setText( layer->name() );
|
lblDataUri->setText( layer->name() );
|
||||||
populateFields();
|
populateFields();
|
||||||
}
|
}
|
||||||
@ -281,6 +273,21 @@ void QgsSearchQueryBuilder::on_btnGreaterThan_clicked()
|
|||||||
txtSQL->insertPlainText( " > " );
|
txtSQL->insertPlainText( " > " );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsSearchQueryBuilder::on_btnPct_clicked()
|
||||||
|
{
|
||||||
|
txtSQL->insertPlainText( "%" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsSearchQueryBuilder::on_btnIn_clicked()
|
||||||
|
{
|
||||||
|
txtSQL->insertPlainText( " IN " );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsSearchQueryBuilder::on_btnNotIn_clicked()
|
||||||
|
{
|
||||||
|
txtSQL->insertPlainText( " NOT IN " );
|
||||||
|
}
|
||||||
|
|
||||||
void QgsSearchQueryBuilder::on_btnLike_clicked()
|
void QgsSearchQueryBuilder::on_btnLike_clicked()
|
||||||
{
|
{
|
||||||
txtSQL->insertPlainText( " LIKE " );
|
txtSQL->insertPlainText( " LIKE " );
|
||||||
@ -343,8 +350,7 @@ void QgsSearchQueryBuilder::on_btnClear_clicked()
|
|||||||
|
|
||||||
void QgsSearchQueryBuilder::on_btnILike_clicked()
|
void QgsSearchQueryBuilder::on_btnILike_clicked()
|
||||||
{
|
{
|
||||||
//txtSQL->insertPlainText(" ILIKE ");
|
txtSQL->insertPlainText( " ILIKE " );
|
||||||
txtSQL->insertPlainText( " ~ " );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsSearchQueryBuilder::saveQuery()
|
void QgsSearchQueryBuilder::saveQuery()
|
||||||
|
@ -57,6 +57,9 @@ class QgsSearchQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
|
|||||||
void on_btnGreaterThan_clicked();
|
void on_btnGreaterThan_clicked();
|
||||||
void on_btnLike_clicked();
|
void on_btnLike_clicked();
|
||||||
void on_btnILike_clicked();
|
void on_btnILike_clicked();
|
||||||
|
void on_btnPct_clicked();
|
||||||
|
void on_btnIn_clicked();
|
||||||
|
void on_btnNotIn_clicked();
|
||||||
|
|
||||||
void on_lstFields_doubleClicked( const QModelIndex &index );
|
void on_lstFields_doubleClicked( const QModelIndex &index );
|
||||||
void on_lstValues_doubleClicked( const QModelIndex &index );
|
void on_lstValues_doubleClicked( const QModelIndex &index );
|
||||||
|
@ -70,6 +70,7 @@ string "'"{str_char}*"'"
|
|||||||
"NULL" { return NULLVALUE; }
|
"NULL" { return NULLVALUE; }
|
||||||
|
|
||||||
"IS" { return IS; }
|
"IS" { return IS; }
|
||||||
|
"IN" { return IN; }
|
||||||
|
|
||||||
"=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; }
|
"=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; }
|
||||||
"!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; }
|
"!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; }
|
||||||
@ -80,6 +81,7 @@ string "'"{str_char}*"'"
|
|||||||
">" { yylval.op = QgsSearchTreeNode::opGT; return COMPARISON; }
|
">" { yylval.op = QgsSearchTreeNode::opGT; return COMPARISON; }
|
||||||
"~" { yylval.op = QgsSearchTreeNode::opRegexp; return COMPARISON; }
|
"~" { yylval.op = QgsSearchTreeNode::opRegexp; return COMPARISON; }
|
||||||
"LIKE" { yylval.op = QgsSearchTreeNode::opLike; return COMPARISON; }
|
"LIKE" { yylval.op = QgsSearchTreeNode::opLike; return COMPARISON; }
|
||||||
|
"ILIKE" { yylval.op = QgsSearchTreeNode::opILike; return COMPARISON; }
|
||||||
|
|
||||||
"sqrt" { yylval.op = QgsSearchTreeNode::opSQRT; return FUNCTION;}
|
"sqrt" { yylval.op = QgsSearchTreeNode::opSQRT; return FUNCTION;}
|
||||||
"sin" { yylval.op = QgsSearchTreeNode::opSIN; return FUNCTION;}
|
"sin" { yylval.op = QgsSearchTreeNode::opSIN; return FUNCTION;}
|
||||||
|
@ -64,6 +64,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
|
|||||||
%token <op> FUNCTION
|
%token <op> FUNCTION
|
||||||
%token CONCAT
|
%token CONCAT
|
||||||
%token IS
|
%token IS
|
||||||
|
%token IN
|
||||||
%token ROWNUM
|
%token ROWNUM
|
||||||
%token AREA
|
%token AREA
|
||||||
%token LENGTH
|
%token LENGTH
|
||||||
@ -83,6 +84,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
|
|||||||
%type <node> predicate
|
%type <node> predicate
|
||||||
%type <node> comp_predicate
|
%type <node> comp_predicate
|
||||||
%type <node> scalar_exp
|
%type <node> scalar_exp
|
||||||
|
%type <node> scalar_exp_list
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
//%error-verbose
|
//%error-verbose
|
||||||
@ -130,9 +132,14 @@ comp_predicate:
|
|||||||
| scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
|
| scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
scalar_exp_list:
|
||||||
|
| scalar_exp_list ',' scalar_exp { $$ = $1; $1->append($3); joinTmpNodes($1,$1,$3); }
|
||||||
|
| scalar_exp { $$ = new QgsSearchTreeNode( QgsSearchTreeNode::tNodeList ); $$->append($1); joinTmpNodes($$,$$,$1); }
|
||||||
|
;
|
||||||
|
|
||||||
scalar_exp:
|
scalar_exp:
|
||||||
FUNCTION '(' scalar_exp ')' { $$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
|
FUNCTION '(' scalar_exp ')' { $$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
|
||||||
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
|
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$,$1,$3); }
|
||||||
| scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
|
| scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
|
||||||
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
|
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
|
||||||
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
|
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
|
||||||
@ -147,6 +154,8 @@ scalar_exp:
|
|||||||
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
|
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
|
||||||
| STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); }
|
| STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); }
|
||||||
| COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); }
|
| COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); }
|
||||||
|
| scalar_exp IN '(' scalar_exp_list ')' { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opIN, $1, $4); joinTmpNodes($$,$1,$4); }
|
||||||
|
| scalar_exp NOT IN '(' scalar_exp_list ')' { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opNOTIN, $1, $5); joinTmpNodes($$,$1,$5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -38,6 +38,16 @@
|
|||||||
|
|
||||||
#define EVAL_STR(x) (x.length() ? x : "(empty)")
|
#define EVAL_STR(x) (x.length() ? x : "(empty)")
|
||||||
|
|
||||||
|
QgsSearchTreeNode::QgsSearchTreeNode( QgsSearchTreeNode::Type t )
|
||||||
|
{
|
||||||
|
Q_ASSERT( t == tNodeList );
|
||||||
|
mType = t;
|
||||||
|
mLeft = NULL;
|
||||||
|
mRight = NULL;
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
QgsSearchTreeNode::QgsSearchTreeNode( double number )
|
QgsSearchTreeNode::QgsSearchTreeNode( double number )
|
||||||
{
|
{
|
||||||
mType = tNumber;
|
mType = tNumber;
|
||||||
@ -49,7 +59,8 @@ QgsSearchTreeNode::QgsSearchTreeNode( double number )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QgsSearchTreeNode::QgsSearchTreeNode( Operator op, QgsSearchTreeNode* left,
|
QgsSearchTreeNode::QgsSearchTreeNode( Operator op,
|
||||||
|
QgsSearchTreeNode* left,
|
||||||
QgsSearchTreeNode* right )
|
QgsSearchTreeNode* right )
|
||||||
{
|
{
|
||||||
mType = tOperator;
|
mType = tOperator;
|
||||||
@ -86,7 +97,6 @@ QgsSearchTreeNode::QgsSearchTreeNode( QString text, bool isColumnRef )
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QgsSearchTreeNode::QgsSearchTreeNode( const QgsSearchTreeNode& node )
|
QgsSearchTreeNode::QgsSearchTreeNode( const QgsSearchTreeNode& node )
|
||||||
{
|
{
|
||||||
mType = node.mType;
|
mType = node.mType;
|
||||||
@ -105,6 +115,9 @@ QgsSearchTreeNode::QgsSearchTreeNode( const QgsSearchTreeNode& node )
|
|||||||
else
|
else
|
||||||
mRight = NULL;
|
mRight = NULL;
|
||||||
|
|
||||||
|
foreach( QgsSearchTreeNode *lnode, node.mNodeList )
|
||||||
|
mNodeList.append( new QgsSearchTreeNode( *lnode ) );
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +132,9 @@ QgsSearchTreeNode::~QgsSearchTreeNode()
|
|||||||
if ( mRight )
|
if ( mRight )
|
||||||
delete mRight;
|
delete mRight;
|
||||||
|
|
||||||
|
while ( !mNodeList.isEmpty() )
|
||||||
|
delete mNodeList.takeFirst();
|
||||||
|
|
||||||
delete mCalc;
|
delete mCalc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +278,9 @@ QString QgsSearchTreeNode::makeSearchString()
|
|||||||
|
|
||||||
case opRegexp: str += " ~ "; break;
|
case opRegexp: str += " ~ "; break;
|
||||||
case opLike: str += " LIKE "; break;
|
case opLike: str += " LIKE "; break;
|
||||||
|
case opILike: str += " ILIKE "; break;
|
||||||
|
case opIN: str += " IN "; break;
|
||||||
|
case opNOTIN: str += " NOT IN "; break;
|
||||||
|
|
||||||
case opCONCAT: str += " || "; break;
|
case opCONCAT: str += " || "; break;
|
||||||
|
|
||||||
@ -283,6 +302,16 @@ QString QgsSearchTreeNode::makeSearchString()
|
|||||||
{
|
{
|
||||||
str += mText;
|
str += mText;
|
||||||
}
|
}
|
||||||
|
else if ( mType == tNodeList )
|
||||||
|
{
|
||||||
|
QStringList items;
|
||||||
|
foreach( QgsSearchTreeNode *node, mNodeList )
|
||||||
|
{
|
||||||
|
items << node->makeSearchString();
|
||||||
|
}
|
||||||
|
|
||||||
|
str += "(" + items.join( "," ) + ")";
|
||||||
|
}
|
||||||
else // unknown type
|
else // unknown type
|
||||||
{
|
{
|
||||||
str += "unknown_node_type:";
|
str += "unknown_node_type:";
|
||||||
@ -422,8 +451,39 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case opIN:
|
||||||
|
case opNOTIN:
|
||||||
|
{
|
||||||
|
if ( !getValue( value1, mLeft, fields, attributes, geom ) ||
|
||||||
|
!mRight || mRight->type() != tNodeList )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach( QgsSearchTreeNode *node, mRight->mNodeList )
|
||||||
|
{
|
||||||
|
if ( !getValue( value2, node, fields, attributes, geom ) )
|
||||||
|
{
|
||||||
|
mError = QObject::tr( "Could not retrieve value of list value" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = QgsSearchTreeValue::compare( value1, value2 );
|
||||||
|
|
||||||
|
if ( res == 0 )
|
||||||
|
{
|
||||||
|
// found
|
||||||
|
return mOp == opIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mOp == opNOTIN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case opRegexp:
|
case opRegexp:
|
||||||
case opLike:
|
case opLike:
|
||||||
|
case opILike:
|
||||||
{
|
{
|
||||||
if ( !getValue( value1, mLeft, fields, attributes, geom ) ||
|
if ( !getValue( value1, mLeft, fields, attributes, geom ) ||
|
||||||
!getValue( value2, mRight, fields, attributes, geom ) )
|
!getValue( value2, mRight, fields, attributes, geom ) )
|
||||||
@ -443,12 +503,12 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
|
|||||||
// TODO: reuse QRegExp
|
// TODO: reuse QRegExp
|
||||||
|
|
||||||
QString str = value2.string();
|
QString str = value2.string();
|
||||||
if ( mOp == opLike ) // change from LIKE syntax to regexp
|
if ( mOp == opLike || mOp == opILike ) // change from LIKE syntax to regexp
|
||||||
{
|
{
|
||||||
// XXX escape % and _ ???
|
// XXX escape % and _ ???
|
||||||
str.replace( "%", ".*" );
|
str.replace( "%", ".*" );
|
||||||
str.replace( "_", "." );
|
str.replace( "_", "." );
|
||||||
return QRegExp( str ).exactMatch( value1.string() );
|
return QRegExp( str, mOp == opLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( value1.string() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -705,7 +765,17 @@ void QgsSearchTreeNode::setCurrentRowNumber( int rownum )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsSearchTreeNode::append( QgsSearchTreeNode *node )
|
||||||
|
{
|
||||||
|
Q_ASSERT( mType == tNodeList );
|
||||||
|
mNodeList.append( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsSearchTreeNode::append( QList<QgsSearchTreeNode *> nodes )
|
||||||
|
{
|
||||||
|
foreach( QgsSearchTreeNode *node, nodes )
|
||||||
|
mNodeList.append( node );
|
||||||
|
}
|
||||||
|
|
||||||
int QgsSearchTreeValue::compare( QgsSearchTreeValue& value1, QgsSearchTreeValue& value2, Qt::CaseSensitivity cs )
|
int QgsSearchTreeValue::compare( QgsSearchTreeValue& value1, QgsSearchTreeValue& value2, Qt::CaseSensitivity cs )
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
#include <qgsfield.h>
|
#include <qgsfield.h>
|
||||||
#include <qgsfeature.h>
|
#include <qgsfeature.h>
|
||||||
@ -48,7 +49,8 @@ class CORE_EXPORT QgsSearchTreeNode
|
|||||||
tOperator = 1,
|
tOperator = 1,
|
||||||
tNumber,
|
tNumber,
|
||||||
tColumnRef,
|
tColumnRef,
|
||||||
tString
|
tString,
|
||||||
|
tNodeList,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! possible operators
|
//! possible operators
|
||||||
@ -83,16 +85,19 @@ class CORE_EXPORT QgsSearchTreeNode
|
|||||||
opAREA,
|
opAREA,
|
||||||
|
|
||||||
// comparison
|
// comparison
|
||||||
opISNULL, // IS NULL
|
opISNULL, // IS NULL
|
||||||
opISNOTNULL, // IS NOT NULL
|
opISNOTNULL, // IS NOT NULL
|
||||||
opEQ, // =
|
opEQ, // =
|
||||||
opNE, // != resp. <>
|
opNE, // != resp. <>
|
||||||
opGT, // >
|
opGT, // >
|
||||||
opLT, // <
|
opLT, // <
|
||||||
opGE, // >=
|
opGE, // >=
|
||||||
opLE, // <=
|
opLE, // <=
|
||||||
opRegexp, // ~
|
opRegexp, // ~
|
||||||
opLike, // LIKE
|
opLike, // LIKE
|
||||||
|
opILike, // ILIKE
|
||||||
|
opIN, // IN
|
||||||
|
opNOTIN, // NOT IN
|
||||||
|
|
||||||
// string handling
|
// string handling
|
||||||
opCONCAT,
|
opCONCAT,
|
||||||
@ -103,6 +108,7 @@ class CORE_EXPORT QgsSearchTreeNode
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! constructors
|
//! constructors
|
||||||
|
QgsSearchTreeNode( Type type );
|
||||||
QgsSearchTreeNode( double number );
|
QgsSearchTreeNode( double number );
|
||||||
QgsSearchTreeNode( Operator op, QgsSearchTreeNode* left, QgsSearchTreeNode* right );
|
QgsSearchTreeNode( Operator op, QgsSearchTreeNode* left, QgsSearchTreeNode* right );
|
||||||
QgsSearchTreeNode( QString text, bool isColumnRef );
|
QgsSearchTreeNode( QString text, bool isColumnRef );
|
||||||
@ -173,6 +179,14 @@ class CORE_EXPORT QgsSearchTreeNode
|
|||||||
//! @note added in 1.6
|
//! @note added in 1.6
|
||||||
void setCurrentRowNumber( int rownum );
|
void setCurrentRowNumber( int rownum );
|
||||||
|
|
||||||
|
//! append a node to the list
|
||||||
|
//! @note added in 1.6
|
||||||
|
void append( QgsSearchTreeNode * );
|
||||||
|
|
||||||
|
//! append nodelist to the list
|
||||||
|
//! @note added in 1.6
|
||||||
|
void append( QList<QgsSearchTreeNode*> );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
@ -197,6 +211,7 @@ class CORE_EXPORT QgsSearchTreeNode
|
|||||||
Operator mOp;
|
Operator mOp;
|
||||||
double mNumber;
|
double mNumber;
|
||||||
QString mText;
|
QString mText;
|
||||||
|
QList<QgsSearchTreeNode *> mNodeList;
|
||||||
|
|
||||||
QString mError;
|
QString mError;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user