Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsqldriver.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsqldriver.h"
5
6#include "qdatetime.h"
7#include "qsqlerror.h"
8#include "qsqlfield.h"
9#include "qsqlindex.h"
10#include "private/qsqldriver_p.h"
11#include "private/qtools_p.h"
12
13#include <limits.h>
14
16
17using namespace Qt::StringLiterals;
18
19static QString prepareIdentifier(const QString &identifier,
21{
22 Q_ASSERT(driver != nullptr);
23 QString ret = identifier;
24 if (!driver->isIdentifierEscaped(identifier, type))
25 ret = driver->escapeIdentifier(identifier, type);
26 return ret;
27}
28
52 : QObject(*new QSqlDriverPrivate, parent)
53{
54}
55
59 : QObject(dd, parent)
60{
61}
62
70
121{
122 Q_D(const QSqlDriver);
123 return d->isOpen;
124}
125
132{
133 Q_D(const QSqlDriver);
134 return d->isOpenError;
135}
136
242{
243 Q_D(QSqlDriver);
244 d->isOpen = open;
245}
246
257{
258 Q_D(QSqlDriver);
259 d->isOpenError = error;
260 if (error)
261 d->isOpen = false;
262}
263
273{
274 return false;
275}
276
286{
287 return false;
288}
289
299{
300 return false;
301}
302
311{
312 Q_D(QSqlDriver);
313 d->error = error;
314}
315
322{
323 Q_D(const QSqlDriver);
324 return d->error;
325}
326
342
350{
351 return QSqlIndex();
352}
353
354
361QSqlRecord QSqlDriver::record(const QString & /* tableName */) const
362{
363 return QSqlRecord();
364}
365
375{
376 return identifier;
377}
378
390{
391 Q_UNUSED(type);
392 return identifier.size() > 2
393 && identifier.startsWith(u'"') //left delimited
394 && identifier.endsWith(u'"'); //right delimited
395}
396
410{
411 QString ret;
412 if (isIdentifierEscaped(identifier, type)) {
413 ret = identifier.mid(1);
414 ret.chop(1);
415 } else {
416 ret = identifier;
417 }
418 return ret;
419}
420
445 const QSqlRecord &rec, bool preparedStatement) const
446{
447 const auto tableNameString = tableName.isEmpty() ? QString()
448 : prepareIdentifier(tableName, QSqlDriver::TableName, this);
449 QString s;
450 s.reserve(128);
451 switch (type) {
452 case SelectStatement:
453 for (qsizetype i = 0; i < rec.count(); ++i) {
454 if (rec.isGenerated(i))
455 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(", "_L1);
456 }
457 if (s.isEmpty())
458 return s;
459 s.chop(2);
460 s = "SELECT "_L1 + s + " FROM "_L1 + tableNameString;
461 break;
462 case WhereStatement:
463 {
464 const QString tableNamePrefix = tableNameString.isEmpty()
465 ? QString() : tableNameString + u'.';
466 for (qsizetype i = 0; i < rec.count(); ++i) {
467 if (!rec.isGenerated(i))
468 continue;
469 s.append(s.isEmpty() ? "WHERE "_L1 : " AND "_L1);
470 s.append(tableNamePrefix);
472 if (rec.isNull(i))
473 s.append(" IS NULL"_L1);
474 else if (preparedStatement)
475 s.append(" = ?"_L1);
476 else
477 s.append(" = "_L1).append(formatValue(rec.field(i)));
478 }
479 break;
480 }
481 case UpdateStatement:
482 s = s + "UPDATE "_L1 + tableNameString + " SET "_L1;
483 for (qsizetype i = 0; i < rec.count(); ++i) {
484 if (!rec.isGenerated(i))
485 continue;
486 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(u'=');
487 if (preparedStatement)
488 s.append(u'?');
489 else
490 s.append(formatValue(rec.field(i)));
491 s.append(", "_L1);
492 }
493 if (s.endsWith(", "_L1))
494 s.chop(2);
495 else
496 s.clear();
497 break;
498 case DeleteStatement:
499 s = s + "DELETE FROM "_L1 + tableNameString;
500 break;
501 case InsertStatement: {
502 s = s + "INSERT INTO "_L1 + tableNameString + " ("_L1;
503 QString vals;
504 for (qsizetype i = 0; i < rec.count(); ++i) {
505 if (!rec.isGenerated(i))
506 continue;
508 if (preparedStatement)
509 vals.append(u'?');
510 else
511 vals.append(formatValue(rec.field(i)));
512 vals.append(", "_L1);
513 }
514 if (vals.isEmpty()) {
515 s.clear();
516 } else {
517 vals.chop(2); // remove trailing comma
518 s[s.size() - 2] = u')';
519 s.append("VALUES ("_L1).append(vals).append(u')');
520 }
521 break; }
522 }
523 return s;
524}
525
559QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const
560{
561 const auto nullTxt = "NULL"_L1;
562
563 QString r;
564 if (field.isNull())
565 r = nullTxt;
566 else {
567 switch (field.metaType().id()) {
568 case QMetaType::Int:
569 case QMetaType::UInt:
570 if (field.value().userType() == QMetaType::Bool)
571 r = field.value().toBool() ? "1"_L1 : "0"_L1;
572 else
573 r = field.value().toString();
574 break;
575#if QT_CONFIG(datestring)
576 case QMetaType::QDate:
577 if (field.value().toDate().isValid())
578 r = u'\'' + field.value().toDate().toString(Qt::ISODate) + u'\'';
579 else
580 r = nullTxt;
581 break;
582 case QMetaType::QTime:
583 if (field.value().toTime().isValid())
584 r = u'\'' + field.value().toTime().toString(Qt::ISODate) + u'\'';
585 else
586 r = nullTxt;
587 break;
588 case QMetaType::QDateTime:
589 if (field.value().toDateTime().isValid())
590 r = u'\'' + field.value().toDateTime().toString(Qt::ISODate) + u'\'';
591 else
592 r = nullTxt;
593 break;
594#endif
595 case QMetaType::QString:
596 case QMetaType::QChar:
597 {
598 QString result = field.value().toString();
599 if (trimStrings) {
600 int end = result.size();
601 while (end && result.at(end-1).isSpace()) /* skip white space from end */
602 end--;
603 result.truncate(end);
604 }
605 /* escape the "'" character */
606 result.replace(u'\'', "''"_L1);
607 r = u'\'' + result + u'\'';
608 break;
609 }
610 case QMetaType::Bool:
611 r = QString::number(field.value().toBool());
612 break;
613 case QMetaType::QByteArray : {
614 if (hasFeature(BLOB)) {
615 const QByteArray ba = field.value().toByteArray();
616 r.reserve((ba.size() + 1) * 2);
617 r += u'\'';
618 for (const char c : ba) {
619 const uchar s = uchar(c);
622 }
623 r += u'\'';
624 break;
625 }
626 }
628 default:
629 r = field.value().toString();
630 break;
631 }
632 }
633 return r;
634}
635
661{
662 return QVariant();
663}
664
685{
686 Q_UNUSED(name);
687 return false;
688}
689
708{
709 Q_UNUSED(name);
710 return false;
711}
712
725
730{
731 Q_D(QSqlDriver);
732 d->precisionPolicy = precisionPolicy;
733}
734
749{
750 Q_D(const QSqlDriver);
751 return d->precisionPolicy;
752}
753
761{
762 Q_D(const QSqlDriver);
763 return d->dbmsType;
764}
765
785{
786 return false;
787}
788
801
803
804#include "moc_qsqldriver.cpp"
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
Definition qbytearray.h:634
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:71
int id(int=0) const
Definition qmetatype.h:475
\inmodule QtCore
Definition qobject.h:103
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
Definition qsqldriver.h:26
virtual QString formatValue(const QSqlField &field, bool trimStrings=false) const
Returns a string representation of the field value for the database.
virtual bool commitTransaction()
This function is called to commit a transaction.
IdentifierType
This enum contains a list of SQL identifier types.
Definition qsqldriver.h:41
virtual bool cancelQuery()
QSqlDriver(QObject *parent=nullptr)
Constructs a new driver with the given parent.
StatementType
This enum contains a list of SQL statement (or clause) types the driver can create.
Definition qsqldriver.h:38
@ DeleteStatement
Definition qsqldriver.h:39
@ UpdateStatement
Definition qsqldriver.h:38
@ InsertStatement
Definition qsqldriver.h:39
@ SelectStatement
Definition qsqldriver.h:38
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
Sets \l numericalPrecisionPolicy to precisionPolicy.
virtual bool unsubscribeFromNotification(const QString &name)
This function is called to unsubscribe from event notifications from the database.
virtual QSqlIndex primaryIndex(const QString &tableName) const
Returns the primary index for table tableName.
virtual QString stripDelimiters(const QString &identifier, IdentifierType type) const
Returns the identifier with the leading and trailing delimiters removed, identifier can either be a t...
virtual bool beginTransaction()
This function is called to begin a transaction.
QSqlError lastError() const
Returns a QSqlError object which contains information about the last error that occurred on the datab...
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.
virtual QSqlRecord record(const QString &tableName) const
Returns a QSqlRecord populated with the names of the fields in table tableName.
virtual bool rollbackTransaction()
This function is called to rollback a transaction.
virtual QString escapeIdentifier(const QString &identifier, IdentifierType type) const
Returns the identifier escaped according to the database rules.
bool isOpenError() const
Returns true if the there was an error opening the database connection; otherwise returns false.
DbmsType dbmsType() const
virtual void setLastError(const QSqlError &e)
This function is used to set the value of the last error, error, that occurred on the database.
virtual QVariant handle() const
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
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...
virtual bool isOpen() const
Returns true if the database connection is open; otherwise returns false.
virtual int maximumIdentifierLength(IdentifierType type) const
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy
Definition qsqldriver.h:58
virtual void setOpenError(bool e)
This function sets the open error state of the database to error.
virtual bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const
Returns whether identifier is escaped according to the database rules.
virtual bool hasFeature(DriverFeature f) const =0
Returns true if the driver supports feature feature; otherwise returns false.
virtual bool subscribeToNotification(const QString &name)
This function is called to subscribe to event notifications from the database.
virtual void setOpen(bool o)
This function sets the open state of the database to open.
~QSqlDriver()
Destroys the object and frees any allocated resources.
virtual QStringList tables(QSql::TableType tableType) const
Returns a list of the names of the tables in the database.
virtual QStringList subscribedToNotifications() const
Returns a list of the names of the event notifications that are currently subscribed to.
The QSqlError class provides SQL database error information.
Definition qsqlerror.h:17
The QSqlField class manipulates the fields in SQL database tables and views.
Definition qsqlfield.h:19
QMetaType metaType
Definition qsqlfield.h:28
bool isNull() const
Returns true if the field's value is NULL; otherwise returns false.
QVariant value
Definition qsqlfield.h:24
The QSqlIndex class provides functions to manipulate and describe database indexes.
Definition qsqlindex.h:18
The QSqlRecord class encapsulates a database record.
Definition qsqlrecord.h:20
bool isNull(int i) const
Returns true if the field index is null or if there is no field at position index; otherwise returns ...
QSqlField field(int i) const
Returns the field at position index.
int count() const
Returns the number of fields in the record.
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...
QString fieldName(int i) const
Returns the name of the field at position index.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
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:5455
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
Definition qstring.h:1325
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6340
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
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:5506
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:8084
QString & append(QChar c)
Definition qstring.cpp:3252
bool isValid() const
Returns true if the time is valid; otherwise returns false.
\inmodule QtCore
Definition qvariant.h:65
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
int userType() const
Definition qvariant.h:339
QTime toTime() const
Returns the variant as a QTime if the variant has userType() \l QMetaType::QTime, \l QMetaType::QDate...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
QDate toDate() const
Returns the variant as a QDate if the variant has userType() \l QMetaType::QDate, \l QMetaType::QDate...
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
list append(new Employee("Blackpool", "Stephen"))
NumericalPrecisionPolicy
Definition qtsqlglobal.h:43
Combined button and popup list for selecting options.
constexpr char toHexLower(char32_t value) noexcept
Definition qtools_p.h:32
@ ISODate
#define Q_FALLTHROUGH()
QList< QString > QStringList
Constructs a string list that contains the given string, str.
DBusConnection const char DBusError * error
return ret
GLboolean r
[2]
GLuint GLuint end
GLenum type
GLuint name
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QString prepareIdentifier(const QString &identifier, QSqlDriver::IdentifierType type, const QSqlDriver *driver)
#define Q_UNUSED(x)
unsigned char uchar
Definition qtypes.h:32
ptrdiff_t qsizetype
Definition qtypes.h:165
QByteArray ba
[0]
file open(QIODevice::ReadOnly)
\inmodule QtCore \reentrant
Definition qchar.h:18