|
|
/* This file is part of the KDB libraries Copyright (c) 2000 Praduroux Alessandro <pradu@thekompany.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef KDB_QUERY_H #define KDB_QUERY_H "$Id: query.h,v 1.7 2001/02/01 03:15:49 garbanzo Exp $" #include <qstring.h> #include <qstringlist.h> #include <qlist.h> #include <qmap.h> #include <ksharedptr.h> #include <kdb/recordset.h> #include <kdb/dataobject.h> namespace KDB { class Connector; class Recordset; class Query; class QueryPrivate; typedef KSharedPtr<Query> QueryPtr; typedef QValueList<QueryPtr> QueryList; typedef QValueListIterator<QueryPtr> QueryIterator; typedef QMap<QString,QString> ParameterList; struct qryField { QString table; QString name; QString aggregate; QString val; }; typedef QList<qryField> FldList; typedef QListIterator<qryField> FldIterator; struct qryCond { QString condition; int type; int level; }; typedef QList<qryCond> CondList; typedef QListIterator<qryCond> CondIterator; /** * Representation of a stored query. * * Through this object we access the fields and * parameters of the query, if any. * * Each query is stored in the database as an XML definition. This definition * will contain the list of fields, calculated fields (not implemented yet), tables, filters - join * expressions and parameters. One exception to that is done when the query is built * using an SQL expression in @ref Database::newQuery . In this case, the SQL is stored. * * Queries are of two types: select queries and command queries. Select queries can * be used to obtain a recordset using @ref openRecordset , while command queries are * executed using @ref execute . Command queries have different types: Update, Insert, * Delete. By default, a newly built query is a Select query. You can change the query * type using @ref setType * * Queries can be parametrized. While building the query, * the user can use the special construct %name, and provide a * corresponding value using the @ref setParameter call. Before the execution (through * @ref openRecordset or @ref execute ), a parameter substitution is done. When there is no * corresponding parameter value, the %xxx keyword is removed. This can lead to incorrect * SQL. Parameter substitution is done on the complete SQL statement, allowing creation * of queries that access data with similar definition in different tables with only one * query definition. * * @author Alessandro Praduroux <pradu@thekompany.com> * @version kdbcore 0.0.2 */ class Query :public DataObject{ friend class Connector; Q_OBJECT public: /** * The type of query. Select queries can be executed using @ref openRecordset, while * command queries through @ref execute. the opposite will generate an error. */ enum QueryType { Select, Insert, Update, Delete }; /** * Type of conditional expression. */ enum ConditionType { And, Or }; public: ~Query(); /** * Sets the query type. */ void setType(QueryType type); /** * Returns the query type */ QueryType type() const; /** * Return the list of known properties. This is a QDict<char> where the keys are * the parameter names and the items are the parameter values */ ParameterList parameters() const; /** * Set the value of a parameter */ void setParameter(const QString &prop, const QString &value); /** * Return the actual value of a parameter */ QString parameter(const QString &prop) const; /** * Append a new field to the field list of the query. * WARNING! aggregate functions aren't yet supported. The sig is here but the SQL ignores * aggregates. * @param table The table to which this field belongs. Ignored for command queries. * @param name The name of the field * @param aggregate The aggregate function to apply to this field * @param value The value this field should get (useful only for update and insert queries, * ignored otherwhise). * @return true if the field has been appended, false oterwise */ bool addField(const QString &table, const QString &name, const QString &value = QString::null, const QString &aggregate = QString::null); /** * Remove a field from the list of fields */ void removeField( const QString & table, const QString &name ); /** * Returns the list of fields */ FldList fields() const; /** * Add a table to the existing list of tables. For insert, update and delete queries * only the first table is taken into consideration. All others will be discarded * silently. * If this table is already present in the table list, and an alias isn't supplied, * it will be created based on the table name. * @returns the alias of the table added. */ QString addTable(const QString &name, const QString & alias = QString::null) ; /** * Remove a table from the list of tables, by alias. This will also remove all fields for the * removed table */ void removeTable(const QString &alias); /** * Return the list of table aliases. */ QStringList tables(); /** * given an alias, retrieve the corresponding table name */ QString tableName(const QString & alias); /** * Add a condition to the query. Ignored for insert queries. * * Conditions can be nested to an arbitrary level. Proper use of the level parameter can * lead to complex conditional expressions. * * for example: * <pre> * qry->addCondition("A = B", And, 0); * qry->addCondition("B = C", And, 1); * qry->addCondition("C = D", Or, 2); * qry->addCondition("E = C", And, 2); * qry->addCondition("F = A", And, 0); * </pre> * will lead to the following SQL condition: * <pre> * WHERE A = B * AND (B = C * OR (C = D * AND E = C * ) * ) * AND F = A * </pre> * @param condition The condition without 'where', 'and', or parenthesis. Something * like "table1.field1 is null" or "table1.field1 = table2.field1" * @param type Wether the condition should be ANDed or ORed with other same level conditions * @param level The nesting level of the condition */ void addCondition(const QString &condition, ConditionType type = And, int level = 0); /** * Remove a condition from the query. It will be removed the first condition that matches */ void removeCondition(const QString &condition, int level = 0); /** * Return a list of conditions */ CondList conditions(); /** * Return the SQL code associated to the query. The statement is computed * on the fly using the stored definition, and parameter parsing is performed. */ QString SQL(); /** * Executes a command query, and return the number of rows affected by this * query. If called on a select query, it will fail and generate an error. */ KDB_ULONG execute(); /** * Creates a recordset based on this query. * If called on a command query, it will fail and generate an error. */ virtual RecordsetPtr openRecordset(); /** * Saves the query into the database as XML definition or SQL, depending on how it is * created */ void save(); /** * Clear the content of all list (parameters, fields, tables) and the SQL */ void clear(); /** * Return true if the query has been modified somewhat */ bool isDirty(); signals: /** * This signal is emitted whenever the definition of the query changes. * That means a field or table or condition is added or removed */ void definitionChanged(); /** * This signal is emitted once when the query is saved the first time into * the database. It is used by Database to add the query name to the list of * database queries */ void created(Query *); protected: Query( Connector * conn, QObject *parent = 0L, const char *name = 0L, const QString &sql = QString::null ); /** * This function will create the SQL string to pass to * the DBMS engine. It can be overridden by special types of * queries ?? dunno if it will help */ virtual QString buildSQL(); private: QueryPrivate *d; Connector * connector; }; } #endif
Generated by: root@sparc.ports.openbsd.org on Wed May 2 09:48:14 2001, using kdoc 2.0a53. |