KDb

KDbNArgExpression.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2016 Jarosław Staniek <staniek@kde.org>
3
4 Based on nexp.cpp : Parser module of Python-like language
5 (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl)
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#include "KDbExpression.h"
24#include "KDb.h"
25#include "KDbDriver.h"
26#include "KDbQuerySchema.h"
27#include "KDbParser_p.h"
28#include "kdb_debug.h"
29
30KDbNArgExpressionData::KDbNArgExpressionData()
32{
33 ExpressionDebug << "NArgExpressionData" << ref;
34}
35
36KDbNArgExpressionData::~KDbNArgExpressionData()
37{
38 ExpressionDebug << "~NArgExpressionData" << ref;
39}
40
41KDbField::Type KDbNArgExpressionData::typeInternal(KDb::ExpressionCallStack *callStack) const
42{
43 if (token == KDbToken::BETWEEN_AND || token == KDbToken::NOT_BETWEEN_AND) {
44 for (int i = 0; i < children.count(); i++) {
45 KDbField::Type t = children.at(0)->type(callStack);
46 if (t == KDbField::InvalidType || t == KDbField::Null) {
47 return t;
48 }
49 }
50 return KDbField::Boolean;
51 }
52 return KDbField::Tuple;
53}
54
55KDbNArgExpressionData* KDbNArgExpressionData::clone()
56{
57 ExpressionDebug << "NArgExpressionData::clone" << *this;
58 return new KDbNArgExpressionData(*this);
59}
60
61bool KDbNArgExpressionData::validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack)
62{
63 foreach(ExplicitlySharedExpressionDataPointer data, children) {
64 if (!data->validate(parseInfo, callStack))
65 return false;
66 }
67
68 if (token == KDbToken::BETWEEN_AND || token == KDbToken::NOT_BETWEEN_AND) {
69 if (children.count() != 3) {
70 parseInfo->setErrorMessage(tr("Three arguments required"));
71 parseInfo->setErrorDescription(
72 tr("%1 operator requires exactly three arguments.", "BETWEEN..AND error")
73 .arg(QLatin1String("BETWEEN...AND")));
74 return false;
75 }
76 const KDbField::Type t0 = children[0]->type();
77 const KDbField::Type t1 = children[1]->type();
78 const KDbField::Type t2 = children[2]->type();
79 if (t0 == KDbField::Null || t1 == KDbField::Null || t2 == KDbField::Null) {
80 return true;
81 }
82 if (!( !KDbField::isNumericType(t0)
85 {
86 return true;
87 } else if (!( !KDbField::isTextType(t0)
89 || !KDbField::isTextType(t2)))
90 {
91 return true;
92 }
93
94 if (t0 == t1 && t1 == t2) {
95 return true;
96 }
97
98 parseInfo->setErrorMessage(tr("Incompatible types of arguments"));
99 parseInfo->setErrorDescription(
100 tr("Operator \"%1\" requires compatible types of arguments. "
101 "Specified arguments are of type %2, %3, %4.",
102 "BETWEEN..AND arguments type error")
103 .arg(QLatin1String("BETWEEN..AND"),
106 KDbField::typeName(t2)));
107 return false;
108 }
109 return true;
110}
111
113{
114 dbg.nospace() << "NArgExp("
115 << token.name() << ", class=" << expressionClassName(expressionClass);
116 foreach(ExplicitlySharedExpressionDataPointer data, children) {
117 dbg.nospace() << ", ";
118 data->debug(dbg, callStack);
119 }
120 dbg.nospace() << ",type=" << KDbDriver::defaultSqlTypeName(type()) << ")";
121}
122
123KDbEscapedString KDbNArgExpressionData::toStringInternal(
124 const KDbDriver *driver,
126 KDb::ExpressionCallStack* callStack) const
127{
128 if (token == KDbToken::BETWEEN_AND && children.count() == 3) {
129 return children[0]->toString(driver, params, callStack) + " BETWEEN "
130 + children[1]->toString(driver, params, callStack) + " AND "
131 + children[2]->toString(driver, params, callStack);
132 }
133 if (token == KDbToken::NOT_BETWEEN_AND && children.count() == 3) {
134 return children[0]->toString(driver, params, callStack) + " NOT BETWEEN "
135 + children[1]->toString(driver, params, callStack) + " AND "
136 + children[2]->toString(driver, params, callStack);
137 }
138
140 s.reserve(256);
141 foreach(ExplicitlySharedExpressionDataPointer data, children) {
142 if (!s.isEmpty())
143 s += ", ";
144 s += data->toString(driver, params, callStack);
145 }
146 return s;
147}
148
149void KDbNArgExpressionData::getQueryParameters(QList<KDbQuerySchemaParameter>* params)
150{
151 Q_ASSERT(params);
152 foreach(ExplicitlySharedExpressionDataPointer data, children) {
153 data->getQueryParameters(params);
154 }
155}
156
157bool KDbNArgExpressionData::containsInvalidArgument() const
158{
159 foreach(ExplicitlySharedExpressionDataPointer data, children) {
160 const KDbField::Type type = data->type();
162 return true;
163 }
164 }
165 return false;
166}
167
168bool KDbNArgExpressionData::containsNullArgument() const
169{
170 foreach(ExplicitlySharedExpressionDataPointer data, children) {
171 const KDbField::Type type = data->type();
172 if (type == KDbField::Null) {
173 return true;
174 }
175 }
176 return false;
177}
178
179//=========================================
180
183{
184 ExpressionDebug << "KDbNArgExpression() ctor" << *this;
185}
186
188 : KDbExpression(data)
189{
190 ExpressionDebug << "KDbNArgExpression(KDbExpressionData*) ctor" << *this;
191}
192
194 : KDbExpression(new KDbNArgExpressionData, aClass, token)
195{
196 ExpressionDebug << "KDbNArgExpression(KDb::ExpressionClass, int) ctor" << *this;
197}
198
203
205 : KDbExpression(ptr)
206{
207}
208
212
214{
215 appendChild(expr);
216}
217
219{
220 prependChild(expr);
221}
222
224{
225 return KDbExpression(d->children.value(i));
226}
227
229{
230 insertChild(i, expr);
231}
232
234{
235 if (!checkBeforeInsert(expr.d))
236 return;
237 if (i < 0 || i > d->children.count())
238 return;
239 d->children.at(i)->parent.reset();
240 d->children.replace(i, expr.d);
241 expr.d->parent = d;
242}
243
245{
246 return removeChild(expr);
247}
248
250{
251 removeChild(i);
252}
253
255{
256 return takeChild(i);
257}
258
259int KDbNArgExpression::indexOf(const KDbExpression& expr, int from) const
260{
261 return indexOfChild(expr, from);
262}
263
264int KDbNArgExpression::lastIndexOf(const KDbExpression& expr, int from) const
265{
266 return lastIndexOfChild(expr, from);
267}
268
270{
271 return d->children.count();
272}
273
275{
276 return d->children.isEmpty();
277}
278
283
Database driver's abstraction.
Definition KDbDriver.h:50
static QString defaultSqlTypeName(KDbField::Type type)
Specialized string for escaping.
Internal data class used to implement implicitly shared class KDbExpression.
KDbField::Type type() const
KDb::ExpressionClass expressionClass
The KDbExpression class represents a base class for all expressions.
ExplicitlySharedExpressionDataPointer d
bool isNumericType() const
Definition KDbField.h:317
bool isTextType() const
Definition KDbField.h:353
QString typeName() const
Definition KDbField.h:377
@ Boolean
Definition KDbField.h:92
@ InvalidType
Definition KDbField.h:86
Internal data class used to implement implicitly shared class KDbNArgExpression.
void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override
Sends information about this expression to debug output dbg (internal).
The KDbNArgExpression class represents a base class N-argument expression.
int lastIndexOf(const KDbExpression &expr, int from=-1) const
bool containsNullArgument() const
bool remove(const KDbExpression &expr)
~KDbNArgExpression() override
Destroys the expression.
KDbExpression arg(int i) const
void replace(int i, const KDbExpression &expr)
Replaces expression argument at index i with expression expr.
KDbExpression takeAt(int i)
void prepend(const KDbExpression &expr)
Inserts expression argument expr at the beginning of this expression.
bool containsInvalidArgument() const
int indexOf(const KDbExpression &expr, int from=0) const
void append(const KDbExpression &expr)
Inserts expression argument expr at the end of this expression.
void insert(int i, const KDbExpression &expr)
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
A type-safe KDbSQL token It can be used in KDb expressions.
Definition KDbToken.h:37
static const KDbToken BETWEEN_AND
Custom tokens are not used in parser but used as an extension in expression classes.
Definition KDbToken.h:173
QString name() const
Definition KDbToken.cpp:38
ExpressionClass
Classes of expressions.
QDebug & nospace()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:00:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.