Qt 6.x
The Qt SDK
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
53{
54}
55
59 : QObject(dd, parent)
60{
61}
62
68{
69}
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
339{
340 return QStringList();
341}
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
411{
412 QString ret;
413 if (isIdentifierEscaped(identifier, type)) {
414 ret = identifier.mid(1);
415 ret.chop(1);
416 } else {
417 ret = identifier;
418 }
419 return ret;
420}
421
446 const QSqlRecord &rec, bool preparedStatement) const
447{
448 const auto tableNameString = tableName.isEmpty() ? QString()
449 : prepareIdentifier(tableName, QSqlDriver::TableName, this);
450 QString s;
451 s.reserve(128);
452 switch (type) {
453 case SelectStatement:
454 for (qsizetype i = 0; i < rec.count(); ++i) {
455 if (rec.isGenerated(i))
456 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(", "_L1);
457 }
458 if (s.isEmpty())
459 return s;
460 s.chop(2);
461 s = "SELECT "_L1 + s + " FROM "_L1 + tableNameString;
462 break;
463 case WhereStatement:
464 {
465 const QString tableNamePrefix = tableNameString.isEmpty()
466 ? QString() : tableNameString + u'.';
467 for (qsizetype i = 0; i < rec.count(); ++i) {
468 if (!rec.isGenerated(i))
469 continue;
470 s.append(s.isEmpty() ? "WHERE "_L1 : " AND "_L1);
471 s.append(tableNamePrefix);
473 if (rec.isNull(i))
474 s.append(" IS NULL"_L1);
475 else if (preparedStatement)
476 s.append(" = ?"_L1);
477 else
478 s.append(" = "_L1).append(formatValue(rec.field(i)));
479 }
480 break;
481 }
482 case UpdateStatement:
483 s = s + "UPDATE "_L1 + tableNameString + " SET "_L1;
484 for (qsizetype i = 0; i < rec.count(); ++i) {
485 if (!rec.isGenerated(i))
486 continue;
487 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(u'=');
488 if (preparedStatement)
489 s.append(u'?');
490 else
491 s.append(formatValue(rec.field(i)));
492 s.append(", "_L1);
493 }
494 if (s.endsWith(", "_L1))
495 s.chop(2);
496 else
497 s.clear();
498 break;
499 case DeleteStatement:
500 s = s + "DELETE FROM "_L1 + tableNameString;
501 break;
502 case InsertStatement: {
503 s = s + "INSERT INTO "_L1 + tableNameString + " ("_L1;
504 QString vals;
505 for (qsizetype i = 0; i < rec.count(); ++i) {
506 if (!rec.isGenerated(i))
507 continue;
509 if (preparedStatement)
510 vals.append(u'?');
511 else
512 vals.append(formatValue(rec.field(i)));
513 vals.append(", "_L1);
514 }
515 if (vals.isEmpty()) {
516 s.clear();
517 } else {
518 vals.chop(2); // remove trailing comma
519 s[s.size() - 2] = u')';
520 s.append("VALUES ("_L1).append(vals).append(u')');
521 }
522 break; }
523 }
524 return s;
525}
526
560QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const
561{
562 const auto nullTxt = "NULL"_L1;
563
564 QString r;
565 if (field.isNull())
566 r = nullTxt;
567 else {
568 switch (field.metaType().id()) {
569 case QMetaType::Int:
570 case QMetaType::UInt:
571 if (field.value().userType() == QMetaType::Bool)
572 r = field.value().toBool() ? "1"_L1 : "0"_L1;
573 else
574 r = field.value().toString();
575 break;
576#if QT_CONFIG(datestring)
577 case QMetaType::QDate:
578 if (field.value().toDate().isValid())
579 r = u'\'' + field.value().toDate().toString(Qt::ISODate) + u'\'';
580 else
581 r = nullTxt;
582 break;
583 case QMetaType::QTime:
584 if (field.value().toTime().isValid())
585 r = u'\'' + field.value().toTime().toString(Qt::ISODate) + u'\'';
586 else
587 r = nullTxt;
588 break;
589 case QMetaType::QDateTime:
590 if (field.value().toDateTime().isValid())
591 r = u'\'' + field.value().toDateTime().toString(Qt::ISODate) + u'\'';
592 else
593 r = nullTxt;
594 break;
595#endif
596 case QMetaType::QString:
597 case QMetaType::QChar:
598 {
599 QString result = field.value().toString();
600 if (trimStrings) {
601 int end = result.size();
602 while (end && result.at(end-1).isSpace()) /* skip white space from end */
603 end--;
604 result.truncate(end);
605 }
606 /* escape the "'" character */
607 result.replace(u'\'', "''"_L1);
608 r = u'\'' + result + u'\'';
609 break;
610 }
611 case QMetaType::Bool:
612 r = QString::number(field.value().toBool());
613 break;
614 case QMetaType::QByteArray : {
615 if (hasFeature(BLOB)) {
616 const QByteArray ba = field.value().toByteArray();
617 r.reserve((ba.size() + 1) * 2);
618 r += u'\'';
619 for (const char c : ba) {
620 const uchar s = uchar(c);
623 }
624 r += u'\'';
625 break;
626 }
627 }
629 default:
630 r = field.value().toString();
631 break;
632 }
633 }
634 return r;
635}
636
662{
663 return QVariant();
664}
665
687{
688 Q_UNUSED(name);
689 return false;
690}
691
711{
712 Q_UNUSED(name);
713 return false;
714}
715
726{
727 return QStringList();
728}
729
743{
744 Q_D(QSqlDriver);
745 d->precisionPolicy = precisionPolicy;
746}
747
757{
758 Q_D(const QSqlDriver);
759 return d->precisionPolicy;
760}
761
769{
770 Q_D(const QSqlDriver);
771 return d->dbmsType;
772}
773
793{
794 return false;
795}
796
805{
806 Q_UNUSED(type);
807 return INT_MAX;
808}
809
811
812#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:474
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
Definition qbytearray.h:557
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:86
int id(int=0) const
Definition qmetatype.h:454
\inmodule QtCore
Definition qobject.h:90
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
Definition qsqldriver.h:25
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:40
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:37
@ DeleteStatement
Definition qsqldriver.h:38
@ UpdateStatement
Definition qsqldriver.h:37
@ InsertStatement
Definition qsqldriver.h:38
@ SelectStatement
Definition qsqldriver.h:37
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy 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
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() 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
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() const
Returns the field's type as stored in the database.
QVariant value() const
Returns the value of the field as a QVariant.
Definition qsqlfield.h:37
bool isNull() const
Returns true if the field's value is NULL; otherwise returns false.
The QSqlIndex class provides functions to manipulate and describe database indexes.
Definition qsqlindex.h:16
The QSqlRecord class encapsulates a database record.
Definition qsqlrecord.h:20
bool isNull(int i) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
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
This is an overloaded member function, provided for convenience. It differs from the above function o...
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:127
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:5299
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
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:5350
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
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:7822
QString & append(QChar c)
Definition qstring.cpp:3227
bool isValid() const
Returns true if the time is valid; otherwise returns false.
\inmodule QtCore
Definition qvariant.h:64
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
int userType() const
Definition qvariant.h:336
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:44
Combined button and popup list for selecting options.
constexpr char toHexLower(char32_t value) noexcept
Definition qtools_p.h:32
@ ISODate
#define Q_FALLTHROUGH()
DBusConnection const char DBusError * error
return ret
GLboolean r
[2]
GLuint GLuint end
GLenum type
GLuint name
const GLubyte * c
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
#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:27
ptrdiff_t qsizetype
Definition qtypes.h:70
QByteArray ba
[0]
file open(QIODevice::ReadOnly)
\inmodule QtCore \reentrant
Definition qchar.h:17
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent