File indexing completed on 2024-11-10 04:40:37

0001 /*
0002     SPDX-FileCopyrightText: 2019 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "attributestorage_p.h"
0008 
0009 #include <QSharedData>
0010 
0011 using namespace Akonadi;
0012 
0013 namespace Akonadi
0014 {
0015 
0016 class AttributeStoragePrivate : public QSharedData
0017 {
0018 public:
0019     AttributeStoragePrivate() = default;
0020     AttributeStoragePrivate(AttributeStoragePrivate &other)
0021         : QSharedData(other)
0022         , atributes(other.atributes)
0023         , modifiedAttributes(other.modifiedAttributes)
0024         , deletedAttributes(other.deletedAttributes)
0025     {
0026         for (Attribute *attr : std::as_const(atributes)) {
0027             atributes.insert(attr->type(), attr->clone());
0028         }
0029     }
0030 
0031     ~AttributeStoragePrivate()
0032     {
0033         qDeleteAll(atributes);
0034     }
0035 
0036     QHash<QByteArray, Attribute *> atributes;
0037     std::set<QByteArray> modifiedAttributes;
0038     QSet<QByteArray> deletedAttributes;
0039 };
0040 
0041 } // namespace Akonadi
0042 
0043 AttributeStorage::AttributeStorage()
0044     : d(new AttributeStoragePrivate)
0045 {
0046 }
0047 
0048 AttributeStorage::AttributeStorage(const AttributeStorage &other)
0049     : d(other.d)
0050 {
0051 }
0052 
0053 AttributeStorage::AttributeStorage(AttributeStorage &&other) noexcept
0054 {
0055     d.swap(other.d);
0056 }
0057 
0058 AttributeStorage &AttributeStorage::operator=(const AttributeStorage &other)
0059 {
0060     d = other.d;
0061     return *this;
0062 }
0063 
0064 AttributeStorage &AttributeStorage::operator=(AttributeStorage &&other) noexcept
0065 {
0066     d.swap(other.d);
0067     return *this;
0068 }
0069 
0070 AttributeStorage::~AttributeStorage() = default;
0071 
0072 void AttributeStorage::addAttribute(Attribute *attr)
0073 {
0074     Q_ASSERT(attr);
0075     const QByteArray type = attr->type();
0076     Attribute *existing = d->atributes.value(type);
0077     if (existing) {
0078         if (attr == existing) {
0079             return;
0080         }
0081         d->atributes.remove(type);
0082         delete existing;
0083     }
0084     d->atributes.insert(type, attr);
0085     markAttributeModified(type);
0086 }
0087 
0088 void AttributeStorage::removeAttribute(const QByteArray &type)
0089 {
0090     d->modifiedAttributes.erase(type);
0091     d->deletedAttributes.insert(type);
0092     delete d->atributes.take(type);
0093 }
0094 
0095 bool AttributeStorage::hasAttribute(const QByteArray &type) const
0096 {
0097     return d->atributes.contains(type);
0098 }
0099 
0100 Attribute::List AttributeStorage::attributes() const
0101 {
0102     return d->atributes.values();
0103 }
0104 
0105 void AttributeStorage::clearAttributes()
0106 {
0107     for (Attribute *attr : std::as_const(d->atributes)) {
0108         d->deletedAttributes.insert(attr->type());
0109         delete attr;
0110     }
0111     d->atributes.clear();
0112     d->modifiedAttributes.clear();
0113 }
0114 
0115 const Attribute *AttributeStorage::attribute(const QByteArray &type) const
0116 {
0117     return d->atributes.value(type);
0118 }
0119 
0120 Attribute *AttributeStorage::attribute(const QByteArray &type)
0121 {
0122     Attribute *attr = d->atributes.value(type);
0123     if (attr) {
0124         markAttributeModified(type);
0125     }
0126     return attr;
0127 }
0128 
0129 void AttributeStorage::markAttributeModified(const QByteArray &type)
0130 {
0131     if (d->atributes.contains(type)) {
0132         d->deletedAttributes.remove(type);
0133         d->modifiedAttributes.insert(type);
0134     }
0135 }
0136 
0137 void AttributeStorage::resetChangeLog()
0138 {
0139     d->modifiedAttributes.clear();
0140     d->deletedAttributes.clear();
0141 }
0142 
0143 QSet<QByteArray> AttributeStorage::deletedAttributes() const
0144 {
0145     return d->deletedAttributes;
0146 }
0147 
0148 bool AttributeStorage::hasModifiedAttributes() const
0149 {
0150     return !d->modifiedAttributes.empty();
0151 }
0152 
0153 std::vector<Attribute *> AttributeStorage::modifiedAttributes() const
0154 {
0155     std::vector<Attribute *> ret;
0156     ret.reserve(d->modifiedAttributes.size());
0157     for (const auto &type : d->modifiedAttributes) {
0158         Attribute *attr = d->atributes.value(type);
0159         Q_ASSERT(attr);
0160         ret.push_back(attr);
0161     }
0162     return ret;
0163 }