File indexing completed on 2024-11-10 12:47:12
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #ifndef KDB_DRIVER_H 0021 #define KDB_DRIVER_H 0022 0023 #include <QDateTime> 0024 0025 #include "KDb.h" 0026 #include "KDbResult.h" 0027 #include "KDbEscapedString.h" 0028 #include "KDbExpressionData.h" 0029 0030 class KDbAdminTools; 0031 class KDbConnection; 0032 class KDbConnectionData; 0033 class KDbConnectionOptions; 0034 class KDbDriverBehavior; 0035 class KDbDriverMetaData; 0036 class KDbBinaryExpression; 0037 class KDbNArgExpression; 0038 class KDbQuerySchemaParameterValueListIterator; 0039 class KDbDriverPrivate; 0040 0041 #define KDB_DRIVER_PLUGIN_FACTORY(class_name, name) \ 0042 K_PLUGIN_FACTORY_WITH_JSON(class_name ## Factory, name, registerPlugin<class_name>();) 0043 0044 //! Database driver's abstraction. 0045 /*! This class is a prototype of the database driver. 0046 KDbDriver allows new connections to be created, and groups as their parent. 0047 Before destruction, all owned connections are destructed. 0048 */ 0049 class KDB_EXPORT KDbDriver : public QObject, public KDbResultable 0050 { 0051 Q_OBJECT 0052 0053 public: 0054 /*! Features supported by driver (sum of few Features enum items). */ 0055 enum Features { 0056 NoFeatures = 0, 0057 //! single trasactions are only supported 0058 SingleTransactions = 1, 0059 //! multiple concurrent trasactions are supported 0060 //! (this implies !SingleTransactions) 0061 MultipleTransactions = 2, 0062 //(js) NOT YET IN USE: 0063 /*! nested trasactions are supported 0064 (this should imply !SingleTransactions and MultipleTransactions) */ 0065 NestedTransactions = 4, 0066 /*! forward moving is supported for cursors 0067 (if not available, no cursors available at all) */ 0068 CursorForward = 8, 0069 /*! backward moving is supported for cursors (this implies CursorForward) */ 0070 CursorBackward = (CursorForward + 16), 0071 /*! compacting database supported (aka VACUUM) */ 0072 CompactingDatabaseSupported = 32, 0073 //-- temporary options: can be removed later, use at your own risk -- 0074 /*! If set, actions related to transactions will be silently bypassed 0075 with success. Set this if your driver does not support transactions at all 0076 Currently, this is only way to get it working with KDb. 0077 Keep in mind that this hack do not provide data integrity! 0078 This flag is currently used for MySQL driver. */ 0079 IgnoreTransactions = 1024 0080 }; 0081 0082 /*! Creates connection using @a connData as parameters. 0083 @return @c nullptr and sets error message on error. 0084 driverId member of @a connData will be updated with the driver's ID. 0085 @a options can be set for the new connection. */ 0086 KDbConnection *createConnection(const KDbConnectionData& connData, 0087 const KDbConnectionOptions &options); 0088 0089 //! @overload createConnection(const KDbConnectionData&, const KDbConnectionOptions&) 0090 KDbConnection *createConnection(const KDbConnectionData& connData); 0091 0092 /*! @return Set of created connections. */ 0093 const QSet<KDbConnection*> connections() const; 0094 0095 /*! Info about the driver. */ 0096 const KDbDriverMetaData* metaData() const; 0097 0098 /*! @return true if @a n is a database type-specific system object's name, 0099 e.g. name of a built-in system table that cannot be created by the user, 0100 and in most cases a name that user shouldn't even see. 0101 @see isSystemDatabaseName() isKDbSystemObjectName() isSystemFieldName() 0102 */ 0103 virtual bool isSystemObjectName(const QString& name) const = 0; 0104 0105 /*! @return true if @a name is a related to KDb's 'system' object's 0106 name, i.e. when @a name starts with "kexi__" prefix. 0107 @see isSystemDatabaseName() isSystemObjectName() isSystemFieldName() 0108 */ 0109 static bool isKDbSystemObjectName(const QString& name); 0110 0111 /*! @return true if @a name is a database type-specific system database's name, 0112 e.g. name of a built-in system database that cannot be created by a user, 0113 and in most cases user a name that user shouldn't even see. 0114 @see isKDbSystemObjectName() isSystemObjectName() isSystemFieldName() 0115 */ 0116 virtual bool isSystemDatabaseName(const QString& name) const = 0; 0117 0118 /*! @return true if @a name is a system field's name, build-in system 0119 field that cannot be used or created by a user, 0120 and in most cases user even shouldn't see this. The list is specific for 0121 a given driver implementation. 0122 @see isSystemDatabaseName() isKDbSystemObjectName() isSystemObjectName() 0123 */ 0124 bool isSystemFieldName(const QString& name) const; 0125 0126 /*! @return true if @a word is a driver-specific keyword. 0127 @see KDb::isKDbSqlKeyword(const QByteArray&) */ 0128 bool isDriverSpecificKeyword(const QByteArray& word) const; 0129 0130 /*! @return driver's features that are combination of KDbDriver::Features enum. 0131 @todo change int to Features */ 0132 int features() const; 0133 0134 /*! @return true if transaction are supported (single or multiple). */ 0135 bool transactionsSupported() const; 0136 0137 /*! @return admin tools object providing a number of database administration 0138 tools for the driver. Tools availablility varies from driver to driver. 0139 You can check it using features(). */ 0140 KDbAdminTools& adminTools() const; 0141 0142 /*! SQL-implementation-dependent name of given type */ 0143 virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const; 0144 0145 /*! used when we do not have KDbDriver instance yet */ 0146 static QString defaultSqlTypeName(KDbField::Type type); 0147 0148 /*! Escapes and converts value @a v (for type @a ftype) 0149 to string representation required by SQL commands. 0150 Reimplement this if you need other behavior (eg. for 'date' type handling) 0151 This implementation return date, datetime and time values in ISO format, 0152 what seems to be accepted by SQL servers. 0153 @see Qt::DateFormat */ 0154 virtual KDbEscapedString valueToSql(KDbField::Type ftype, const QVariant& v) const; 0155 0156 //! Like above but with the fildtype as string. 0157 inline KDbEscapedString valueToSql(const QString& ftype, const QVariant& v) const { 0158 return valueToSql(KDbField::typeForString(ftype), v); 0159 } 0160 0161 //! Like above method, for @a field. 0162 inline KDbEscapedString valueToSql(const KDbField *field, const QVariant& v) const { 0163 return valueToSql((field ? field->type() : KDbField::InvalidType), v); 0164 } 0165 0166 /** 0167 * Converts date value to string 0168 * 0169 * Default implementation uses KDb::dateToSql(). 0170 * 0171 * Not compatible with all drivers - reimplement. 0172 * 0173 * @since 3.2.0 0174 */ 0175 virtual KDbEscapedString dateToSql(const QVariant &v) const; 0176 0177 /** 0178 * Converts time value to string 0179 * 0180 * Default implementation uses KDb::timeToIsoString(). 0181 * 0182 * Not compatible with all drivers - reimplement. 0183 * 0184 * @since 3.2.0 0185 */ 0186 virtual KDbEscapedString timeToSql(const QVariant &v) const; 0187 0188 /** 0189 * Converts date/time value to string 0190 * 0191 * Default implementation uses KDb::dateTimeToIsoString(). 0192 * 0193 * Not compatible with all drivers - reimplement. 0194 * 0195 * @since 3.2.0 0196 */ 0197 virtual KDbEscapedString dateTimeToSql(const QVariant &v) const; 0198 0199 /** 0200 * Converts date/time value to string 0201 * 0202 * Default implementation uses dateTimeToSql(QVariant). 0203 * Deprecated, use dateTimeToSql(QVariant). 0204 * 0205 * Not compatible with all drivers - reimplement. 0206 */ 0207 KDB_DEPRECATED virtual KDbEscapedString dateTimeToSql(const QDateTime& v) const; 0208 0209 /*! Driver-specific SQL string escaping. 0210 Implement escaping for any character like " or ' as your 0211 database engine requires. Prepend and append quotation marks. 0212 */ 0213 virtual KDbEscapedString escapeString(const QString& str) const = 0; 0214 0215 /*! This is overloaded version of escapeString( const QString& str ) 0216 to be implemented in the same way. 0217 */ 0218 virtual KDbEscapedString escapeString(const QByteArray& str) const = 0; 0219 0220 /*! Driver-specific SQL BLOB value escaping. 0221 Implement escaping for any character like " or ' and \\0 as your 0222 database engine requires. Prepend and append quotation marks. 0223 */ 0224 virtual KDbEscapedString escapeBLOB(const QByteArray& array) const = 0; 0225 0226 /*! @return SQL clause to add for unicode text collation sequence 0227 used in ORDER BY clauses of SQL statements generated by KDb. 0228 Later other clauses may use this statement. 0229 One space character should be be prepended. 0230 Can be reimplemented for other drivers, e.g. the SQLite3 driver returns " COLLATE ''". 0231 Default implementation returns empty string. */ 0232 virtual KDbEscapedString collationSql() const { 0233 return KDbEscapedString(); 0234 } 0235 0236 //! @return @a str string with applied driver-specific identifier escaping 0237 /*! This escaping can be used for field, table, database names, etc. 0238 @see KDb::escapeIdentifier */ 0239 QString escapeIdentifier(const QString& str) const; 0240 0241 //! @overload QString escapeIdentifier(const QString&) const 0242 QByteArray escapeIdentifier(const QByteArray& str) const; 0243 0244 //! @return internal property with a name @a name for this driver. 0245 //! If there's no such property defined for driver, a null property is returned. 0246 KDbUtils::Property internalProperty(const QByteArray& name) const; 0247 0248 //! @return a list of internal property names for this driver. 0249 QList<QByteArray> internalPropertyNames() const; 0250 0251 //! @internal 0252 ~KDbDriver() override; 0253 0254 //! Generates native (driver-specific) HEX() function call. 0255 //! Default implementation uses HEX(val). 0256 virtual KDbEscapedString hexFunctionToString( 0257 const KDbNArgExpression &args, 0258 KDbQuerySchemaParameterValueListIterator* params, 0259 KDb::ExpressionCallStack* callStack) const; 0260 0261 //! Generates native (driver-specific) IFNULL() function call. 0262 //! Default implementation uses IFNULL(). 0263 virtual KDbEscapedString ifnullFunctionToString( 0264 const KDbNArgExpression &args, 0265 KDbQuerySchemaParameterValueListIterator* params, 0266 KDb::ExpressionCallStack* callStack) const; 0267 0268 //! Generates native (driver-specific) LENGTH() function call. 0269 //! Default implementation uses LENGTH(). 0270 virtual KDbEscapedString lengthFunctionToString( 0271 const KDbNArgExpression &args, 0272 KDbQuerySchemaParameterValueListIterator* params, 0273 KDb::ExpressionCallStack* callStack) const; 0274 0275 //! Generates native (driver-specific) GREATEST() and LEAST() function calls. 0276 //! Default implementation just uses GREATEST() and LEAST(), respectively. 0277 //! (this works only with MySQL >= 5.0.13). 0278 //! For backends workarounds are added. 0279 virtual KDbEscapedString greatestOrLeastFunctionToString( 0280 const QString &name, 0281 const KDbNArgExpression &args, 0282 KDbQuerySchemaParameterValueListIterator* params, 0283 KDb::ExpressionCallStack* callStack) const; 0284 0285 //! Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls. 0286 //! Accepted @a args can contain zero or two positive integer arguments X, Y; X < Y. 0287 //! In case of numeric arguments, RANDOM(X, Y) returns a random integer that is equal 0288 //! or greater than X and less than Y. 0289 //! Default implementation for RANDOM() returns F() where F is behavior()->RANDOM_FUNCTION. 0290 //! This works with PostgreSQL. 0291 //! Default implementation for RANDOM(X,Y) returns (X + FLOOR(F()*(Y-X+1))) where 0292 //! F is behavior()->RANDOM_FUNCTION. This works with PostgreSQL. 0293 //! If @a args has neither zero nor two arguments, empty string is returned. 0294 virtual KDbEscapedString randomFunctionToString( 0295 const KDbNArgExpression &args, 0296 KDbQuerySchemaParameterValueListIterator* params, 0297 KDb::ExpressionCallStack* callStack) const; 0298 0299 //! Generates native (driver-specific) CEILING() and FLOOR() function calls. 0300 //! Default implementation USES CEILING() and FLOOR(), respectively. 0301 //! Special case is for SQLite. 0302 virtual KDbEscapedString ceilingOrFloorFunctionToString( 0303 const QString &name, 0304 const KDbNArgExpression &args, 0305 KDbQuerySchemaParameterValueListIterator* params, 0306 KDb::ExpressionCallStack* callStack) const; 0307 0308 //! Generates native (driver-specific) UNICODE() function call. 0309 //! Default implementation USES UNICODE(). 0310 //! Special case is for MYSQL and PostgreSQL. 0311 virtual KDbEscapedString unicodeFunctionToString( 0312 const KDbNArgExpression &args, 0313 KDbQuerySchemaParameterValueListIterator* params, 0314 KDb::ExpressionCallStack* callStack) const; 0315 0316 //! Generates native (driver-specific) function call for concatenation of two strings. 0317 //! Default implementation USES infix "||" operator. 0318 //! Special case is for MYSQL (CONCAT()). 0319 //! @todo API supporting KDbNArgExpression would be useful so instead of a||b||c can be 0320 //! expressed as CONCAT(a,b,c) instead of CONCAT(CONCAT(a,b),c). 0321 //! This requires changes to the KDbSQL parser. 0322 KDbEscapedString concatenateFunctionToString(const KDbBinaryExpression &args, 0323 KDbQuerySchemaParameterValueListIterator* params, 0324 KDb::ExpressionCallStack* callStack) const; 0325 0326 protected: 0327 /** 0328 * @brief Returns structure that provides detailed information about driver's default behavior 0329 * 0330 * @since 3.1 0331 */ 0332 KDbDriverBehavior *behavior(); 0333 0334 /** 0335 * @overload 0336 */ 0337 const KDbDriverBehavior *behavior() const; 0338 0339 /*! Used by KDbDriverManager. 0340 Note for driver developers: Reimplement this. 0341 In your reimplementation you should initialize: 0342 - beh->typeNames - to types accepted by your engine 0343 - beh->features - to combination of selected values from Features enum 0344 0345 You may also want to change options in KDbDriverBehavior *beh member. 0346 See drivers/mySQL/mysqldriver.cpp for usage example. 0347 */ 0348 KDbDriver(QObject *parent, const QVariantList &args); 0349 0350 /*! For reimplementation: creates and returns connection object 0351 with additional structures specific for a given driver. 0352 KDbConnection object should inherit KDbConnection and have a destructor 0353 that descructs all allocated driver-dependent connection structures. */ 0354 virtual KDbConnection *drv_createConnection(const KDbConnectionData& connData, 0355 const KDbConnectionOptions &options) = 0; 0356 0357 /*! Driver-specific SQL string escaping. 0358 This method is used by escapeIdentifier(). 0359 Implement escaping for any character like " or ' as your 0360 database engine requires. Do not append or prepend any quotation 0361 marks characters - it is automatically done by escapeIdentifier() using 0362 KDbDriverBehavior::OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER 0363 and KDbDriverBehavior::CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER. 0364 */ 0365 virtual QString drv_escapeIdentifier(const QString& str) const = 0; 0366 0367 /*! This is overloaded version of drv_escapeIdentifier( const QString& str ) 0368 to be implemented in the same way. 0369 */ 0370 virtual QByteArray drv_escapeIdentifier(const QByteArray& str) const = 0; 0371 0372 /*! @return true if @a name is a system field's name, build-in system 0373 field that cannot be used or created by a user, 0374 and in most cases user even shouldn't see this. The list is specific for 0375 a given driver implementation. For implementation.*/ 0376 virtual bool drv_isSystemFieldName(const QString& name) const = 0; 0377 0378 /*! Creates admin tools object providing a number of database administration 0379 tools for the driver. This is called once per driver. 0380 0381 Note for driver developers: Reimplement this method by returning 0382 a KDbAdminTools-derived object. Default implementation creates 0383 anmd returns an empty admin tools KDbAdminTools object. 0384 @see adminTools() */ 0385 virtual KDbAdminTools* drv_createAdminTools() const; 0386 0387 /*! @return connection @a conn, does not delete it nor affect. 0388 Returns @c nullptr if @a conn is not owned by this driver. 0389 After this, you are owner of @a conn object, so you should 0390 eventually delete it. Better use KDbConnection destructor. */ 0391 KDbConnection* removeConnection(KDbConnection *conn); 0392 0393 /*! Used to initialise the dictionary of driver-specific keywords. 0394 Should be called by the driver's constructor. 0395 @a keywords should be 0-terminated array of null-terminated strings. */ 0396 void initDriverSpecificKeywords(const char* const* keywords); 0397 0398 /*! @return SQL statement @a sql modified by appending a "LIMIT 1" clause, 0399 (if possible and if @a add is @c true). Used for optimization for the server side. 0400 Can be reimplemented for other drivers. */ 0401 virtual KDbEscapedString addLimitTo1(const KDbEscapedString& sql, bool add = true); 0402 0403 /*! @return true if the database supports specifying default values for field @a field. 0404 @c true by default. 0405 For example MySQL does not support default values for BLOB, TEXT, GEOMETRY, and JSON types. 0406 (https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html). */ 0407 virtual bool supportsDefaultValue(const KDbField &field) const { Q_UNUSED(field); return true; } 0408 0409 /*! Used by the driver manager to set metaData for just loaded driver. */ 0410 void setMetaData(const KDbDriverMetaData *metaData); 0411 0412 /*! @return true if this driver's implementation is valid. 0413 Just a few constraints are checked to ensure that driver developer didn't forget something. 0414 This method is called automatically on createConnection(), and proper error message 0415 is set properly on error. 0416 Drivers can reimpement this method but should call KDbDriver::isValid() first. */ 0417 virtual bool isValid(); 0418 0419 friend class KDbConnection; 0420 friend class KDbCursor; 0421 friend class KDbDriverBehavior; 0422 friend class KDbNativeStatementBuilder; 0423 friend class DriverManagerInternal; 0424 friend class KDbDriverPrivate; 0425 0426 KDbDriverPrivate * const d; 0427 private: 0428 Q_DISABLE_COPY(KDbDriver) 0429 }; 0430 0431 namespace KDb { 0432 0433 //! @return string @a string with applied driver-specific identifier escaping if @a driver 0434 //! is not KDbSQL general identifier escaping when @a driver is 0. 0435 /*! This escaping can be used for field, table, database names, etc. 0436 @see KDb::escapeIdentifier */ 0437 KDB_EXPORT QString escapeIdentifier(const KDbDriver* driver, 0438 const QString& string); 0439 0440 //! @overload QString escapeIdentifier(const KDbDriver*, const QString&) 0441 KDB_EXPORT QByteArray escapeIdentifier(const KDbDriver* driver, 0442 const QByteArray& str); 0443 0444 inline KDbEscapedString valueToSql(const KDbDriver *driver, KDbField::Type ftype, const QVariant& v) 0445 { 0446 return driver ? driver->valueToSql(ftype, v) : KDb::valueToSql(ftype, v); 0447 } 0448 0449 } 0450 0451 #endif