File indexing completed on 2024-06-23 05:20:11

0001 /*
0002  * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) version 3, or any
0008  * later version accepted by the membership of KDE e.V. (or its
0009  * successor approved by the membership of KDE e.V.), which shall
0010  * act as a proxy defined in Section 6 of version 3 of the license.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 #pragma once
0021 
0022 #include "sink_export.h"
0023 
0024 #include <memory>
0025 #include "domaintypeadaptorfactoryinterface.h"
0026 #include "query.h"
0027 #include "storage.h"
0028 #include "key.h"
0029 #include "resourcecontext.h"
0030 #include "metadata_generated.h"
0031 
0032 namespace Sink {
0033 class EntityBuffer;
0034 namespace Storage {
0035 
0036 class SINK_EXPORT EntityStore
0037 {
0038 public:
0039     typedef QSharedPointer<EntityStore> Ptr;
0040     EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &);
0041     ~EntityStore() = default;
0042 
0043     using ApplicationDomainType = ApplicationDomain::ApplicationDomainType;
0044 
0045     void initialize();
0046 
0047     //Only the pipeline may call the following functions outside of tests
0048     bool add(const QByteArray &type, ApplicationDomainType newEntity, bool replayToSource);
0049     bool modify(const QByteArray &type, const ApplicationDomainType &diff, const QByteArrayList &deletions, bool replayToSource);
0050     bool modify(const QByteArray &type, const ApplicationDomainType &current, ApplicationDomainType newEntity, bool replayToSource);
0051     bool remove(const QByteArray &type, const ApplicationDomainType &current, bool replayToSource);
0052     bool cleanupRevisions(qint64 revision);
0053     qint64 lastCleanRevision();
0054     ApplicationDomainType applyDiff(const QByteArray &type, const ApplicationDomainType &current, const ApplicationDomainType &diff, const QByteArrayList &deletions, const QSet<QByteArray> &excludeProperties = {}) const;
0055 
0056     void startTransaction(Sink::Storage::DataStore::AccessMode);
0057     void commitTransaction();
0058     void abortTransaction();
0059     bool hasTransaction() const;
0060 
0061     QVector<Sink::Storage::Identifier> fullScan(const QByteArray &type);
0062     QVector<Sink::Storage::Identifier> indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting);
0063     QVector<Sink::Storage::Identifier> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const QVector<Sink::Storage::Identifier> &filter);
0064     void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback);
0065     template<typename EntityType, typename PropertyType>
0066     void indexLookup(const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) {
0067         return indexLookup(ApplicationDomain::getTypeName<EntityType>(), PropertyType::name, value, callback);
0068     }
0069 
0070     ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
0071     void readLatest(const QByteArray &type, const Identifier &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> &callback);
0072     void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> &callback);
0073     ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
0074     void readLatest(const QByteArray &type, const Identifier &uid, const std::function<void(const ApplicationDomainType &entity)> &callback);
0075     void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomainType &entity)> &callback);
0076     ///Returns an entity and operation. Note that the memory only remains valid until the next operation or transaction end.
0077     void readLatest(const QByteArray &type, const Identifier &uid, const std::function<void(const ApplicationDomainType &entity, Sink::Operation)> &callback);
0078     void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomainType &entity, Sink::Operation)> &callback);
0079 
0080     ///Returns a copy
0081     ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid);
0082 
0083     template<typename T>
0084     T readLatest(const QByteArray &uid) {
0085         return T(readLatest(ApplicationDomain::getTypeName<T>(), uid));
0086     }
0087 
0088     ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
0089     void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> &callback);
0090     ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
0091     void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomainType &entity)> &callback);
0092     ///Returns a copy
0093     ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key);
0094 
0095     template<typename T>
0096     T readEntity(const QByteArray &key) {
0097         return T(readEntity(ApplicationDomain::getTypeName<T>(), key));
0098     }
0099 
0100 
0101     void readPrevious(const QByteArray &type, const Sink::Storage::Identifier &id, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> &callback);
0102     void readPrevious(const QByteArray &type, const Sink::Storage::Identifier &id, qint64 revision, const std::function<void(const ApplicationDomainType &entity)> &callback);
0103     ///Returns a copy
0104     ApplicationDomainType readPrevious(const QByteArray &type, const Sink::Storage::Identifier &id, qint64 revision);
0105 
0106     template<typename T>
0107     T readPrevious(const QByteArray &uid, qint64 revision) {
0108         return T(readPrevious(ApplicationDomain::getTypeName<T>(), uid, revision));
0109     }
0110 
0111     void readAllUids(const QByteArray &type, const std::function<void(const QByteArray &uid)> &callback);
0112 
0113     void readAll(const QByteArray &type, const std::function<void(const ApplicationDomainType &entity)> &callback);
0114 
0115     template<typename T>
0116     void readAll(const std::function<void(const T &entity)> &callback) {
0117         return readAll(ApplicationDomain::getTypeName<T>(), [&](const ApplicationDomainType &entity) {
0118             callback(T(entity));
0119         });
0120     }
0121 
0122     void readRevisions(qint64 baseRevision, const QByteArray &type, const std::function<void(const Key &key)> &callback);
0123 
0124     ///Db contains entity (but may already be marked as removed
0125     bool contains(const QByteArray &type, const QByteArray &uid);
0126 
0127     ///Db contains entity and entity is not yet removed
0128     bool exists(const QByteArray &type, const QByteArray &uid);
0129 
0130     void readRevisions(const QByteArray &type, const QByteArray &uid, size_t baseRevision, const std::function<void(const QByteArray &uid, qint64 revision, const EntityBuffer &entity)> &callback);
0131 
0132     qint64 maxRevision();
0133 
0134     Sink::Log::Context logContext() const;
0135 
0136 private:
0137     /*
0138      * Remove any old revisions of the same entity up until @param revision
0139      */
0140     void cleanupEntityRevisionsUntil(qint64 revision);
0141     void copyBlobs(ApplicationDomainType &entity, qint64 newRevision);
0142     class Private;
0143     const QSharedPointer<Private> d;
0144 };
0145 
0146 }
0147 }