KDb

KDbDriver.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "KDbDriver.h"
21#include "KDbAdmin.h"
22#include "KDbConnectionData.h"
23#include "KDbConnection.h"
24#include "KDbConnectionOptions.h"
25#include "KDbDriverManager_p.h"
26#include "KDbDriverMetaData.h"
27#include "KDbDriver_p.h"
28#include "KDbDriverBehavior.h"
29#include "KDbError.h"
30#include "KDbExpression.h"
31#include "kdb_debug.h"
32
33#include <algorithm>
34
35/*! @internal Used in KDbDriver::defaultSqlTypeName(int)
36 when we do not have KDbDriver instance yet, or when we cannot get one */
37static const char* const KDb_defaultSqlTypeNames[] = {
38 "InvalidType",
39 "Byte",
40 "ShortInteger",
41 "Integer",
42 "BigInteger",
43 "Boolean",
44 "Date",
45 "DateTime",
46 "Time",
47 "Float",
48 "Double",
49 "Text",
50 "LongText",
51 "BLOB"
52};
53
54//---------------------------------------------
55
56KDbDriver::KDbDriver(QObject *parent, const QVariantList &args)
57 : QObject(parent)
58 , d(new KDbDriverPrivate(this))
59{
60 Q_UNUSED(args);
61 d->driverBehavior.typeNames.resize(KDbField::LastType + 1);
62}
63
65{
66 // make a copy because d->connections will be touched by ~KDbConnection
67 QSet<KDbConnection*> connections(d->connections);
68 qDeleteAll(connections);
69 d->connections.clear();
70 delete d;
71// kdbDebug() << "ok";
72}
73
75{
76 return &d->driverBehavior;
77}
78
80{
81 return &d->driverBehavior;
82}
83
85{
86 clearResult();
87 QString inv_impl(tr("Invalid database driver's \"%1\" implementation.").arg(metaData()->name()));
88 QString not_init(tr("Value of \"%1\" is not initialized for the driver."));
89 if (d->driverBehavior.ROW_ID_FIELD_NAME.isEmpty()) {
90 m_result = KDbResult(ERR_INVALID_DRIVER_IMPL,
91 inv_impl + QLatin1Char(' ')
92 + not_init.arg(QLatin1String("KDbDriverBehavior::ROW_ID_FIELD_NAME")));
93 return false;
94 }
95 return true;
96}
97
99{
100 return d->connections;
101}
102
104{
105 return d->metaData;
106}
107
109{
110 return d->driverBehavior.features;
111}
112
114{
115 return d->driverBehavior.features & (SingleTransactions | MultipleTransactions);
116}
117
119{
120 if (!d->adminTools)
121 d->adminTools = drv_createAdminTools();
122 return *d->adminTools;
123}
124
126{
127 return new KDbAdminTools(); //empty impl.
128}
129
131{
132 Q_UNUSED(field);
133 if (type > KDbField::InvalidType && type <= KDbField::LastType) { /*sanity*/
134 return d->driverBehavior.typeNames[type];
135 }
136 return d->driverBehavior.typeNames[KDbField::InvalidType];
137}
138
140 const KDbConnectionOptions &options)
141{
142 clearResult();
143 if (!isValid())
144 return nullptr;
145
146 KDbConnection *conn = drv_createConnection(connData, options);
147
148//! @todo needed? connData->setDriverId(id());
149 d->connections.insert(conn);
150 return conn;
151}
152
154{
155 return createConnection(connData, KDbConnectionOptions());
156}
157
159{
160 clearResult();
161 if (d->connections.remove(conn))
162 return conn;
163 return nullptr;
164}
165
167{
168 if (type > KDbField::LastType)
169 return QLatin1String("Null");
170 return QLatin1String(KDb_defaultSqlTypeNames[type]);
171}
172
174{
175 if (!name.startsWith(QLatin1String("kexi__"), Qt::CaseInsensitive))
176 return false;
178}
179
181{
182 if (!d->driverBehavior.ROW_ID_FIELD_NAME.isEmpty()
183 && 0 == name.compare(d->driverBehavior.ROW_ID_FIELD_NAME, Qt::CaseInsensitive))
184 {
185 return true;
186 }
187 return drv_isSystemFieldName(name);
188}
189
190KDbEscapedString valueToSqlInternal(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v)
191{
192 if (v.isNull() || ftype == KDbField::Null) {
193 return KDbEscapedString("NULL");
194 }
195 switch (ftype) {
196 case KDbField::Text:
197 case KDbField::LongText: {
198 return driver ? driver->escapeString(v.toString())
200 }
201 case KDbField::Byte:
205 return KDbEscapedString(v.toByteArray());
206 case KDbField::Float:
207 case KDbField::Double: {
208 if (v.type() == QVariant::String) {
209 //workaround for values stored as string that should be casted to floating-point
211 return s.replace(',', '.');
212 }
213 return KDbEscapedString(v.toByteArray());
214 }
215//! @todo here special encoding method needed
217 return driver
218 ? KDbEscapedString(v.toInt() == 0 ? KDbDriverPrivate::behavior(driver)->BOOLEAN_FALSE_LITERAL
219 : KDbDriverPrivate::behavior(driver)->BOOLEAN_TRUE_LITERAL)
220 : KDbEscapedString(v.toInt() == 0 ? "FALSE" : "TRUE");
221 case KDbField::Time:
222 return driver ? driver->timeToSql(v) : KDb::timeToSql(v);
223 case KDbField::Date:
224 return driver ? driver->dateToSql(v) : KDb::dateToSql(v);
225 case KDbField::DateTime:
226 return driver ? driver->dateTimeToSql(v) : KDb::dateTimeToSql(v);
227 case KDbField::BLOB: {
228 if (v.toByteArray().isEmpty()) {
229 return KDbEscapedString("NULL");
230 }
231 if (v.type() == QVariant::String) {
232 return driver ? driver->escapeBLOB(v.toString().toUtf8())
234 }
235 return driver ? driver->escapeBLOB(v.toByteArray())
237 }
239 return KDbEscapedString("!INVALIDTYPE!");
240 default:
241 kdbDebug() << KDbEscapedString("UNKNOWN!");
242 }
243 return KDbEscapedString();
244}
245
247{
248 //! @note it was compatible with SQLite: https://www.sqlite.org/lang_datefunc.html
249 return valueToSqlInternal(this, ftype, v);
250}
251
256
261
266
271
273{
274 return QLatin1Char(d->driverBehavior.OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER)
276 + QLatin1Char(d->driverBehavior.CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER);
277}
278
280{
281 return d->driverBehavior.OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
283 + d->driverBehavior.CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER;
284}
285
287{
288 return d->driverBehavior.properties.property(name);
289}
290
292{
293 QList<QByteArray> names(d->driverBehavior.properties.names());
294 std::sort(names.begin(), names.end());
295 return names;
296}
297
298void KDbDriver::initDriverSpecificKeywords(const char* const* keywords)
299{
300 d->driverSpecificSqlKeywords.setStrings(keywords);
301}
302
304{
305 return add ? (sql + " LIMIT 1") : sql;
306}
307
309{
310 return d->driverSpecificSqlKeywords.contains(word);
311}
312
314{
315 d->metaData = metaData;
316 d->driverBehavior.initInternalProperties();
317}
318
320 const KDbNArgExpression &args,
322 KDb::ExpressionCallStack* callStack) const
323{
324 return KDbFunctionExpression::toString(QLatin1String("HEX"), this, args, params, callStack);
325}
326
328 const KDbNArgExpression &args,
330 KDb::ExpressionCallStack* callStack) const
331{
332 return KDbFunctionExpression::toString(QLatin1String("IFNULL"), this, args, params, callStack);
333}
334
336 const KDbNArgExpression &args,
338 KDb::ExpressionCallStack* callStack) const
339{
340 return KDbFunctionExpression::toString(QLatin1String("LENGTH"), this, args, params, callStack);
341}
342
344 const QString &name,
345 const KDbNArgExpression &args,
347 KDb::ExpressionCallStack* callStack) const
348{
349 return KDbFunctionExpression::toString(name, this, args, params, callStack);
350}
351
353 const KDbNArgExpression &args,
355 KDb::ExpressionCallStack* callStack) const
356{
357 static QLatin1String randomStatic("()");
358 if (!args.isNull() || args.argCount() < 1 ) {
359 return KDbEscapedString(d->driverBehavior.RANDOM_FUNCTION + randomStatic);
360 }
361 if (args.argCount() != 2) {
362 return KDbEscapedString();
363 }
364 const KDbEscapedString x(args.arg(0).toString(this, params, callStack));
365 const KDbEscapedString y(args.arg(1).toString(this, params, callStack));
366 static KDbEscapedString floorRandomStatic("+FLOOR(");
367 static KDbEscapedString floorRandomStatic2("()*(");
368 static KDbEscapedString floorRandomStatic3(")))");
369 return KDbEscapedString('(') + x + floorRandomStatic + d->driverBehavior.RANDOM_FUNCTION
370 + floorRandomStatic2 + y + QLatin1Char('-') + x + floorRandomStatic3;
371}
372
374 const QString &name,
375 const KDbNArgExpression &args,
377 KDb::ExpressionCallStack* callStack) const
378{
379 return KDbFunctionExpression::toString(name, this, args, params, callStack);
380}
381
383 const KDbNArgExpression &args,
385 KDb::ExpressionCallStack* callStack) const
386{
387 return KDbFunctionExpression::toString(QLatin1String("UNICODE"), this, args, params, callStack);
388}
389
392 KDb::ExpressionCallStack* callStack) const
393{
394 return args.left().toString(this, params, callStack) + KDbEscapedString("||")
395 + args.right().toString(this, params, callStack);
396}
397
398//---------------
399
400Q_GLOBAL_STATIC_WITH_ARGS(
402 KDb_kdbSqlKeywords,
403 (KDbDriverPrivate::kdbSQLKeywords) )
404
405KDB_EXPORT bool KDb::isKDbSqlKeyword(const QByteArray& word)
406{
407 return KDb_kdbSqlKeywords->contains(word.toUpper());
408}
409
410KDB_EXPORT QString KDb::escapeIdentifier(const KDbDriver* driver,
411 const QString& str)
412{
413 return driver ? driver->escapeIdentifier(str)
415}
416
417KDB_EXPORT QByteArray KDb::escapeIdentifier(const KDbDriver* driver,
418 const QByteArray& str)
419{
420 return driver ? driver->escapeIdentifier(str)
422}
An interface containing a set of tools for database administration.
Definition KDbAdmin.h:31
The KDbBinaryExpression class represents binary operation.
Database specific connection data, e.g. host, port.
Generic options for a single connection. The options are accessible using key/value pairs....
Provides database connection, allowing queries and data modification.
static QStringList kdbSystemTableNames()
Detailed definition of driver's default behavior.
Provides information about a single driver plugin.
Database driver's abstraction.
Definition KDbDriver.h:50
virtual KDbEscapedString greatestOrLeastFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) GREATEST() and LEAST() function calls.
KDbDriver(QObject *parent, const QVariantList &args)
Definition KDbDriver.cpp:56
virtual KDbAdminTools * drv_createAdminTools() const
virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const
QString escapeIdentifier(const QString &str) const
virtual bool drv_isSystemFieldName(const QString &name) const =0
KDbConnection * createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options)
static QString defaultSqlTypeName(KDbField::Type type)
virtual KDbEscapedString ifnullFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) IFNULL() function call.
void initDriverSpecificKeywords(const char *const *keywords)
virtual KDbEscapedString timeToSql(const QVariant &v) const
Converts time value to string.
bool isDriverSpecificKeyword(const QByteArray &word) const
const KDbDriverMetaData * metaData() const
virtual bool isValid()
Definition KDbDriver.cpp:84
const QSet< KDbConnection * > connections() const
Definition KDbDriver.cpp:98
virtual KDbEscapedString dateTimeToSql(const QVariant &v) const
Converts date/time value to string.
KDbAdminTools & adminTools() const
virtual KDbEscapedString escapeBLOB(const QByteArray &array) const =0
static bool isKDbSystemObjectName(const QString &name)
virtual QString drv_escapeIdentifier(const QString &str) const =0
QList< QByteArray > internalPropertyNames() const
int features() const
@ SingleTransactions
single trasactions are only supported
Definition KDbDriver.h:58
@ MultipleTransactions
multiple concurrent trasactions are supported (this implies !SingleTransactions)
Definition KDbDriver.h:61
KDbDriverBehavior * behavior()
Returns structure that provides detailed information about driver's default behavior.
Definition KDbDriver.cpp:74
~KDbDriver() override
Definition KDbDriver.cpp:64
virtual KDbEscapedString dateToSql(const QVariant &v) const
Converts date value to string.
virtual KDbEscapedString escapeString(const QString &str) const =0
virtual KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant &v) const
virtual KDbEscapedString randomFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls.
bool isSystemFieldName(const QString &name) const
virtual KDbEscapedString lengthFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) LENGTH() function call.
KDbConnection * removeConnection(KDbConnection *conn)
virtual KDbEscapedString hexFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) HEX() function call.
bool transactionsSupported() const
virtual KDbEscapedString ceilingOrFloorFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) CEILING() and FLOOR() function calls.
virtual KDbEscapedString unicodeFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) UNICODE() function call.
virtual KDbConnection * drv_createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options)=0
virtual KDbEscapedString addLimitTo1(const KDbEscapedString &sql, bool add=true)
KDbEscapedString concatenateFunctionToString(const KDbBinaryExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) function call for concatenation of two strings.
KDbUtils::Property internalProperty(const QByteArray &name) const
void setMetaData(const KDbDriverMetaData *metaData)
Specialized string for escaping.
bool isNull() const
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
Meta-data for a field.
Definition KDbField.h:72
@ Integer
Definition KDbField.h:90
@ Boolean
Definition KDbField.h:92
@ ShortInteger
Definition KDbField.h:89
@ InvalidType
Definition KDbField.h:86
@ BigInteger
Definition KDbField.h:91
@ LongText
Definition KDbField.h:99
static KDbEscapedString toString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
The KDbNArgExpression class represents a base class N-argument expression.
KDbExpression arg(int i) const
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
A single property.
Definition KDbUtils.h:446
A set created from static (0-terminated) array of raw null-terminated strings.
Definition KDbUtils.h:388
KDB_EXPORT KDbEscapedString timeToSql(const QVariant &v)
Converts time value to its string representation required by KDBSQL commands.
KDB_EXPORT KDbEscapedString dateToSql(const QVariant &v)
Converts date value to its string representation required by KDBSQL commands.
@ ZeroXHex
Escaping like 0x1FAD, used by mysql (hex numbers)
KDB_EXPORT QString escapeBLOB(const QByteArray &array, BLOBEscapingType type)
KDB_EXPORT QString escapeIdentifier(const QString &string)
Definition KDb.cpp:1334
KDB_EXPORT KDbEscapedString timeToIsoString(const QVariant &v)
Converts time value to its string representation in ISO 8601 Time format.
KDB_EXPORT KDbEscapedString dateToIsoString(const QVariant &v)
Converts date value to its string representation in ISO 8601 DateTime format.
KDB_EXPORT QString escapeString(const QString &string)
Definition KDb.cpp:1356
KDB_EXPORT bool isKDbSqlKeyword(const QByteArray &word)
KDB_EXPORT KDbEscapedString dateTimeToIsoString(const QVariant &v)
Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimite...
KDB_DEPRECATED_EXPORT KDbEscapedString dateTimeToSql(const QDateTime &v)
Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimite...
bool isEmpty() const const
QByteArray toUpper() const const
iterator begin()
iterator end()
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toUtf8() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
CaseInsensitive
Type type() const const
bool isNull() const const
QByteArray toByteArray() const const
int toInt(bool *ok) const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Nov 6 2024 12:12:56 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.