File indexing completed on 2024-05-12 05:26:02

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  * Copyright (C) 2015 Christian Mollekopf <mollekopf@kolabsys.com>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2.1 of the License, or (at your option) version 3, or any
0009  * later version accepted by the membership of KDE e.V. (or its
0010  * successor approved by the membership of KDE e.V.), which shall
0011  * act as a proxy defined in Section 6 of version 3 of the license.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Lesser General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Lesser General Public
0019  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020  */
0021 
0022 #pragma once
0023 
0024 #include <flatbuffers/flatbuffers.h>
0025 
0026 #include <QSharedDataPointer>
0027 #include <QObject>
0028 
0029 #include "sink_export.h"
0030 #include <storage.h>
0031 
0032 #include <KAsync/Async>
0033 
0034 #include <bufferadaptor.h>
0035 #include <resourcecontext.h>
0036 
0037 namespace Sink {
0038 namespace Storage {
0039     class EntityStore;
0040 }
0041 
0042 class Preprocessor;
0043 
0044 class SINK_EXPORT Pipeline : public QObject
0045 {
0046     Q_OBJECT
0047 
0048 public:
0049     Pipeline(const ResourceContext &context, const Sink::Log::Context &ctx);
0050     ~Pipeline();
0051 
0052     void setPreprocessors(const QString &entityType, const QVector<Preprocessor *> &preprocessors);
0053     void startTransaction();
0054     void commit();
0055 
0056     KAsync::Job<qint64> newEntity(void const *command, size_t size);
0057     KAsync::Job<qint64> modifiedEntity(void const *command, size_t size);
0058     KAsync::Job<qint64> deletedEntity(void const *command, size_t size);
0059 
0060     /*
0061      * Cleans up all revisions until @param revision.
0062      */
0063     void cleanupRevisions(qint64 revision);
0064 
0065 
0066 signals:
0067     void revisionUpdated(qint64);
0068 
0069 private:
0070     class Private;
0071     const std::unique_ptr<Private> d;
0072 };
0073 
0074 class SINK_EXPORT Preprocessor
0075 {
0076 public:
0077     Preprocessor();
0078     virtual ~Preprocessor();
0079 
0080     enum Action {
0081         NoAction,
0082         MoveToResource,
0083         CopyToResource,
0084         DropModification,
0085         DeleteEntity
0086     };
0087 
0088     enum Type {
0089         Creation,
0090         Modification,
0091         Deletion
0092     };
0093     struct Result {
0094         Action action;
0095     };
0096 
0097     virtual void startBatch();
0098     virtual void newEntity(ApplicationDomain::ApplicationDomainType &newEntity);
0099     virtual void modifiedEntity(const ApplicationDomain::ApplicationDomainType &oldEntity, ApplicationDomain::ApplicationDomainType &newEntity);
0100     virtual void deletedEntity(const ApplicationDomain::ApplicationDomainType &oldEntity);
0101     virtual Result process(Type type, const ApplicationDomain::ApplicationDomainType &current, ApplicationDomain::ApplicationDomainType &diff);
0102     virtual void finalizeBatch();
0103 
0104     void setup(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Pipeline *, Storage::EntityStore *entityStore);
0105 
0106 protected:
0107     template <typename DomainType>
0108     void createEntity(const DomainType &entity)
0109     {
0110         createEntity(entity, ApplicationDomain::getTypeName<DomainType>());
0111     }
0112     void createEntity(const ApplicationDomain::ApplicationDomainType &entity, const QByteArray &type, bool replayToSource = true);
0113     void deleteEntity(const Sink::ApplicationDomain::ApplicationDomainType &entity, const QByteArray &typeName, bool replayToSource = true);
0114 
0115     QByteArray resourceInstanceIdentifier() const;
0116 
0117     Storage::EntityStore &entityStore() const;
0118 
0119 private:
0120     friend class Pipeline;
0121     class Private;
0122     const std::unique_ptr<Private> d;
0123 };
0124 
0125 template<typename DomainType>
0126 class SINK_EXPORT EntityPreprocessor: public Preprocessor
0127 {
0128 public:
0129     virtual void newEntity(DomainType &) {};
0130     virtual void modifiedEntity(const DomainType &oldEntity, DomainType &newEntity) {};
0131     virtual void deletedEntity(const DomainType &oldEntity) {};
0132 
0133 private:
0134     virtual void newEntity(ApplicationDomain::ApplicationDomainType &newEntity_)  Q_DECL_OVERRIDE
0135     {
0136         //Modifications still work due to the underlying shared adaptor
0137         auto newEntityCopy = DomainType(newEntity_);
0138         newEntity(newEntityCopy);
0139     }
0140 
0141     virtual void modifiedEntity(const ApplicationDomain::ApplicationDomainType &oldEntity, ApplicationDomain::ApplicationDomainType &newEntity_) Q_DECL_OVERRIDE
0142     {
0143         //Modifications still work due to the underlying shared adaptor
0144         auto newEntityCopy = DomainType(newEntity_);
0145         modifiedEntity(DomainType(oldEntity), newEntityCopy);
0146     }
0147 
0148     virtual void deletedEntity(const ApplicationDomain::ApplicationDomainType &oldEntity) Q_DECL_OVERRIDE
0149     {
0150         deletedEntity(DomainType(oldEntity));
0151     }
0152 };
0153 
0154 } // namespace Sink