diff options
Diffstat (limited to 'src/sql/kernel/qsqlrecord.cpp')
-rw-r--r-- | src/sql/kernel/qsqlrecord.cpp | 273 |
1 files changed, 137 insertions, 136 deletions
diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp index 5f4a4a8ab1..3c3b2b3390 100644 --- a/src/sql/kernel/qsqlrecord.cpp +++ b/src/sql/kernel/qsqlrecord.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtSql module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qsqlrecord.h" @@ -44,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 + QLatin1Char('.'); - f += fields.at(index).name(); - return f; -} +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlRecordPrivate) /*! \class QSqlRecord @@ -122,8 +91,8 @@ QString QSqlRecordPrivate::createField(int index, const QString &prefix) const */ QSqlRecord::QSqlRecord() + : d(new QSqlRecordPrivate) { - d = new QSqlRecordPrivate(); } /*! @@ -133,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. @@ -146,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 @@ -201,10 +193,12 @@ 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() -*/ + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. -QVariant QSqlRecord::value(const QString& name) const + \sa indexOf(), isNull() +*/ +QVariant QSqlRecord::value(QAnyStringView name) const { return value(indexOf(name)); } @@ -227,31 +221,17 @@ QString QSqlRecord::fieldName(int index) const case-sensitive. If more than one field matches, the first one is returned. - \sa fieldName() -*/ + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. -int QSqlRecord::indexOf(const QString& name) const + \sa fieldName() + */ +int QSqlRecord::indexOf(QAnyStringView name) const { - QStringView tableName; - QStringView fieldName(name); - const int idx = name.indexOf(QLatin1Char('.')); - 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); + }); } /*! @@ -264,10 +244,17 @@ 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}. + + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. */ -QSqlField QSqlRecord::field(const QString &name) const +QSqlField QSqlRecord::field(QAnyStringView name) const { return field(indexOf(name)); } @@ -279,7 +266,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); @@ -290,7 +277,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); @@ -303,7 +290,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; @@ -352,13 +339,14 @@ 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 + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. +*/ +bool QSqlRecord::contains(QAnyStringView name) const { return indexOf(name) >= 0; } @@ -373,9 +361,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(); } /*! @@ -384,17 +371,17 @@ void QSqlRecord::clearValues() fields that have \a generated set to true are included in the SQL that is generated by QSqlQueryModel for example. + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. + \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() @@ -409,10 +396,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 { @@ -420,12 +407,17 @@ 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. + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. + \sa setNull() */ -bool QSqlRecord::isNull(const QString& name) const +bool QSqlRecord::isNull(QAnyStringView name) const { return isNull(indexOf(name)); } @@ -449,26 +441,32 @@ void QSqlRecord::setNull(int index) Sets the value of the field called \a name to null. If the field does not exist, nothing happens. + + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. */ -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. + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. + \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. @@ -487,7 +485,7 @@ bool QSqlRecord::isGenerated(int index) const int QSqlRecord::count() const { - return d->fields.count(); + return d->fields.size(); } /*! @@ -497,7 +495,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; @@ -505,15 +503,18 @@ 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) + \note In Qt versions prior to 6.8, this function took QString, not + QAnyStringView. + + \sa setNull() +*/ +void QSqlRecord::setValue(QAnyStringView name, const QVariant &val) { setValue(indexOf(name), val); } @@ -523,7 +524,7 @@ void QSqlRecord::setValue(const QString& name, const QVariant& val) */ void QSqlRecord::detach() { - qAtomicDetach(d); + d.detach(); } #ifndef QT_NO_DEBUG_STREAM |