mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
603 lines
20 KiB
Plaintext
603 lines
20 KiB
Plaintext
class QgsSQLStatement
|
|
{
|
|
%TypeHeaderCode
|
|
#include "qgssqlstatement.h"
|
|
%End
|
|
|
|
public:
|
|
/**
|
|
* Creates a new SQL statement based on the provided string.
|
|
*/
|
|
QgsSQLStatement( const QString& statement );
|
|
~QgsSQLStatement();
|
|
|
|
//! Returns true if an error occurred when parsing the input statement
|
|
bool hasParserError() const;
|
|
//! Returns parser error
|
|
QString parserErrorString() const;
|
|
|
|
/** Performs basic validity checks. Basically checking that columns referencing
|
|
* a table, references a specified table. Returns true if the validation is
|
|
* successful */
|
|
bool doBasicValidationChecks( QString& errorMsgOut /Out/ ) const;
|
|
|
|
//! Returns root node of the statement. Root node is null is parsing has failed
|
|
const QgsSQLStatement::Node* rootNode() const;
|
|
|
|
//! Return the original, unmodified statement string.
|
|
//! If there was none supplied because it was constructed by sole
|
|
//! API calls, dump() will be used to create one instead.
|
|
QString statement() const;
|
|
|
|
//! Return a statement string, constructed from the internal
|
|
//! abstract syntax tree. This does not contain any nice whitespace
|
|
//! formatting or comments. In general it is preferrable to use
|
|
//! statement() instead.
|
|
QString dump() const;
|
|
|
|
/**
|
|
* @brief list of unary operators
|
|
* @note if any change is made here, the definition of QgsSQLStatement::UnaryOperatorText[] must be adapted.
|
|
*/
|
|
enum UnaryOperator
|
|
{
|
|
uoNot,
|
|
uoMinus,
|
|
};
|
|
|
|
/**
|
|
* @brief list of binary operators
|
|
* @note if any change is made here, the definition of QgsSQLStatement::BinaryOperatorText[] must be adapted.
|
|
*/
|
|
enum BinaryOperator
|
|
{
|
|
// logical
|
|
boOr,
|
|
boAnd,
|
|
|
|
// comparison
|
|
boEQ, // =
|
|
boNE, // <>
|
|
boLE, // <=
|
|
boGE, // >=
|
|
boLT, // <
|
|
boGT, // >
|
|
boLike,
|
|
boNotLike,
|
|
boILike,
|
|
boNotILike,
|
|
boIs,
|
|
boIsNot,
|
|
|
|
// math
|
|
boPlus,
|
|
boMinus,
|
|
boMul,
|
|
boDiv,
|
|
boIntDiv,
|
|
boMod,
|
|
boPow,
|
|
|
|
// strings
|
|
boConcat,
|
|
};
|
|
|
|
/**
|
|
* @brief list of join types
|
|
* @note if any change is made here, the definition of QgsSQLStatement::JoinTypeText[] must be adapted.
|
|
*/
|
|
enum JoinType
|
|
{
|
|
jtDefault,
|
|
jtLeft,
|
|
jtLeftOuter,
|
|
jtRight,
|
|
jtRightOuter,
|
|
jtCross,
|
|
jtInner,
|
|
jtFull
|
|
};
|
|
|
|
//! @note not available in Python bindings
|
|
// static const char* BinaryOperatorText[];
|
|
|
|
//! @note not available in Python bindings
|
|
// static const char* UnaryOperatorText[];
|
|
|
|
/** Returns a quoted column reference (in double quotes)
|
|
* @see quotedString(), quotedIdentifierIfNeeded()
|
|
*/
|
|
static QString quotedIdentifier( QString name );
|
|
|
|
/** Returns a quoted column reference (in double quotes) if needed, or
|
|
* otherwise the original string.
|
|
* @see quotedString(), quotedIdentifier()
|
|
*/
|
|
static QString quotedIdentifierIfNeeded( QString name );
|
|
|
|
/** Remove double quotes from an identifier.
|
|
* @see quotedIdentifier()
|
|
*/
|
|
static QString stripQuotedIdentifier(QString text);
|
|
|
|
/** Returns a quoted version of a string (in single quotes)
|
|
* @see quotedIdentifier(), quotedIdentifierIfNeeded()
|
|
*/
|
|
static QString quotedString( QString text );
|
|
|
|
|
|
//////
|
|
|
|
/** Node type */
|
|
enum NodeType
|
|
{
|
|
ntUnaryOperator,
|
|
ntBinaryOperator,
|
|
ntInOperator,
|
|
ntBetweenOperator,
|
|
ntFunction,
|
|
ntLiteral,
|
|
ntColumnRef,
|
|
ntSelectedColumn,
|
|
ntSelect,
|
|
ntTableDef,
|
|
ntJoin,
|
|
ntColumnSorted,
|
|
ntCast
|
|
};
|
|
|
|
/** Abstract node class */
|
|
class Node
|
|
{
|
|
%ConvertToSubClassCode
|
|
switch (sipCpp->nodeType())
|
|
{
|
|
case QgsSQLStatement::ntUnaryOperator: sipType = sipType_QgsSQLStatement_NodeUnaryOperator; break;
|
|
case QgsSQLStatement::ntBinaryOperator: sipType = sipType_QgsSQLStatement_NodeBinaryOperator; break;
|
|
case QgsSQLStatement::ntInOperator: sipType = sipType_QgsSQLStatement_NodeInOperator; break;
|
|
case QgsSQLStatement::ntBetweenOperator: sipType = sipType_QgsSQLStatement_NodeBetweenOperator; break;
|
|
case QgsSQLStatement::ntFunction: sipType = sipType_QgsSQLStatement_NodeFunction; break;
|
|
case QgsSQLStatement::ntLiteral: sipType = sipType_QgsSQLStatement_NodeLiteral; break;
|
|
case QgsSQLStatement::ntColumnRef: sipType = sipType_QgsSQLStatement_NodeColumnRef; break;
|
|
case QgsSQLStatement::ntSelectedColumn: sipType = sipType_QgsSQLStatement_NodeSelectedColumn; break;
|
|
case QgsSQLStatement::ntSelect: sipType = sipType_QgsSQLStatement_NodeSelect; break;
|
|
case QgsSQLStatement::ntTableDef: sipType = sipType_QgsSQLStatement_NodeTableDef; break;
|
|
case QgsSQLStatement::ntJoin: sipType = sipType_QgsSQLStatement_NodeJoin; break;
|
|
case QgsSQLStatement::ntColumnSorted: sipType = sipType_QgsSQLStatement_NodeColumnSorted; break;
|
|
case QgsSQLStatement::ntCast: sipType = sipType_QgsSQLStatement_NodeCast; break;
|
|
default: sipType = 0; break;
|
|
}
|
|
%End
|
|
|
|
public:
|
|
virtual ~Node();
|
|
|
|
/**
|
|
* Abstract virtual that returns the type of this node.
|
|
*
|
|
* @return The type of this node
|
|
*/
|
|
virtual QgsSQLStatement::NodeType nodeType() const = 0;
|
|
|
|
/**
|
|
* Abstract virtual dump method
|
|
*
|
|
* @return A statement which represents this node as string
|
|
*/
|
|
virtual QString dump() const = 0;
|
|
|
|
/**
|
|
* Generate a clone of this node.
|
|
* Make sure that the clone does not contain any information which is
|
|
* generated in prepare and context related.
|
|
* Ownership is transferred to the caller.
|
|
*
|
|
* @return a deep copy of this node.
|
|
*/
|
|
virtual QgsSQLStatement::Node* clone() const = 0 /Factory/;
|
|
|
|
/**
|
|
* Support the visitor pattern.
|
|
*
|
|
* For any implementation this should look like
|
|
*
|
|
* C++:
|
|
*
|
|
* v.visit( *this );
|
|
*
|
|
* Python:
|
|
*
|
|
* v.visit( self)
|
|
*
|
|
* @param v A visitor that visits this node.
|
|
*/
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const = 0;
|
|
};
|
|
|
|
/** List of nodes */
|
|
class NodeList
|
|
{
|
|
public:
|
|
NodeList();
|
|
~NodeList();
|
|
/** Takes ownership of the provided node */
|
|
void append( QgsSQLStatement::Node* node /Transfer/ );
|
|
|
|
/** Returns the number of nodes in the list.
|
|
*/
|
|
int count() const;
|
|
|
|
/** Accept visitor */
|
|
void accept( QgsSQLStatement::Visitor& v ) const;
|
|
|
|
const QList<QgsSQLStatement::Node*>& list();
|
|
|
|
/** Creates a deep copy of this list. Ownership is transferred to the caller */
|
|
QgsSQLStatement::NodeList* clone() const /Factory/;
|
|
|
|
virtual QString dump() const;
|
|
};
|
|
|
|
/** Unary logicial/arithmetical operator ( NOT, - ) */
|
|
class NodeUnaryOperator : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeUnaryOperator( QgsSQLStatement::UnaryOperator op, QgsSQLStatement::Node* operand /Transfer/ );
|
|
~NodeUnaryOperator();
|
|
|
|
/** Operator */
|
|
QgsSQLStatement::UnaryOperator op() const;
|
|
|
|
/** Operand */
|
|
QgsSQLStatement::Node* operand() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
/** Binary logical/arithmetical operator (AND, OR, =, +, ...) */
|
|
class NodeBinaryOperator : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeBinaryOperator( QgsSQLStatement::BinaryOperator op, QgsSQLStatement::Node* opLeft /Transfer/, QgsSQLStatement::Node* opRight /Transfer/ );
|
|
~NodeBinaryOperator();
|
|
|
|
/** Operator */
|
|
QgsSQLStatement::BinaryOperator op() const;
|
|
|
|
/** Left operand */
|
|
QgsSQLStatement::Node* opLeft() const;
|
|
|
|
/** Right operand */
|
|
QgsSQLStatement::Node* opRight() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
|
|
/** Precedence */
|
|
int precedence() const;
|
|
|
|
/** Is left associative ? */
|
|
bool leftAssociative() const;
|
|
};
|
|
|
|
/** 'x IN (y, z)' operator */
|
|
class NodeInOperator : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeInOperator( QgsSQLStatement::Node* node /Transfer/, QgsSQLStatement::NodeList* list /Transfer/, bool notin = false );
|
|
~NodeInOperator();
|
|
|
|
/** Variable at the left of IN */
|
|
QgsSQLStatement::Node* node() const;
|
|
|
|
/** Whether this is a NOT IN operator */
|
|
bool isNotIn() const;
|
|
|
|
/** Values list */
|
|
QgsSQLStatement::NodeList* list() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
/** 'X BETWEEN y and z' operator */
|
|
class NodeBetweenOperator : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeBetweenOperator( QgsSQLStatement::Node* node /Transfer/, QgsSQLStatement::Node* minVal /Transfer/, QgsSQLStatement::Node* maxVal /Transfer/, bool notbetween = false );
|
|
~NodeBetweenOperator();
|
|
|
|
/** Variable at the left of BETWEEN */
|
|
QgsSQLStatement::Node* node() const;
|
|
|
|
/** Whether this is a NOT BETWEEN operator */
|
|
bool isNotBetween() const;
|
|
|
|
/** Minimum bound */
|
|
QgsSQLStatement::Node* minVal() const;
|
|
|
|
/** Maximum bound */
|
|
QgsSQLStatement::Node* maxVal() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
/** Function with a name and arguments node */
|
|
class NodeFunction : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeFunction( QString name, QgsSQLStatement::NodeList* args /Transfer/ );
|
|
~NodeFunction();
|
|
|
|
/** Return function name */
|
|
QString name() const;
|
|
|
|
/** Return arguments */
|
|
QgsSQLStatement::NodeList* args() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
/** Literal value (integer, integer64, double, string) */
|
|
class NodeLiteral : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeLiteral( const QVariant& value );
|
|
|
|
/** The value of the literal. */
|
|
const QVariant& value() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
};
|
|
|
|
/** Reference to a column */
|
|
class NodeColumnRef : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeColumnRef( const QString& tableName, const QString& name, bool star );
|
|
NodeColumnRef( const QString& name, bool star );
|
|
|
|
/** Set whether this is prefixed by DISTINCT */
|
|
void setDistinct( bool distinct = true );
|
|
|
|
/** The name of the table. May be empty. */
|
|
QString tableName() const;
|
|
|
|
/** The name of the column. */
|
|
QString name() const;
|
|
|
|
/** Whether this is prefixed by DISTINCT */
|
|
bool distinct() const;
|
|
|
|
/** Whether this is the * column */
|
|
bool star() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
/** Clone with same type return */
|
|
QgsSQLStatement::NodeColumnRef* cloneThis() const /Factory/;
|
|
};
|
|
|
|
/** Selected column */
|
|
class NodeSelectedColumn : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeSelectedColumn( QgsSQLStatement::Node* node /Transfer/ );
|
|
|
|
/** Set alias name */
|
|
void setAlias( const QString& alias );
|
|
|
|
/** Column that is refered to */
|
|
QgsSQLStatement::Node* column() const;
|
|
|
|
/** Alias name */
|
|
QString alias() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
|
|
/** Clone with same type return */
|
|
QgsSQLStatement::NodeSelectedColumn* cloneThis() const /Factory/;
|
|
};
|
|
|
|
/** CAST operator */
|
|
class NodeCast : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeCast( QgsSQLStatement::Node* node /Transfer/, const QString& type );
|
|
|
|
/** Node that is refered to */
|
|
QgsSQLStatement::Node* node() const;
|
|
|
|
/** Type */
|
|
QString type() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
/** Table definition */
|
|
class NodeTableDef : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeTableDef( const QString& name, const QString& alias );
|
|
NodeTableDef( const QString& name );
|
|
|
|
/** Table name */
|
|
QString name() const;
|
|
|
|
/** Table alias */
|
|
QString alias() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
/** Clone with same type return */
|
|
QgsSQLStatement::NodeTableDef* cloneThis() const /Factory/;
|
|
};
|
|
|
|
/** Join definition */
|
|
class NodeJoin : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeJoin( QgsSQLStatement::NodeTableDef* tabledef /Transfer/, QgsSQLStatement::Node* onExpr /Transfer/, QgsSQLStatement::JoinType type );
|
|
NodeJoin( QgsSQLStatement::NodeTableDef* tabledef /Transfer/, QList<QString> usingColumns, QgsSQLStatement::JoinType type );
|
|
|
|
/** Table definition */
|
|
QgsSQLStatement::NodeTableDef* tableDef() const;
|
|
|
|
/** On expression. Will be nullptr if usingColumns() is not empty */
|
|
QgsSQLStatement::Node* onExpr() const;
|
|
|
|
/** Columns referenced by USING */
|
|
QList<QString> usingColumns() const;
|
|
|
|
/** Join type */
|
|
QgsSQLStatement::JoinType type() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
/** Clone with same type return */
|
|
QgsSQLStatement::NodeJoin* cloneThis() const /Factory/;
|
|
};
|
|
|
|
/** Column in a ORDER BY */
|
|
class NodeColumnSorted : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeColumnSorted( QgsSQLStatement::NodeColumnRef* column /Transfer/, bool asc );
|
|
|
|
/** The name of the column. */
|
|
QgsSQLStatement::NodeColumnRef* column() const;
|
|
|
|
/** Whether the column is sorted in ascending order */
|
|
bool ascending() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
/** Clone with same type return */
|
|
QgsSQLStatement::NodeColumnSorted* cloneThis() const /Factory/;
|
|
};
|
|
|
|
/** SELECT node */
|
|
class NodeSelect : QgsSQLStatement::Node
|
|
{
|
|
public:
|
|
NodeSelect( QList<QgsSQLStatement::NodeTableDef*> tableList /Transfer/, QList<QgsSQLStatement::NodeSelectedColumn*> columns /Transfer/, bool distinct );
|
|
|
|
/** Set joins */
|
|
void setJoins( QList<QgsSQLStatement::NodeJoin*> joins /Transfer/ );
|
|
/** Append a join */
|
|
void appendJoin( QgsSQLStatement::NodeJoin* join /Transfer/ );
|
|
/** Set where clause */
|
|
void setWhere( QgsSQLStatement::Node* where /Transfer/ );
|
|
/** Set order by columns */
|
|
void setOrderBy( QList<QgsSQLStatement::NodeColumnSorted*> orderBy /Transfer/ );
|
|
|
|
/** Return the list of tables */
|
|
QList<QgsSQLStatement::NodeTableDef*> tables() const;
|
|
/** Return the list of columns */
|
|
QList<QgsSQLStatement::NodeSelectedColumn*> columns() const;
|
|
/** Return if the SELECT is DISTINCT */
|
|
bool distinct() const;
|
|
/** Return the list of joins */
|
|
QList<QgsSQLStatement::NodeJoin*> joins() const;
|
|
/** Return the where clause */
|
|
QgsSQLStatement::Node* where() const;
|
|
/** Return the list of order by columns */
|
|
QList<QgsSQLStatement::NodeColumnSorted*> orderBy() const;
|
|
|
|
virtual QgsSQLStatement::NodeType nodeType() const;
|
|
virtual QString dump() const;
|
|
|
|
virtual void accept( QgsSQLStatement::Visitor& v ) const;
|
|
virtual QgsSQLStatement::Node* clone() const /Factory/;
|
|
};
|
|
|
|
//////
|
|
|
|
/** Support for visitor pattern - algorithms dealing with the statement
|
|
may be implemented without modifying the Node classes */
|
|
class Visitor
|
|
{
|
|
public:
|
|
virtual ~Visitor();
|
|
virtual void visit( const QgsSQLStatement::NodeUnaryOperator& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeBinaryOperator& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeInOperator& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeBetweenOperator& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeFunction& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeLiteral& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeColumnRef& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeSelectedColumn& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeTableDef& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeJoin& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeColumnSorted& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeSelect& n ) = 0;
|
|
virtual void visit( const QgsSQLStatement::NodeCast& n ) = 0;
|
|
};
|
|
|
|
/** A visitor that recursively explores all children */
|
|
class RecursiveVisitor: public QgsSQLStatement::Visitor
|
|
{
|
|
public:
|
|
RecursiveVisitor();
|
|
|
|
virtual void visit( const QgsSQLStatement::NodeUnaryOperator& n );
|
|
virtual void visit( const QgsSQLStatement::NodeBinaryOperator& n );
|
|
virtual void visit( const QgsSQLStatement::NodeInOperator& n );
|
|
virtual void visit( const QgsSQLStatement::NodeBetweenOperator& n) ;
|
|
virtual void visit( const QgsSQLStatement::NodeFunction& n );
|
|
virtual void visit( const QgsSQLStatement::NodeLiteral& n );
|
|
virtual void visit( const QgsSQLStatement::NodeColumnRef& n );
|
|
virtual void visit( const QgsSQLStatement::NodeSelectedColumn& n );
|
|
virtual void visit( const QgsSQLStatement::NodeTableDef& n );
|
|
virtual void visit( const QgsSQLStatement::NodeJoin& n );
|
|
virtual void visit( const QgsSQLStatement::NodeColumnSorted& n );
|
|
virtual void visit( const QgsSQLStatement::NodeSelect& n );
|
|
virtual void visit( const QgsSQLStatement::NodeCast& n );
|
|
};
|
|
|
|
/** Entry function for the visitor pattern */
|
|
void acceptVisitor( QgsSQLStatement::Visitor& v ) const;
|
|
};
|