KDb

KDbDriver.h
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 #ifndef KDB_DRIVER_H
21 #define KDB_DRIVER_H
22 
23 #include <QDateTime>
24 
25 #include "KDb.h"
26 #include "KDbResult.h"
27 #include "KDbEscapedString.h"
28 #include "KDbExpressionData.h"
29 
30 class KDbAdminTools;
31 class KDbConnection;
32 class KDbConnectionData;
34 class KDbDriverBehavior;
35 class KDbDriverMetaData;
37 class KDbNArgExpression;
39 class KDbDriverPrivate;
40 
41 #define KDB_DRIVER_PLUGIN_FACTORY(class_name, name) \
42  K_PLUGIN_FACTORY_WITH_JSON(class_name ## Factory, name, registerPlugin<class_name>();)
43 
44 //! Database driver's abstraction.
45 /*! This class is a prototype of the database driver.
46  KDbDriver allows new connections to be created, and groups as their parent.
47  Before destruction, all owned connections are destructed.
48 */
49 class KDB_EXPORT KDbDriver : public QObject, public KDbResultable
50 {
51  Q_OBJECT
52 
53 public:
54  /*! Features supported by driver (sum of few Features enum items). */
55  enum Features {
56  NoFeatures = 0,
57  //! single trasactions are only supported
58  SingleTransactions = 1,
59  //! multiple concurrent trasactions are supported
60  //! (this implies !SingleTransactions)
61  MultipleTransactions = 2,
62 //(js) NOT YET IN USE:
63  /*! nested trasactions are supported
64  (this should imply !SingleTransactions and MultipleTransactions) */
65  NestedTransactions = 4,
66  /*! forward moving is supported for cursors
67  (if not available, no cursors available at all) */
68  CursorForward = 8,
69  /*! backward moving is supported for cursors (this implies CursorForward) */
70  CursorBackward = (CursorForward + 16),
71  /*! compacting database supported (aka VACUUM) */
72  CompactingDatabaseSupported = 32,
73  //-- temporary options: can be removed later, use at your own risk --
74  /*! If set, actions related to transactions will be silently bypassed
75  with success. Set this if your driver does not support transactions at all
76  Currently, this is only way to get it working with KDb.
77  Keep in mind that this hack do not provide data integrity!
78  This flag is currently used for MySQL driver. */
79  IgnoreTransactions = 1024
80  };
81 
82  /*! Creates connection using @a connData as parameters.
83  @return @c nullptr and sets error message on error.
84  driverId member of @a connData will be updated with the driver's ID.
85  @a options can be set for the new connection. */
86  KDbConnection *createConnection(const KDbConnectionData& connData,
87  const KDbConnectionOptions &options);
88 
89  //! @overload createConnection(const KDbConnectionData&, const KDbConnectionOptions&)
90  KDbConnection *createConnection(const KDbConnectionData& connData);
91 
92  /*! @return Set of created connections. */
93  const QSet<KDbConnection*> connections() const;
94 
95  /*! Info about the driver. */
96  const KDbDriverMetaData* metaData() const;
97 
98  /*! @return true if @a n is a database type-specific system object's name,
99  e.g. name of a built-in system table that cannot be created by the user,
100  and in most cases a name that user shouldn't even see.
101  @see isSystemDatabaseName() isKDbSystemObjectName() isSystemFieldName()
102  */
103  virtual bool isSystemObjectName(const QString& name) const = 0;
104 
105  /*! @return true if @a name is a related to KDb's 'system' object's
106  name, i.e. when @a name starts with "kexi__" prefix.
107  @see isSystemDatabaseName() isSystemObjectName() isSystemFieldName()
108  */
109  static bool isKDbSystemObjectName(const QString& name);
110 
111  /*! @return true if @a name is a database type-specific system database's name,
112  e.g. name of a built-in system database that cannot be created by a user,
113  and in most cases user a name that user shouldn't even see.
114  @see isKDbSystemObjectName() isSystemObjectName() isSystemFieldName()
115  */
116  virtual bool isSystemDatabaseName(const QString& name) const = 0;
117 
118  /*! @return true if @a name is a system field's name, build-in system
119  field that cannot be used or created by a user,
120  and in most cases user even shouldn't see this. The list is specific for
121  a given driver implementation.
122  @see isSystemDatabaseName() isKDbSystemObjectName() isSystemObjectName()
123  */
124  bool isSystemFieldName(const QString& name) const;
125 
126  /*! @return true if @a word is a driver-specific keyword.
127  @see KDb::isKDbSqlKeyword(const QByteArray&) */
128  bool isDriverSpecificKeyword(const QByteArray& word) const;
129 
130  /*! @return driver's features that are combination of KDbDriver::Features enum.
131  @todo change int to Features */
132  int features() const;
133 
134  /*! @return true if transaction are supported (single or multiple). */
135  bool transactionsSupported() const;
136 
137  /*! @return admin tools object providing a number of database administration
138  tools for the driver. Tools availablility varies from driver to driver.
139  You can check it using features(). */
140  KDbAdminTools& adminTools() const;
141 
142  /*! SQL-implementation-dependent name of given type */
143  virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const;
144 
145  /*! used when we do not have KDbDriver instance yet */
146  static QString defaultSqlTypeName(KDbField::Type type);
147 
148  /*! Escapes and converts value @a v (for type @a ftype)
149  to string representation required by SQL commands.
150  Reimplement this if you need other behavior (eg. for 'date' type handling)
151  This implementation return date, datetime and time values in ISO format,
152  what seems to be accepted by SQL servers.
153  @see Qt::DateFormat */
154  virtual KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant& v) const;
155 
156  //! Like above but with the fildtype as string.
157  inline KDbEscapedString valueToSql(const QString& ftype, const QVariant& v) const {
158  return valueToSql(KDbField::typeForString(ftype), v);
159  }
160 
161  //! Like above method, for @a field.
162  inline KDbEscapedString valueToSql(const KDbField *field, const QVariant& v) const {
163  return valueToSql((field ? field->type() : KDbField::InvalidType), v);
164  }
165 
166  /**
167  * Converts date value to string
168  *
169  * Default implementation uses KDb::dateToSql().
170  *
171  * Not compatible with all drivers - reimplement.
172  *
173  * @since 3.2.0
174  */
175  virtual KDbEscapedString dateToSql(const QVariant &v) const;
176 
177  /**
178  * Converts time value to string
179  *
180  * Default implementation uses KDb::timeToIsoString().
181  *
182  * Not compatible with all drivers - reimplement.
183  *
184  * @since 3.2.0
185  */
186  virtual KDbEscapedString timeToSql(const QVariant &v) const;
187 
188  /**
189  * Converts date/time value to string
190  *
191  * Default implementation uses KDb::dateTimeToIsoString().
192  *
193  * Not compatible with all drivers - reimplement.
194  *
195  * @since 3.2.0
196  */
197  virtual KDbEscapedString dateTimeToSql(const QVariant &v) const;
198 
199  /**
200  * Converts date/time value to string
201  *
202  * Default implementation uses dateTimeToSql(QVariant).
203  * Deprecated, use dateTimeToSql(QVariant).
204  *
205  * Not compatible with all drivers - reimplement.
206  */
207  KDB_DEPRECATED virtual KDbEscapedString dateTimeToSql(const QDateTime& v) const;
208 
209  /*! Driver-specific SQL string escaping.
210  Implement escaping for any character like " or ' as your
211  database engine requires. Prepend and append quotation marks.
212  */
213  virtual KDbEscapedString escapeString(const QString& str) const = 0;
214 
215  /*! This is overloaded version of escapeString( const QString& str )
216  to be implemented in the same way.
217  */
218  virtual KDbEscapedString escapeString(const QByteArray& str) const = 0;
219 
220  /*! Driver-specific SQL BLOB value escaping.
221  Implement escaping for any character like " or ' and \\0 as your
222  database engine requires. Prepend and append quotation marks.
223  */
224  virtual KDbEscapedString escapeBLOB(const QByteArray& array) const = 0;
225 
226  /*! @return SQL clause to add for unicode text collation sequence
227  used in ORDER BY clauses of SQL statements generated by KDb.
228  Later other clauses may use this statement.
229  One space character should be be prepended.
230  Can be reimplemented for other drivers, e.g. the SQLite3 driver returns " COLLATE ''".
231  Default implementation returns empty string. */
232  virtual KDbEscapedString collationSql() const {
233  return KDbEscapedString();
234  }
235 
236  //! @return @a str string with applied driver-specific identifier escaping
237  /*! This escaping can be used for field, table, database names, etc.
238  @see KDb::escapeIdentifier */
239  QString escapeIdentifier(const QString& str) const;
240 
241  //! @overload QString escapeIdentifier(const QString&) const
242  QByteArray escapeIdentifier(const QByteArray& str) const;
243 
244  //! @return internal property with a name @a name for this driver.
245  //! If there's no such property defined for driver, a null property is returned.
246  KDbUtils::Property internalProperty(const QByteArray& name) const;
247 
248  //! @return a list of internal property names for this driver.
249  QList<QByteArray> internalPropertyNames() const;
250 
251  //! @internal
252  ~KDbDriver() override;
253 
254  //! Generates native (driver-specific) HEX() function call.
255  //! Default implementation uses HEX(val).
256  virtual KDbEscapedString hexFunctionToString(
257  const KDbNArgExpression &args,
259  KDb::ExpressionCallStack* callStack) const;
260 
261  //! Generates native (driver-specific) IFNULL() function call.
262  //! Default implementation uses IFNULL().
263  virtual KDbEscapedString ifnullFunctionToString(
264  const KDbNArgExpression &args,
266  KDb::ExpressionCallStack* callStack) const;
267 
268  //! Generates native (driver-specific) LENGTH() function call.
269  //! Default implementation uses LENGTH().
270  virtual KDbEscapedString lengthFunctionToString(
271  const KDbNArgExpression &args,
273  KDb::ExpressionCallStack* callStack) const;
274 
275  //! Generates native (driver-specific) GREATEST() and LEAST() function calls.
276  //! Default implementation just uses GREATEST() and LEAST(), respectively.
277  //! (this works only with MySQL >= 5.0.13).
278  //! For backends workarounds are added.
279  virtual KDbEscapedString greatestOrLeastFunctionToString(
280  const QString &name,
281  const KDbNArgExpression &args,
283  KDb::ExpressionCallStack* callStack) const;
284 
285  //! Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls.
286  //! Accepted @a args can contain zero or two positive integer arguments X, Y; X < Y.
287  //! In case of numeric arguments, RANDOM(X, Y) returns a random integer that is equal
288  //! or greater than X and less than Y.
289  //! Default implementation for RANDOM() returns F() where F is behavior()->RANDOM_FUNCTION.
290  //! This works with PostgreSQL.
291  //! Default implementation for RANDOM(X,Y) returns (X + FLOOR(F()*(Y-X+1))) where
292  //! F is behavior()->RANDOM_FUNCTION. This works with PostgreSQL.
293  //! If @a args has neither zero nor two arguments, empty string is returned.
294  virtual KDbEscapedString randomFunctionToString(
295  const KDbNArgExpression &args,
297  KDb::ExpressionCallStack* callStack) const;
298 
299  //! Generates native (driver-specific) CEILING() and FLOOR() function calls.
300  //! Default implementation USES CEILING() and FLOOR(), respectively.
301  //! Special case is for SQLite.
302  virtual KDbEscapedString ceilingOrFloorFunctionToString(
303  const QString &name,
304  const KDbNArgExpression &args,
306  KDb::ExpressionCallStack* callStack) const;
307 
308  //! Generates native (driver-specific) UNICODE() function call.
309  //! Default implementation USES UNICODE().
310  //! Special case is for MYSQL and PostgreSQL.
311  virtual KDbEscapedString unicodeFunctionToString(
312  const KDbNArgExpression &args,
314  KDb::ExpressionCallStack* callStack) const;
315 
316  //! Generates native (driver-specific) function call for concatenation of two strings.
317  //! Default implementation USES infix "||" operator.
318  //! Special case is for MYSQL (CONCAT()).
319  //! @todo API supporting KDbNArgExpression would be useful so instead of a||b||c can be
320  //! expressed as CONCAT(a,b,c) instead of CONCAT(CONCAT(a,b),c).
321  //! This requires changes to the KDbSQL parser.
322  KDbEscapedString concatenateFunctionToString(const KDbBinaryExpression &args,
324  KDb::ExpressionCallStack* callStack) const;
325 
326 protected:
327  /**
328  * @brief Returns structure that provides detailed information about driver's default behavior
329  *
330  * @since 3.1
331  */
332  KDbDriverBehavior *behavior();
333 
334  /**
335  * @overload
336  */
337  const KDbDriverBehavior *behavior() const;
338 
339  /*! Used by KDbDriverManager.
340  Note for driver developers: Reimplement this.
341  In your reimplementation you should initialize:
342  - beh->typeNames - to types accepted by your engine
343  - beh->features - to combination of selected values from Features enum
344 
345  You may also want to change options in KDbDriverBehavior *beh member.
346  See drivers/mySQL/mysqldriver.cpp for usage example.
347  */
348  KDbDriver(QObject *parent, const QVariantList &args);
349 
350  /*! For reimplementation: creates and returns connection object
351  with additional structures specific for a given driver.
352  KDbConnection object should inherit KDbConnection and have a destructor
353  that descructs all allocated driver-dependent connection structures. */
354  virtual KDbConnection *drv_createConnection(const KDbConnectionData& connData,
355  const KDbConnectionOptions &options) = 0;
356 
357  /*! Driver-specific SQL string escaping.
358  This method is used by escapeIdentifier().
359  Implement escaping for any character like " or ' as your
360  database engine requires. Do not append or prepend any quotation
361  marks characters - it is automatically done by escapeIdentifier() using
362  KDbDriverBehavior::OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
363  and KDbDriverBehavior::CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER.
364  */
365  virtual QString drv_escapeIdentifier(const QString& str) const = 0;
366 
367  /*! This is overloaded version of drv_escapeIdentifier( const QString& str )
368  to be implemented in the same way.
369  */
370  virtual QByteArray drv_escapeIdentifier(const QByteArray& str) const = 0;
371 
372  /*! @return true if @a name is a system field's name, build-in system
373  field that cannot be used or created by a user,
374  and in most cases user even shouldn't see this. The list is specific for
375  a given driver implementation. For implementation.*/
376  virtual bool drv_isSystemFieldName(const QString& name) const = 0;
377 
378  /*! Creates admin tools object providing a number of database administration
379  tools for the driver. This is called once per driver.
380 
381  Note for driver developers: Reimplement this method by returning
382  a KDbAdminTools-derived object. Default implementation creates
383  anmd returns an empty admin tools KDbAdminTools object.
384  @see adminTools() */
385  virtual KDbAdminTools* drv_createAdminTools() const;
386 
387  /*! @return connection @a conn, does not delete it nor affect.
388  Returns @c nullptr if @a conn is not owned by this driver.
389  After this, you are owner of @a conn object, so you should
390  eventually delete it. Better use KDbConnection destructor. */
391  KDbConnection* removeConnection(KDbConnection *conn);
392 
393  /*! Used to initialise the dictionary of driver-specific keywords.
394  Should be called by the driver's constructor.
395  @a keywords should be 0-terminated array of null-terminated strings. */
396  void initDriverSpecificKeywords(const char* const* keywords);
397 
398  /*! @return SQL statement @a sql modified by appending a "LIMIT 1" clause,
399  (if possible and if @a add is @c true). Used for optimization for the server side.
400  Can be reimplemented for other drivers. */
401  virtual KDbEscapedString addLimitTo1(const KDbEscapedString& sql, bool add = true);
402 
403  /*! @return true if the database supports specifying default values for field @a field.
404  @c true by default.
405  For example MySQL does not support default values for BLOB, TEXT, GEOMETRY, and JSON types.
406  (https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html). */
407  virtual bool supportsDefaultValue(const KDbField &field) const { Q_UNUSED(field); return true; }
408 
409  /*! Used by the driver manager to set metaData for just loaded driver. */
410  void setMetaData(const KDbDriverMetaData *metaData);
411 
412  /*! @return true if this driver's implementation is valid.
413  Just a few constraints are checked to ensure that driver developer didn't forget something.
414  This method is called automatically on createConnection(), and proper error message
415  is set properly on error.
416  Drivers can reimpement this method but should call KDbDriver::isValid() first. */
417  virtual bool isValid();
418 
419  friend class KDbConnection;
420  friend class KDbCursor;
421  friend class KDbDriverBehavior;
422  friend class KDbNativeStatementBuilder;
423  friend class DriverManagerInternal;
424  friend class KDbDriverPrivate;
425 
426  KDbDriverPrivate * const d;
427 private:
429 };
430 
431 namespace KDb {
432 
433 //! @return string @a string with applied driver-specific identifier escaping if @a driver
434 //! is not KDbSQL general identifier escaping when @a driver is 0.
435 /*! This escaping can be used for field, table, database names, etc.
436  @see KDb::escapeIdentifier */
437 KDB_EXPORT QString escapeIdentifier(const KDbDriver* driver,
438  const QString& string);
439 
440 //! @overload QString escapeIdentifier(const KDbDriver*, const QString&)
441 KDB_EXPORT QByteArray escapeIdentifier(const KDbDriver* driver,
442  const QByteArray& str);
443 
444 inline KDbEscapedString valueToSql(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v)
445 {
446  return driver ? driver->valueToSql(ftype, v) : KDb::valueToSql(ftype, v);
447 }
448 
449 }
450 
451 #endif
Provides database cursor functionality.
Definition: KDbCursor.h:68
KDB_EXPORT QString escapeIdentifier(const QString &string)
Definition: KDb.cpp:1334
KDbEscapedString valueToSql(const QString &ftype, const QVariant &v) const
Like above but with the fildtype as string.
Definition: KDbDriver.h:157
Provides information about a single driver plugin.
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.
A builder for generating various types of native SQL statements.
A database connectivity and creation framework.
Specialized string for escaping.
virtual bool supportsDefaultValue(const KDbField &field) const
Definition: KDbDriver.h:407
Database driver's abstraction.
Definition: KDbDriver.h:49
Interface for classes providing a result.
A single property.
Definition: KDbUtils.h:446
Type type() const
Definition: KDbField.cpp:379
KDB_EXPORT KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant &v)
Definition: KDb.cpp:2201
The KDbNArgExpression class represents a base class N-argument expression.
virtual KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant &v) const
Definition: KDbDriver.cpp:246
static Type typeForString(const QString &typeString)
Definition: KDbField.cpp:491
An interface containing a set of tools for database administration.
Definition: KDbAdmin.h:30
Detailed definition of driver's default behavior.
Database specific connection data, e.g. host, port.
Generic options for a single connection. The options are accessible using key/value pairs....
Meta-data for a field.
Definition: KDbField.h:71
Provides database connection, allowing queries and data modification.
Definition: KDbConnection.h:51
virtual KDbEscapedString collationSql() const
Definition: KDbDriver.h:232
Q_DISABLE_COPY(Class)
KDbEscapedString valueToSql(const KDbField *field, const QVariant &v) const
Like above method, for field.
Definition: KDbDriver.h:162
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon May 8 2023 04:07:51 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.