KDb

KDbDriver.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2003-2018 JarosÅ‚aw Staniek <[email protected]>
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 /*! @internal Used in KDbDriver::defaultSqlTypeName(int)
34  when we do not have KDbDriver instance yet, or when we cannot get one */
35 static const char* const KDb_defaultSqlTypeNames[] = {
36  "InvalidType",
37  "Byte",
38  "ShortInteger",
39  "Integer",
40  "BigInteger",
41  "Boolean",
42  "Date",
43  "DateTime",
44  "Time",
45  "Float",
46  "Double",
47  "Text",
48  "LongText",
49  "BLOB"
50 };
51 
52 //---------------------------------------------
53 
54 KDbDriver::KDbDriver(QObject *parent, const QVariantList &args)
55  : QObject(parent)
56  , d(new KDbDriverPrivate(this))
57 {
58  Q_UNUSED(args);
59  d->driverBehavior.typeNames.resize(KDbField::LastType + 1);
60 }
61 
63 {
64  // make a copy because d->connections will be touched by ~KDbConnection
65  QSet<KDbConnection*> connections(d->connections);
66  qDeleteAll(connections);
67  d->connections.clear();
68  delete d;
69 // kdbDebug() << "ok";
70 }
71 
73 {
74  return &d->driverBehavior;
75 }
76 
78 {
79  return &d->driverBehavior;
80 }
81 
83 {
84  clearResult();
85  QString inv_impl(tr("Invalid database driver's \"%1\" implementation.").arg(metaData()->name()));
86  QString not_init(tr("Value of \"%1\" is not initialized for the driver."));
87  if (d->driverBehavior.ROW_ID_FIELD_NAME.isEmpty()) {
88  m_result = KDbResult(ERR_INVALID_DRIVER_IMPL,
89  inv_impl + QLatin1Char(' ')
90  + not_init.arg(QLatin1String("KDbDriverBehavior::ROW_ID_FIELD_NAME")));
91  return false;
92  }
93  return true;
94 }
95 
97 {
98  return d->connections;
99 }
100 
102 {
103  return d->metaData;
104 }
105 
107 {
108  return d->driverBehavior.features;
109 }
110 
112 {
113  return d->driverBehavior.features & (SingleTransactions | MultipleTransactions);
114 }
115 
117 {
118  if (!d->adminTools)
119  d->adminTools = drv_createAdminTools();
120  return *d->adminTools;
121 }
122 
124 {
125  return new KDbAdminTools(); //empty impl.
126 }
127 
129 {
130  Q_UNUSED(field);
131  if (type > KDbField::InvalidType && type <= KDbField::LastType) { /*sanity*/
132  return d->driverBehavior.typeNames[type];
133  }
134  return d->driverBehavior.typeNames[KDbField::InvalidType];
135 }
136 
138  const KDbConnectionOptions &options)
139 {
140  clearResult();
141  if (!isValid())
142  return nullptr;
143 
144  KDbConnection *conn = drv_createConnection(connData, options);
145 
146 //! @todo needed? connData->setDriverId(id());
147  d->connections.insert(conn);
148  return conn;
149 }
150 
152 {
153  return createConnection(connData, KDbConnectionOptions());
154 }
155 
157 {
158  clearResult();
159  if (d->connections.remove(conn))
160  return conn;
161  return nullptr;
162 }
163 
165 {
166  if (type > KDbField::LastType)
167  return QLatin1String("Null");
168  return QLatin1String(KDb_defaultSqlTypeNames[type]);
169 }
170 
172 {
173  if (!name.startsWith(QLatin1String("kexi__"), Qt::CaseInsensitive))
174  return false;
176 }
177 
178 bool KDbDriver::isSystemFieldName(const QString& name) const
179 {
180  if (!d->driverBehavior.ROW_ID_FIELD_NAME.isEmpty()
181  && 0 == name.compare(d->driverBehavior.ROW_ID_FIELD_NAME, Qt::CaseInsensitive))
182  {
183  return true;
184  }
185  return drv_isSystemFieldName(name);
186 }
187 
188 KDbEscapedString valueToSqlInternal(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v)
189 {
190  if (v.isNull() || ftype == KDbField::Null) {
191  return KDbEscapedString("NULL");
192  }
193  switch (ftype) {
194  case KDbField::Text:
195  case KDbField::LongText: {
196  return driver ? driver->escapeString(v.toString())
198  }
199  case KDbField::Byte:
201  case KDbField::Integer:
203  return KDbEscapedString(v.toByteArray());
204  case KDbField::Float:
205  case KDbField::Double: {
206  if (v.type() == QVariant::String) {
207  //workaround for values stored as string that should be casted to floating-point
209  return s.replace(',', '.');
210  }
211  return KDbEscapedString(v.toByteArray());
212  }
213 //! @todo here special encoding method needed
214  case KDbField::Boolean:
215  return driver
216  ? KDbEscapedString(v.toInt() == 0 ? KDbDriverPrivate::behavior(driver)->BOOLEAN_FALSE_LITERAL
217  : KDbDriverPrivate::behavior(driver)->BOOLEAN_TRUE_LITERAL)
218  : KDbEscapedString(v.toInt() == 0 ? "FALSE" : "TRUE");
219  case KDbField::Time:
220  return driver ? driver->timeToSql(v) : KDb::timeToSql(v);
221  case KDbField::Date:
222  return driver ? driver->dateToSql(v) : KDb::dateToSql(v);
223  case KDbField::DateTime:
224  return driver ? driver->dateTimeToSql(v) : KDb::dateTimeToSql(v);
225  case KDbField::BLOB: {
226  if (v.toByteArray().isEmpty()) {
227  return KDbEscapedString("NULL");
228  }
229  if (v.type() == QVariant::String) {
230  return driver ? driver->escapeBLOB(v.toString().toUtf8())
232  }
233  return driver ? driver->escapeBLOB(v.toByteArray())
235  }
237  return KDbEscapedString("!INVALIDTYPE!");
238  default:
239  kdbDebug() << KDbEscapedString("UNKNOWN!");
240  }
241  return KDbEscapedString();
242 }
243 
245 {
246  //! @note it was compatible with SQLite: https://www.sqlite.org/lang_datefunc.html
247  return valueToSqlInternal(this, ftype, v);
248 }
249 
251 {
252  return KDb::dateToIsoString(v);
253 }
254 
256 {
257  return KDb::timeToIsoString(v);
258 }
259 
261 {
262  return KDb::dateTimeToIsoString(v);
263 }
264 
266 {
267  return dateTimeToSql(QVariant(v));
268 }
269 
271 {
272  return QLatin1Char(d->driverBehavior.OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER)
273  + drv_escapeIdentifier(str)
274  + QLatin1Char(d->driverBehavior.CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER);
275 }
276 
278 {
279  return d->driverBehavior.OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
280  + drv_escapeIdentifier(str)
281  + d->driverBehavior.CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER;
282 }
283 
285 {
286  return d->driverBehavior.properties.property(name);
287 }
288 
290 {
291  QList<QByteArray> names(d->driverBehavior.properties.names());
292  qSort(names);
293  return names;
294 }
295 
296 void KDbDriver::initDriverSpecificKeywords(const char* const* keywords)
297 {
298  d->driverSpecificSqlKeywords.setStrings(keywords);
299 }
300 
302 {
303  return add ? (sql + " LIMIT 1") : sql;
304 }
305 
307 {
308  return d->driverSpecificSqlKeywords.contains(word);
309 }
310 
312 {
313  d->metaData = metaData;
314  d->driverBehavior.initInternalProperties();
315 }
316 
318  const KDbNArgExpression &args,
320  KDb::ExpressionCallStack* callStack) const
321 {
322  return KDbFunctionExpression::toString(QLatin1String("HEX"), this, args, params, callStack);
323 }
324 
326  const KDbNArgExpression &args,
328  KDb::ExpressionCallStack* callStack) const
329 {
330  return KDbFunctionExpression::toString(QLatin1String("IFNULL"), this, args, params, callStack);
331 }
332 
334  const KDbNArgExpression &args,
336  KDb::ExpressionCallStack* callStack) const
337 {
338  return KDbFunctionExpression::toString(QLatin1String("LENGTH"), this, args, params, callStack);
339 }
340 
342  const QString &name,
343  const KDbNArgExpression &args,
345  KDb::ExpressionCallStack* callStack) const
346 {
347  return KDbFunctionExpression::toString(name, this, args, params, callStack);
348 }
349 
351  const KDbNArgExpression &args,
353  KDb::ExpressionCallStack* callStack) const
354 {
355  static QLatin1String randomStatic("()");
356  if (!args.isNull() || args.argCount() < 1 ) {
357  return KDbEscapedString(d->driverBehavior.RANDOM_FUNCTION + randomStatic);
358  }
359  if (args.argCount() != 2) {
360  return KDbEscapedString();
361  }
362  const KDbEscapedString x(args.arg(0).toString(this, params, callStack));
363  const KDbEscapedString y(args.arg(1).toString(this, params, callStack));
364  static KDbEscapedString floorRandomStatic("+FLOOR(");
365  static KDbEscapedString floorRandomStatic2("()*(");
366  static KDbEscapedString floorRandomStatic3(")))");
367  return KDbEscapedString('(') + x + floorRandomStatic + d->driverBehavior.RANDOM_FUNCTION
368  + floorRandomStatic2 + y + QLatin1Char('-') + x + floorRandomStatic3;
369 }
370 
372  const QString &name,
373  const KDbNArgExpression &args,
375  KDb::ExpressionCallStack* callStack) const
376 {
377  return KDbFunctionExpression::toString(name, this, args, params, callStack);
378 }
379 
381  const KDbNArgExpression &args,
383  KDb::ExpressionCallStack* callStack) const
384 {
385  return KDbFunctionExpression::toString(QLatin1String("UNICODE"), this, args, params, callStack);
386 }
387 
390  KDb::ExpressionCallStack* callStack) const
391 {
392  return args.left().toString(this, params, callStack) + KDbEscapedString("||")
393  + args.right().toString(this, params, callStack);
394 }
395 
396 //---------------
397 
398 Q_GLOBAL_STATIC_WITH_ARGS(
400  KDb_kdbSqlKeywords,
401  (KDbDriverPrivate::kdbSQLKeywords) )
402 
403 KDB_EXPORT bool KDb::isKDbSqlKeyword(const QByteArray& word)
404 {
405  return KDb_kdbSqlKeywords->contains(word.toUpper());
406 }
407 
408 KDB_EXPORT QString KDb::escapeIdentifier(const KDbDriver* driver,
409  const QString& str)
410 {
411  return driver ? driver->escapeIdentifier(str)
412  : KDb::escapeIdentifier(str);
413 }
414 
415 KDB_EXPORT QByteArray KDb::escapeIdentifier(const KDbDriver* driver,
416  const QByteArray& str)
417 {
418  return driver ? driver->escapeIdentifier(str)
419  : KDb::escapeIdentifier(str);
420 }
virtual KDbAdminTools * drv_createAdminTools() const
Definition: KDbDriver.cpp:123
bool isNull() const const
virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const
Definition: KDbDriver.cpp:128
KDbAdminTools & adminTools() const
Definition: KDbDriver.cpp:116
bool transactionsSupported() const
Definition: KDbDriver.cpp:111
KDB_EXPORT QString escapeIdentifier(const QString &string)
Definition: KDb.cpp:1334
const QSet< KDbConnection * > connections() const
Definition: KDbDriver.cpp:96
bool isDriverSpecificKeyword(const QByteArray &word) const
Definition: KDbDriver.cpp:306
Provides information about a single driver plugin.
virtual KDbEscapedString timeToSql(const QVariant &v) const
Converts time value to string.
Definition: KDbDriver.cpp:255
virtual KDbConnection * drv_createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options)=0
KDbExpression arg(int i) const
CaseInsensitive
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
@ InvalidType
Definition: KDbField.h:86
The KDbBinaryExpression class represents binary operation.
QList< QByteArray > internalPropertyNames() const
Definition: KDbDriver.cpp:289
static QStringList kdbSystemTableNames()
~KDbDriver() override
Definition: KDbDriver.cpp:62
virtual KDbEscapedString dateToSql(const QVariant &v) const
Converts date value to string.
Definition: KDbDriver.cpp:250
@ Text
Definition: KDbField.h:98
@ ZeroXHex
Escaping like 0x1FAD, used by mysql (hex numbers)
KDbUtils::Property internalProperty(const QByteArray &name) const
Definition: KDbDriver.cpp:284
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
KDB_EXPORT KDbEscapedString dateTimeToIsoString(const QVariant &v)
Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimite...
Definition: KDb.cpp:2305
A set created from static (0-terminated) array of raw null-terminated strings.
Definition: KDbUtils.h:387
Specialized string for escaping.
KDB_EXPORT KDbEscapedString dateToSql(const QVariant &v)
Converts date value to its string representation required by KDBSQL commands.
Definition: KDb.cpp:2231
KDbConnection * removeConnection(KDbConnection *conn)
Definition: KDbDriver.cpp:156
Database driver's abstraction.
Definition: KDbDriver.h:49
QByteArray toByteArray() const const
QString escapeIdentifier(const QString &str) const
Definition: KDbDriver.cpp:270
KDB_DEPRECATED_EXPORT KDbEscapedString dateTimeToSql(const QDateTime &v)
Converts date/time value to its string representation in ISO 8601 DateTime format - with "T" delimite...
Definition: KDb.cpp:2290
virtual KDbEscapedString ifnullFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) IFNULL() function call.
Definition: KDbDriver.cpp:325
@ LastType
Definition: KDbField.h:102
static QString defaultSqlTypeName(KDbField::Type type)
Definition: KDbDriver.cpp:164
virtual KDbEscapedString escapeString(const QString &str) const =0
virtual KDbEscapedString addLimitTo1(const KDbEscapedString &sql, bool add=true)
Definition: KDbDriver.cpp:301
virtual KDbEscapedString randomFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls.
Definition: KDbDriver.cpp:350
KDB_EXPORT bool isKDbSqlKeyword(const QByteArray &word)
QVariant::Type type() const const
@ SingleTransactions
single trasactions are only supported
Definition: KDbDriver.h:58
A single property.
Definition: KDbUtils.h:446
KDbConnection * createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options)
Definition: KDbDriver.cpp:137
@ Integer
Definition: KDbField.h:90
QByteArray toUtf8() const const
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
int toInt(bool *ok) const const
virtual QString drv_escapeIdentifier(const QString &str) const =0
static bool isKDbSystemObjectName(const QString &name)
Definition: KDbDriver.cpp:171
QByteArray toUpper() const const
@ BigInteger
Definition: KDbField.h:91
KDbDriverBehavior * behavior()
Returns structure that provides detailed information about driver's default behavior.
Definition: KDbDriver.cpp:72
virtual KDbEscapedString greatestOrLeastFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) GREATEST() and LEAST() function calls.
Definition: KDbDriver.cpp:341
void initDriverSpecificKeywords(const char *const *keywords)
Definition: KDbDriver.cpp:296
@ Double
Definition: KDbField.h:97
bool isSystemFieldName(const QString &name) const
Definition: KDbDriver.cpp:178
@ LongText
Definition: KDbField.h:99
@ Byte
Definition: KDbField.h:87
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
The KDbNArgExpression class represents a base class N-argument expression.
virtual KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant &v) const
Definition: KDbDriver.cpp:244
KDB_EXPORT QString escapeBLOB(const QByteArray &array, BLOBEscapingType type)
An interface containing a set of tools for database administration.
Definition: KDbAdmin.h:30
Detailed definition of driver's default behavior.
KDB_EXPORT KDbEscapedString dateToIsoString(const QVariant &v)
Converts date value to its string representation in ISO 8601 DateTime format.
Definition: KDb.cpp:2295
bool isEmpty() const const
@ Boolean
Definition: KDbField.h:92
KDbDriver(QObject *parent, const QVariantList &args)
Definition: KDbDriver.cpp:54
virtual KDbEscapedString unicodeFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) UNICODE() function call.
Definition: KDbDriver.cpp:380
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isNull() const
int features() const
Definition: KDbDriver.cpp:106
static KDbEscapedString toString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
Database specific connection data, e.g. host, port.
virtual KDbEscapedString lengthFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) LENGTH() function call.
Definition: KDbDriver.cpp:333
Generic options for a single connection. The options are accessible using key/value pairs....
Meta-data for a field.
Definition: KDbField.h:71
KDB_EXPORT QString escapeString(const QString &string)
Definition: KDb.cpp:1356
@ Float
Definition: KDbField.h:96
@ MultipleTransactions
multiple concurrent trasactions are supported (this implies !SingleTransactions)
Definition: KDbDriver.h:61
int compare(const QString &other, Qt::CaseSensitivity cs) const const
KDbEscapedString concatenateFunctionToString(const KDbBinaryExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) function call for concatenation of two strings.
Definition: KDbDriver.cpp:388
KDB_EXPORT KDbEscapedString timeToSql(const QVariant &v)
Converts time value to its string representation required by KDBSQL commands.
Definition: KDb.cpp:2257
Provides database connection, allowing queries and data modification.
Definition: KDbConnection.h:51
virtual bool drv_isSystemFieldName(const QString &name) const =0
virtual KDbEscapedString dateTimeToSql(const QVariant &v) const
Converts date/time value to string.
Definition: KDbDriver.cpp:260
QString tr(const char *sourceText, const char *disambiguation, int n)
@ ShortInteger
Definition: KDbField.h:89
virtual bool isValid()
Definition: KDbDriver.cpp:82
void setMetaData(const KDbDriverMetaData *metaData)
Definition: KDbDriver.cpp:311
virtual KDbEscapedString escapeBLOB(const QByteArray &array) const =0
const KDbDriverMetaData * metaData() const
Definition: KDbDriver.cpp:101
virtual KDbEscapedString hexFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) HEX() function call.
Definition: KDbDriver.cpp:317
KDB_EXPORT KDbEscapedString timeToIsoString(const QVariant &v)
Converts time value to its string representation in ISO 8601 Time format.
Definition: KDb.cpp:2300
QString toString() const 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.
Definition: KDbDriver.cpp:371
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Sep 26 2022 04:04:22 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.