summaryrefslogtreecommitdiffstats
path: root/common/storage/entitystore.h
blob: c89c095c4efb73b80bbc923415a2f8bc41912a4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */
#pragma once

#include "sink_export.h"

#include <memory>
#include "domaintypeadaptorfactoryinterface.h"
#include "query.h"
#include "storage.h"
#include "resourcecontext.h"
#include "metadata_generated.h"

namespace Sink {
class EntityBuffer;
namespace Storage {

class SINK_EXPORT EntityStore
{
public:
    typedef QSharedPointer<EntityStore> Ptr;
    EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &);
    ~EntityStore() = default;

    using ApplicationDomainType = ApplicationDomain::ApplicationDomainType;

    void initialize();

    //Only the pipeline may call the following functions outside of tests
    bool add(const QByteArray &type, ApplicationDomain::ApplicationDomainType newEntity, bool replayToSource);
    bool modify(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &diff, const QByteArrayList &deletions, bool replayToSource);
    bool modify(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &current, ApplicationDomain::ApplicationDomainType newEntity, bool replayToSource);
    bool remove(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &current, bool replayToSource);
    bool cleanupRevisions(qint64 revision);
    ApplicationDomain::ApplicationDomainType applyDiff(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &current, const ApplicationDomain::ApplicationDomainType &diff, const QByteArrayList &deletions) const;

    void startTransaction(Sink::Storage::DataStore::AccessMode);
    void commitTransaction();
    void abortTransaction();
    bool hasTransaction() const;

    QVector<QByteArray> fullScan(const QByteArray &type);
    QVector<QByteArray> indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting);
    QVector<QByteArray> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value);
    void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback);
    template<typename EntityType, typename PropertyType>
    void indexLookup(const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) {
        return indexLookup(ApplicationDomain::getTypeName<EntityType>(), PropertyType::name, value, callback);
    }

    ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
    void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
    ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
    void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
    ///Returns an entity and operation. Note that the memory only remains valid until the next operation or transaction end.
    void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> callback);

    ///Returns a copy
    ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid);

    template<typename T>
    T readLatest(const QByteArray &uid) {
        return T(readLatest(ApplicationDomain::getTypeName<T>(), uid));
    }

    ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
    void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
    ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
    void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
    ///Returns a copy
    ApplicationDomain::ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key);

    template<typename T>
    T readEntity(const QByteArray &key) {
        return T(readEntity(ApplicationDomain::getTypeName<T>(), key));
    }


    void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
    void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
    ///Returns a copy
    ApplicationDomain::ApplicationDomainType readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision);

    template<typename T>
    T readPrevious(const QByteArray &uid, qint64 revision) {
        return T(readPrevious(ApplicationDomain::getTypeName<T>(), uid, revision));
    }

    void readAllUids(const QByteArray &type, const std::function<void(const QByteArray &uid)> callback);

    void readAll(const QByteArray &type, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> &callback);

    template<typename T>
    void readAll(const std::function<void(const T &entity)> &callback) {
        return readAll(ApplicationDomain::getTypeName<T>(), [&](const ApplicationDomain::ApplicationDomainType &entity) {
            callback(T(entity));
        });
    }

    void readRevisions(qint64 baseRevision, const QByteArray &type, const std::function<void(const QByteArray &key)> &callback);

    ///Db contains entity (but may already be marked as removed
    bool contains(const QByteArray &type, const QByteArray &uid);

    ///Db contains entity and entity is not yet removed
    bool exists(const QByteArray &type, const QByteArray &uid);

    qint64 maxRevision();

    Sink::Log::Context logContext() const;

private:
    /*
     * Remove any old revisions of the same entity up until @param revision
     */
    void cleanupEntityRevisionsUntil(qint64 revision);
    void copyBlobs(ApplicationDomain::ApplicationDomainType &entity, qint64 newRevision);
    class Private;
    const QSharedPointer<Private> d;
};

}
}