diff options
Diffstat (limited to 'src/sql/kernel/qsqlrecord.cpp')
-rw-r--r-- | src/sql/kernel/qsqlrecord.cpp | 206 |
1 files changed, 108 insertions, 98 deletions
diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp index 41fcd745cd..89af1a52fe 100644 --- a/src/sql/kernel/qsqlrecord.cpp +++ b/src/sql/kernel/qsqlrecord.cpp @@ -8,42 +8,47 @@ #include "qlist.h" #include "qsqlfield.h" #include "qstring.h" -#include "qstringlist.h" QT_BEGIN_NAMESPACE -class QSqlRecordPrivate +class QSqlRecordPrivate : public QSharedData { public: - QSqlRecordPrivate(); - QSqlRecordPrivate(const QSqlRecordPrivate &other); + inline bool contains(qsizetype index) const + { + return index >= 0 && index < fields.size(); + } - inline bool contains(int index) { return index >= 0 && index < fields.count(); } - QString createField(int index, const QString &prefix) const; + template <typename T> + qsizetype indexOfImpl(T name) + { + T tableName; + T fieldName; + const auto it = std::find(name.begin(), name.end(), u'.'); + const auto idx = (it == name.end()) ? -1 : it - name.begin(); + if (idx != -1) { + tableName = name.left(idx); + fieldName = name.mid(idx + 1); + } + const auto cnt = fields.size(); + for (qsizetype i = 0; i < cnt; ++i) { + // Check the passed in name first in case it is an alias using a dot. + // Then check if both the table and field match when there is a table name specified. + const auto ¤tField = fields.at(i); + const auto ¤tFieldName = currentField.name(); + if (name.compare(currentFieldName, Qt::CaseInsensitive) == 0) + return i; + if (idx != -1 && + tableName.compare(currentField.tableName(), Qt::CaseInsensitive) == 0 && + fieldName.compare(currentFieldName, Qt::CaseInsensitive) == 0) + return i; + } + return -1; + } QList<QSqlField> fields; - QAtomicInt ref; }; - -QSqlRecordPrivate::QSqlRecordPrivate() : ref(1) -{ -} - -QSqlRecordPrivate::QSqlRecordPrivate(const QSqlRecordPrivate &other): fields(other.fields), ref(1) -{ -} - -/*! \internal - Just for compat -*/ -QString QSqlRecordPrivate::createField(int index, const QString &prefix) const -{ - QString f; - if (!prefix.isEmpty()) - f = prefix + u'.'; - f += fields.at(index).name(); - return f; -} +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlRecordPrivate) /*! \class QSqlRecord @@ -86,8 +91,8 @@ QString QSqlRecordPrivate::createField(int index, const QString &prefix) const */ QSqlRecord::QSqlRecord() + : d(new QSqlRecordPrivate) { - d = new QSqlRecordPrivate(); } /*! @@ -97,11 +102,39 @@ QSqlRecord::QSqlRecord() of a record in \l{constant time}. */ -QSqlRecord::QSqlRecord(const QSqlRecord& other) -{ - d = other.d; - d->ref.ref(); -} +QSqlRecord::QSqlRecord(const QSqlRecord &other) + = default; + +/*! + \fn QSqlRecord::QSqlRecord(QSqlRecord &&other) + \since 6.6 + + Move-constructs a new QSqlRecord from \a other. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn QSqlRecord &QSqlRecord::operator=(QSqlRecord &&other) + \since 6.6 + + Move-assigns \a other to this QSqlRecord instance. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn void QSqlRecord::swap(QSqlRecord &other) + \since 6.6 + + Swaps SQL record \a other with this SQL record. This operation is very fast + and never fails. +*/ + /*! Sets the record equal to \a other. @@ -110,21 +143,16 @@ QSqlRecord::QSqlRecord(const QSqlRecord& other) of a record in \l{constant time}. */ -QSqlRecord& QSqlRecord::operator=(const QSqlRecord& other) -{ - qAtomicAssign(d, other.d); - return *this; -} +QSqlRecord& QSqlRecord::operator=(const QSqlRecord &other) + = default; /*! Destroys the object and frees any allocated resources. */ QSqlRecord::~QSqlRecord() -{ - if (!d->ref.deref()) - delete d; -} + = default; + /*! \fn bool QSqlRecord::operator!=(const QSqlRecord &other) const @@ -165,10 +193,9 @@ QVariant QSqlRecord::value(int index) const Returns the value of the field called \a name in the record. If field \a name does not exist an invalid variant is returned. - \sa indexOf() + \sa indexOf(), isNull() */ - -QVariant QSqlRecord::value(const QString& name) const +QVariant QSqlRecord::value(QAnyStringView name) const { return value(indexOf(name)); } @@ -192,30 +219,13 @@ QString QSqlRecord::fieldName(int index) const returned. \sa fieldName() -*/ - -int QSqlRecord::indexOf(const QString& name) const + */ +int QSqlRecord::indexOf(QAnyStringView name) const { - QStringView tableName; - QStringView fieldName(name); - const qsizetype idx = name.indexOf(u'.'); - if (idx != -1) { - tableName = fieldName.left(idx); - fieldName = fieldName.mid(idx + 1); - } - const int cnt = count(); - for (int i = 0; i < cnt; ++i) { - // Check the passed in name first in case it is an alias using a dot. - // Then check if both the table and field match when there is a table name specified. - const auto ¤tField = d->fields.at(i); - const auto ¤tFieldName = currentField.name(); - if (currentFieldName.compare(name, Qt::CaseInsensitive) == 0 - || (idx != -1 && currentFieldName.compare(fieldName, Qt::CaseInsensitive) == 0 - && currentField.tableName().compare(tableName, Qt::CaseInsensitive) == 0)) { - return i; - } - } - return -1; + return name.visit([&](auto v) + { + return d->indexOfImpl(v); + }); } /*! @@ -228,10 +238,14 @@ QSqlField QSqlRecord::field(int index) const return d->fields.value(index); } -/*! \overload - Returns the field called \a name. +/*! + \overload + + Returns the field called \a name. If the field called + \a name is not found, function returns + a \l{default-constructed value}. */ -QSqlField QSqlRecord::field(const QString &name) const +QSqlField QSqlRecord::field(QAnyStringView name) const { return field(indexOf(name)); } @@ -243,7 +257,7 @@ QSqlField QSqlRecord::field(const QString &name) const \sa insert(), replace(), remove() */ -void QSqlRecord::append(const QSqlField& field) +void QSqlRecord::append(const QSqlField &field) { detach(); d->fields.append(field); @@ -254,7 +268,7 @@ void QSqlRecord::append(const QSqlField& field) \sa append(), replace(), remove() */ -void QSqlRecord::insert(int pos, const QSqlField& field) +void QSqlRecord::insert(int pos, const QSqlField &field) { detach(); d->fields.insert(pos, field); @@ -267,7 +281,7 @@ void QSqlRecord::insert(int pos, const QSqlField& field) \sa append(), insert(), remove() */ -void QSqlRecord::replace(int pos, const QSqlField& field) +void QSqlRecord::replace(int pos, const QSqlField &field) { if (!d->contains(pos)) return; @@ -316,13 +330,11 @@ bool QSqlRecord::isEmpty() const return d->fields.isEmpty(); } - /*! Returns \c true if there is a field in the record called \a name; otherwise returns \c false. */ - -bool QSqlRecord::contains(const QString& name) const +bool QSqlRecord::contains(QAnyStringView name) const { return indexOf(name) >= 0; } @@ -337,9 +349,8 @@ bool QSqlRecord::contains(const QString& name) const void QSqlRecord::clearValues() { detach(); - int count = d->fields.count(); - for (int i = 0; i < count; ++i) - d->fields[i].clear(); + for (QSqlField &f : d->fields) + f.clear(); } /*! @@ -350,15 +361,12 @@ void QSqlRecord::clearValues() \sa isGenerated() */ - -void QSqlRecord::setGenerated(const QString& name, bool generated) +void QSqlRecord::setGenerated(QAnyStringView name, bool generated) { setGenerated(indexOf(name), generated); } /*! - \overload - Sets the generated flag for the field \a index to \a generated. \sa isGenerated() @@ -373,10 +381,10 @@ void QSqlRecord::setGenerated(int index, bool generated) } /*! - \overload - Returns \c true if the field \a index is null or if there is no field at position \a index; otherwise returns \c false. + + \sa setNull() */ bool QSqlRecord::isNull(int index) const { @@ -384,12 +392,14 @@ bool QSqlRecord::isNull(int index) const } /*! + \overload + Returns \c true if the field called \a name is null or if there is no field called \a name; otherwise returns \c false. \sa setNull() */ -bool QSqlRecord::isNull(const QString& name) const +bool QSqlRecord::isNull(QAnyStringView name) const { return isNull(indexOf(name)); } @@ -414,25 +424,25 @@ void QSqlRecord::setNull(int index) Sets the value of the field called \a name to null. If the field does not exist, nothing happens. */ -void QSqlRecord::setNull(const QString& name) +void QSqlRecord::setNull(QAnyStringView name) { setNull(indexOf(name)); } - /*! + \overload + Returns \c true if the record has a field called \a name and this field is to be generated (the default); otherwise returns \c false. \sa setGenerated() */ -bool QSqlRecord::isGenerated(const QString& name) const +bool QSqlRecord::isGenerated(QAnyStringView name) const { return isGenerated(indexOf(name)); } -/*! \overload - +/*! Returns \c true if the record has a field at position \a index and this field is to be generated (the default); otherwise returns \c false. @@ -451,7 +461,7 @@ bool QSqlRecord::isGenerated(int index) const int QSqlRecord::count() const { - return d->fields.count(); + return d->fields.size(); } /*! @@ -461,7 +471,7 @@ int QSqlRecord::count() const \sa setNull() */ -void QSqlRecord::setValue(int index, const QVariant& val) +void QSqlRecord::setValue(int index, const QVariant &val) { if (!d->contains(index)) return; @@ -469,15 +479,15 @@ void QSqlRecord::setValue(int index, const QVariant& val) d->fields[index].setValue(val); } - /*! \overload Sets the value of the field called \a name to \a val. If the field does not exist, nothing happens. -*/ -void QSqlRecord::setValue(const QString& name, const QVariant& val) + \sa setNull() +*/ +void QSqlRecord::setValue(QAnyStringView name, const QVariant &val) { setValue(indexOf(name), val); } @@ -487,7 +497,7 @@ void QSqlRecord::setValue(const QString& name, const QVariant& val) */ void QSqlRecord::detach() { - qAtomicDetach(d); + d.detach(); } #ifndef QT_NO_DEBUG_STREAM |