Qt 4.8
qsqldriver.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtSql module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qsqldriver.h"
43 
44 #include "qdatetime.h"
45 #include "qsqlerror.h"
46 #include "qsqlfield.h"
47 #include "qsqlindex.h"
48 #include "private/qobject_p.h"
49 
51 
52 static QString prepareIdentifier(const QString &identifier,
54 {
55  Q_ASSERT( driver != NULL );
56  QString ret = identifier;
57  if (!driver->isIdentifierEscaped(identifier, type)) {
58  ret = driver->escapeIdentifier(identifier, type);
59  }
60  return ret;
61 }
62 
64 {
65 public:
67  virtual ~QSqlDriverPrivate();
68 
69 public:
70  // @CHECK: this member is never used. It was named q, which expanded to q_func().
71  QSqlDriver *q_func();
72  uint isOpen : 1;
76 };
77 
80 {
81 }
82 
84 {
85 }
86 
113  : QObject(*new QSqlDriverPrivate, parent)
114 {
115 }
116 
122 {
123 }
124 
182 bool QSqlDriver::isOpen() const
183 {
184  return d_func()->isOpen;
185 }
186 
193 {
194  return d_func()->isOpenError;
195 }
196 
284 {
285  d_func()->isOpen = open;
286 }
287 
298 {
299  d_func()->isOpenError = error;
300  if (error)
301  d_func()->isOpen = false;
302 }
303 
313 {
314  return false;
315 }
316 
326 {
327  return false;
328 }
329 
339 {
340  return false;
341 }
342 
351 {
352  d_func()->error = error;
353 }
354 
361 {
362  return d_func()->error;
363 }
364 
377 {
378  return QStringList();
379 }
380 
388 {
389  return QSqlIndex();
390 }
391 
392 
399 QSqlRecord QSqlDriver::record(const QString & /* tableName */) const
400 {
401  return QSqlRecord();
402 }
403 
413 {
414  return identifier;
415 }
416 
430 {
431  bool result;
432  QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
433  "isIdentifierEscapedImplementation", Qt::DirectConnection,
434  Q_RETURN_ARG(bool, result),
435  Q_ARG(QString, identifier),
436  Q_ARG(IdentifierType, type));
437  return result;
438 }
439 
456 {
457  QString result;
458  QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
459  "stripDelimitersImplementation", Qt::DirectConnection,
460  Q_RETURN_ARG(QString, result),
461  Q_ARG(QString, identifier),
462  Q_ARG(IdentifierType, type));
463  return result;
464 }
465 
476  const QSqlRecord &rec, bool preparedStatement) const
477 {
478  int i;
479  QString s;
480  s.reserve(128);
481  switch (type) {
482  case SelectStatement:
483  for (i = 0; i < rec.count(); ++i) {
484  if (rec.isGenerated(i))
486  }
487  if (s.isEmpty())
488  return s;
489  s.chop(2);
490  s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
491  break;
492  case WhereStatement:
493  if (preparedStatement) {
494  for (int i = 0; i < rec.count(); ++i) {
495  s.append(prepareIdentifier(rec.fieldName(i), FieldName,this));
496  if (rec.isNull(i))
497  s.append(QLatin1String(" IS NULL"));
498  else
499  s.append(QLatin1String(" = ?"));
500  s.append(QLatin1String(" AND "));
501  }
502  } else {
503  for (i = 0; i < rec.count(); ++i) {
505  QString val = formatValue(rec.field(i));
506  if (val == QLatin1String("NULL"))
507  s.append(QLatin1String(" IS NULL"));
508  else
509  s.append(QLatin1String(" = ")).append(val);
510  s.append(QLatin1String(" AND "));
511  }
512  }
513  if (!s.isEmpty()) {
514  s.prepend(QLatin1String("WHERE "));
515  s.chop(5); // remove tailing AND
516  }
517  break;
518  case UpdateStatement:
519  s.append(QLatin1String("UPDATE ")).append(tableName).append(
520  QLatin1String(" SET "));
521  for (i = 0; i < rec.count(); ++i) {
522  if (!rec.isGenerated(i))
523  continue;
525  if (preparedStatement)
526  s.append(QLatin1Char('?'));
527  else
528  s.append(formatValue(rec.field(i)));
529  s.append(QLatin1String(", "));
530  }
531  if (s.endsWith(QLatin1String(", ")))
532  s.chop(2);
533  else
534  s.clear();
535  break;
536  case DeleteStatement:
537  s.append(QLatin1String("DELETE FROM ")).append(tableName);
538  break;
539  case InsertStatement: {
540  s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
541  QString vals;
542  for (i = 0; i < rec.count(); ++i) {
543  if (!rec.isGenerated(i))
544  continue;
546  if (preparedStatement)
547  vals.append(QLatin1Char('?'));
548  else
549  vals.append(formatValue(rec.field(i)));
550  vals.append(QLatin1String(", "));
551  }
552  if (vals.isEmpty()) {
553  s.clear();
554  } else {
555  vals.chop(2); // remove trailing comma
556  s[s.length() - 2] = QLatin1Char(')');
557  s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')'));
558  }
559  break; }
560  }
561  return s;
562 }
563 
597 QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const
598 {
599  const QLatin1String nullTxt("NULL");
600 
601  QString r;
602  if (field.isNull())
603  r = nullTxt;
604  else {
605  switch (field.type()) {
606  case QVariant::Int:
607  case QVariant::UInt:
608  if (field.value().type() == QVariant::Bool)
609  r = field.value().toBool() ? QLatin1String("1") : QLatin1String("0");
610  else
611  r = field.value().toString();
612  break;
613 #ifndef QT_NO_DATESTRING
614  case QVariant::Date:
615  if (field.value().toDate().isValid())
616  r = QLatin1Char('\'') + field.value().toDate().toString(Qt::ISODate)
617  + QLatin1Char('\'');
618  else
619  r = nullTxt;
620  break;
621  case QVariant::Time:
622  if (field.value().toTime().isValid())
623  r = QLatin1Char('\'') + field.value().toTime().toString(Qt::ISODate)
624  + QLatin1Char('\'');
625  else
626  r = nullTxt;
627  break;
628  case QVariant::DateTime:
629  if (field.value().toDateTime().isValid())
630  r = QLatin1Char('\'') +
631  field.value().toDateTime().toString(Qt::ISODate) + QLatin1Char('\'');
632  else
633  r = nullTxt;
634  break;
635 #endif
636  case QVariant::String:
637  case QVariant::Char:
638  {
639  QString result = field.value().toString();
640  if (trimStrings) {
641  int end = result.length();
642  while (end && result.at(end-1).isSpace()) /* skip white space from end */
643  end--;
644  result.truncate(end);
645  }
646  /* escape the "'" character */
647  result.replace(QLatin1Char('\''), QLatin1String("''"));
648  r = QLatin1Char('\'') + result + QLatin1Char('\'');
649  break;
650  }
651  case QVariant::Bool:
652  r = QString::number(field.value().toBool());
653  break;
654  case QVariant::ByteArray : {
655  if (hasFeature(BLOB)) {
656  QByteArray ba = field.value().toByteArray();
657  QString res;
658  static const char hexchars[] = "0123456789abcdef";
659  for (int i = 0; i < ba.size(); ++i) {
660  uchar s = (uchar) ba[i];
661  res += QLatin1Char(hexchars[s >> 4]);
662  res += QLatin1Char(hexchars[s & 0x0f]);
663  }
664  r = QLatin1Char('\'') + res + QLatin1Char('\'');
665  break;
666  }
667  }
668  default:
669  r = field.value().toString();
670  break;
671  }
672  }
673  return r;
674 }
675 
701 {
702  return QVariant();
703 }
704 
767 {
768  bool result;
769  QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this),
770  "subscribeToNotificationImplementation", Qt::DirectConnection,
771  Q_RETURN_ARG(bool, result),
772  Q_ARG(QString, name));
773  return result;
774 }
775 
797 {
798  bool result;
799  QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this),
800  "unsubscribeFromNotificationImplementation", Qt::DirectConnection,
801  Q_RETURN_ARG(bool, result),
802  Q_ARG(QString, name));
803  return result;
804 }
805 
818 {
819  QStringList result;
820  QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this),
821  "subscribedToNotificationsImplementation", Qt::DirectConnection,
822  Q_RETURN_ARG(QStringList, result));
823  return result;
824 }
825 
850 {
851  Q_UNUSED(name);
852  return false;
853 }
854 
877 {
878  Q_UNUSED(name);
879  return false;
880 }
881 
895 {
896  return QStringList();
897 }
898 
919 {
920  Q_UNUSED(type);
921  return identifier.size() > 2
922  && identifier.startsWith(QLatin1Char('"')) //left delimited
923  && identifier.endsWith(QLatin1Char('"')); //right delimited
924 }
925 
945 {
946  QString ret;
947  if (this->isIdentifierEscaped(identifier, type)) {
948  ret = identifier.mid(1);
949  ret.chop(1);
950  } else {
951  ret = identifier;
952  }
953  return ret;
954 }
955 
972 {
973  d_func()->precisionPolicy = precisionPolicy;
974 }
975 
988 {
989  return d_func()->precisionPolicy;
990 }
991 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QSqlError class provides SQL database error information.
Definition: qsqlerror.h:53
The QSqlIndex class provides functions to manipulate and describe database indexes.
Definition: qsqlindex.h:55
virtual bool rollbackTransaction()
This function is called to rollback a transaction.
Definition: qsqldriver.cpp:338
bool unsubscribeFromNotificationImplementation(const QString &name)
This slot is called to unsubscribe from event notifications from the database.
Definition: qsqldriver.cpp:876
NumericalPrecisionPolicy
Definition: qsql.h:82
int type
Definition: qmetatype.cpp:239
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
virtual QSqlIndex primaryIndex(const QString &tableName) const
Returns the primary index for table tableName.
Definition: qsqldriver.cpp:387
virtual void setOpen(bool o)
This function sets the open state of the database to open.
Definition: qsqldriver.cpp:283
virtual QString sqlStatement(StatementType type, const QString &tableName, const QSqlRecord &rec, bool preparedStatement) const
Returns a SQL statement of type type for the table tableName with the values from rec...
Definition: qsqldriver.cpp:475
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
virtual QStringList tables(QSql::TableType tableType) const
Returns a list of the names of the tables in the database.
Definition: qsqldriver.cpp:376
bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition: qdatetime.cpp:340
QStringList subscribedToNotificationsImplementation() const
Returns a list of the names of the event notifications that are currently subscribed to...
Definition: qsqldriver.cpp:894
virtual bool hasFeature(DriverFeature f) const =0
Returns true if the driver supports feature feature; otherwise returns false.
virtual void setOpenError(bool e)
This function sets the open error state of the database to error.
Definition: qsqldriver.cpp:297
bool unsubscribeFromNotification(const QString &name)
This function is called to unsubscribe from event notifications from the database.
Definition: qsqldriver.cpp:796
QVariant value() const
Returns the value of the field as a QVariant.
Definition: qsqlfield.h:71
#define error(msg)
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void chop(int n)
Removes n characters from the end of the string.
Definition: qstring.cpp:4623
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QString & prepend(QChar c)
Definition: qstring.h:261
StatementType
This enum contains a list of SQL statement (or clause) types the driver can create.
Definition: qsqldriver.h:80
QSql::NumericalPrecisionPolicy precisionPolicy
Definition: qsqldriver.cpp:75
virtual QString escapeIdentifier(const QString &identifier, IdentifierType type) const
Returns the identifier escaped according to the database rules.
Definition: qsqldriver.cpp:412
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
Definition: qvariant.cpp:2349
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
#define Q_ARG(type, data)
Definition: qobjectdefs.h:246
bool isValid() const
Returns true if both the date and the time are valid; otherwise returns false.
Definition: qdatetime.cpp:2346
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool toBool() const
Returns the variant as a bool if the variant has type() Bool.
Definition: qvariant.cpp:2691
virtual QSqlRecord record(const QString &tableName) const
Returns a QSqlRecord populated with the names of the fields in table tableName.
Definition: qsqldriver.cpp:399
virtual bool isOpen() const
Returns true if the database connection is open; otherwise returns false.
Definition: qsqldriver.cpp:182
bool isNull(int i) const
Returns true if the field index is null or if there is no field at position index; otherwise returns ...
Definition: qsqlrecord.cpp:453
The QSqlRecord class encapsulates a database record.
Definition: qsqlrecord.h:58
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
Definition: qsqldriver.h:68
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool open(const QString &db, const QString &user=QString(), const QString &password=QString(), const QString &host=QString(), int port=-1, const QString &connOpts=QString())=0
Derived classes must reimplement this pure virtual function to open a database connection on database...
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
Sets the default numerical precision policy used by queries created by this driver to precisionPolicy...
Definition: qsqldriver.cpp:971
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the datetime as a string in the format given.
Definition: qdatetime.cpp:2628
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
bool isSpace() const
Returns true if the character is a separator character (Separator_* categories); otherwise returns fa...
Definition: qchar.cpp:609
bool subscribeToNotificationImplementation(const QString &name)
This slot is called to subscribe to event notifications from the database.
Definition: qsqldriver.cpp:849
bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const
Returns whether identifier is escaped according to the database rules.
Definition: qsqldriver.cpp:429
bool isOpenError() const
Returns true if the there was an error opening the database connection; otherwise returns false...
Definition: qsqldriver.cpp:192
bool isGenerated(int i) const
Returns true if the record has a field at position index and this field is to be generated (the defau...
Definition: qsqlrecord.cpp:519
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
unsigned char uchar
Definition: qglobal.h:994
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QSqlDriver * q_func()
QSqlError lastError() const
Returns a QSqlError object which contains information about the last error that occurred on the datab...
Definition: qsqldriver.cpp:360
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
virtual bool commitTransaction()
This function is called to commit a transaction.
Definition: qsqldriver.cpp:325
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static QString prepareIdentifier(const QString &identifier, QSqlDriver::IdentifierType type, const QSqlDriver *driver)
Definition: qsqldriver.cpp:52
const char * name
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
unsigned int uint
Definition: qglobal.h:996
#define Q_RETURN_ARG(type, data)
Definition: qobjectdefs.h:247
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
TableType
Definition: qsql.h:74
QVariant::Type type() const
Returns the field&#39;s type as stored in the database.
Definition: qsqlfield.cpp:394
QSqlField field(int i) const
Returns the field at position index.
Definition: qsqlrecord.cpp:289
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the time as a string.
Definition: qdatetime.cpp:1653
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
bool subscribeToNotification(const QString &name)
This function is called to subscribe to event notifications from the database.
Definition: qsqldriver.cpp:766
QDate toDate() const
Returns the variant as a QDate if the variant has type() Date , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2311
virtual bool beginTransaction()
This function is called to begin a transaction.
Definition: qsqldriver.cpp:312
int count() const
Returns the number of fields in the record.
Definition: qsqlrecord.cpp:573
bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
This slot returns whether identifier is escaped according to the database rules.
Definition: qsqldriver.cpp:918
QString & append(QChar c)
Definition: qstring.cpp:1777
QSqlDriver(QObject *parent=0)
Constructs a new driver with the given parent.
Definition: qsqldriver.cpp:112
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
bool isNull() const
Returns true if the field&#39;s value is NULL; otherwise returns false.
Definition: qsqlfield.cpp:428
virtual QString formatValue(const QSqlField &field, bool trimStrings=false) const
Returns a string representation of the field value for the database.
Definition: qsqldriver.cpp:597
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
Returns the current default precision policy for the database connection.
Definition: qsqldriver.cpp:987
QObject * parent
Definition: qobject.h:92
virtual QVariant handle() const
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
Definition: qsqldriver.cpp:700
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
~QSqlDriver()
Destroys the object and frees any allocated resources.
Definition: qsqldriver.cpp:121
QStringList subscribedToNotifications() const
Returns a list of the names of the event notifications that are currently subscribed to...
Definition: qsqldriver.cpp:817
QTime toTime() const
Returns the variant as a QTime if the variant has type() Time , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2330
The QSqlField class manipulates the fields in SQL database tables and views.
Definition: qsqlfield.h:56
virtual void setLastError(const QSqlError &e)
This function is used to set the value of the last error, error, that occurred on the database...
Definition: qsqldriver.cpp:350
virtual ~QSqlDriverPrivate()
Definition: qsqldriver.cpp:83
Definition: qsql.h:53
QString stripDelimiters(const QString &identifier, IdentifierType type) const
Returns the identifier with the leading and trailing delimiters removed, identifier can either be a t...
Definition: qsqldriver.cpp:455
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
static const KeyPair *const end
QString fieldName(int i) const
Returns the name of the field at position index.
Definition: qsqlrecord.cpp:232
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the date as a string.
Definition: qdatetime.cpp:823
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
IdentifierType
This enum contains a list of SQL identifier types.
Definition: qsqldriver.h:83
QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const
This slot returns identifier with the leading and trailing delimiters removed, identifier can either ...
Definition: qsqldriver.cpp:944
bool isValid() const
Returns true if the time is valid; otherwise returns false.
Definition: qdatetime.cpp:1566