1 /* This file is part of the KDE project
2    Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
3    Copyright (C) 2004-2018 Jarosław Staniek <staniek@kde.org>
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14 
15    You should have received a copy of the GNU Library General Public License
16    along with this library; see the file COPYING.LIB.  If not, write to
17    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19 */
20 
21 #ifndef KDB_PARSER_H
22 #define KDB_PARSER_H
23 
24 #include "kdb_export.h"
25 
26 #include <QString>
27 #include <QCoreApplication>
28 
29 class KDbConnection;
30 class KDbQuerySchema;
31 class KDbTableSchema;
32 class KDbEscapedString;
33 
34 /**
35  * Provides detailed error description about KDbParser.
36  *
37  * @todo Make it explicitly shared using SDC
38  * @todo change type to enum
39  */
40 class KDB_EXPORT KDbParserError
41 {
42 public:
43     /**
44      * Empty constructor.
45      */
46     KDbParserError();
47 
48     /**
49      * Constructor.
50      *
51      * @param type The error type.
52      * @param message A description of the error.
53      * @param token Token where the Error happend.
54      * @param position The position where the error happened.
55      */
56     KDbParserError(const QString &type, const QString &message, const QByteArray &token, int position);
57 
58     /**
59      * Copy constructor.
60      */
61     KDbParserError(const KDbParserError &other);
62 
63     ~KDbParserError();
64 
65     KDbParserError& operator=(const KDbParserError &other);
66 
67     bool operator==(const KDbParserError &other) const;
68 
69     inline bool operator!=(const KDbParserError &other) const { return !operator==(other); }
70 
71     /**
72      * @return the error type.
73      */
74     QString type() const;
75 
76     /**
77      * @return translated error message.
78      */
79     QString message() const;
80 
81     /**
82      * @return (character) position where the error happened.
83      */
84     int position() const;
85 
86 private:
87     class Private;
88     Private * const d;
89 };
90 
91 class KDbParserPrivate; //!< @internal
92 
93 /**
94  * A parser tool for SQL statements.
95  *
96  * The KDbParser class offers functionality of a SQL parser for database-backend-independent
97  * KDbSQL dialect. Schema objects such as KDbQuerySchema that are created after successful parsing
98  * can be then used for running the queries on actual data or used for further modification.
99  *
100  * @todo Add examples
101  * @todo Support more types than the SELECT
102  */
103 class KDB_EXPORT KDbParser
104 {
105     Q_DECLARE_TR_FUNCTIONS(KDbParser)
106 public:
107 
108     /**
109      * The type of the statement.
110      */
111     enum StatementType {
112         NoType,      //!< No statement type specified or detected
113         Select,      //!< Query-statement
114         CreateTable, //!< Create a new table
115         AlterTable,  //!< Alter schema of an existing table
116         Insert,      //!< Insert new records
117         Update,      //!< Update existing records
118         Delete       //!< Delete existing records
119     };
120 
121     /**
122      * Constructs an new parser object.
123      * @a connection is used to obtain context, for example wildcards "T.*" resolution
124      * is possible only if information about table T is available.
125      */
126     explicit KDbParser(KDbConnection *connection);
127 
128     ~KDbParser();
129 
130     /**
131      * @brief Clears the parser's status and runs the parsing for a raw SQL statement
132      *
133      * If parsing of @a sql results in a proper query and @a query is present, it will be set to
134      * representation of the parsed query.
135      * @since 3.1
136      */
137     bool parse(const KDbEscapedString &sql, KDbQuerySchema *query = nullptr);
138 
139     /**
140      * Reset the parser's status (table, query, error, statement, statement type).
141      */
142     void reset();
143 
144     /**
145      * @return the resulting statement type
146      * NoType is returned if parsing failed or it has not been yet performed or reset() was called.
147      */
148     StatementType statementType() const;
149 
150     /**
151      * @return the resulting statement type as string. It is not translated.
152      */
153     QString statementTypeString() const;
154 
155     /**
156      * @return a pointer to a query schema if 'CREATE TABLE ...' statement was parsed
157      * or @c nullptr for any other statements or on error.
158      * @note A proper table schema is returned only once for each successful parse() call,
159      * and the object is owned by the caller. In all other cases @c nullptr is returned.
160      *
161      * @todo Implement this
162      */
163     KDbTableSchema *table() Q_REQUIRED_RESULT;
164 
165     /**
166      * @return a pointer to a new query schema created by parsing 'SELECT ...' statement
167      * or @c nullptr for any other statements or on error.
168      * If existing query was supplied to parse() @c nullptr is returned.
169      * @note A proper query schema is returned only once for each successful parse() call,
170      * and the object is owned by the caller. In all other cases nullptr is returned.
171      */
172     KDbQuerySchema *query() Q_REQUIRED_RESULT;
173 
174     /**
175      * @return a pointer to the used database connection or @c nullptr if it was not set.
176      */
177     KDbConnection *connection();
178 
179     //! @overload
180     //! @since 3.1
181     const KDbConnection *connection() const;
182 
183     /**
184      * @return detailed information about last error.
185      * If no error occurred KDbParserError::type() is empty.
186      */
187     KDbParserError error() const;
188 
189     /**
190      * @return the statement passed on the most recent call of parse().
191      */
192     KDbEscapedString statement() const;
193 
194 private:
195     void init();
196 
197     friend class KDbParserPrivate;
198     KDbParserPrivate * const d; //!< @internal d-pointer class.
199     Q_DISABLE_COPY(KDbParser)
200 };
201 
202 //! Sends information about parser error @a error to debug output @a dbg.
203 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbParserError& error);
204 
205 #endif
206