diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-16 14:55:20 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-21 09:02:21 +0200 |
commit | 237b9ae4113e7a9f489632296941becb71afdb45 (patch) | |
tree | 01cde58f495944f01cad9d282391d4efd2897141 | |
parent | 95d11bf0be98a4e3c08502fe23417b800233ce14 (diff) | |
download | sink-237b9ae4113e7a9f489632296941becb71afdb45.tar.gz sink-237b9ae4113e7a9f489632296941becb71afdb45.zip |
Refactor how the storage is used.
This is the initial refactoring to improve how we deal with the storage.
It does a couple of things:
* Rename Sink::Storage to Sink::Storage::DataStore to free up the
Sink::Storage namespace
* Introduce a Sink::ResourceContext to have a single object that can be
passed around containing everything that is necessary to operate on a
resource. This is a lot better than the multiple separate parameters
that we used to pass around all over the place, while still allowing
for dependency injection for tests.
* Tie storage access together using the new EntityStore that directly
works with ApplicationDomainTypes. This gives us a central place where
main storage, indexes and buffer adaptors are tied together, which
will also give us a place to implement external indexes, such as a
fulltextindex using xapian.
* Use ApplicationDomainTypes as the default way to pass around entities.
Instead of using various ways to pass around entities (buffers,
buffer adaptors, ApplicationDomainTypes), only use a single way.
The old approach was confusing, and was only done as:
* optimization; really shouldn't be necessary and otherwise I'm sure
we can find better ways to optimize ApplicationDomainType itself.
* a way to account for entities that have multiple buffers, a concept
that I no longer deem relevant.
While this commit does the bulk of the work to get there, the following
commits will refactor more stuff to get things back to normal.
89 files changed, 1524 insertions, 1066 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 84fe474..e1e7a51 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt | |||
@@ -76,6 +76,7 @@ set(command_SRCS | |||
76 | mailpreprocessor.cpp | 76 | mailpreprocessor.cpp |
77 | specialpurposepreprocessor.cpp | 77 | specialpurposepreprocessor.cpp |
78 | datastorequery.cpp | 78 | datastorequery.cpp |
79 | storage/entitystore.cpp | ||
79 | ${storage_SRCS}) | 80 | ${storage_SRCS}) |
80 | 81 | ||
81 | add_library(${PROJECT_NAME} SHARED ${command_SRCS}) | 82 | add_library(${PROJECT_NAME} SHARED ${command_SRCS}) |
diff --git a/common/adaptorfactoryregistry.cpp b/common/adaptorfactoryregistry.cpp index 323a02d..91b5a4c 100644 --- a/common/adaptorfactoryregistry.cpp +++ b/common/adaptorfactoryregistry.cpp | |||
@@ -61,8 +61,20 @@ std::shared_ptr<DomainTypeAdaptorFactoryInterface> AdaptorFactoryRegistry::getFa | |||
61 | return std::static_pointer_cast<DomainTypeAdaptorFactoryInterface>(ptr); | 61 | return std::static_pointer_cast<DomainTypeAdaptorFactoryInterface>(ptr); |
62 | } | 62 | } |
63 | 63 | ||
64 | QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> AdaptorFactoryRegistry::getFactories(const QByteArray &resource) | ||
65 | { | ||
66 | QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> map; | ||
67 | for (const auto &type : mTypes.values(resource)) { | ||
68 | auto f = getFactory(resource, type); | ||
69 | //Convert the std::shared_ptr to a QSharedPointer | ||
70 | map.insert(type, DomainTypeAdaptorFactoryInterface::Ptr(f.get(), [](DomainTypeAdaptorFactoryInterface *) {})); | ||
71 | } | ||
72 | return map; | ||
73 | } | ||
74 | |||
64 | void AdaptorFactoryRegistry::registerFactory(const QByteArray &resource, const std::shared_ptr<void> &instance, const QByteArray typeName) | 75 | void AdaptorFactoryRegistry::registerFactory(const QByteArray &resource, const std::shared_ptr<void> &instance, const QByteArray typeName) |
65 | { | 76 | { |
77 | mTypes.insert(resource, typeName); | ||
66 | mRegistry.insert(key(resource, typeName), instance); | 78 | mRegistry.insert(key(resource, typeName), instance); |
67 | } | 79 | } |
68 | 80 | ||
diff --git a/common/adaptorfactoryregistry.h b/common/adaptorfactoryregistry.h index f06120a..47f2612 100644 --- a/common/adaptorfactoryregistry.h +++ b/common/adaptorfactoryregistry.h | |||
@@ -54,11 +54,14 @@ public: | |||
54 | 54 | ||
55 | std::shared_ptr<DomainTypeAdaptorFactoryInterface> getFactory(const QByteArray &resource, const QByteArray &typeName); | 55 | std::shared_ptr<DomainTypeAdaptorFactoryInterface> getFactory(const QByteArray &resource, const QByteArray &typeName); |
56 | 56 | ||
57 | QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> getFactories(const QByteArray &resource); | ||
58 | |||
57 | private: | 59 | private: |
58 | AdaptorFactoryRegistry(); | 60 | AdaptorFactoryRegistry(); |
59 | void registerFactory(const QByteArray &resource, const std::shared_ptr<void> &instance, const QByteArray typeName); | 61 | void registerFactory(const QByteArray &resource, const std::shared_ptr<void> &instance, const QByteArray typeName); |
60 | 62 | ||
61 | QHash<QByteArray, std::shared_ptr<void>> mRegistry; | 63 | QHash<QByteArray, std::shared_ptr<void>> mRegistry; |
64 | QMultiHash<QByteArray, QByteArray> mTypes; | ||
62 | static QMutex sMutex; | 65 | static QMutex sMutex; |
63 | }; | 66 | }; |
64 | } | 67 | } |
diff --git a/common/changereplay.cpp b/common/changereplay.cpp index e3b7158..6e58564 100644 --- a/common/changereplay.cpp +++ b/common/changereplay.cpp | |||
@@ -27,31 +27,32 @@ | |||
27 | #include <QTimer> | 27 | #include <QTimer> |
28 | 28 | ||
29 | using namespace Sink; | 29 | using namespace Sink; |
30 | using namespace Sink::Storage; | ||
30 | 31 | ||
31 | SINK_DEBUG_AREA("changereplay"); | 32 | SINK_DEBUG_AREA("changereplay"); |
32 | 33 | ||
33 | ChangeReplay::ChangeReplay(const QByteArray &resourceName) | 34 | ChangeReplay::ChangeReplay(const ResourceContext &resourceContext) |
34 | : mStorage(storageLocation(), resourceName, Storage::ReadOnly), mChangeReplayStore(storageLocation(), resourceName + ".changereplay", Storage::ReadWrite), mReplayInProgress(false) | 35 | : mStorage(storageLocation(), resourceContext.instanceId(), DataStore::ReadOnly), mChangeReplayStore(storageLocation(), resourceContext.instanceId() + ".changereplay", DataStore::ReadWrite), mReplayInProgress(false) |
35 | { | 36 | { |
36 | SinkTrace() << "Created change replay: " << resourceName; | 37 | SinkTrace() << "Created change replay: " << resourceContext.instanceId(); |
37 | } | 38 | } |
38 | 39 | ||
39 | qint64 ChangeReplay::getLastReplayedRevision() | 40 | qint64 ChangeReplay::getLastReplayedRevision() |
40 | { | 41 | { |
41 | qint64 lastReplayedRevision = 0; | 42 | qint64 lastReplayedRevision = 0; |
42 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(Storage::ReadOnly); | 43 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(DataStore::ReadOnly); |
43 | replayStoreTransaction.openDatabase().scan("lastReplayedRevision", | 44 | replayStoreTransaction.openDatabase().scan("lastReplayedRevision", |
44 | [&lastReplayedRevision](const QByteArray &key, const QByteArray &value) -> bool { | 45 | [&lastReplayedRevision](const QByteArray &key, const QByteArray &value) -> bool { |
45 | lastReplayedRevision = value.toLongLong(); | 46 | lastReplayedRevision = value.toLongLong(); |
46 | return false; | 47 | return false; |
47 | }, | 48 | }, |
48 | [](const Storage::Error &) {}); | 49 | [](const DataStore::Error &) {}); |
49 | return lastReplayedRevision; | 50 | return lastReplayedRevision; |
50 | } | 51 | } |
51 | 52 | ||
52 | bool ChangeReplay::allChangesReplayed() | 53 | bool ChangeReplay::allChangesReplayed() |
53 | { | 54 | { |
54 | const qint64 topRevision = Storage::maxRevision(mStorage.createTransaction(Storage::ReadOnly, [](const Sink::Storage::Error &error) { | 55 | const qint64 topRevision = DataStore::maxRevision(mStorage.createTransaction(DataStore::ReadOnly, [](const Sink::Storage::DataStore::Error &error) { |
55 | SinkWarning() << error.message; | 56 | SinkWarning() << error.message; |
56 | })); | 57 | })); |
57 | const qint64 lastReplayedRevision = getLastReplayedRevision(); | 58 | const qint64 lastReplayedRevision = getLastReplayedRevision(); |
@@ -61,7 +62,7 @@ bool ChangeReplay::allChangesReplayed() | |||
61 | 62 | ||
62 | void ChangeReplay::recordReplayedRevision(qint64 revision) | 63 | void ChangeReplay::recordReplayedRevision(qint64 revision) |
63 | { | 64 | { |
64 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(Storage::ReadWrite, [](const Sink::Storage::Error &error) { | 65 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(DataStore::ReadWrite, [](const Sink::Storage::DataStore::Error &error) { |
65 | SinkWarning() << error.message; | 66 | SinkWarning() << error.message; |
66 | }); | 67 | }); |
67 | replayStoreTransaction.openDatabase().write("lastReplayedRevision", QByteArray::number(revision)); | 68 | replayStoreTransaction.openDatabase().write("lastReplayedRevision", QByteArray::number(revision)); |
@@ -74,10 +75,10 @@ KAsync::Job<void> ChangeReplay::replayNextRevision() | |||
74 | auto topRevision = QSharedPointer<qint64>::create(0); | 75 | auto topRevision = QSharedPointer<qint64>::create(0); |
75 | return KAsync::syncStart<void>([this, lastReplayedRevision, topRevision]() { | 76 | return KAsync::syncStart<void>([this, lastReplayedRevision, topRevision]() { |
76 | mReplayInProgress = true; | 77 | mReplayInProgress = true; |
77 | mMainStoreTransaction = mStorage.createTransaction(Storage::ReadOnly, [](const Sink::Storage::Error &error) { | 78 | mMainStoreTransaction = mStorage.createTransaction(DataStore::ReadOnly, [](const Sink::Storage::DataStore::Error &error) { |
78 | SinkWarning() << error.message; | 79 | SinkWarning() << error.message; |
79 | }); | 80 | }); |
80 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(Storage::ReadOnly, [](const Sink::Storage::Error &error) { | 81 | auto replayStoreTransaction = mChangeReplayStore.createTransaction(DataStore::ReadOnly, [](const Sink::Storage::DataStore::Error &error) { |
81 | SinkWarning() << error.message; | 82 | SinkWarning() << error.message; |
82 | }); | 83 | }); |
83 | replayStoreTransaction.openDatabase().scan("lastReplayedRevision", | 84 | replayStoreTransaction.openDatabase().scan("lastReplayedRevision", |
@@ -85,8 +86,8 @@ KAsync::Job<void> ChangeReplay::replayNextRevision() | |||
85 | *lastReplayedRevision = value.toLongLong(); | 86 | *lastReplayedRevision = value.toLongLong(); |
86 | return false; | 87 | return false; |
87 | }, | 88 | }, |
88 | [](const Storage::Error &) {}); | 89 | [](const DataStore::Error &) {}); |
89 | *topRevision = Storage::maxRevision(mMainStoreTransaction); | 90 | *topRevision = DataStore::maxRevision(mMainStoreTransaction); |
90 | SinkTrace() << "Changereplay from " << *lastReplayedRevision << " to " << *topRevision; | 91 | SinkTrace() << "Changereplay from " << *lastReplayedRevision << " to " << *topRevision; |
91 | }) | 92 | }) |
92 | .then(KAsync::dowhile( | 93 | .then(KAsync::dowhile( |
@@ -98,11 +99,11 @@ KAsync::Job<void> ChangeReplay::replayNextRevision() | |||
98 | qint64 revision = *lastReplayedRevision + 1; | 99 | qint64 revision = *lastReplayedRevision + 1; |
99 | KAsync::Job<void> replayJob = KAsync::null<void>(); | 100 | KAsync::Job<void> replayJob = KAsync::null<void>(); |
100 | while (revision <= *topRevision) { | 101 | while (revision <= *topRevision) { |
101 | const auto uid = Storage::getUidFromRevision(mMainStoreTransaction, revision); | 102 | const auto uid = DataStore::getUidFromRevision(mMainStoreTransaction, revision); |
102 | const auto type = Storage::getTypeFromRevision(mMainStoreTransaction, revision); | 103 | const auto type = DataStore::getTypeFromRevision(mMainStoreTransaction, revision); |
103 | const auto key = Storage::assembleKey(uid, revision); | 104 | const auto key = DataStore::assembleKey(uid, revision); |
104 | bool exitLoop = false; | 105 | bool exitLoop = false; |
105 | Storage::mainDatabase(mMainStoreTransaction, type) | 106 | DataStore::mainDatabase(mMainStoreTransaction, type) |
106 | .scan(key, | 107 | .scan(key, |
107 | [&lastReplayedRevision, type, this, &replayJob, &exitLoop, revision](const QByteArray &key, const QByteArray &value) -> bool { | 108 | [&lastReplayedRevision, type, this, &replayJob, &exitLoop, revision](const QByteArray &key, const QByteArray &value) -> bool { |
108 | SinkTrace() << "Replaying " << key; | 109 | SinkTrace() << "Replaying " << key; |
@@ -123,7 +124,7 @@ KAsync::Job<void> ChangeReplay::replayNextRevision() | |||
123 | } | 124 | } |
124 | return false; | 125 | return false; |
125 | }, | 126 | }, |
126 | [key](const Storage::Error &) { SinkError() << "Failed to replay change " << key; }); | 127 | [key](const DataStore::Error &) { SinkError() << "Failed to replay change " << key; }); |
127 | if (exitLoop) { | 128 | if (exitLoop) { |
128 | break; | 129 | break; |
129 | } | 130 | } |
diff --git a/common/changereplay.h b/common/changereplay.h index 88d6ce3..e86c4f2 100644 --- a/common/changereplay.h +++ b/common/changereplay.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <Async/Async> | 24 | #include <Async/Async> |
25 | 25 | ||
26 | #include "storage.h" | 26 | #include "storage.h" |
27 | #include "resourcecontext.h" | ||
27 | 28 | ||
28 | namespace Sink { | 29 | namespace Sink { |
29 | 30 | ||
@@ -38,7 +39,7 @@ class SINK_EXPORT ChangeReplay : public QObject | |||
38 | { | 39 | { |
39 | Q_OBJECT | 40 | Q_OBJECT |
40 | public: | 41 | public: |
41 | ChangeReplay(const QByteArray &resourceName); | 42 | ChangeReplay(const ResourceContext &resourceContext); |
42 | 43 | ||
43 | qint64 getLastReplayedRevision(); | 44 | qint64 getLastReplayedRevision(); |
44 | bool allChangesReplayed(); | 45 | bool allChangesReplayed(); |
@@ -53,20 +54,20 @@ public slots: | |||
53 | protected: | 54 | protected: |
54 | virtual KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) = 0; | 55 | virtual KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) = 0; |
55 | virtual bool canReplay(const QByteArray &type, const QByteArray &key, const QByteArray &value) = 0; | 56 | virtual bool canReplay(const QByteArray &type, const QByteArray &key, const QByteArray &value) = 0; |
56 | Sink::Storage mStorage; | 57 | Sink::Storage::DataStore mStorage; |
57 | 58 | ||
58 | private: | 59 | private: |
59 | void recordReplayedRevision(qint64 revision); | 60 | void recordReplayedRevision(qint64 revision); |
60 | KAsync::Job<void> replayNextRevision(); | 61 | KAsync::Job<void> replayNextRevision(); |
61 | Sink::Storage mChangeReplayStore; | 62 | Sink::Storage::DataStore mChangeReplayStore; |
62 | bool mReplayInProgress; | 63 | bool mReplayInProgress; |
63 | Sink::Storage::Transaction mMainStoreTransaction; | 64 | Sink::Storage::DataStore::Transaction mMainStoreTransaction; |
64 | }; | 65 | }; |
65 | 66 | ||
66 | class NullChangeReplay : public ChangeReplay | 67 | class NullChangeReplay : public ChangeReplay |
67 | { | 68 | { |
68 | public: | 69 | public: |
69 | NullChangeReplay(const QByteArray &resourceName) : ChangeReplay(resourceName) {} | 70 | NullChangeReplay(const ResourceContext &resourceContext) : ChangeReplay(resourceContext) {} |
70 | KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE { return KAsync::null<void>(); } | 71 | KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE { return KAsync::null<void>(); } |
71 | bool canReplay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE { return false; } | 72 | bool canReplay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE { return false; } |
72 | }; | 73 | }; |
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index 7b7d3a3..d4a83b1 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "event.h" | 28 | #include "event.h" |
29 | 29 | ||
30 | using namespace Sink; | 30 | using namespace Sink; |
31 | using namespace Sink::Storage; | ||
31 | 32 | ||
32 | 33 | ||
33 | SINK_DEBUG_AREA("datastorequery") | 34 | SINK_DEBUG_AREA("datastorequery") |
@@ -299,42 +300,18 @@ public: | |||
299 | } | 300 | } |
300 | }; | 301 | }; |
301 | 302 | ||
302 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) | 303 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore::Ptr store, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) |
303 | : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) | 304 | : mQuery(query), mType(type), mTypeIndex(typeIndex), mGetProperty(getProperty), mStore(store) |
304 | { | 305 | { |
305 | setupQuery(); | 306 | setupQuery(); |
306 | } | 307 | } |
307 | 308 | ||
308 | static inline QVector<QByteArray> fullScan(const Sink::Storage::Transaction &transaction, const QByteArray &bufferType) | ||
309 | { | ||
310 | // TODO use a result set with an iterator, to read values on demand | ||
311 | SinkTrace() << "Looking for : " << bufferType; | ||
312 | //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. | ||
313 | QSet<QByteArray> keys; | ||
314 | Storage::mainDatabase(transaction, bufferType) | ||
315 | .scan(QByteArray(), | ||
316 | [&](const QByteArray &key, const QByteArray &value) -> bool { | ||
317 | if (keys.contains(Sink::Storage::uidFromKey(key))) { | ||
318 | //Not something that should persist if the replay works, so we keep a message for now. | ||
319 | SinkTrace() << "Multiple revisions for key: " << key; | ||
320 | } | ||
321 | keys << Sink::Storage::uidFromKey(key); | ||
322 | return true; | ||
323 | }, | ||
324 | [](const Sink::Storage::Error &error) { SinkWarning() << "Error during query: " << error.message; }); | ||
325 | |||
326 | SinkTrace() << "Full scan retrieved " << keys.size() << " results."; | ||
327 | return keys.toList().toVector(); | ||
328 | } | ||
329 | |||
330 | void DataStoreQuery::readEntity(const QByteArray &key, const BufferCallback &resultCallback) | 309 | void DataStoreQuery::readEntity(const QByteArray &key, const BufferCallback &resultCallback) |
331 | { | 310 | { |
332 | mDb.findLatest(key, | 311 | mStore->readLatest(mType, key, [=](const QByteArray &key, const Sink::EntityBuffer &buffer) { |
333 | [=](const QByteArray &key, const QByteArray &value) -> bool { | 312 | resultCallback(DataStore::uidFromKey(key), buffer); |
334 | resultCallback(Sink::Storage::uidFromKey(key), Sink::EntityBuffer(value.data(), value.size())); | ||
335 | return false; | 313 | return false; |
336 | }, | 314 | }); |
337 | [&](const Sink::Storage::Error &error) { SinkWarning() << "Error during query: " << error.message << key; }); | ||
338 | } | 315 | } |
339 | 316 | ||
340 | QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArray &property) | 317 | QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArray &property) |
@@ -344,7 +321,7 @@ QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArra | |||
344 | 321 | ||
345 | QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) | 322 | QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) |
346 | { | 323 | { |
347 | return mTypeIndex.lookup(property, value, mTransaction); | 324 | return mStore->indexLookup(mType, property, value); |
348 | } | 325 | } |
349 | 326 | ||
350 | /* ResultSet DataStoreQuery::filterAndSortSet(ResultSet &resultSet, const FilterFunction &filter, const QByteArray &sortProperty) */ | 327 | /* ResultSet DataStoreQuery::filterAndSortSet(ResultSet &resultSet, const FilterFunction &filter, const QByteArray &sortProperty) */ |
@@ -444,7 +421,7 @@ QSharedPointer<DataStoreQuery> prepareQuery(const QByteArray &type, Args && ... | |||
444 | QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) | 421 | QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) |
445 | { | 422 | { |
446 | Q_ASSERT(!subquery.type.isEmpty()); | 423 | Q_ASSERT(!subquery.type.isEmpty()); |
447 | auto sub = prepareQuery(subquery.type, subquery, mTransaction); | 424 | auto sub = prepareQuery(subquery.type, subquery, mStore); |
448 | auto result = sub->execute(); | 425 | auto result = sub->execute(); |
449 | QByteArrayList ids; | 426 | QByteArrayList ids; |
450 | while (result.next([&ids](const ResultSet::Result &result) { | 427 | while (result.next([&ids](const ResultSet::Result &result) { |
@@ -476,13 +453,13 @@ void DataStoreQuery::setupQuery() | |||
476 | } else { | 453 | } else { |
477 | QSet<QByteArray> appliedFilters; | 454 | QSet<QByteArray> appliedFilters; |
478 | 455 | ||
479 | auto resultSet = mTypeIndex.query(mQuery, appliedFilters, appliedSorting, mTransaction); | 456 | auto resultSet = mStore->indexLookup(mType, mQuery, appliedFilters, appliedSorting); |
480 | remainingFilters = remainingFilters - appliedFilters; | 457 | remainingFilters = remainingFilters - appliedFilters; |
481 | 458 | ||
482 | // We do a full scan if there were no indexes available to create the initial set. | 459 | // We do a full scan if there were no indexes available to create the initial set. |
483 | if (appliedFilters.isEmpty()) { | 460 | if (appliedFilters.isEmpty()) { |
484 | // TODO this should be replaced by an index lookup on the uid index | 461 | // TODO this should be replaced by an index lookup on the uid index |
485 | mSource = Source::Ptr::create(fullScan(mTransaction, mType), this); | 462 | mSource = Source::Ptr::create(mStore->fullScan(mType), this); |
486 | } else { | 463 | } else { |
487 | mSource = Source::Ptr::create(resultSet, this); | 464 | mSource = Source::Ptr::create(resultSet, this); |
488 | } | 465 | } |
@@ -523,26 +500,11 @@ void DataStoreQuery::setupQuery() | |||
523 | 500 | ||
524 | QVector<QByteArray> DataStoreQuery::loadIncrementalResultSet(qint64 baseRevision) | 501 | QVector<QByteArray> DataStoreQuery::loadIncrementalResultSet(qint64 baseRevision) |
525 | { | 502 | { |
526 | const auto bufferType = mType; | ||
527 | auto revisionCounter = QSharedPointer<qint64>::create(baseRevision); | 503 | auto revisionCounter = QSharedPointer<qint64>::create(baseRevision); |
528 | QVector<QByteArray> changedKeys; | 504 | QVector<QByteArray> changedKeys; |
529 | const qint64 topRevision = Sink::Storage::maxRevision(mTransaction); | 505 | mStore->readRevisions(baseRevision, mType, [&](const QByteArray &key) { |
530 | // Spit out the revision keys one by one. | ||
531 | while (*revisionCounter <= topRevision) { | ||
532 | const auto uid = Sink::Storage::getUidFromRevision(mTransaction, *revisionCounter); | ||
533 | const auto type = Sink::Storage::getTypeFromRevision(mTransaction, *revisionCounter); | ||
534 | // SinkTrace() << "Revision" << *revisionCounter << type << uid; | ||
535 | Q_ASSERT(!uid.isEmpty()); | ||
536 | Q_ASSERT(!type.isEmpty()); | ||
537 | if (type != bufferType) { | ||
538 | // Skip revision | ||
539 | *revisionCounter += 1; | ||
540 | continue; | ||
541 | } | ||
542 | const auto key = Sink::Storage::assembleKey(uid, *revisionCounter); | ||
543 | *revisionCounter += 1; | ||
544 | changedKeys << key; | 506 | changedKeys << key; |
545 | } | 507 | }); |
546 | SinkTrace() << "Finished reading incremental result set:" << *revisionCounter; | 508 | SinkTrace() << "Finished reading incremental result set:" << *revisionCounter; |
547 | return changedKeys; | 509 | return changedKeys; |
548 | } | 510 | } |
diff --git a/common/datastorequery.h b/common/datastorequery.h index 164d721..4cf25b2 100644 --- a/common/datastorequery.h +++ b/common/datastorequery.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "query.h" | 25 | #include "query.h" |
26 | #include "entitybuffer.h" | 26 | #include "entitybuffer.h" |
27 | #include "log.h" | 27 | #include "log.h" |
28 | #include "storage/entitystore.h" | ||
28 | 29 | ||
29 | 30 | ||
30 | class Source; | 31 | class Source; |
@@ -35,11 +36,11 @@ class DataStoreQuery { | |||
35 | public: | 36 | public: |
36 | typedef QSharedPointer<DataStoreQuery> Ptr; | 37 | typedef QSharedPointer<DataStoreQuery> Ptr; |
37 | 38 | ||
38 | DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty); | 39 | DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::EntityStore::Ptr store, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty); |
39 | ResultSet execute(); | 40 | ResultSet execute(); |
40 | ResultSet update(qint64 baseRevision); | 41 | ResultSet update(qint64 baseRevision); |
41 | 42 | ||
42 | protected: | 43 | private: |
43 | 44 | ||
44 | typedef std::function<bool(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> FilterFunction; | 45 | typedef std::function<bool(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> FilterFunction; |
45 | typedef std::function<void(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> BufferCallback; | 46 | typedef std::function<void(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> BufferCallback; |
@@ -56,15 +57,15 @@ protected: | |||
56 | QByteArrayList executeSubquery(const Sink::Query &subquery); | 57 | QByteArrayList executeSubquery(const Sink::Query &subquery); |
57 | 58 | ||
58 | Sink::Query mQuery; | 59 | Sink::Query mQuery; |
59 | Sink::Storage::Transaction &mTransaction; | ||
60 | const QByteArray mType; | 60 | const QByteArray mType; |
61 | TypeIndex &mTypeIndex; | 61 | TypeIndex &mTypeIndex; |
62 | Sink::Storage::NamedDatabase mDb; | ||
63 | std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> mGetProperty; | 62 | std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> mGetProperty; |
64 | bool mInitialQuery; | 63 | bool mInitialQuery; |
65 | QSharedPointer<FilterBase> mCollector; | 64 | QSharedPointer<FilterBase> mCollector; |
66 | QSharedPointer<Source> mSource; | 65 | QSharedPointer<Source> mSource; |
67 | 66 | ||
67 | QSharedPointer<Sink::Storage::EntityStore> mStore; | ||
68 | |||
68 | SINK_DEBUG_COMPONENT(mType) | 69 | SINK_DEBUG_COMPONENT(mType) |
69 | }; | 70 | }; |
70 | 71 | ||
diff --git a/common/domain/applicationdomaintype.cpp b/common/domain/applicationdomaintype.cpp index 2a0d977..3109966 100644 --- a/common/domain/applicationdomaintype.cpp +++ b/common/domain/applicationdomaintype.cpp | |||
@@ -73,7 +73,7 @@ ApplicationDomainType::~ApplicationDomainType() | |||
73 | 73 | ||
74 | QByteArray ApplicationDomainType::generateUid() | 74 | QByteArray ApplicationDomainType::generateUid() |
75 | { | 75 | { |
76 | return Sink::Storage::generateUid(); | 76 | return Sink::Storage::DataStore::generateUid(); |
77 | } | 77 | } |
78 | 78 | ||
79 | bool ApplicationDomainType::hasProperty(const QByteArray &key) const | 79 | bool ApplicationDomainType::hasProperty(const QByteArray &key) const |
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index e581e07..39ce2b9 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h | |||
@@ -241,6 +241,8 @@ struct SINK_EXPORT SinkResource : public ApplicationDomainType { | |||
241 | struct SINK_EXPORT Entity : public ApplicationDomainType { | 241 | struct SINK_EXPORT Entity : public ApplicationDomainType { |
242 | typedef QSharedPointer<Entity> Ptr; | 242 | typedef QSharedPointer<Entity> Ptr; |
243 | using ApplicationDomainType::ApplicationDomainType; | 243 | using ApplicationDomainType::ApplicationDomainType; |
244 | Entity() = default; | ||
245 | Entity(const ApplicationDomainType &other) : ApplicationDomainType(other) {} | ||
244 | virtual ~Entity(); | 246 | virtual ~Entity(); |
245 | }; | 247 | }; |
246 | 248 | ||
diff --git a/common/domain/event.cpp b/common/domain/event.cpp index f3abd62..d801592 100644 --- a/common/domain/event.cpp +++ b/common/domain/event.cpp | |||
@@ -42,23 +42,28 @@ static QMutex sMutex; | |||
42 | 42 | ||
43 | using namespace Sink::ApplicationDomain; | 43 | using namespace Sink::ApplicationDomain; |
44 | 44 | ||
45 | void TypeImplementation<Event>::configureIndex(TypeIndex &index) | ||
46 | { | ||
47 | index.addProperty<QByteArray>(Event::Uid::name); | ||
48 | } | ||
49 | |||
45 | static TypeIndex &getIndex() | 50 | static TypeIndex &getIndex() |
46 | { | 51 | { |
47 | QMutexLocker locker(&sMutex); | 52 | QMutexLocker locker(&sMutex); |
48 | static TypeIndex *index = 0; | 53 | static TypeIndex *index = 0; |
49 | if (!index) { | 54 | if (!index) { |
50 | index = new TypeIndex("event"); | 55 | index = new TypeIndex("event"); |
51 | index->addProperty<QByteArray>("uid"); | 56 | TypeImplementation<Event>::configureIndex(*index); |
52 | } | 57 | } |
53 | return *index; | 58 | return *index; |
54 | } | 59 | } |
55 | 60 | ||
56 | void TypeImplementation<Event>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 61 | void TypeImplementation<Event>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
57 | { | 62 | { |
58 | return getIndex().add(identifier, bufferAdaptor, transaction); | 63 | return getIndex().add(identifier, bufferAdaptor, transaction); |
59 | } | 64 | } |
60 | 65 | ||
61 | void TypeImplementation<Event>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 66 | void TypeImplementation<Event>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
62 | { | 67 | { |
63 | return getIndex().remove(identifier, bufferAdaptor, transaction); | 68 | return getIndex().remove(identifier, bufferAdaptor, transaction); |
64 | } | 69 | } |
@@ -83,10 +88,10 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Event>::BufferBuilder> > T | |||
83 | return propertyMapper; | 88 | return propertyMapper; |
84 | } | 89 | } |
85 | 90 | ||
86 | DataStoreQuery::Ptr TypeImplementation<Event>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) | 91 | DataStoreQuery::Ptr TypeImplementation<Event>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store) |
87 | { | 92 | { |
88 | auto mapper = initializeReadPropertyMapper(); | 93 | auto mapper = initializeReadPropertyMapper(); |
89 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Event>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) { | 94 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Event>(), store, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) { |
90 | 95 | ||
91 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); | 96 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); |
92 | return mapper->getProperty(property, localBuffer); | 97 | return mapper->getProperty(property, localBuffer); |
diff --git a/common/domain/event.h b/common/domain/event.h index 684b58e..ce9691d 100644 --- a/common/domain/event.h +++ b/common/domain/event.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "applicationdomaintype.h" | 21 | #include "applicationdomaintype.h" |
22 | 22 | ||
23 | #include "storage.h" | 23 | #include "storage.h" |
24 | #include "storage/entitystore.h" | ||
24 | 25 | ||
25 | class ResultSet; | 26 | class ResultSet; |
26 | class QByteArray; | 27 | class QByteArray; |
@@ -32,6 +33,8 @@ class WritePropertyMapper; | |||
32 | 33 | ||
33 | class DataStoreQuery; | 34 | class DataStoreQuery; |
34 | 35 | ||
36 | class TypeIndex; | ||
37 | |||
35 | namespace Sink { | 38 | namespace Sink { |
36 | class Query; | 39 | class Query; |
37 | 40 | ||
@@ -51,10 +54,12 @@ class TypeImplementation<Sink::ApplicationDomain::Event> { | |||
51 | public: | 54 | public: |
52 | typedef Sink::ApplicationDomain::Buffer::Event Buffer; | 55 | typedef Sink::ApplicationDomain::Buffer::Event Buffer; |
53 | typedef Sink::ApplicationDomain::Buffer::EventBuilder BufferBuilder; | 56 | typedef Sink::ApplicationDomain::Buffer::EventBuilder BufferBuilder; |
57 | static void configureIndex(TypeIndex &index); | ||
54 | static QSet<QByteArray> indexedProperties(); | 58 | static QSet<QByteArray> indexedProperties(); |
55 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction); | 59 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store); |
56 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 60 | |
57 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 61 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
62 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); | ||
58 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); | 63 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); |
59 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); | 64 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); |
60 | }; | 65 | }; |
diff --git a/common/domain/folder.cpp b/common/domain/folder.cpp index 824fa0b..f04a3e7 100644 --- a/common/domain/folder.cpp +++ b/common/domain/folder.cpp | |||
@@ -44,25 +44,30 @@ static QMutex sMutex; | |||
44 | 44 | ||
45 | using namespace Sink::ApplicationDomain; | 45 | using namespace Sink::ApplicationDomain; |
46 | 46 | ||
47 | void TypeImplementation<Folder>::configureIndex(TypeIndex &index) | ||
48 | { | ||
49 | index.addProperty<QByteArray>(Folder::Parent::name); | ||
50 | index.addProperty<QString>(Folder::Name::name); | ||
51 | } | ||
52 | |||
47 | static TypeIndex &getIndex() | 53 | static TypeIndex &getIndex() |
48 | { | 54 | { |
49 | QMutexLocker locker(&sMutex); | 55 | QMutexLocker locker(&sMutex); |
50 | static TypeIndex *index = 0; | 56 | static TypeIndex *index = 0; |
51 | if (!index) { | 57 | if (!index) { |
52 | index = new TypeIndex("folder"); | 58 | index = new TypeIndex("folder"); |
53 | index->addProperty<QByteArray>("parent"); | 59 | TypeImplementation<Folder>::configureIndex(*index); |
54 | index->addProperty<QString>("name"); | ||
55 | } | 60 | } |
56 | return *index; | 61 | return *index; |
57 | } | 62 | } |
58 | 63 | ||
59 | void TypeImplementation<Folder>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 64 | void TypeImplementation<Folder>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
60 | { | 65 | { |
61 | SinkTrace() << "Indexing " << identifier; | 66 | SinkTrace() << "Indexing " << identifier; |
62 | getIndex().add(identifier, bufferAdaptor, transaction); | 67 | getIndex().add(identifier, bufferAdaptor, transaction); |
63 | } | 68 | } |
64 | 69 | ||
65 | void TypeImplementation<Folder>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 70 | void TypeImplementation<Folder>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
66 | { | 71 | { |
67 | getIndex().remove(identifier, bufferAdaptor, transaction); | 72 | getIndex().remove(identifier, bufferAdaptor, transaction); |
68 | } | 73 | } |
@@ -87,10 +92,10 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Folder>::BufferBuilder> > | |||
87 | return propertyMapper; | 92 | return propertyMapper; |
88 | } | 93 | } |
89 | 94 | ||
90 | DataStoreQuery::Ptr TypeImplementation<Folder>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) | 95 | DataStoreQuery::Ptr TypeImplementation<Folder>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store) |
91 | { | 96 | { |
92 | auto mapper = initializeReadPropertyMapper(); | 97 | auto mapper = initializeReadPropertyMapper(); |
93 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Folder>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) { | 98 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Folder>(), store, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) { |
94 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); | 99 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); |
95 | return mapper->getProperty(property, localBuffer); | 100 | return mapper->getProperty(property, localBuffer); |
96 | }); | 101 | }); |
diff --git a/common/domain/folder.h b/common/domain/folder.h index e4631de..0a52b01 100644 --- a/common/domain/folder.h +++ b/common/domain/folder.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "applicationdomaintype.h" | 21 | #include "applicationdomaintype.h" |
22 | 22 | ||
23 | #include "storage.h" | 23 | #include "storage.h" |
24 | #include "storage/entitystore.h" | ||
24 | 25 | ||
25 | class ResultSet; | 26 | class ResultSet; |
26 | class QByteArray; | 27 | class QByteArray; |
@@ -31,6 +32,8 @@ class ReadPropertyMapper; | |||
31 | template<typename T> | 32 | template<typename T> |
32 | class WritePropertyMapper; | 33 | class WritePropertyMapper; |
33 | 34 | ||
35 | class TypeIndex; | ||
36 | |||
34 | namespace Sink { | 37 | namespace Sink { |
35 | class Query; | 38 | class Query; |
36 | 39 | ||
@@ -45,10 +48,11 @@ class TypeImplementation<Sink::ApplicationDomain::Folder> { | |||
45 | public: | 48 | public: |
46 | typedef Sink::ApplicationDomain::Buffer::Folder Buffer; | 49 | typedef Sink::ApplicationDomain::Buffer::Folder Buffer; |
47 | typedef Sink::ApplicationDomain::Buffer::FolderBuilder BufferBuilder; | 50 | typedef Sink::ApplicationDomain::Buffer::FolderBuilder BufferBuilder; |
48 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction); | 51 | static void configureIndex(TypeIndex &index); |
52 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store); | ||
49 | static QSet<QByteArray> indexedProperties(); | 53 | static QSet<QByteArray> indexedProperties(); |
50 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 54 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
51 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 55 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
52 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); | 56 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); |
53 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); | 57 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); |
54 | }; | 58 | }; |
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp index 2b6eb84..1b46e28 100644 --- a/common/domain/mail.cpp +++ b/common/domain/mail.cpp | |||
@@ -45,25 +45,31 @@ static QMutex sMutex; | |||
45 | using namespace Sink; | 45 | using namespace Sink; |
46 | using namespace Sink::ApplicationDomain; | 46 | using namespace Sink::ApplicationDomain; |
47 | 47 | ||
48 | void TypeImplementation<Mail>::configureIndex(TypeIndex &index) | ||
49 | { | ||
50 | index.addProperty<QByteArray>(Mail::Uid::name); | ||
51 | index.addProperty<QByteArray>(Mail::Sender::name); | ||
52 | index.addProperty<QByteArray>(Mail::SenderName::name); | ||
53 | /* index->addProperty<QString>(Mail::Subject::name); */ | ||
54 | /* index->addFulltextProperty<QString>(Mail::Subject::name); */ | ||
55 | index.addProperty<QDateTime>(Mail::Date::name); | ||
56 | index.addProperty<QByteArray>(Mail::Folder::name); | ||
57 | index.addPropertyWithSorting<QByteArray, QDateTime>(Mail::Folder::name, Mail::Date::name); | ||
58 | index.addProperty<QByteArray>(Mail::MessageId::name); | ||
59 | index.addProperty<QByteArray>(Mail::ParentMessageId::name); | ||
60 | |||
61 | index.addProperty<Mail::MessageId>(); | ||
62 | index.addSecondaryProperty<Mail::MessageId, Mail::ThreadId>(); | ||
63 | index.addSecondaryProperty<Mail::ThreadId, Mail::MessageId>(); | ||
64 | } | ||
65 | |||
48 | static TypeIndex &getIndex() | 66 | static TypeIndex &getIndex() |
49 | { | 67 | { |
50 | QMutexLocker locker(&sMutex); | 68 | QMutexLocker locker(&sMutex); |
51 | static TypeIndex *index = 0; | 69 | static TypeIndex *index = 0; |
52 | if (!index) { | 70 | if (!index) { |
53 | index = new TypeIndex("mail"); | 71 | index = new TypeIndex("mail"); |
54 | index->addProperty<QByteArray>(Mail::Uid::name); | 72 | TypeImplementation<Mail>::configureIndex(*index); |
55 | index->addProperty<QByteArray>(Mail::Sender::name); | ||
56 | index->addProperty<QByteArray>(Mail::SenderName::name); | ||
57 | index->addProperty<QString>(Mail::Subject::name); | ||
58 | index->addProperty<QDateTime>(Mail::Date::name); | ||
59 | index->addProperty<QByteArray>(Mail::Folder::name); | ||
60 | index->addPropertyWithSorting<QByteArray, QDateTime>(Mail::Folder::name, Mail::Date::name); | ||
61 | index->addProperty<QByteArray>(Mail::MessageId::name); | ||
62 | index->addProperty<QByteArray>(Mail::ParentMessageId::name); | ||
63 | |||
64 | index->addProperty<Mail::MessageId>(); | ||
65 | index->addSecondaryProperty<Mail::MessageId, Mail::ThreadId>(); | ||
66 | index->addSecondaryProperty<Mail::ThreadId, Mail::MessageId>(); | ||
67 | } | 73 | } |
68 | return *index; | 74 | return *index; |
69 | } | 75 | } |
@@ -122,7 +128,7 @@ static QString stripOffPrefixes(const QString &subject) | |||
122 | } | 128 | } |
123 | 129 | ||
124 | 130 | ||
125 | static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 131 | static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
126 | { | 132 | { |
127 | auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name); | 133 | auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name); |
128 | auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name); | 134 | auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name); |
@@ -164,16 +170,17 @@ static void updateThreadingIndex(const QByteArray &identifier, const BufferAdapt | |||
164 | } | 170 | } |
165 | } | 171 | } |
166 | 172 | ||
167 | void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 173 | void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
168 | { | 174 | { |
169 | SinkTrace() << "Indexing " << identifier; | 175 | SinkTrace() << "Indexing " << identifier; |
170 | getIndex().add(identifier, bufferAdaptor, transaction); | 176 | getIndex().add(identifier, bufferAdaptor, transaction); |
171 | updateThreadingIndex(identifier, bufferAdaptor, transaction); | 177 | updateThreadingIndex(identifier, bufferAdaptor, transaction); |
172 | } | 178 | } |
173 | 179 | ||
174 | void TypeImplementation<Mail>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 180 | void TypeImplementation<Mail>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
175 | { | 181 | { |
176 | getIndex().remove(identifier, bufferAdaptor, transaction); | 182 | getIndex().remove(identifier, bufferAdaptor, transaction); |
183 | //TODO cleanup threading index | ||
177 | } | 184 | } |
178 | 185 | ||
179 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplementation<Mail>::initializeReadPropertyMapper() | 186 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplementation<Mail>::initializeReadPropertyMapper() |
@@ -218,18 +225,21 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Mail>::BufferBuilder> > Ty | |||
218 | } | 225 | } |
219 | 226 | ||
220 | 227 | ||
221 | DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) | 228 | DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store) |
222 | { | 229 | { |
223 | auto mapper = initializeReadPropertyMapper(); | 230 | auto mapper = initializeReadPropertyMapper(); |
224 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper, &transaction](const Sink::Entity &entity, const QByteArray &property) -> QVariant { | 231 | return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), store, getIndex(), [mapper, store](const Sink::Entity &entity, const QByteArray &property) -> QVariant { |
225 | if (property == Mail::ThreadId::name) { | 232 | if (property == Mail::ThreadId::name) { |
226 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); | 233 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); |
227 | Q_ASSERT(localBuffer); | 234 | Q_ASSERT(localBuffer); |
228 | auto messageId = mapper->getProperty(Mail::MessageId::name, localBuffer); | 235 | auto messageId = mapper->getProperty(Mail::MessageId::name, localBuffer); |
236 | //FIXME | ||
229 | //This is an index property that we have too lookup | 237 | //This is an index property that we have too lookup |
230 | auto thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId, transaction); | 238 | /* auto thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); */ |
231 | Q_ASSERT(!thread.isEmpty()); | 239 | /* auto thread = store->secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); */ |
232 | return thread.first(); | 240 | /* Q_ASSERT(!thread.isEmpty()); */ |
241 | /* return thread.first(); */ | ||
242 | return QVariant(); | ||
233 | } else { | 243 | } else { |
234 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); | 244 | const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); |
235 | Q_ASSERT(localBuffer); | 245 | Q_ASSERT(localBuffer); |
diff --git a/common/domain/mail.h b/common/domain/mail.h index ea3ef9e..6c1f670 100644 --- a/common/domain/mail.h +++ b/common/domain/mail.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "applicationdomaintype.h" | 21 | #include "applicationdomaintype.h" |
22 | 22 | ||
23 | #include "storage.h" | 23 | #include "storage.h" |
24 | #include "datastorequery.h" | 24 | #include "storage/entitystore.h" |
25 | 25 | ||
26 | class ResultSet; | 26 | class ResultSet; |
27 | class QByteArray; | 27 | class QByteArray; |
@@ -32,6 +32,8 @@ class ReadPropertyMapper; | |||
32 | template<typename T> | 32 | template<typename T> |
33 | class WritePropertyMapper; | 33 | class WritePropertyMapper; |
34 | 34 | ||
35 | class TypeIndex; | ||
36 | |||
35 | namespace Sink { | 37 | namespace Sink { |
36 | class Query; | 38 | class Query; |
37 | 39 | ||
@@ -46,10 +48,11 @@ class TypeImplementation<Sink::ApplicationDomain::Mail> { | |||
46 | public: | 48 | public: |
47 | typedef Sink::ApplicationDomain::Buffer::Mail Buffer; | 49 | typedef Sink::ApplicationDomain::Buffer::Mail Buffer; |
48 | typedef Sink::ApplicationDomain::Buffer::MailBuilder BufferBuilder; | 50 | typedef Sink::ApplicationDomain::Buffer::MailBuilder BufferBuilder; |
49 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction); | 51 | static void configureIndex(TypeIndex &index); |
52 | static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr storage); | ||
50 | static QSet<QByteArray> indexedProperties(); | 53 | static QSet<QByteArray> indexedProperties(); |
51 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 54 | static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
52 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 55 | static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
53 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); | 56 | static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); |
54 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); | 57 | static QSharedPointer<WritePropertyMapper<BufferBuilder> > initializeWritePropertyMapper(); |
55 | }; | 58 | }; |
diff --git a/common/domainadaptor.h b/common/domainadaptor.h index 16fc8c2..6a9d755 100644 --- a/common/domainadaptor.h +++ b/common/domainadaptor.h | |||
@@ -164,7 +164,7 @@ public: | |||
164 | return adaptor; | 164 | return adaptor; |
165 | } | 165 | } |
166 | 166 | ||
167 | virtual void | 167 | virtual bool |
168 | createBuffer(const Sink::ApplicationDomain::ApplicationDomainType &domainObject, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) Q_DECL_OVERRIDE | 168 | createBuffer(const Sink::ApplicationDomain::ApplicationDomainType &domainObject, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) Q_DECL_OVERRIDE |
169 | { | 169 | { |
170 | flatbuffers::FlatBufferBuilder localFbb; | 170 | flatbuffers::FlatBufferBuilder localFbb; |
@@ -180,15 +180,16 @@ public: | |||
180 | } | 180 | } |
181 | 181 | ||
182 | Sink::EntityBuffer::assembleEntityBuffer(fbb, metadataData, metadataSize, resFbb.GetBufferPointer(), resFbb.GetSize(), localFbb.GetBufferPointer(), localFbb.GetSize()); | 182 | Sink::EntityBuffer::assembleEntityBuffer(fbb, metadataData, metadataSize, resFbb.GetBufferPointer(), resFbb.GetSize(), localFbb.GetBufferPointer(), localFbb.GetSize()); |
183 | return true; | ||
183 | } | 184 | } |
184 | 185 | ||
185 | virtual void createBuffer(const QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> &bufferAdaptor, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) Q_DECL_OVERRIDE | 186 | virtual bool createBuffer(const QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> &bufferAdaptor, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) Q_DECL_OVERRIDE |
186 | { | 187 | { |
187 | //TODO rewrite the unterlying functions so we don't have to wrap the bufferAdaptor | 188 | //TODO rewrite the unterlying functions so we don't have to wrap the bufferAdaptor |
188 | auto newObject = Sink::ApplicationDomain::ApplicationDomainType("", "", 0, bufferAdaptor); | 189 | auto newObject = Sink::ApplicationDomain::ApplicationDomainType("", "", 0, bufferAdaptor); |
189 | //Serialize all properties | 190 | //Serialize all properties |
190 | newObject.setChangedProperties(bufferAdaptor->availableProperties().toSet()); | 191 | newObject.setChangedProperties(bufferAdaptor->availableProperties().toSet()); |
191 | createBuffer(newObject, fbb, metadataData, metadataSize); | 192 | return createBuffer(newObject, fbb, metadataData, metadataSize); |
192 | } | 193 | } |
193 | 194 | ||
194 | 195 | ||
diff --git a/common/domaintypeadaptorfactoryinterface.h b/common/domaintypeadaptorfactoryinterface.h index b498796..8829c87 100644 --- a/common/domaintypeadaptorfactoryinterface.h +++ b/common/domaintypeadaptorfactoryinterface.h | |||
@@ -44,7 +44,7 @@ public: | |||
44 | * | 44 | * |
45 | * Note that this only serialized parameters that are part of ApplicationDomainType::changedProperties() | 45 | * Note that this only serialized parameters that are part of ApplicationDomainType::changedProperties() |
46 | */ | 46 | */ |
47 | virtual void | 47 | virtual bool |
48 | createBuffer(const Sink::ApplicationDomain::ApplicationDomainType &domainType, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) = 0; | 48 | createBuffer(const Sink::ApplicationDomain::ApplicationDomainType &domainType, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) = 0; |
49 | virtual void createBuffer(const QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> &bufferAdaptor, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) = 0; | 49 | virtual bool createBuffer(const QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> &bufferAdaptor, flatbuffers::FlatBufferBuilder &fbb, void const *metadataData = 0, size_t metadataSize = 0) = 0; |
50 | }; | 50 | }; |
diff --git a/common/entityreader.cpp b/common/entityreader.cpp index cca1511..c49d1f7 100644 --- a/common/entityreader.cpp +++ b/common/entityreader.cpp | |||
@@ -28,75 +28,82 @@ SINK_DEBUG_AREA("entityreader") | |||
28 | 28 | ||
29 | using namespace Sink; | 29 | using namespace Sink; |
30 | 30 | ||
31 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::getLatest(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) | 31 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::getLatest(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) */ |
32 | { | 32 | /* { */ |
33 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; | 33 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; */ |
34 | db.findLatest(uid, | 34 | /* db.findLatest(uid, */ |
35 | [¤t, &adaptorFactory, &retrievedRevision](const QByteArray &key, const QByteArray &data) -> bool { | 35 | /* [¤t, &adaptorFactory, &retrievedRevision](const QByteArray &key, const QByteArray &data) -> bool { */ |
36 | Sink::EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | 36 | /* Sink::EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); */ |
37 | if (!buffer.isValid()) { | 37 | /* if (!buffer.isValid()) { */ |
38 | SinkWarning() << "Read invalid buffer from disk"; | 38 | /* SinkWarning() << "Read invalid buffer from disk"; */ |
39 | } else { | 39 | /* } else { */ |
40 | SinkTrace() << "Found value " << key; | 40 | /* SinkTrace() << "Found value " << key; */ |
41 | current = adaptorFactory.createAdaptor(buffer.entity()); | 41 | /* current = adaptorFactory.createAdaptor(buffer.entity()); */ |
42 | retrievedRevision = Sink::Storage::revisionFromKey(key); | 42 | /* retrievedRevision = Sink::Storage::DataStore::revisionFromKey(key); */ |
43 | } | 43 | /* } */ |
44 | return false; | 44 | /* return false; */ |
45 | }, | 45 | /* }, */ |
46 | [](const Sink::Storage::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }); | 46 | /* [](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }); */ |
47 | return current; | 47 | /* return current; */ |
48 | } | 48 | /* } */ |
49 | 49 | ||
50 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::get(const Sink::Storage::NamedDatabase &db, const QByteArray &key, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) | 50 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::get(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &key, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) */ |
51 | { | 51 | /* { */ |
52 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; | 52 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; */ |
53 | db.scan(key, | 53 | /* db.scan(key, */ |
54 | [¤t, &adaptorFactory, &retrievedRevision](const QByteArray &key, const QByteArray &data) -> bool { | 54 | /* [¤t, &adaptorFactory, &retrievedRevision](const QByteArray &key, const QByteArray &data) -> bool { */ |
55 | Sink::EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | 55 | /* Sink::EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); */ |
56 | if (!buffer.isValid()) { | 56 | /* if (!buffer.isValid()) { */ |
57 | SinkWarning() << "Read invalid buffer from disk"; | 57 | /* SinkWarning() << "Read invalid buffer from disk"; */ |
58 | } else { | 58 | /* } else { */ |
59 | current = adaptorFactory.createAdaptor(buffer.entity()); | 59 | /* current = adaptorFactory.createAdaptor(buffer.entity()); */ |
60 | retrievedRevision = Sink::Storage::revisionFromKey(key); | 60 | /* retrievedRevision = Sink::Storage::DataStore::revisionFromKey(key); */ |
61 | } | 61 | /* } */ |
62 | return false; | 62 | /* return false; */ |
63 | }, | 63 | /* }, */ |
64 | [](const Sink::Storage::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }); | 64 | /* [](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }); */ |
65 | return current; | 65 | /* return current; */ |
66 | } | 66 | /* } */ |
67 | 67 | ||
68 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::getPrevious(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, qint64 revision, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) | 68 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> EntityReaderUtils::getPrevious(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &uid, qint64 revision, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision) */ |
69 | { | 69 | /* { */ |
70 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; | 70 | /* QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; */ |
71 | qint64 latestRevision = 0; | 71 | /* qint64 latestRevision = 0; */ |
72 | db.scan(uid, | 72 | /* db.scan(uid, */ |
73 | [¤t, &latestRevision, revision](const QByteArray &key, const QByteArray &) -> bool { | 73 | /* [¤t, &latestRevision, revision](const QByteArray &key, const QByteArray &) -> bool { */ |
74 | auto foundRevision = Sink::Storage::revisionFromKey(key); | 74 | /* auto foundRevision = Sink::Storage::DataStore::revisionFromKey(key); */ |
75 | if (foundRevision < revision && foundRevision > latestRevision) { | 75 | /* if (foundRevision < revision && foundRevision > latestRevision) { */ |
76 | latestRevision = foundRevision; | 76 | /* latestRevision = foundRevision; */ |
77 | } | 77 | /* } */ |
78 | return true; | 78 | /* return true; */ |
79 | }, | 79 | /* }, */ |
80 | [](const Sink::Storage::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }, true); | 80 | /* [](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }, true); */ |
81 | return get(db, Sink::Storage::assembleKey(uid, latestRevision), adaptorFactory, retrievedRevision); | 81 | /* return get(db, Sink::Storage::DataStore::assembleKey(uid, latestRevision), adaptorFactory, retrievedRevision); */ |
82 | } | 82 | /* } */ |
83 | |||
84 | /* template <class DomainType> */ | ||
85 | /* EntityReader<DomainType>::EntityReader(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Sink::Storage::DataStore::Transaction &transaction) */ | ||
86 | /* : mResourceInstanceIdentifier(resourceInstanceIdentifier), */ | ||
87 | /* mTransaction(transaction), */ | ||
88 | /* mDomainTypeAdaptorFactoryPtr(Sink::AdaptorFactoryRegistry::instance().getFactory<DomainType>(resourceType)), */ | ||
89 | /* mDomainTypeAdaptorFactory(*mDomainTypeAdaptorFactoryPtr) */ | ||
90 | /* { */ | ||
91 | /* Q_ASSERT(!resourceType.isEmpty()); */ | ||
92 | /* Q_ASSERT(mDomainTypeAdaptorFactoryPtr); */ | ||
93 | /* } */ | ||
94 | |||
95 | /* template <class DomainType> */ | ||
96 | /* EntityReader<DomainType>::EntityReader(DomainTypeAdaptorFactoryInterface &domainTypeAdaptorFactory, const QByteArray &resourceInstanceIdentifier, Sink::Storage::DataStore::Transaction &transaction) */ | ||
97 | /* : mResourceInstanceIdentifier(resourceInstanceIdentifier), */ | ||
98 | /* mTransaction(transaction), */ | ||
99 | /* mDomainTypeAdaptorFactory(domainTypeAdaptorFactory) */ | ||
100 | /* { */ | ||
101 | |||
102 | /* } */ | ||
83 | 103 | ||
84 | template <class DomainType> | 104 | template <class DomainType> |
85 | EntityReader<DomainType>::EntityReader(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Sink::Storage::Transaction &transaction) | 105 | EntityReader<DomainType>::EntityReader(Storage::EntityStore &entityStore) |
86 | : mResourceInstanceIdentifier(resourceInstanceIdentifier), | 106 | : mEntityStore(entityStore) |
87 | mTransaction(transaction), | ||
88 | mDomainTypeAdaptorFactoryPtr(Sink::AdaptorFactoryRegistry::instance().getFactory<DomainType>(resourceType)), | ||
89 | mDomainTypeAdaptorFactory(*mDomainTypeAdaptorFactoryPtr) | ||
90 | { | ||
91 | Q_ASSERT(!resourceType.isEmpty()); | ||
92 | Q_ASSERT(mDomainTypeAdaptorFactoryPtr); | ||
93 | } | ||
94 | |||
95 | template <class DomainType> | ||
96 | EntityReader<DomainType>::EntityReader(DomainTypeAdaptorFactoryInterface &domainTypeAdaptorFactory, const QByteArray &resourceInstanceIdentifier, Sink::Storage::Transaction &transaction) | ||
97 | : mResourceInstanceIdentifier(resourceInstanceIdentifier), | ||
98 | mTransaction(transaction), | ||
99 | mDomainTypeAdaptorFactory(domainTypeAdaptorFactory) | ||
100 | { | 107 | { |
101 | 108 | ||
102 | } | 109 | } |
@@ -105,40 +112,28 @@ template <class DomainType> | |||
105 | DomainType EntityReader<DomainType>::read(const QByteArray &identifier) const | 112 | DomainType EntityReader<DomainType>::read(const QByteArray &identifier) const |
106 | { | 113 | { |
107 | auto typeName = ApplicationDomain::getTypeName<DomainType>(); | 114 | auto typeName = ApplicationDomain::getTypeName<DomainType>(); |
108 | auto mainDatabase = Storage::mainDatabase(mTransaction, typeName); | 115 | return mEntityStore.readLatest<DomainType>(identifier); |
109 | qint64 retrievedRevision = 0; | ||
110 | auto bufferAdaptor = EntityReaderUtils::getLatest(mainDatabase, identifier, mDomainTypeAdaptorFactory, retrievedRevision); | ||
111 | if (!bufferAdaptor) { | ||
112 | return DomainType(); | ||
113 | } | ||
114 | return DomainType(mResourceInstanceIdentifier, identifier, retrievedRevision, bufferAdaptor); | ||
115 | } | 116 | } |
116 | 117 | ||
117 | template <class DomainType> | 118 | template <class DomainType> |
118 | DomainType EntityReader<DomainType>::readFromKey(const QByteArray &key) const | 119 | DomainType EntityReader<DomainType>::readFromKey(const QByteArray &key) const |
119 | { | 120 | { |
120 | auto typeName = ApplicationDomain::getTypeName<DomainType>(); | 121 | /* auto typeName = ApplicationDomain::getTypeName<DomainType>(); */ |
121 | auto mainDatabase = Storage::mainDatabase(mTransaction, typeName); | 122 | /* auto mainDatabase = Storage::DataStore::mainDatabase(mTransaction, typeName); */ |
122 | qint64 retrievedRevision = 0; | 123 | /* qint64 retrievedRevision = 0; */ |
123 | auto bufferAdaptor = EntityReaderUtils::get(mainDatabase, key, mDomainTypeAdaptorFactory, retrievedRevision); | 124 | /* auto bufferAdaptor = EntityReaderUtils::get(mainDatabase, key, mDomainTypeAdaptorFactory, retrievedRevision); */ |
124 | const auto identifier = Storage::uidFromKey(key); | 125 | /* const auto identifier = Storage::DataStore::uidFromKey(key); */ |
125 | if (!bufferAdaptor) { | 126 | /* if (!bufferAdaptor) { */ |
126 | return DomainType(); | 127 | /* return DomainType(); */ |
127 | } | 128 | /* } */ |
128 | return DomainType(mResourceInstanceIdentifier, identifier, retrievedRevision, bufferAdaptor); | 129 | /* return DomainType(mResourceInstanceIdentifier, identifier, retrievedRevision, bufferAdaptor); */ |
130 | return mEntityStore.readEntity<DomainType>(key); | ||
129 | } | 131 | } |
130 | 132 | ||
131 | template <class DomainType> | 133 | template <class DomainType> |
132 | DomainType EntityReader<DomainType>::readPrevious(const QByteArray &uid, qint64 revision) const | 134 | DomainType EntityReader<DomainType>::readPrevious(const QByteArray &uid, qint64 revision) const |
133 | { | 135 | { |
134 | auto typeName = ApplicationDomain::getTypeName<DomainType>(); | 136 | return mEntityStore.readPrevious<DomainType>(uid, revision); |
135 | auto mainDatabase = Storage::mainDatabase(mTransaction, typeName); | ||
136 | qint64 retrievedRevision = 0; | ||
137 | auto bufferAdaptor = EntityReaderUtils::getPrevious(mainDatabase, uid, revision, mDomainTypeAdaptorFactory, retrievedRevision); | ||
138 | if (!bufferAdaptor) { | ||
139 | return DomainType(); | ||
140 | } | ||
141 | return DomainType(mResourceInstanceIdentifier, uid, retrievedRevision, bufferAdaptor); | ||
142 | } | 137 | } |
143 | 138 | ||
144 | template <class DomainType> | 139 | template <class DomainType> |
@@ -157,14 +152,14 @@ QPair<qint64, qint64> EntityReader<DomainType>::executeInitialQuery(const Sink:: | |||
157 | QTime time; | 152 | QTime time; |
158 | time.start(); | 153 | time.start(); |
159 | 154 | ||
160 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, mTransaction); | 155 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, Storage::EntityStore::Ptr(&mEntityStore, [](Storage::EntityStore *){})); |
161 | auto resultSet = preparedQuery->execute(); | 156 | auto resultSet = preparedQuery->execute(); |
162 | 157 | ||
163 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); | 158 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); |
164 | auto replayedEntities = replaySet(resultSet, offset, batchsize, callback); | 159 | auto replayedEntities = replaySet(resultSet, offset, batchsize, callback); |
165 | 160 | ||
166 | SinkTrace() << "Initial query took: " << Log::TraceTime(time.elapsed()); | 161 | SinkTrace() << "Initial query took: " << Log::TraceTime(time.elapsed()); |
167 | return qMakePair(Sink::Storage::maxRevision(mTransaction), replayedEntities); | 162 | return qMakePair(mEntityStore.maxRevision(), replayedEntities); |
168 | } | 163 | } |
169 | 164 | ||
170 | template <class DomainType> | 165 | template <class DomainType> |
@@ -174,14 +169,14 @@ QPair<qint64, qint64> EntityReader<DomainType>::executeIncrementalQuery(const Si | |||
174 | time.start(); | 169 | time.start(); |
175 | const qint64 baseRevision = lastRevision + 1; | 170 | const qint64 baseRevision = lastRevision + 1; |
176 | 171 | ||
177 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, mTransaction); | 172 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, Storage::EntityStore::Ptr(&mEntityStore, [](Storage::EntityStore *){})); |
178 | auto resultSet = preparedQuery->update(baseRevision); | 173 | auto resultSet = preparedQuery->update(baseRevision); |
179 | 174 | ||
180 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); | 175 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); |
181 | auto replayedEntities = replaySet(resultSet, 0, 0, callback); | 176 | auto replayedEntities = replaySet(resultSet, 0, 0, callback); |
182 | 177 | ||
183 | SinkTrace() << "Incremental query took: " << Log::TraceTime(time.elapsed()); | 178 | SinkTrace() << "Incremental query took: " << Log::TraceTime(time.elapsed()); |
184 | return qMakePair(Sink::Storage::maxRevision(mTransaction), replayedEntities); | 179 | return qMakePair(mEntityStore.maxRevision(), replayedEntities); |
185 | } | 180 | } |
186 | 181 | ||
187 | template <class DomainType> | 182 | template <class DomainType> |
@@ -190,18 +185,18 @@ qint64 EntityReader<DomainType>::replaySet(ResultSet &resultSet, int offset, int | |||
190 | SinkTrace() << "Skipping over " << offset << " results"; | 185 | SinkTrace() << "Skipping over " << offset << " results"; |
191 | resultSet.skip(offset); | 186 | resultSet.skip(offset); |
192 | int counter = 0; | 187 | int counter = 0; |
193 | while (!batchSize || (counter < batchSize)) { | 188 | /* while (!batchSize || (counter < batchSize)) { */ |
194 | const bool ret = | 189 | /* const bool ret = */ |
195 | resultSet.next([this, &counter, callback](const ResultSet::Result &result) -> bool { | 190 | /* resultSet.next([this, &counter, callback](const ResultSet::Result &result) -> bool { */ |
196 | counter++; | 191 | /* counter++; */ |
197 | auto adaptor = mDomainTypeAdaptorFactory.createAdaptor(result.buffer.entity()); | 192 | /* auto adaptor = mResourceContext.adaptorFactory<DomainType>().createAdaptor(result.buffer.entity()); */ |
198 | Q_ASSERT(adaptor); | 193 | /* Q_ASSERT(adaptor); */ |
199 | return callback(QSharedPointer<DomainType>::create(mResourceInstanceIdentifier, result.uid, result.buffer.revision(), adaptor), result.operation, result.aggregateValues); | 194 | /* return callback(QSharedPointer<DomainType>::create(mResourceContext, result.uid, result.buffer.revision(), adaptor), result.operation, result.aggregateValues); */ |
200 | }); | 195 | /* }); */ |
201 | if (!ret) { | 196 | /* if (!ret) { */ |
202 | break; | 197 | /* break; */ |
203 | } | 198 | /* } */ |
204 | }; | 199 | /* }; */ |
205 | SinkTrace() << "Replayed " << counter << " results." | 200 | SinkTrace() << "Replayed " << counter << " results." |
206 | << "Limit " << batchSize; | 201 | << "Limit " << batchSize; |
207 | return counter; | 202 | return counter; |
diff --git a/common/entityreader.h b/common/entityreader.h index 1e7b086..a641106 100644 --- a/common/entityreader.h +++ b/common/entityreader.h | |||
@@ -30,9 +30,9 @@ | |||
30 | namespace Sink { | 30 | namespace Sink { |
31 | 31 | ||
32 | namespace EntityReaderUtils { | 32 | namespace EntityReaderUtils { |
33 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getLatest(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); | 33 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getLatest(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); |
34 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> get(const Sink::Storage::NamedDatabase &db, const QByteArray &key, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); | 34 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> get(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &key, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); |
35 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getPrevious(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, qint64 revision, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); | 35 | SINK_EXPORT QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getPrevious(const Sink::Storage::DataStore::NamedDatabase &db, const QByteArray &uid, qint64 revision, DomainTypeAdaptorFactoryInterface &adaptorFactory, qint64 &retrievedRevision); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | /** | 38 | /** |
@@ -41,7 +41,7 @@ namespace EntityReaderUtils { | |||
41 | * All callbacks will be called before the end of the function. | 41 | * All callbacks will be called before the end of the function. |
42 | * The caller must ensure passed in references remain valid for the lifetime of the object. | 42 | * The caller must ensure passed in references remain valid for the lifetime of the object. |
43 | * | 43 | * |
44 | * This class is meaent to be instantiated temporarily during reads on the stack. | 44 | * This class is meant to be instantiated temporarily during reads on the stack. |
45 | * | 45 | * |
46 | * Note that all objects returned in callbacks are only valid during the execution of the callback and may start pointing into invalid memory if shallow-copied. | 46 | * Note that all objects returned in callbacks are only valid during the execution of the callback and may start pointing into invalid memory if shallow-copied. |
47 | */ | 47 | */ |
@@ -51,8 +51,7 @@ class SINK_EXPORT EntityReader | |||
51 | typedef std::function<bool(const typename DomainType::Ptr &domainObject, Sink::Operation operation, const QMap<QByteArray, QVariant> &aggregateValues)> ResultCallback; | 51 | typedef std::function<bool(const typename DomainType::Ptr &domainObject, Sink::Operation operation, const QMap<QByteArray, QVariant> &aggregateValues)> ResultCallback; |
52 | 52 | ||
53 | public: | 53 | public: |
54 | EntityReader(const QByteArray &resourceType, const QByteArray &mResourceInstanceIdentifier, Sink::Storage::Transaction &transaction); | 54 | EntityReader(Storage::EntityStore &store); |
55 | EntityReader(DomainTypeAdaptorFactoryInterface &domainTypeAdaptorFactory, const QByteArray &resourceInstanceIdentifier, Sink::Storage::Transaction &transaction); | ||
56 | 55 | ||
57 | /** | 56 | /** |
58 | * Reads the latest revision of an entity identified by @param uid | 57 | * Reads the latest revision of an entity identified by @param uid |
@@ -90,10 +89,7 @@ private: | |||
90 | qint64 replaySet(ResultSet &resultSet, int offset, int batchSize, const ResultCallback &callback); | 89 | qint64 replaySet(ResultSet &resultSet, int offset, int batchSize, const ResultCallback &callback); |
91 | 90 | ||
92 | private: | 91 | private: |
93 | QByteArray mResourceInstanceIdentifier; | 92 | Sink::Storage::EntityStore &mEntityStore; |
94 | Sink::Storage::Transaction &mTransaction; | ||
95 | std::shared_ptr<DomainTypeAdaptorFactoryInterface> mDomainTypeAdaptorFactoryPtr; | ||
96 | DomainTypeAdaptorFactoryInterface &mDomainTypeAdaptorFactory; | ||
97 | }; | 93 | }; |
98 | 94 | ||
99 | } | 95 | } |
diff --git a/common/entitystore.cpp b/common/entitystore.cpp index 5fb213d..b7b03aa 100644 --- a/common/entitystore.cpp +++ b/common/entitystore.cpp | |||
@@ -21,9 +21,8 @@ | |||
21 | 21 | ||
22 | using namespace Sink; | 22 | using namespace Sink; |
23 | 23 | ||
24 | EntityStore::EntityStore(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Sink::Storage::Transaction &transaction) | 24 | EntityStore::EntityStore(Storage::EntityStore &store_) |
25 | : mResourceType(resourceType), mResourceInstanceIdentifier(resourceInstanceIdentifier), | 25 | : store(store_) |
26 | mTransaction(transaction) | ||
27 | { | 26 | { |
28 | 27 | ||
29 | } | 28 | } |
diff --git a/common/entitystore.h b/common/entitystore.h index 6bfe414..3d9ca36 100644 --- a/common/entitystore.h +++ b/common/entitystore.h | |||
@@ -20,50 +20,42 @@ | |||
20 | #pragma once | 20 | #pragma once |
21 | 21 | ||
22 | #include "sink_export.h" | 22 | #include "sink_export.h" |
23 | #include <domainadaptor.h> | ||
24 | 23 | ||
25 | #include "storage.h" | 24 | #include "storage/entitystore.h" |
26 | #include "adaptorfactoryregistry.h" | ||
27 | #include "entityreader.h" | ||
28 | 25 | ||
29 | namespace Sink { | 26 | namespace Sink { |
30 | 27 | ||
31 | class SINK_EXPORT EntityStore | 28 | class SINK_EXPORT EntityStore |
32 | { | 29 | { |
33 | public: | 30 | public: |
34 | EntityStore(const QByteArray &resourceType, const QByteArray &mResourceInstanceIdentifier, Sink::Storage::Transaction &transaction); | 31 | EntityStore(Storage::EntityStore &store); |
35 | 32 | ||
36 | template<typename T> | 33 | template<typename T> |
37 | T read(const QByteArray &identifier) const | 34 | T read(const QByteArray &identifier) const |
38 | { | 35 | { |
39 | EntityReader<T> reader(mResourceType, mResourceInstanceIdentifier, mTransaction); | 36 | return store.readLatest<T>(identifier); |
40 | return reader.read(identifier); | ||
41 | } | 37 | } |
42 | 38 | ||
43 | template<typename T> | 39 | template<typename T> |
44 | T readFromKey(const QByteArray &key) const | 40 | T readFromKey(const QByteArray &key) const |
45 | { | 41 | { |
46 | EntityReader<T> reader(mResourceType, mResourceInstanceIdentifier, mTransaction); | 42 | return store.readEntity<T>(key); |
47 | return reader.readFromKey(key); | ||
48 | } | 43 | } |
49 | 44 | ||
50 | template<typename T> | 45 | template<typename T> |
51 | T readPrevious(const QByteArray &uid, qint64 revision) const | 46 | T readPrevious(const QByteArray &uid, qint64 revision) const |
52 | { | 47 | { |
53 | EntityReader<T> reader(mResourceType, mResourceInstanceIdentifier, mTransaction); | 48 | return store.readPrevious<T>(uid, revision); |
54 | return reader.readPrevious(uid, revision); | ||
55 | } | 49 | } |
56 | 50 | ||
57 | template<typename T> | 51 | /* template<typename T> */ |
58 | EntityReader<T> reader() | 52 | /* EntityReader<T> reader() */ |
59 | { | 53 | /* { */ |
60 | return EntityReader<T>(mResourceType, mResourceInstanceIdentifier, mTransaction); | 54 | /* return EntityReader<T>(mResourceType, mResourceInstanceIdentifier, mTransaction); */ |
61 | } | 55 | /* } */ |
62 | 56 | ||
63 | private: | 57 | private: |
64 | QByteArray mResourceType; | 58 | Sink::Storage::EntityStore &store; |
65 | QByteArray mResourceInstanceIdentifier; | ||
66 | Sink::Storage::Transaction &mTransaction; | ||
67 | }; | 59 | }; |
68 | 60 | ||
69 | } | 61 | } |
diff --git a/common/facade.cpp b/common/facade.cpp index 72f7414..3ec58e3 100644 --- a/common/facade.cpp +++ b/common/facade.cpp | |||
@@ -31,13 +31,9 @@ | |||
31 | using namespace Sink; | 31 | using namespace Sink; |
32 | 32 | ||
33 | template <class DomainType> | 33 | template <class DomainType> |
34 | GenericFacade<DomainType>::GenericFacade( | 34 | GenericFacade<DomainType>::GenericFacade(const ResourceContext &context) |
35 | const QByteArray &resourceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory, const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess) | 35 | : Sink::StoreFacade<DomainType>(), mResourceContext(context), mResourceAccess(mResourceContext.resourceAccess()) |
36 | : Sink::StoreFacade<DomainType>(), mResourceAccess(resourceAccess), mDomainTypeAdaptorFactory(adaptorFactory), mResourceInstanceIdentifier(resourceIdentifier) | ||
37 | { | 36 | { |
38 | if (!mResourceAccess) { | ||
39 | mResourceAccess = ResourceAccessFactory::instance().getAccess(resourceIdentifier, ResourceConfig::getResourceType(resourceIdentifier)); | ||
40 | } | ||
41 | } | 37 | } |
42 | 38 | ||
43 | template <class DomainType> | 39 | template <class DomainType> |
@@ -55,25 +51,23 @@ QByteArray GenericFacade<DomainType>::bufferTypeForDomainType() | |||
55 | template <class DomainType> | 51 | template <class DomainType> |
56 | KAsync::Job<void> GenericFacade<DomainType>::create(const DomainType &domainObject) | 52 | KAsync::Job<void> GenericFacade<DomainType>::create(const DomainType &domainObject) |
57 | { | 53 | { |
58 | if (!mDomainTypeAdaptorFactory) { | 54 | flatbuffers::FlatBufferBuilder entityFbb; |
55 | if (!mResourceContext.adaptorFactory<DomainType>().createBuffer(domainObject, entityFbb)) { | ||
59 | SinkWarning() << "No domain type adaptor factory available"; | 56 | SinkWarning() << "No domain type adaptor factory available"; |
60 | return KAsync::error<void>(); | 57 | return KAsync::error<void>(); |
61 | } | 58 | } |
62 | flatbuffers::FlatBufferBuilder entityFbb; | ||
63 | mDomainTypeAdaptorFactory->createBuffer(domainObject, entityFbb); | ||
64 | return mResourceAccess->sendCreateCommand(domainObject.identifier(), bufferTypeForDomainType(), BufferUtils::extractBuffer(entityFbb)); | 59 | return mResourceAccess->sendCreateCommand(domainObject.identifier(), bufferTypeForDomainType(), BufferUtils::extractBuffer(entityFbb)); |
65 | } | 60 | } |
66 | 61 | ||
67 | template <class DomainType> | 62 | template <class DomainType> |
68 | KAsync::Job<void> GenericFacade<DomainType>::modify(const DomainType &domainObject) | 63 | KAsync::Job<void> GenericFacade<DomainType>::modify(const DomainType &domainObject) |
69 | { | 64 | { |
70 | if (!mDomainTypeAdaptorFactory) { | 65 | SinkTrace() << "Modifying entity: " << domainObject.identifier() << domainObject.changedProperties(); |
66 | flatbuffers::FlatBufferBuilder entityFbb; | ||
67 | if (!mResourceContext.adaptorFactory<DomainType>().createBuffer(domainObject, entityFbb)) { | ||
71 | SinkWarning() << "No domain type adaptor factory available"; | 68 | SinkWarning() << "No domain type adaptor factory available"; |
72 | return KAsync::error<void>(); | 69 | return KAsync::error<void>(); |
73 | } | 70 | } |
74 | SinkTrace() << "Modifying entity: " << domainObject.identifier() << domainObject.changedProperties(); | ||
75 | flatbuffers::FlatBufferBuilder entityFbb; | ||
76 | mDomainTypeAdaptorFactory->createBuffer(domainObject, entityFbb); | ||
77 | return mResourceAccess->sendModifyCommand(domainObject.identifier(), domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties()); | 71 | return mResourceAccess->sendModifyCommand(domainObject.identifier(), domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties()); |
78 | } | 72 | } |
79 | 73 | ||
@@ -87,7 +81,7 @@ template <class DomainType> | |||
87 | QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> GenericFacade<DomainType>::load(const Sink::Query &query) | 81 | QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> GenericFacade<DomainType>::load(const Sink::Query &query) |
88 | { | 82 | { |
89 | // The runner lives for the lifetime of the query | 83 | // The runner lives for the lifetime of the query |
90 | auto runner = new QueryRunner<DomainType>(query, mResourceAccess, mResourceInstanceIdentifier, mDomainTypeAdaptorFactory, bufferTypeForDomainType()); | 84 | auto runner = new QueryRunner<DomainType>(query, mResourceContext, bufferTypeForDomainType()); |
91 | runner->setResultTransformation(mResultTransformation); | 85 | runner->setResultTransformation(mResultTransformation); |
92 | return qMakePair(KAsync::null<void>(), runner->emitter()); | 86 | return qMakePair(KAsync::null<void>(), runner->emitter()); |
93 | } | 87 | } |
diff --git a/common/facade.h b/common/facade.h index b193580..50d93e0 100644 --- a/common/facade.h +++ b/common/facade.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "resourceaccess.h" | 28 | #include "resourceaccess.h" |
29 | #include "domaintypeadaptorfactoryinterface.h" | 29 | #include "domaintypeadaptorfactoryinterface.h" |
30 | #include "storage.h" | 30 | #include "storage.h" |
31 | #include "resourcecontext.h" | ||
31 | 32 | ||
32 | namespace Sink { | 33 | namespace Sink { |
33 | 34 | ||
@@ -48,7 +49,7 @@ class SINK_EXPORT GenericFacade : public Sink::StoreFacade<DomainType> | |||
48 | { | 49 | { |
49 | protected: | 50 | protected: |
50 | SINK_DEBUG_AREA("facade") | 51 | SINK_DEBUG_AREA("facade") |
51 | SINK_DEBUG_COMPONENT(mResourceInstanceIdentifier) | 52 | SINK_DEBUG_COMPONENT(mResourceContext.resourceInstanceIdentifier) |
52 | public: | 53 | public: |
53 | /** | 54 | /** |
54 | * Create a new GenericFacade | 55 | * Create a new GenericFacade |
@@ -56,8 +57,7 @@ public: | |||
56 | * @param resourceIdentifier is the identifier of the resource instance | 57 | * @param resourceIdentifier is the identifier of the resource instance |
57 | * @param adaptorFactory is the adaptor factory used to generate the mappings from domain to resource types and vice versa | 58 | * @param adaptorFactory is the adaptor factory used to generate the mappings from domain to resource types and vice versa |
58 | */ | 59 | */ |
59 | GenericFacade(const QByteArray &resourceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory = DomainTypeAdaptorFactoryInterface::Ptr(), | 60 | GenericFacade(const ResourceContext &context); |
60 | const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess = QSharedPointer<Sink::ResourceAccessInterface>()); | ||
61 | virtual ~GenericFacade(); | 61 | virtual ~GenericFacade(); |
62 | 62 | ||
63 | static QByteArray bufferTypeForDomainType(); | 63 | static QByteArray bufferTypeForDomainType(); |
@@ -68,20 +68,18 @@ public: | |||
68 | 68 | ||
69 | protected: | 69 | protected: |
70 | std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> mResultTransformation; | 70 | std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> mResultTransformation; |
71 | // TODO use one resource access instance per application & per resource | 71 | ResourceContext mResourceContext; |
72 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; | 72 | Sink::ResourceAccessInterface::Ptr mResourceAccess; |
73 | DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; | ||
74 | QByteArray mResourceInstanceIdentifier; | ||
75 | }; | 73 | }; |
76 | 74 | ||
77 | /** | 75 | /** |
78 | * A default facade implemenation that simply instantiates a generic resource with the given DomainTypeAdaptorFactory | 76 | * A default facade implemenation that simply instantiates a generic resource |
79 | */ | 77 | */ |
80 | template<typename DomainType, typename DomainTypeAdaptorFactory> | 78 | template<typename DomainType> |
81 | class DefaultFacade : public GenericFacade<DomainType> | 79 | class DefaultFacade : public GenericFacade<DomainType> |
82 | { | 80 | { |
83 | public: | 81 | public: |
84 | DefaultFacade(const QByteArray &resourceIdentifier) : GenericFacade<DomainType>(resourceIdentifier, QSharedPointer<DomainTypeAdaptorFactory>::create()) {} | 82 | DefaultFacade(const ResourceContext &context) : GenericFacade<DomainType>(context) {} |
85 | virtual ~DefaultFacade(){} | 83 | virtual ~DefaultFacade(){} |
86 | }; | 84 | }; |
87 | 85 | ||
diff --git a/common/facadefactory.cpp b/common/facadefactory.cpp index b5a0ff2..107d575 100644 --- a/common/facadefactory.cpp +++ b/common/facadefactory.cpp | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "resourcefacade.h" | 22 | #include "resourcefacade.h" |
23 | #include "resource.h" | 23 | #include "resource.h" |
24 | #include "adaptorfactoryregistry.h" | ||
24 | 25 | ||
25 | using namespace Sink; | 26 | using namespace Sink; |
26 | 27 | ||
@@ -72,7 +73,7 @@ std::shared_ptr<void> FacadeFactory::getFacade(const QByteArray &resource, const | |||
72 | } | 73 | } |
73 | 74 | ||
74 | if (auto factoryFunction = mFacadeRegistry.value(k)) { | 75 | if (auto factoryFunction = mFacadeRegistry.value(k)) { |
75 | return factoryFunction(instanceIdentifier); | 76 | return factoryFunction(ResourceContext{instanceIdentifier, resource, AdaptorFactoryRegistry::instance().getFactories(resource)}); |
76 | } | 77 | } |
77 | qWarning() << "Failed to find facade for resource: " << resource << " and type: " << typeName; | 78 | qWarning() << "Failed to find facade for resource: " << resource << " and type: " << typeName; |
78 | return std::shared_ptr<void>(); | 79 | return std::shared_ptr<void>(); |
diff --git a/common/facadefactory.h b/common/facadefactory.h index 7313970..8d41705 100644 --- a/common/facadefactory.h +++ b/common/facadefactory.h | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include "facadeinterface.h" | 30 | #include "facadeinterface.h" |
31 | #include "applicationdomaintype.h" | 31 | #include "applicationdomaintype.h" |
32 | #include "resourcecontext.h" | ||
32 | #include "log.h" | 33 | #include "log.h" |
33 | 34 | ||
34 | namespace Sink { | 35 | namespace Sink { |
@@ -41,7 +42,7 @@ namespace Sink { | |||
41 | class SINK_EXPORT FacadeFactory | 42 | class SINK_EXPORT FacadeFactory |
42 | { | 43 | { |
43 | public: | 44 | public: |
44 | typedef std::function<std::shared_ptr<void>(const QByteArray &)> FactoryFunction; | 45 | typedef std::function<std::shared_ptr<void>(const ResourceContext &)> FactoryFunction; |
45 | 46 | ||
46 | void registerStaticFacades(); | 47 | void registerStaticFacades(); |
47 | 48 | ||
@@ -52,13 +53,13 @@ public: | |||
52 | template <class DomainType, class Facade> | 53 | template <class DomainType, class Facade> |
53 | void registerFacade(const QByteArray &resource) | 54 | void registerFacade(const QByteArray &resource) |
54 | { | 55 | { |
55 | registerFacade(resource, [](const QByteArray &instanceIdentifier) { return std::make_shared<Facade>(instanceIdentifier); }, ApplicationDomain::getTypeName<DomainType>()); | 56 | registerFacade(resource, [](const ResourceContext &context) { return std::make_shared<Facade>(context); }, ApplicationDomain::getTypeName<DomainType>()); |
56 | } | 57 | } |
57 | 58 | ||
58 | template <class DomainType, class Facade> | 59 | template <class DomainType, class Facade> |
59 | void registerFacade() | 60 | void registerFacade() |
60 | { | 61 | { |
61 | registerFacade(QByteArray(), [](const QByteArray &) { return std::make_shared<Facade>(); }, ApplicationDomain::getTypeName<DomainType>()); | 62 | registerFacade(QByteArray(), [](const ResourceContext &) { return std::make_shared<Facade>(); }, ApplicationDomain::getTypeName<DomainType>()); |
62 | } | 63 | } |
63 | 64 | ||
64 | /* | 65 | /* |
diff --git a/common/genericresource.cpp b/common/genericresource.cpp index ef6edc8..e0d395a 100644 --- a/common/genericresource.cpp +++ b/common/genericresource.cpp | |||
@@ -45,6 +45,7 @@ static int sBatchSize = 100; | |||
45 | static int sCommitInterval = 10; | 45 | static int sCommitInterval = 10; |
46 | 46 | ||
47 | using namespace Sink; | 47 | using namespace Sink; |
48 | using namespace Sink::Storage; | ||
48 | 49 | ||
49 | /** | 50 | /** |
50 | * Drives the pipeline using the output from all command queues | 51 | * Drives the pipeline using the output from all command queues |
@@ -58,7 +59,7 @@ class CommandProcessor : public QObject | |||
58 | public: | 59 | public: |
59 | CommandProcessor(Sink::Pipeline *pipeline, QList<MessageQueue *> commandQueues) : QObject(), mPipeline(pipeline), mCommandQueues(commandQueues), mProcessingLock(false) | 60 | CommandProcessor(Sink::Pipeline *pipeline, QList<MessageQueue *> commandQueues) : QObject(), mPipeline(pipeline), mCommandQueues(commandQueues), mProcessingLock(false) |
60 | { | 61 | { |
61 | mLowerBoundRevision = Storage::maxRevision(mPipeline->storage().createTransaction(Storage::ReadOnly, [](const Sink::Storage::Error &error) { | 62 | mLowerBoundRevision = DataStore::maxRevision(mPipeline->storage().createTransaction(DataStore::ReadOnly, [](const Sink::Storage::DataStore::Error &error) { |
62 | SinkWarning() << error.message; | 63 | SinkWarning() << error.message; |
63 | })); | 64 | })); |
64 | 65 | ||
@@ -226,17 +227,15 @@ private: | |||
226 | InspectionFunction mInspect; | 227 | InspectionFunction mInspect; |
227 | }; | 228 | }; |
228 | 229 | ||
229 | GenericResource::GenericResource(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, const QSharedPointer<Pipeline> &pipeline ) | 230 | GenericResource::GenericResource(const ResourceContext &resourceContext, const QSharedPointer<Pipeline> &pipeline ) |
230 | : Sink::Resource(), | 231 | : Sink::Resource(), |
231 | mUserQueue(Sink::storageLocation(), resourceInstanceIdentifier + ".userqueue"), | 232 | mResourceContext(resourceContext), |
232 | mSynchronizerQueue(Sink::storageLocation(), resourceInstanceIdentifier + ".synchronizerqueue"), | 233 | mUserQueue(Sink::storageLocation(), resourceContext.instanceId() + ".userqueue"), |
233 | mResourceType(resourceType), | 234 | mSynchronizerQueue(Sink::storageLocation(), resourceContext.instanceId() + ".synchronizerqueue"), |
234 | mResourceInstanceIdentifier(resourceInstanceIdentifier), | 235 | mPipeline(pipeline ? pipeline : QSharedPointer<Sink::Pipeline>::create(resourceContext)), |
235 | mPipeline(pipeline ? pipeline : QSharedPointer<Sink::Pipeline>::create(resourceInstanceIdentifier)), | ||
236 | mError(0), | 236 | mError(0), |
237 | mClientLowerBoundRevision(std::numeric_limits<qint64>::max()) | 237 | mClientLowerBoundRevision(std::numeric_limits<qint64>::max()) |
238 | { | 238 | { |
239 | mPipeline->setResourceType(mResourceType); | ||
240 | mProcessor = std::unique_ptr<CommandProcessor>(new CommandProcessor(mPipeline.data(), QList<MessageQueue *>() << &mUserQueue << &mSynchronizerQueue)); | 239 | mProcessor = std::unique_ptr<CommandProcessor>(new CommandProcessor(mPipeline.data(), QList<MessageQueue *>() << &mUserQueue << &mSynchronizerQueue)); |
241 | mProcessor->setInspectionCommand([this](void const *command, size_t size) { | 240 | mProcessor->setInspectionCommand([this](void const *command, size_t size) { |
242 | flatbuffers::Verifier verifier((const uint8_t *)command, size); | 241 | flatbuffers::Verifier verifier((const uint8_t *)command, size); |
@@ -357,19 +356,19 @@ void GenericResource::setupChangereplay(const QSharedPointer<ChangeReplay> &chan | |||
357 | 356 | ||
358 | void GenericResource::removeFromDisk(const QByteArray &instanceIdentifier) | 357 | void GenericResource::removeFromDisk(const QByteArray &instanceIdentifier) |
359 | { | 358 | { |
360 | Sink::Storage(Sink::storageLocation(), instanceIdentifier, Sink::Storage::ReadWrite).removeFromDisk(); | 359 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier, Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
361 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".userqueue", Sink::Storage::ReadWrite).removeFromDisk(); | 360 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".userqueue", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
362 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronizerqueue", Sink::Storage::ReadWrite).removeFromDisk(); | 361 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronizerqueue", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
363 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".changereplay", Sink::Storage::ReadWrite).removeFromDisk(); | 362 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".changereplay", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
364 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); | 363 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
365 | } | 364 | } |
366 | 365 | ||
367 | qint64 GenericResource::diskUsage(const QByteArray &instanceIdentifier) | 366 | qint64 GenericResource::diskUsage(const QByteArray &instanceIdentifier) |
368 | { | 367 | { |
369 | auto size = Sink::Storage(Sink::storageLocation(), instanceIdentifier, Sink::Storage::ReadOnly).diskUsage(); | 368 | auto size = Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier, Sink::Storage::DataStore::ReadOnly).diskUsage(); |
370 | size += Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".userqueue", Sink::Storage::ReadOnly).diskUsage(); | 369 | size += Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".userqueue", Sink::Storage::DataStore::ReadOnly).diskUsage(); |
371 | size += Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronizerqueue", Sink::Storage::ReadOnly).diskUsage(); | 370 | size += Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronizerqueue", Sink::Storage::DataStore::ReadOnly).diskUsage(); |
372 | size += Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".changereplay", Sink::Storage::ReadOnly).diskUsage(); | 371 | size += Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".changereplay", Sink::Storage::DataStore::ReadOnly).diskUsage(); |
373 | return size; | 372 | return size; |
374 | } | 373 | } |
375 | 374 | ||
diff --git a/common/genericresource.h b/common/genericresource.h index ec43939..687e307 100644 --- a/common/genericresource.h +++ b/common/genericresource.h | |||
@@ -43,7 +43,7 @@ class SINK_EXPORT GenericResource : public Resource | |||
43 | protected: | 43 | protected: |
44 | SINK_DEBUG_AREA("resource") | 44 | SINK_DEBUG_AREA("resource") |
45 | public: | 45 | public: |
46 | GenericResource(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, const QSharedPointer<Pipeline> &pipeline); | 46 | GenericResource(const Sink::ResourceContext &context, const QSharedPointer<Pipeline> &pipeline); |
47 | virtual ~GenericResource(); | 47 | virtual ~GenericResource(); |
48 | 48 | ||
49 | virtual void processCommand(int commandId, const QByteArray &data) Q_DECL_OVERRIDE; | 49 | virtual void processCommand(int commandId, const QByteArray &data) Q_DECL_OVERRIDE; |
@@ -71,10 +71,9 @@ protected: | |||
71 | void onProcessorError(int errorCode, const QString &errorMessage); | 71 | void onProcessorError(int errorCode, const QString &errorMessage); |
72 | void enqueueCommand(MessageQueue &mq, int commandId, const QByteArray &data); | 72 | void enqueueCommand(MessageQueue &mq, int commandId, const QByteArray &data); |
73 | 73 | ||
74 | ResourceContext mResourceContext; | ||
74 | MessageQueue mUserQueue; | 75 | MessageQueue mUserQueue; |
75 | MessageQueue mSynchronizerQueue; | 76 | MessageQueue mSynchronizerQueue; |
76 | QByteArray mResourceType; | ||
77 | QByteArray mResourceInstanceIdentifier; | ||
78 | QSharedPointer<Pipeline> mPipeline; | 77 | QSharedPointer<Pipeline> mPipeline; |
79 | 78 | ||
80 | private: | 79 | private: |
diff --git a/common/index.cpp b/common/index.cpp index beed45c..c864e77 100644 --- a/common/index.cpp +++ b/common/index.cpp | |||
@@ -4,15 +4,15 @@ | |||
4 | 4 | ||
5 | SINK_DEBUG_AREA("index") | 5 | SINK_DEBUG_AREA("index") |
6 | 6 | ||
7 | Index::Index(const QString &storageRoot, const QString &name, Sink::Storage::AccessMode mode) | 7 | Index::Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode) |
8 | : mTransaction(Sink::Storage(storageRoot, name, mode).createTransaction(mode)), | 8 | : mTransaction(Sink::Storage::DataStore(storageRoot, name, mode).createTransaction(mode)), |
9 | mDb(mTransaction.openDatabase(name.toLatin1(), std::function<void(const Sink::Storage::Error &)>(), true)), | 9 | mDb(mTransaction.openDatabase(name.toLatin1(), std::function<void(const Sink::Storage::DataStore::Error &)>(), true)), |
10 | mName(name) | 10 | mName(name) |
11 | { | 11 | { |
12 | } | 12 | } |
13 | 13 | ||
14 | Index::Index(const QByteArray &name, Sink::Storage::Transaction &transaction) | 14 | Index::Index(const QByteArray &name, Sink::Storage::DataStore::Transaction &transaction) |
15 | : mDb(transaction.openDatabase(name, std::function<void(const Sink::Storage::Error &)>(), true)), mName(name) | 15 | : mDb(transaction.openDatabase(name, std::function<void(const Sink::Storage::DataStore::Error &)>(), true)), mName(name) |
16 | { | 16 | { |
17 | } | 17 | } |
18 | 18 | ||
@@ -33,7 +33,7 @@ void Index::lookup(const QByteArray &key, const std::function<void(const QByteAr | |||
33 | resultHandler(value); | 33 | resultHandler(value); |
34 | return true; | 34 | return true; |
35 | }, | 35 | }, |
36 | [this, errorHandler](const Sink::Storage::Error &error) { | 36 | [this, errorHandler](const Sink::Storage::DataStore::Error &error) { |
37 | SinkWarning() << "Error while retrieving value" << error.message; | 37 | SinkWarning() << "Error while retrieving value" << error.message; |
38 | errorHandler(Error(error.store, error.code, error.message)); | 38 | errorHandler(Error(error.store, error.code, error.message)); |
39 | }, | 39 | }, |
diff --git a/common/index.h b/common/index.h index bfedf9a..cfcc7a0 100644 --- a/common/index.h +++ b/common/index.h | |||
@@ -29,8 +29,8 @@ public: | |||
29 | int code; | 29 | int code; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | Index(const QString &storageRoot, const QString &name, Sink::Storage::AccessMode mode = Sink::Storage::ReadOnly); | 32 | Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly); |
33 | Index(const QByteArray &name, Sink::Storage::Transaction &); | 33 | Index(const QByteArray &name, Sink::Storage::DataStore::Transaction &); |
34 | 34 | ||
35 | void add(const QByteArray &key, const QByteArray &value); | 35 | void add(const QByteArray &key, const QByteArray &value); |
36 | void remove(const QByteArray &key, const QByteArray &value); | 36 | void remove(const QByteArray &key, const QByteArray &value); |
@@ -41,8 +41,8 @@ public: | |||
41 | 41 | ||
42 | private: | 42 | private: |
43 | Q_DISABLE_COPY(Index); | 43 | Q_DISABLE_COPY(Index); |
44 | Sink::Storage::Transaction mTransaction; | 44 | Sink::Storage::DataStore::Transaction mTransaction; |
45 | Sink::Storage::NamedDatabase mDb; | 45 | Sink::Storage::DataStore::NamedDatabase mDb; |
46 | QString mName; | 46 | QString mName; |
47 | SINK_DEBUG_COMPONENT(mName.toLatin1()) | 47 | SINK_DEBUG_COMPONENT(mName.toLatin1()) |
48 | }; | 48 | }; |
diff --git a/common/indexupdater.h b/common/indexupdater.h index 79499c3..221a4ed 100644 --- a/common/indexupdater.h +++ b/common/indexupdater.h | |||
@@ -28,32 +28,32 @@ public: | |||
28 | { | 28 | { |
29 | } | 29 | } |
30 | 30 | ||
31 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 31 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
32 | { | 32 | { |
33 | add(newEntity.getProperty(mProperty), uid, transaction); | 33 | add(newEntity.getProperty(mProperty), uid, transaction); |
34 | } | 34 | } |
35 | 35 | ||
36 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 36 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
37 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 37 | Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
38 | { | 38 | { |
39 | remove(oldEntity.getProperty(mProperty), uid, transaction); | 39 | remove(oldEntity.getProperty(mProperty), uid, transaction); |
40 | add(newEntity.getProperty(mProperty), uid, transaction); | 40 | add(newEntity.getProperty(mProperty), uid, transaction); |
41 | } | 41 | } |
42 | 42 | ||
43 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 43 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
44 | { | 44 | { |
45 | remove(oldEntity.getProperty(mProperty), uid, transaction); | 45 | remove(oldEntity.getProperty(mProperty), uid, transaction); |
46 | } | 46 | } |
47 | 47 | ||
48 | private: | 48 | private: |
49 | void add(const QVariant &value, const QByteArray &uid, Sink::Storage::Transaction &transaction) | 49 | void add(const QVariant &value, const QByteArray &uid, Sink::Storage::DataStore::Transaction &transaction) |
50 | { | 50 | { |
51 | if (value.isValid()) { | 51 | if (value.isValid()) { |
52 | Index(mIndexIdentifier, transaction).add(value.toByteArray(), uid); | 52 | Index(mIndexIdentifier, transaction).add(value.toByteArray(), uid); |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | void remove(const QVariant &value, const QByteArray &uid, Sink::Storage::Transaction &transaction) | 56 | void remove(const QVariant &value, const QByteArray &uid, Sink::Storage::DataStore::Transaction &transaction) |
57 | { | 57 | { |
58 | if (value.isValid()) { | 58 | if (value.isValid()) { |
59 | const auto data = value.toByteArray(); | 59 | const auto data = value.toByteArray(); |
@@ -72,19 +72,19 @@ template <typename DomainType> | |||
72 | class DefaultIndexUpdater : public Sink::Preprocessor | 72 | class DefaultIndexUpdater : public Sink::Preprocessor |
73 | { | 73 | { |
74 | public: | 74 | public: |
75 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 75 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
76 | { | 76 | { |
77 | Sink::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction); | 77 | Sink::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction); |
78 | } | 78 | } |
79 | 79 | ||
80 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 80 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
81 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 81 | Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
82 | { | 82 | { |
83 | Sink::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction); | 83 | Sink::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction); |
84 | Sink::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction); | 84 | Sink::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction); |
85 | } | 85 | } |
86 | 86 | ||
87 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 87 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
88 | { | 88 | { |
89 | Sink::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction); | 89 | Sink::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction); |
90 | } | 90 | } |
diff --git a/common/listener.cpp b/common/listener.cpp index 1a8f392..0742017 100644 --- a/common/listener.cpp +++ b/common/listener.cpp | |||
@@ -23,6 +23,8 @@ | |||
23 | #include "common/resource.h" | 23 | #include "common/resource.h" |
24 | #include "common/log.h" | 24 | #include "common/log.h" |
25 | #include "common/definitions.h" | 25 | #include "common/definitions.h" |
26 | #include "common/resourcecontext.h" | ||
27 | #include "common/adaptorfactoryregistry.h" | ||
26 | 28 | ||
27 | // commands | 29 | // commands |
28 | #include "common/commandcompletion_generated.h" | 30 | #include "common/commandcompletion_generated.h" |
@@ -455,8 +457,8 @@ void Listener::notify(const Sink::Notification ¬ification) | |||
455 | Sink::Resource &Listener::loadResource() | 457 | Sink::Resource &Listener::loadResource() |
456 | { | 458 | { |
457 | if (!m_resource) { | 459 | if (!m_resource) { |
458 | if (Sink::ResourceFactory *resourceFactory = Sink::ResourceFactory::load(m_resourceName)) { | 460 | if (auto resourceFactory = Sink::ResourceFactory::load(m_resourceName)) { |
459 | m_resource = std::unique_ptr<Sink::Resource>(resourceFactory->createResource(m_resourceInstanceIdentifier)); | 461 | m_resource = std::unique_ptr<Sink::Resource>(resourceFactory->createResource(Sink::ResourceContext{m_resourceInstanceIdentifier, m_resourceName, Sink::AdaptorFactoryRegistry::instance().getFactories(m_resourceName)})); |
460 | if (!m_resource) { | 462 | if (!m_resource) { |
461 | SinkError() << "Failed to instantiate the resource " << m_resourceName; | 463 | SinkError() << "Failed to instantiate the resource " << m_resourceName; |
462 | m_resource = std::unique_ptr<Sink::Resource>(new Sink::Resource); | 464 | m_resource = std::unique_ptr<Sink::Resource>(new Sink::Resource); |
diff --git a/common/mailpreprocessor.cpp b/common/mailpreprocessor.cpp index ec5748f..b978323 100644 --- a/common/mailpreprocessor.cpp +++ b/common/mailpreprocessor.cpp | |||
@@ -116,7 +116,7 @@ static void updatedIndexedProperties(Sink::ApplicationDomain::Mail &mail, KMime: | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | void MailPropertyExtractor::newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) | 119 | void MailPropertyExtractor::newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) |
120 | { | 120 | { |
121 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(mail.getMimeMessagePath())); | 121 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(mail.getMimeMessagePath())); |
122 | auto msg = mimeMessageReader.mimeMessage(); | 122 | auto msg = mimeMessageReader.mimeMessage(); |
@@ -125,7 +125,7 @@ void MailPropertyExtractor::newEntity(Sink::ApplicationDomain::Mail &mail, Sink: | |||
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | void MailPropertyExtractor::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail,Sink::Storage::Transaction &transaction) | 128 | void MailPropertyExtractor::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail,Sink::Storage::DataStore::Transaction &transaction) |
129 | { | 129 | { |
130 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(newMail.getMimeMessagePath())); | 130 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(newMail.getMimeMessagePath())); |
131 | auto msg = mimeMessageReader.mimeMessage(); | 131 | auto msg = mimeMessageReader.mimeMessage(); |
@@ -161,21 +161,21 @@ QString MimeMessageMover::moveMessage(const QString &oldPath, const Sink::Applic | |||
161 | return oldPath; | 161 | return oldPath; |
162 | } | 162 | } |
163 | 163 | ||
164 | void MimeMessageMover::newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) | 164 | void MimeMessageMover::newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) |
165 | { | 165 | { |
166 | if (!mail.getMimeMessagePath().isEmpty()) { | 166 | if (!mail.getMimeMessagePath().isEmpty()) { |
167 | mail.setMimeMessagePath(moveMessage(mail.getMimeMessagePath(), mail)); | 167 | mail.setMimeMessagePath(moveMessage(mail.getMimeMessagePath(), mail)); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | void MimeMessageMover::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::Transaction &transaction) | 171 | void MimeMessageMover::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::DataStore::Transaction &transaction) |
172 | { | 172 | { |
173 | if (!newMail.getMimeMessagePath().isEmpty()) { | 173 | if (!newMail.getMimeMessagePath().isEmpty()) { |
174 | newMail.setMimeMessagePath(moveMessage(newMail.getMimeMessagePath(), newMail)); | 174 | newMail.setMimeMessagePath(moveMessage(newMail.getMimeMessagePath(), newMail)); |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | void MimeMessageMover::deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) | 178 | void MimeMessageMover::deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) |
179 | { | 179 | { |
180 | QFile::remove(mail.getMimeMessagePath()); | 180 | QFile::remove(mail.getMimeMessagePath()); |
181 | } | 181 | } |
diff --git a/common/mailpreprocessor.h b/common/mailpreprocessor.h index b7cd0e7..c66517e 100644 --- a/common/mailpreprocessor.h +++ b/common/mailpreprocessor.h | |||
@@ -24,8 +24,8 @@ class SINK_EXPORT MailPropertyExtractor : public Sink::EntityPreprocessor<Sink:: | |||
24 | { | 24 | { |
25 | public: | 25 | public: |
26 | virtual ~MailPropertyExtractor(){} | 26 | virtual ~MailPropertyExtractor(){} |
27 | virtual void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 27 | virtual void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
28 | virtual void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail,Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 28 | virtual void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail,Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
29 | protected: | 29 | protected: |
30 | virtual QString getFilePathFromMimeMessagePath(const QString &) const; | 30 | virtual QString getFilePathFromMimeMessagePath(const QString &) const; |
31 | }; | 31 | }; |
@@ -36,9 +36,9 @@ public: | |||
36 | MimeMessageMover(); | 36 | MimeMessageMover(); |
37 | virtual ~MimeMessageMover(){} | 37 | virtual ~MimeMessageMover(){} |
38 | 38 | ||
39 | void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 39 | void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
40 | void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 40 | void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
41 | void deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 41 | void deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
42 | 42 | ||
43 | private: | 43 | private: |
44 | QString moveMessage(const QString &oldPath, const Sink::ApplicationDomain::Mail &mail); | 44 | QString moveMessage(const QString &oldPath, const Sink::ApplicationDomain::Mail &mail); |
diff --git a/common/messagequeue.cpp b/common/messagequeue.cpp index e050bcd..0fcbf99 100644 --- a/common/messagequeue.cpp +++ b/common/messagequeue.cpp | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | SINK_DEBUG_AREA("messagequeue") | 6 | SINK_DEBUG_AREA("messagequeue") |
7 | 7 | ||
8 | MessageQueue::MessageQueue(const QString &storageRoot, const QString &name) : mStorage(storageRoot, name, Sink::Storage::ReadWrite) | 8 | MessageQueue::MessageQueue(const QString &storageRoot, const QString &name) : mStorage(storageRoot, name, Sink::Storage::DataStore::ReadWrite) |
9 | { | 9 | { |
10 | } | 10 | } |
11 | 11 | ||
@@ -27,13 +27,13 @@ void MessageQueue::startTransaction() | |||
27 | return; | 27 | return; |
28 | } | 28 | } |
29 | processRemovals(); | 29 | processRemovals(); |
30 | mWriteTransaction = mStorage.createTransaction(Sink::Storage::ReadWrite); | 30 | mWriteTransaction = mStorage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
31 | } | 31 | } |
32 | 32 | ||
33 | void MessageQueue::commit() | 33 | void MessageQueue::commit() |
34 | { | 34 | { |
35 | mWriteTransaction.commit(); | 35 | mWriteTransaction.commit(); |
36 | mWriteTransaction = Sink::Storage::Transaction(); | 36 | mWriteTransaction = Sink::Storage::DataStore::Transaction(); |
37 | processRemovals(); | 37 | processRemovals(); |
38 | emit messageReady(); | 38 | emit messageReady(); |
39 | } | 39 | } |
@@ -45,10 +45,10 @@ void MessageQueue::enqueue(const QByteArray &value) | |||
45 | implicitTransaction = true; | 45 | implicitTransaction = true; |
46 | startTransaction(); | 46 | startTransaction(); |
47 | } | 47 | } |
48 | const qint64 revision = Sink::Storage::maxRevision(mWriteTransaction) + 1; | 48 | const qint64 revision = Sink::Storage::DataStore::maxRevision(mWriteTransaction) + 1; |
49 | const QByteArray key = QString("%1").arg(revision).toUtf8(); | 49 | const QByteArray key = QString("%1").arg(revision).toUtf8(); |
50 | mWriteTransaction.openDatabase().write(key, value); | 50 | mWriteTransaction.openDatabase().write(key, value); |
51 | Sink::Storage::setMaxRevision(mWriteTransaction, revision); | 51 | Sink::Storage::DataStore::setMaxRevision(mWriteTransaction, revision); |
52 | if (implicitTransaction) { | 52 | if (implicitTransaction) { |
53 | commit(); | 53 | commit(); |
54 | } | 54 | } |
@@ -59,7 +59,7 @@ void MessageQueue::processRemovals() | |||
59 | if (mWriteTransaction) { | 59 | if (mWriteTransaction) { |
60 | return; | 60 | return; |
61 | } | 61 | } |
62 | auto transaction = mStorage.createTransaction(Sink::Storage::ReadWrite); | 62 | auto transaction = mStorage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
63 | for (const auto &key : mPendingRemoval) { | 63 | for (const auto &key : mPendingRemoval) { |
64 | transaction.openDatabase().remove(key); | 64 | transaction.openDatabase().remove(key); |
65 | } | 65 | } |
@@ -82,7 +82,7 @@ KAsync::Job<void> MessageQueue::dequeueBatch(int maxBatchSize, const std::functi | |||
82 | return KAsync::start<void>([this, maxBatchSize, resultHandler, resultCount](KAsync::Future<void> &future) { | 82 | return KAsync::start<void>([this, maxBatchSize, resultHandler, resultCount](KAsync::Future<void> &future) { |
83 | int count = 0; | 83 | int count = 0; |
84 | QList<KAsync::Future<void>> waitCondition; | 84 | QList<KAsync::Future<void>> waitCondition; |
85 | mStorage.createTransaction(Sink::Storage::ReadOnly) | 85 | mStorage.createTransaction(Sink::Storage::DataStore::ReadOnly) |
86 | .openDatabase() | 86 | .openDatabase() |
87 | .scan("", | 87 | .scan("", |
88 | [this, resultHandler, resultCount, &count, maxBatchSize, &waitCondition](const QByteArray &key, const QByteArray &value) -> bool { | 88 | [this, resultHandler, resultCount, &count, maxBatchSize, &waitCondition](const QByteArray &key, const QByteArray &value) -> bool { |
@@ -101,7 +101,7 @@ KAsync::Job<void> MessageQueue::dequeueBatch(int maxBatchSize, const std::functi | |||
101 | } | 101 | } |
102 | return false; | 102 | return false; |
103 | }, | 103 | }, |
104 | [](const Sink::Storage::Error &error) { | 104 | [](const Sink::Storage::DataStore::Error &error) { |
105 | SinkError() << "Error while retrieving value" << error.message; | 105 | SinkError() << "Error while retrieving value" << error.message; |
106 | // errorHandler(Error(error.store, error.code, error.message)); | 106 | // errorHandler(Error(error.store, error.code, error.message)); |
107 | }); | 107 | }); |
@@ -126,7 +126,7 @@ KAsync::Job<void> MessageQueue::dequeueBatch(int maxBatchSize, const std::functi | |||
126 | bool MessageQueue::isEmpty() | 126 | bool MessageQueue::isEmpty() |
127 | { | 127 | { |
128 | int count = 0; | 128 | int count = 0; |
129 | auto t = mStorage.createTransaction(Sink::Storage::ReadOnly); | 129 | auto t = mStorage.createTransaction(Sink::Storage::DataStore::ReadOnly); |
130 | auto db = t.openDatabase(); | 130 | auto db = t.openDatabase(); |
131 | if (db) { | 131 | if (db) { |
132 | db.scan("", | 132 | db.scan("", |
@@ -137,7 +137,7 @@ bool MessageQueue::isEmpty() | |||
137 | } | 137 | } |
138 | return true; | 138 | return true; |
139 | }, | 139 | }, |
140 | [](const Sink::Storage::Error &error) { SinkError() << "Error while checking if empty" << error.message; }); | 140 | [](const Sink::Storage::DataStore::Error &error) { SinkError() << "Error while checking if empty" << error.message; }); |
141 | } | 141 | } |
142 | return count == 0; | 142 | return count == 0; |
143 | } | 143 | } |
diff --git a/common/messagequeue.h b/common/messagequeue.h index 6f0bddb..f23ddcf 100644 --- a/common/messagequeue.h +++ b/common/messagequeue.h | |||
@@ -56,7 +56,7 @@ private slots: | |||
56 | 56 | ||
57 | private: | 57 | private: |
58 | Q_DISABLE_COPY(MessageQueue); | 58 | Q_DISABLE_COPY(MessageQueue); |
59 | Sink::Storage mStorage; | 59 | Sink::Storage::DataStore mStorage; |
60 | Sink::Storage::Transaction mWriteTransaction; | 60 | Sink::Storage::DataStore::Transaction mWriteTransaction; |
61 | QByteArrayList mPendingRemoval; | 61 | QByteArrayList mPendingRemoval; |
62 | }; | 62 | }; |
diff --git a/common/pipeline.cpp b/common/pipeline.cpp index ce864f7..e257857 100644 --- a/common/pipeline.cpp +++ b/common/pipeline.cpp | |||
@@ -40,45 +40,45 @@ | |||
40 | 40 | ||
41 | SINK_DEBUG_AREA("pipeline") | 41 | SINK_DEBUG_AREA("pipeline") |
42 | 42 | ||
43 | namespace Sink { | 43 | using namespace Sink; |
44 | using namespace Sink::Storage; | ||
44 | 45 | ||
45 | class Pipeline::Private | 46 | class Pipeline::Private |
46 | { | 47 | { |
47 | public: | 48 | public: |
48 | Private(const QString &resourceName) : storage(Sink::storageLocation(), resourceName, Storage::ReadWrite), revisionChanged(false), resourceInstanceIdentifier(resourceName.toUtf8()) | 49 | Private(const ResourceContext &context) : resourceContext(context), storage(Sink::storageLocation(), context.instanceId(), DataStore::ReadWrite), revisionChanged(false) |
49 | { | 50 | { |
50 | } | 51 | } |
51 | 52 | ||
52 | Storage storage; | 53 | ResourceContext resourceContext; |
53 | Storage::Transaction transaction; | 54 | DataStore storage; |
55 | DataStore::Transaction transaction; | ||
54 | QHash<QString, QVector<QSharedPointer<Preprocessor>>> processors; | 56 | QHash<QString, QVector<QSharedPointer<Preprocessor>>> processors; |
55 | bool revisionChanged; | 57 | bool revisionChanged; |
56 | void storeNewRevision(qint64 newRevision, const flatbuffers::FlatBufferBuilder &fbb, const QByteArray &bufferType, const QByteArray &uid); | 58 | void storeNewRevision(qint64 newRevision, const flatbuffers::FlatBufferBuilder &fbb, const QByteArray &bufferType, const QByteArray &uid); |
57 | QTime transactionTime; | 59 | QTime transactionTime; |
58 | int transactionItemCount; | 60 | int transactionItemCount; |
59 | QByteArray resourceType; | ||
60 | QByteArray resourceInstanceIdentifier; | ||
61 | }; | 61 | }; |
62 | 62 | ||
63 | void Pipeline::Private::storeNewRevision(qint64 newRevision, const flatbuffers::FlatBufferBuilder &fbb, const QByteArray &bufferType, const QByteArray &uid) | 63 | void Pipeline::Private::storeNewRevision(qint64 newRevision, const flatbuffers::FlatBufferBuilder &fbb, const QByteArray &bufferType, const QByteArray &uid) |
64 | { | 64 | { |
65 | SinkTrace() << "Committing new revision: " << uid << newRevision; | 65 | SinkTrace() << "Committing new revision: " << uid << newRevision; |
66 | Storage::mainDatabase(transaction, bufferType) | 66 | DataStore::mainDatabase(transaction, bufferType) |
67 | .write(Storage::assembleKey(uid, newRevision), BufferUtils::extractBuffer(fbb), | 67 | .write(DataStore::assembleKey(uid, newRevision), BufferUtils::extractBuffer(fbb), |
68 | [uid, newRevision](const Storage::Error &error) { SinkWarning() << "Failed to write entity" << uid << newRevision; }); | 68 | [uid, newRevision](const DataStore::Error &error) { SinkWarning() << "Failed to write entity" << uid << newRevision; }); |
69 | revisionChanged = true; | 69 | revisionChanged = true; |
70 | Storage::setMaxRevision(transaction, newRevision); | 70 | DataStore::setMaxRevision(transaction, newRevision); |
71 | Storage::recordRevision(transaction, newRevision, uid, bufferType); | 71 | DataStore::recordRevision(transaction, newRevision, uid, bufferType); |
72 | } | 72 | } |
73 | 73 | ||
74 | 74 | ||
75 | Pipeline::Pipeline(const QString &resourceName, QObject *parent) : QObject(parent), d(new Private(resourceName)) | 75 | Pipeline::Pipeline(const ResourceContext &context) : QObject(nullptr), d(new Private(context)) |
76 | { | 76 | { |
77 | } | 77 | } |
78 | 78 | ||
79 | Pipeline::~Pipeline() | 79 | Pipeline::~Pipeline() |
80 | { | 80 | { |
81 | d->transaction = Storage::Transaction(); | 81 | d->transaction = DataStore::Transaction(); |
82 | } | 82 | } |
83 | 83 | ||
84 | void Pipeline::setPreprocessors(const QString &entityType, const QVector<Preprocessor *> &processors) | 84 | void Pipeline::setPreprocessors(const QString &entityType, const QVector<Preprocessor *> &processors) |
@@ -86,16 +86,11 @@ void Pipeline::setPreprocessors(const QString &entityType, const QVector<Preproc | |||
86 | auto &list = d->processors[entityType]; | 86 | auto &list = d->processors[entityType]; |
87 | list.clear(); | 87 | list.clear(); |
88 | for (auto p : processors) { | 88 | for (auto p : processors) { |
89 | p->setup(d->resourceType, d->resourceInstanceIdentifier, this); | 89 | p->setup(d->resourceContext.resourceType, d->resourceContext.instanceId(), this); |
90 | list.append(QSharedPointer<Preprocessor>(p)); | 90 | list.append(QSharedPointer<Preprocessor>(p)); |
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | void Pipeline::setResourceType(const QByteArray &resourceType) | ||
95 | { | ||
96 | d->resourceType = resourceType; | ||
97 | } | ||
98 | |||
99 | void Pipeline::startTransaction() | 94 | void Pipeline::startTransaction() |
100 | { | 95 | { |
101 | // TODO call for all types | 96 | // TODO call for all types |
@@ -109,7 +104,7 @@ void Pipeline::startTransaction() | |||
109 | SinkTrace() << "Starting transaction."; | 104 | SinkTrace() << "Starting transaction."; |
110 | d->transactionTime.start(); | 105 | d->transactionTime.start(); |
111 | d->transactionItemCount = 0; | 106 | d->transactionItemCount = 0; |
112 | d->transaction = storage().createTransaction(Storage::ReadWrite, [](const Sink::Storage::Error &error) { | 107 | d->transaction = storage().createTransaction(DataStore::ReadWrite, [](const DataStore::Error &error) { |
113 | SinkWarning() << error.message; | 108 | SinkWarning() << error.message; |
114 | }); | 109 | }); |
115 | 110 | ||
@@ -119,7 +114,7 @@ void Pipeline::startTransaction() | |||
119 | if (d->storage.exists()) { | 114 | if (d->storage.exists()) { |
120 | while (!d->transaction.validateNamedDatabases()) { | 115 | while (!d->transaction.validateNamedDatabases()) { |
121 | SinkWarning() << "Opened an invalid transaction!!!!!!"; | 116 | SinkWarning() << "Opened an invalid transaction!!!!!!"; |
122 | d->transaction = storage().createTransaction(Storage::ReadWrite, [](const Sink::Storage::Error &error) { | 117 | d->transaction = storage().createTransaction(DataStore::ReadWrite, [](const DataStore::Error &error) { |
123 | SinkWarning() << error.message; | 118 | SinkWarning() << error.message; |
124 | }); | 119 | }); |
125 | } | 120 | } |
@@ -135,29 +130,29 @@ void Pipeline::commit() | |||
135 | // } | 130 | // } |
136 | if (!d->revisionChanged) { | 131 | if (!d->revisionChanged) { |
137 | d->transaction.abort(); | 132 | d->transaction.abort(); |
138 | d->transaction = Storage::Transaction(); | 133 | d->transaction = DataStore::Transaction(); |
139 | return; | 134 | return; |
140 | } | 135 | } |
141 | const auto revision = Storage::maxRevision(d->transaction); | 136 | const auto revision = DataStore::maxRevision(d->transaction); |
142 | const auto elapsed = d->transactionTime.elapsed(); | 137 | const auto elapsed = d->transactionTime.elapsed(); |
143 | SinkLog() << "Committing revision: " << revision << ":" << d->transactionItemCount << " items in: " << Log::TraceTime(elapsed) << " " | 138 | SinkLog() << "Committing revision: " << revision << ":" << d->transactionItemCount << " items in: " << Log::TraceTime(elapsed) << " " |
144 | << (double)elapsed / (double)qMax(d->transactionItemCount, 1) << "[ms/item]"; | 139 | << (double)elapsed / (double)qMax(d->transactionItemCount, 1) << "[ms/item]"; |
145 | if (d->transaction) { | 140 | if (d->transaction) { |
146 | d->transaction.commit(); | 141 | d->transaction.commit(); |
147 | } | 142 | } |
148 | d->transaction = Storage::Transaction(); | 143 | d->transaction = DataStore::Transaction(); |
149 | if (d->revisionChanged) { | 144 | if (d->revisionChanged) { |
150 | d->revisionChanged = false; | 145 | d->revisionChanged = false; |
151 | emit revisionUpdated(revision); | 146 | emit revisionUpdated(revision); |
152 | } | 147 | } |
153 | } | 148 | } |
154 | 149 | ||
155 | Storage::Transaction &Pipeline::transaction() | 150 | DataStore::Transaction &Pipeline::transaction() |
156 | { | 151 | { |
157 | return d->transaction; | 152 | return d->transaction; |
158 | } | 153 | } |
159 | 154 | ||
160 | Storage &Pipeline::storage() const | 155 | DataStore &Pipeline::storage() const |
161 | { | 156 | { |
162 | return d->storage; | 157 | return d->storage; |
163 | } | 158 | } |
@@ -180,14 +175,14 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, size_t size) | |||
180 | QByteArray key; | 175 | QByteArray key; |
181 | if (createEntity->entityId()) { | 176 | if (createEntity->entityId()) { |
182 | key = QByteArray(reinterpret_cast<char const *>(createEntity->entityId()->Data()), createEntity->entityId()->size()); | 177 | key = QByteArray(reinterpret_cast<char const *>(createEntity->entityId()->Data()), createEntity->entityId()->size()); |
183 | if (Storage::mainDatabase(d->transaction, bufferType).contains(key)) { | 178 | if (DataStore::mainDatabase(d->transaction, bufferType).contains(key)) { |
184 | SinkError() << "An entity with this id already exists: " << key; | 179 | SinkError() << "An entity with this id already exists: " << key; |
185 | return KAsync::error<qint64>(0); | 180 | return KAsync::error<qint64>(0); |
186 | } | 181 | } |
187 | } | 182 | } |
188 | 183 | ||
189 | if (key.isEmpty()) { | 184 | if (key.isEmpty()) { |
190 | key = Sink::Storage::generateUid(); | 185 | key = DataStore::generateUid(); |
191 | } | 186 | } |
192 | SinkTrace() << "New Entity. Type: " << bufferType << "uid: "<< key << " replayToSource: " << replayToSource; | 187 | SinkTrace() << "New Entity. Type: " << bufferType << "uid: "<< key << " replayToSource: " << replayToSource; |
193 | Q_ASSERT(!key.isEmpty()); | 188 | Q_ASSERT(!key.isEmpty()); |
@@ -205,7 +200,7 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, size_t size) | |||
205 | return KAsync::error<qint64>(0); | 200 | return KAsync::error<qint64>(0); |
206 | } | 201 | } |
207 | 202 | ||
208 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceType, bufferType); | 203 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceContext.resourceType, bufferType); |
209 | if (!adaptorFactory) { | 204 | if (!adaptorFactory) { |
210 | SinkWarning() << "no adaptor factory for type " << bufferType; | 205 | SinkWarning() << "no adaptor factory for type " << bufferType; |
211 | return KAsync::error<qint64>(0); | 206 | return KAsync::error<qint64>(0); |
@@ -214,10 +209,10 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, size_t size) | |||
214 | auto adaptor = adaptorFactory->createAdaptor(*entity); | 209 | auto adaptor = adaptorFactory->createAdaptor(*entity); |
215 | auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(*(adaptor), adaptor->availableProperties()); | 210 | auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(*(adaptor), adaptor->availableProperties()); |
216 | foreach (const auto &processor, d->processors[bufferType]) { | 211 | foreach (const auto &processor, d->processors[bufferType]) { |
217 | processor->newEntity(key, Storage::maxRevision(d->transaction) + 1, *memoryAdaptor, d->transaction); | 212 | processor->newEntity(key, DataStore::maxRevision(d->transaction) + 1, *memoryAdaptor, d->transaction); |
218 | } | 213 | } |
219 | //The maxRevision may have changed meanwhile if the entity created sub-entities | 214 | //The maxRevision may have changed meanwhile if the entity created sub-entities |
220 | const qint64 newRevision = Storage::maxRevision(d->transaction) + 1; | 215 | const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; |
221 | 216 | ||
222 | // Add metadata buffer | 217 | // Add metadata buffer |
223 | flatbuffers::FlatBufferBuilder metadataFbb; | 218 | flatbuffers::FlatBufferBuilder metadataFbb; |
@@ -233,6 +228,8 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, size_t size) | |||
233 | 228 | ||
234 | d->storeNewRevision(newRevision, fbb, bufferType, key); | 229 | d->storeNewRevision(newRevision, fbb, bufferType, key); |
235 | 230 | ||
231 | //FIXME entityStore->create(bufferType, memoryAdaptor, replayToSource) | ||
232 | |||
236 | return KAsync::value(newRevision); | 233 | return KAsync::value(newRevision); |
237 | } | 234 | } |
238 | 235 | ||
@@ -273,7 +270,7 @@ KAsync::Job<qint64> Pipeline::modifiedEntity(void const *command, size_t size) | |||
273 | } | 270 | } |
274 | 271 | ||
275 | // TODO use only readPropertyMapper and writePropertyMapper | 272 | // TODO use only readPropertyMapper and writePropertyMapper |
276 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceType, bufferType); | 273 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceContext.resourceType, bufferType); |
277 | if (!adaptorFactory) { | 274 | if (!adaptorFactory) { |
278 | SinkWarning() << "no adaptor factory for type " << bufferType; | 275 | SinkWarning() << "no adaptor factory for type " << bufferType; |
279 | return KAsync::error<qint64>(0); | 276 | return KAsync::error<qint64>(0); |
@@ -284,7 +281,7 @@ KAsync::Job<qint64> Pipeline::modifiedEntity(void const *command, size_t size) | |||
284 | auto diff = adaptorFactory->createAdaptor(*diffEntity); | 281 | auto diff = adaptorFactory->createAdaptor(*diffEntity); |
285 | 282 | ||
286 | QSharedPointer<ApplicationDomain::BufferAdaptor> current; | 283 | QSharedPointer<ApplicationDomain::BufferAdaptor> current; |
287 | Storage::mainDatabase(d->transaction, bufferType) | 284 | DataStore::mainDatabase(d->transaction, bufferType) |
288 | .findLatest(key, | 285 | .findLatest(key, |
289 | [¤t, adaptorFactory](const QByteArray &key, const QByteArray &data) -> bool { | 286 | [¤t, adaptorFactory](const QByteArray &key, const QByteArray &data) -> bool { |
290 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | 287 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); |
@@ -295,7 +292,7 @@ KAsync::Job<qint64> Pipeline::modifiedEntity(void const *command, size_t size) | |||
295 | } | 292 | } |
296 | return false; | 293 | return false; |
297 | }, | 294 | }, |
298 | [baseRevision](const Storage::Error &error) { SinkWarning() << "Failed to read old revision from storage: " << error.message << "Revision: " << baseRevision; }); | 295 | [baseRevision](const DataStore::Error &error) { SinkWarning() << "Failed to read old revision from storage: " << error.message << "Revision: " << baseRevision; }); |
299 | 296 | ||
300 | if (!current) { | 297 | if (!current) { |
301 | SinkWarning() << "Failed to read local value " << key; | 298 | SinkWarning() << "Failed to read local value " << key; |
@@ -323,10 +320,10 @@ KAsync::Job<qint64> Pipeline::modifiedEntity(void const *command, size_t size) | |||
323 | 320 | ||
324 | newAdaptor->resetChangedProperties(); | 321 | newAdaptor->resetChangedProperties(); |
325 | foreach (const auto &processor, d->processors[bufferType]) { | 322 | foreach (const auto &processor, d->processors[bufferType]) { |
326 | processor->modifiedEntity(key, Storage::maxRevision(d->transaction) + 1, *current, *newAdaptor, d->transaction); | 323 | processor->modifiedEntity(key, DataStore::maxRevision(d->transaction) + 1, *current, *newAdaptor, d->transaction); |
327 | } | 324 | } |
328 | //The maxRevision may have changed meanwhile if the entity created sub-entities | 325 | //The maxRevision may have changed meanwhile if the entity created sub-entities |
329 | const qint64 newRevision = Storage::maxRevision(d->transaction) + 1; | 326 | const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; |
330 | 327 | ||
331 | // Add metadata buffer | 328 | // Add metadata buffer |
332 | flatbuffers::FlatBufferBuilder metadataFbb; | 329 | flatbuffers::FlatBufferBuilder metadataFbb; |
@@ -369,7 +366,7 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
369 | 366 | ||
370 | bool found = false; | 367 | bool found = false; |
371 | bool alreadyRemoved = false; | 368 | bool alreadyRemoved = false; |
372 | Storage::mainDatabase(d->transaction, bufferType) | 369 | DataStore::mainDatabase(d->transaction, bufferType) |
373 | .findLatest(key, | 370 | .findLatest(key, |
374 | [&found, &alreadyRemoved](const QByteArray &key, const QByteArray &data) -> bool { | 371 | [&found, &alreadyRemoved](const QByteArray &key, const QByteArray &data) -> bool { |
375 | auto entity = GetEntity(data.data()); | 372 | auto entity = GetEntity(data.data()); |
@@ -382,7 +379,7 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
382 | } | 379 | } |
383 | return false; | 380 | return false; |
384 | }, | 381 | }, |
385 | [](const Storage::Error &error) { SinkWarning() << "Failed to read old revision from storage: " << error.message; }); | 382 | [](const DataStore::Error &error) { SinkWarning() << "Failed to read old revision from storage: " << error.message; }); |
386 | 383 | ||
387 | if (!found) { | 384 | if (!found) { |
388 | SinkWarning() << "Failed to find entity " << key; | 385 | SinkWarning() << "Failed to find entity " << key; |
@@ -393,7 +390,7 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
393 | return KAsync::error<qint64>(0); | 390 | return KAsync::error<qint64>(0); |
394 | } | 391 | } |
395 | 392 | ||
396 | const qint64 newRevision = Storage::maxRevision(d->transaction) + 1; | 393 | const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; |
397 | 394 | ||
398 | // Add metadata buffer | 395 | // Add metadata buffer |
399 | flatbuffers::FlatBufferBuilder metadataFbb; | 396 | flatbuffers::FlatBufferBuilder metadataFbb; |
@@ -407,14 +404,14 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
407 | flatbuffers::FlatBufferBuilder fbb; | 404 | flatbuffers::FlatBufferBuilder fbb; |
408 | EntityBuffer::assembleEntityBuffer(fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize(), 0, 0, 0, 0); | 405 | EntityBuffer::assembleEntityBuffer(fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize(), 0, 0, 0, 0); |
409 | 406 | ||
410 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceType, bufferType); | 407 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(d->resourceContext.resourceType, bufferType); |
411 | if (!adaptorFactory) { | 408 | if (!adaptorFactory) { |
412 | SinkWarning() << "no adaptor factory for type " << bufferType; | 409 | SinkWarning() << "no adaptor factory for type " << bufferType; |
413 | return KAsync::error<qint64>(0); | 410 | return KAsync::error<qint64>(0); |
414 | } | 411 | } |
415 | 412 | ||
416 | QSharedPointer<ApplicationDomain::BufferAdaptor> current; | 413 | QSharedPointer<ApplicationDomain::BufferAdaptor> current; |
417 | Storage::mainDatabase(d->transaction, bufferType) | 414 | DataStore::mainDatabase(d->transaction, bufferType) |
418 | .findLatest(key, | 415 | .findLatest(key, |
419 | [this, bufferType, newRevision, adaptorFactory, key, ¤t](const QByteArray &, const QByteArray &data) -> bool { | 416 | [this, bufferType, newRevision, adaptorFactory, key, ¤t](const QByteArray &, const QByteArray &data) -> bool { |
420 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | 417 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); |
@@ -425,7 +422,7 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
425 | } | 422 | } |
426 | return false; | 423 | return false; |
427 | }, | 424 | }, |
428 | [this](const Storage::Error &error) { SinkError() << "Failed to find value in pipeline: " << error.message; }); | 425 | [this](const DataStore::Error &error) { SinkError() << "Failed to find value in pipeline: " << error.message; }); |
429 | 426 | ||
430 | d->storeNewRevision(newRevision, fbb, bufferType, key); | 427 | d->storeNewRevision(newRevision, fbb, bufferType, key); |
431 | 428 | ||
@@ -439,10 +436,10 @@ KAsync::Job<qint64> Pipeline::deletedEntity(void const *command, size_t size) | |||
439 | void Pipeline::cleanupRevision(qint64 revision) | 436 | void Pipeline::cleanupRevision(qint64 revision) |
440 | { | 437 | { |
441 | d->revisionChanged = true; | 438 | d->revisionChanged = true; |
442 | const auto uid = Storage::getUidFromRevision(d->transaction, revision); | 439 | const auto uid = DataStore::getUidFromRevision(d->transaction, revision); |
443 | const auto bufferType = Storage::getTypeFromRevision(d->transaction, revision); | 440 | const auto bufferType = DataStore::getTypeFromRevision(d->transaction, revision); |
444 | SinkTrace() << "Cleaning up revision " << revision << uid << bufferType; | 441 | SinkTrace() << "Cleaning up revision " << revision << uid << bufferType; |
445 | Storage::mainDatabase(d->transaction, bufferType) | 442 | DataStore::mainDatabase(d->transaction, bufferType) |
446 | .scan(uid, | 443 | .scan(uid, |
447 | [&](const QByteArray &key, const QByteArray &data) -> bool { | 444 | [&](const QByteArray &key, const QByteArray &data) -> bool { |
448 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | 445 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); |
@@ -453,20 +450,20 @@ void Pipeline::cleanupRevision(qint64 revision) | |||
453 | const qint64 rev = metadata->revision(); | 450 | const qint64 rev = metadata->revision(); |
454 | // Remove old revisions, and the current if the entity has already been removed | 451 | // Remove old revisions, and the current if the entity has already been removed |
455 | if (rev < revision || metadata->operation() == Operation_Removal) { | 452 | if (rev < revision || metadata->operation() == Operation_Removal) { |
456 | Storage::removeRevision(d->transaction, rev); | 453 | DataStore::removeRevision(d->transaction, rev); |
457 | Storage::mainDatabase(d->transaction, bufferType).remove(key); | 454 | DataStore::mainDatabase(d->transaction, bufferType).remove(key); |
458 | } | 455 | } |
459 | } | 456 | } |
460 | 457 | ||
461 | return true; | 458 | return true; |
462 | }, | 459 | }, |
463 | [](const Storage::Error &error) { SinkWarning() << "Error while reading: " << error.message; }, true); | 460 | [](const DataStore::Error &error) { SinkWarning() << "Error while reading: " << error.message; }, true); |
464 | Storage::setCleanedUpRevision(d->transaction, revision); | 461 | DataStore::setCleanedUpRevision(d->transaction, revision); |
465 | } | 462 | } |
466 | 463 | ||
467 | qint64 Pipeline::cleanedUpRevision() | 464 | qint64 Pipeline::cleanedUpRevision() |
468 | { | 465 | { |
469 | return Storage::cleanedUpRevision(d->transaction); | 466 | return DataStore::cleanedUpRevision(d->transaction); |
470 | } | 467 | } |
471 | 468 | ||
472 | class Preprocessor::Private { | 469 | class Preprocessor::Private { |
@@ -523,8 +520,6 @@ void Preprocessor::createEntity(const Sink::ApplicationDomain::ApplicationDomain | |||
523 | d->pipeline->newEntity(data, data.size()).exec(); | 520 | d->pipeline->newEntity(data, data.size()).exec(); |
524 | } | 521 | } |
525 | 522 | ||
526 | } // namespace Sink | ||
527 | |||
528 | #pragma clang diagnostic push | 523 | #pragma clang diagnostic push |
529 | #pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" | 524 | #pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" |
530 | #include "moc_pipeline.cpp" | 525 | #include "moc_pipeline.cpp" |
diff --git a/common/pipeline.h b/common/pipeline.h index ef89cf0..bf94017 100644 --- a/common/pipeline.h +++ b/common/pipeline.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> | 2 | * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> |
3 | * Copyright (C) 2015 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | 4 | * |
4 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public | 6 | * modify it under the terms of the GNU Lesser General Public |
@@ -41,16 +42,15 @@ class SINK_EXPORT Pipeline : public QObject | |||
41 | Q_OBJECT | 42 | Q_OBJECT |
42 | 43 | ||
43 | public: | 44 | public: |
44 | Pipeline(const QString &storagePath, QObject *parent = 0); | 45 | Pipeline(const ResourceContext &context); |
45 | ~Pipeline(); | 46 | ~Pipeline(); |
46 | 47 | ||
47 | Storage &storage() const; | 48 | Storage::DataStore &storage() const; |
48 | 49 | ||
49 | void setResourceType(const QByteArray &resourceType); | ||
50 | void setPreprocessors(const QString &entityType, const QVector<Preprocessor *> &preprocessors); | 50 | void setPreprocessors(const QString &entityType, const QVector<Preprocessor *> &preprocessors); |
51 | void startTransaction(); | 51 | void startTransaction(); |
52 | void commit(); | 52 | void commit(); |
53 | Storage::Transaction &transaction(); | 53 | Storage::DataStore::Transaction &transaction(); |
54 | 54 | ||
55 | KAsync::Job<qint64> newEntity(void const *command, size_t size); | 55 | KAsync::Job<qint64> newEntity(void const *command, size_t size); |
56 | KAsync::Job<qint64> modifiedEntity(void const *command, size_t size); | 56 | KAsync::Job<qint64> modifiedEntity(void const *command, size_t size); |
@@ -82,10 +82,10 @@ public: | |||
82 | virtual ~Preprocessor(); | 82 | virtual ~Preprocessor(); |
83 | 83 | ||
84 | virtual void startBatch(); | 84 | virtual void startBatch(); |
85 | virtual void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) {}; | 85 | virtual void newEntity(const QByteArray &uid, qint64 revision, ApplicationDomain::BufferAdaptor &newEntity, Storage::DataStore::Transaction &transaction) {}; |
86 | virtual void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, | 86 | virtual void modifiedEntity(const QByteArray &uid, qint64 revision, const ApplicationDomain::BufferAdaptor &oldEntity, |
87 | Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) {}; | 87 | ApplicationDomain::BufferAdaptor &newEntity, Storage::DataStore::Transaction &transaction) {}; |
88 | virtual void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) {}; | 88 | virtual void deletedEntity(const QByteArray &uid, qint64 revision, const ApplicationDomain::BufferAdaptor &oldEntity, Storage::DataStore::Transaction &transaction) {}; |
89 | virtual void finalize(); | 89 | virtual void finalize(); |
90 | 90 | ||
91 | void setup(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Pipeline *); | 91 | void setup(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier, Pipeline *); |
@@ -94,9 +94,9 @@ protected: | |||
94 | template <typename DomainType> | 94 | template <typename DomainType> |
95 | void createEntity(const DomainType &entity) | 95 | void createEntity(const DomainType &entity) |
96 | { | 96 | { |
97 | createEntity(entity, Sink::ApplicationDomain::getTypeName<DomainType>()); | 97 | createEntity(entity, ApplicationDomain::getTypeName<DomainType>()); |
98 | } | 98 | } |
99 | void createEntity(const Sink::ApplicationDomain::ApplicationDomainType &entity, const QByteArray &type); | 99 | void createEntity(const ApplicationDomain::ApplicationDomainType &entity, const QByteArray &type); |
100 | 100 | ||
101 | QByteArray resourceInstanceIdentifier() const; | 101 | QByteArray resourceInstanceIdentifier() const; |
102 | 102 | ||
@@ -110,27 +110,27 @@ template<typename DomainType> | |||
110 | class SINK_EXPORT EntityPreprocessor: public Preprocessor | 110 | class SINK_EXPORT EntityPreprocessor: public Preprocessor |
111 | { | 111 | { |
112 | public: | 112 | public: |
113 | virtual void newEntity(DomainType &, Sink::Storage::Transaction &transaction) {}; | 113 | virtual void newEntity(DomainType &, Storage::DataStore::Transaction &transaction) {}; |
114 | virtual void modifiedEntity(const DomainType &oldEntity, DomainType &newEntity, Sink::Storage::Transaction &transaction) {}; | 114 | virtual void modifiedEntity(const DomainType &oldEntity, DomainType &newEntity, Storage::DataStore::Transaction &transaction) {}; |
115 | virtual void deletedEntity(const DomainType &oldEntity, Sink::Storage::Transaction &transaction) {}; | 115 | virtual void deletedEntity(const DomainType &oldEntity, Storage::DataStore::Transaction &transaction) {}; |
116 | 116 | ||
117 | private: | 117 | private: |
118 | static void nullDeleter(Sink::ApplicationDomain::BufferAdaptor *) {} | 118 | static void nullDeleter(ApplicationDomain::BufferAdaptor *) {} |
119 | virtual void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 119 | virtual void newEntity(const QByteArray &uid, qint64 revision, ApplicationDomain::BufferAdaptor &bufferAdaptor, Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
120 | { | 120 | { |
121 | auto o = DomainType("", uid, revision, QSharedPointer<Sink::ApplicationDomain::BufferAdaptor>(&bufferAdaptor, nullDeleter)); | 121 | auto o = DomainType("", uid, revision, QSharedPointer<ApplicationDomain::BufferAdaptor>(&bufferAdaptor, nullDeleter)); |
122 | newEntity(o, transaction); | 122 | newEntity(o, transaction); |
123 | } | 123 | } |
124 | 124 | ||
125 | virtual void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, | 125 | virtual void modifiedEntity(const QByteArray &uid, qint64 revision, const ApplicationDomain::BufferAdaptor &oldEntity, |
126 | Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 126 | ApplicationDomain::BufferAdaptor &bufferAdaptor, Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
127 | { | 127 | { |
128 | auto o = DomainType("", uid, revision, QSharedPointer<Sink::ApplicationDomain::BufferAdaptor>(&bufferAdaptor, nullDeleter)); | 128 | auto o = DomainType("", uid, revision, QSharedPointer<ApplicationDomain::BufferAdaptor>(&bufferAdaptor, nullDeleter)); |
129 | modifiedEntity(DomainType("", uid, 0, QSharedPointer<Sink::ApplicationDomain::BufferAdaptor>(const_cast<Sink::ApplicationDomain::BufferAdaptor*>(&oldEntity), nullDeleter)), o, transaction); | 129 | modifiedEntity(DomainType("", uid, 0, QSharedPointer<ApplicationDomain::BufferAdaptor>(const_cast<ApplicationDomain::BufferAdaptor*>(&oldEntity), nullDeleter)), o, transaction); |
130 | } | 130 | } |
131 | virtual void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 131 | virtual void deletedEntity(const QByteArray &uid, qint64 revision, const ApplicationDomain::BufferAdaptor &bufferAdaptor, Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
132 | { | 132 | { |
133 | deletedEntity(DomainType("", uid, revision, QSharedPointer<Sink::ApplicationDomain::BufferAdaptor>(const_cast<Sink::ApplicationDomain::BufferAdaptor*>(&bufferAdaptor), nullDeleter)), transaction); | 133 | deletedEntity(DomainType("", uid, revision, QSharedPointer<ApplicationDomain::BufferAdaptor>(const_cast<ApplicationDomain::BufferAdaptor*>(&bufferAdaptor), nullDeleter)), transaction); |
134 | } | 134 | } |
135 | }; | 135 | }; |
136 | 136 | ||
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index f037cfc..e7963a3 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp | |||
@@ -28,11 +28,13 @@ | |||
28 | #include "definitions.h" | 28 | #include "definitions.h" |
29 | #include "domainadaptor.h" | 29 | #include "domainadaptor.h" |
30 | #include "asyncutils.h" | 30 | #include "asyncutils.h" |
31 | #include "entityreader.h" | 31 | #include "storage.h" |
32 | #include "datastorequery.h" | ||
32 | 33 | ||
33 | SINK_DEBUG_AREA("queryrunner") | 34 | SINK_DEBUG_AREA("queryrunner") |
34 | 35 | ||
35 | using namespace Sink; | 36 | using namespace Sink; |
37 | using namespace Sink::Storage; | ||
36 | 38 | ||
37 | /* | 39 | /* |
38 | * This class wraps the actual query implementation. | 40 | * This class wraps the actual query implementation. |
@@ -43,30 +45,28 @@ using namespace Sink; | |||
43 | template <typename DomainType> | 45 | template <typename DomainType> |
44 | class QueryWorker : public QObject | 46 | class QueryWorker : public QObject |
45 | { | 47 | { |
48 | typedef std::function<bool(const typename DomainType::Ptr &domainObject, Sink::Operation operation, const QMap<QByteArray, QVariant> &aggregateValues)> ResultCallback; | ||
46 | // SINK_DEBUG_COMPONENT(mResourceInstanceIdentifier, mId) | 49 | // SINK_DEBUG_COMPONENT(mResourceInstanceIdentifier, mId) |
47 | SINK_DEBUG_COMPONENT(mResourceInstanceIdentifier) | 50 | SINK_DEBUG_COMPONENT(mResourceContext.resourceInstanceIdentifier) |
48 | public: | 51 | public: |
49 | QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType, | 52 | QueryWorker(const Sink::Query &query, const ResourceContext &context, const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation); |
50 | const QueryRunnerBase::ResultTransformation &transformation); | ||
51 | virtual ~QueryWorker(); | 53 | virtual ~QueryWorker(); |
52 | 54 | ||
55 | qint64 replaySet(ResultSet &resultSet, int offset, int batchSize, const ResultCallback &callback); | ||
53 | QPair<qint64, qint64> executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); | 56 | QPair<qint64, qint64> executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); |
54 | QPair<qint64, qint64> executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int offset, int batchsize); | 57 | QPair<qint64, qint64> executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int offset, int batchsize); |
55 | 58 | ||
56 | private: | 59 | private: |
57 | Storage::Transaction getTransaction(); | ||
58 | std::function<bool(const typename DomainType::Ptr &, Sink::Operation, const QMap<QByteArray, QVariant> &)> resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); | 60 | std::function<bool(const typename DomainType::Ptr &, Sink::Operation, const QMap<QByteArray, QVariant> &)> resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); |
59 | 61 | ||
60 | QueryRunnerBase::ResultTransformation mResultTransformation; | 62 | QueryRunnerBase::ResultTransformation mResultTransformation; |
61 | DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; | 63 | ResourceContext mResourceContext; |
62 | QByteArray mResourceInstanceIdentifier; | ||
63 | QByteArray mId; //Used for identification in debug output | 64 | QByteArray mId; //Used for identification in debug output |
64 | }; | 65 | }; |
65 | 66 | ||
66 | template <class DomainType> | 67 | template <class DomainType> |
67 | QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::ResourceAccessInterface::Ptr &resourceAccess, const QByteArray &instanceIdentifier, | 68 | QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::ResourceContext &context, const QByteArray &bufferType) |
68 | const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType) | 69 | : QueryRunnerBase(), mResourceContext(context), mResourceAccess(mResourceContext.resourceAccess()), mResultProvider(new ResultProvider<typename DomainType::Ptr>), mBatchSize(query.limit) |
69 | : QueryRunnerBase(), mResourceInstanceIdentifier(instanceIdentifier), mResourceAccess(resourceAccess), mResultProvider(new ResultProvider<typename DomainType::Ptr>), mBatchSize(query.limit) | ||
70 | { | 70 | { |
71 | SinkTrace() << "Starting query"; | 71 | SinkTrace() << "Starting query"; |
72 | if (query.limit && query.sortProperty.isEmpty()) { | 72 | if (query.limit && query.sortProperty.isEmpty()) { |
@@ -79,16 +79,17 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
79 | SinkTrace() << "Running fetcher. Offset: " << mOffset[parentId] << " Batchsize: " << mBatchSize; | 79 | SinkTrace() << "Running fetcher. Offset: " << mOffset[parentId] << " Batchsize: " << mBatchSize; |
80 | auto resultProvider = mResultProvider; | 80 | auto resultProvider = mResultProvider; |
81 | if (query.synchronousQuery) { | 81 | if (query.synchronousQuery) { |
82 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); | 82 | QueryWorker<DomainType> worker(query, mResourceContext, bufferType, mResultTransformation); |
83 | worker.executeInitialQuery(query, parent, *resultProvider, mOffset[parentId], mBatchSize); | 83 | worker.executeInitialQuery(query, parent, *resultProvider, mOffset[parentId], mBatchSize); |
84 | resultProvider->initialResultSetComplete(parent); | 84 | resultProvider->initialResultSetComplete(parent); |
85 | } else { | 85 | } else { |
86 | auto resultTransformation = mResultTransformation; | 86 | auto resultTransformation = mResultTransformation; |
87 | auto offset = mOffset[parentId]; | 87 | auto offset = mOffset[parentId]; |
88 | auto batchSize = mBatchSize; | 88 | auto batchSize = mBatchSize; |
89 | auto resourceContext = mResourceContext; | ||
89 | //The lambda will be executed in a separate thread, so we're extra careful | 90 | //The lambda will be executed in a separate thread, so we're extra careful |
90 | async::run<QPair<qint64, qint64> >([resultTransformation, offset, batchSize, query, bufferType, instanceIdentifier, factory, resultProvider, parent]() { | 91 | async::run<QPair<qint64, qint64> >([resultTransformation, offset, batchSize, query, bufferType, resourceContext, resultProvider, parent]() { |
91 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, resultTransformation); | 92 | QueryWorker<DomainType> worker(query, resourceContext, bufferType, resultTransformation); |
92 | const auto newRevisionAndReplayedEntities = worker.executeInitialQuery(query, parent, *resultProvider, offset, batchSize); | 93 | const auto newRevisionAndReplayedEntities = worker.executeInitialQuery(query, parent, *resultProvider, offset, batchSize); |
93 | return newRevisionAndReplayedEntities; | 94 | return newRevisionAndReplayedEntities; |
94 | }) | 95 | }) |
@@ -115,8 +116,9 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
115 | // Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting | 116 | // Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting |
116 | setQuery([=]() -> KAsync::Job<void> { | 117 | setQuery([=]() -> KAsync::Job<void> { |
117 | auto resultProvider = mResultProvider; | 118 | auto resultProvider = mResultProvider; |
119 | auto resourceContext = mResourceContext; | ||
118 | return async::run<QPair<qint64, qint64> >([=]() { | 120 | return async::run<QPair<qint64, qint64> >([=]() { |
119 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); | 121 | QueryWorker<DomainType> worker(query, resourceContext, bufferType, mResultTransformation); |
120 | const auto newRevisionAndReplayedEntities = worker.executeIncrementalQuery(query, *resultProvider); | 122 | const auto newRevisionAndReplayedEntities = worker.executeIncrementalQuery(query, *resultProvider); |
121 | return newRevisionAndReplayedEntities; | 123 | return newRevisionAndReplayedEntities; |
122 | }) | 124 | }) |
@@ -158,11 +160,10 @@ typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainTy | |||
158 | return mResultProvider->emitter(); | 160 | return mResultProvider->emitter(); |
159 | } | 161 | } |
160 | 162 | ||
161 | |||
162 | template <class DomainType> | 163 | template <class DomainType> |
163 | QueryWorker<DomainType>::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, | 164 | QueryWorker<DomainType>::QueryWorker(const Sink::Query &query, const Sink::ResourceContext &resourceContext, |
164 | const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation) | 165 | const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation) |
165 | : QObject(), mResultTransformation(transformation), mDomainTypeAdaptorFactory(factory), mResourceInstanceIdentifier(instanceIdentifier), mId(QUuid::createUuid().toByteArray()) | 166 | : QObject(), mResultTransformation(transformation), mResourceContext(resourceContext), mId(QUuid::createUuid().toByteArray()) |
166 | { | 167 | { |
167 | SinkTrace() << "Starting query worker"; | 168 | SinkTrace() << "Starting query worker"; |
168 | } | 169 | } |
@@ -203,41 +204,46 @@ std::function<bool(const typename DomainType::Ptr &, Sink::Operation, const QMap | |||
203 | } | 204 | } |
204 | 205 | ||
205 | template <class DomainType> | 206 | template <class DomainType> |
207 | qint64 QueryWorker<DomainType>::replaySet(ResultSet &resultSet, int offset, int batchSize, const ResultCallback &callback) | ||
208 | { | ||
209 | SinkTrace() << "Skipping over " << offset << " results"; | ||
210 | resultSet.skip(offset); | ||
211 | int counter = 0; | ||
212 | while (!batchSize || (counter < batchSize)) { | ||
213 | const bool ret = | ||
214 | resultSet.next([this, &counter, callback](const ResultSet::Result &result) -> bool { | ||
215 | counter++; | ||
216 | auto adaptor = mResourceContext.adaptorFactory<DomainType>().createAdaptor(result.buffer.entity()); | ||
217 | Q_ASSERT(adaptor); | ||
218 | return callback(QSharedPointer<DomainType>::create(mResourceContext.instanceId(), result.uid, result.buffer.revision(), adaptor), result.operation, result.aggregateValues); | ||
219 | }); | ||
220 | if (!ret) { | ||
221 | break; | ||
222 | } | ||
223 | }; | ||
224 | SinkTrace() << "Replayed " << counter << " results." | ||
225 | << "Limit " << batchSize; | ||
226 | return counter; | ||
227 | } | ||
228 | |||
229 | template <class DomainType> | ||
206 | QPair<qint64, qint64> QueryWorker<DomainType>::executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) | 230 | QPair<qint64, qint64> QueryWorker<DomainType>::executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) |
207 | { | 231 | { |
208 | QTime time; | 232 | QTime time; |
209 | time.start(); | 233 | time.start(); |
210 | 234 | ||
211 | auto transaction = getTransaction(); | 235 | auto entityStore = EntityStore::Ptr::create(mResourceContext); |
212 | 236 | ||
213 | Sink::EntityReader<DomainType> reader(*mDomainTypeAdaptorFactory, mResourceInstanceIdentifier, transaction); | 237 | const qint64 baseRevision = resultProvider.revision() + 1; |
214 | auto revisionAndReplayedEntities = reader.executeIncrementalQuery(query, resultProvider.revision(), resultProviderCallback(query, resultProvider)); | ||
215 | SinkTrace() << "Incremental query took: " << Log::TraceTime(time.elapsed()); | ||
216 | return revisionAndReplayedEntities; | ||
217 | } | ||
218 | 238 | ||
219 | template <class DomainType> | 239 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, entityStore); |
220 | Storage::Transaction QueryWorker<DomainType>::getTransaction() | 240 | auto resultSet = preparedQuery->update(baseRevision); |
221 | { | ||
222 | Sink::Storage::Transaction transaction; | ||
223 | { | ||
224 | Sink::Storage storage(Sink::storageLocation(), mResourceInstanceIdentifier); | ||
225 | if (!storage.exists()) { | ||
226 | //This is not an error if the resource wasn't started before | ||
227 | SinkLog() << "Store doesn't exist: " << mResourceInstanceIdentifier; | ||
228 | return Sink::Storage::Transaction(); | ||
229 | } | ||
230 | storage.setDefaultErrorHandler([this](const Sink::Storage::Error &error) { SinkWarning() << "Error during query: " << error.store << error.message; }); | ||
231 | transaction = storage.createTransaction(Sink::Storage::ReadOnly); | ||
232 | } | ||
233 | 241 | ||
234 | //FIXME this is a temporary measure to recover from a failure to open the named databases correctly. | 242 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); |
235 | //Once the actual problem is fixed it will be enough to simply crash if we open the wrong database (which we check in openDatabase already). | 243 | auto replayedEntities = replaySet(resultSet, 0, 0, resultProviderCallback(query, resultProvider)); |
236 | while (!transaction.validateNamedDatabases()) { | 244 | |
237 | Sink::Storage storage(Sink::storageLocation(), mResourceInstanceIdentifier); | 245 | SinkTrace() << "Incremental query took: " << Log::TraceTime(time.elapsed()); |
238 | transaction = storage.createTransaction(Sink::Storage::ReadOnly); | 246 | return qMakePair(entityStore->maxRevision(), replayedEntities); |
239 | } | ||
240 | return transaction; | ||
241 | } | 247 | } |
242 | 248 | ||
243 | template <class DomainType> | 249 | template <class DomainType> |
@@ -258,12 +264,16 @@ QPair<qint64, qint64> QueryWorker<DomainType>::executeInitialQuery( | |||
258 | } | 264 | } |
259 | } | 265 | } |
260 | 266 | ||
261 | auto transaction = getTransaction(); | 267 | auto entityStore = EntityStore::Ptr::create(mResourceContext); |
268 | |||
269 | auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, entityStore); | ||
270 | auto resultSet = preparedQuery->execute(); | ||
271 | |||
272 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); | ||
273 | auto replayedEntities = replaySet(resultSet, offset, batchsize, resultProviderCallback(query, resultProvider)); | ||
262 | 274 | ||
263 | Sink::EntityReader<DomainType> reader(*mDomainTypeAdaptorFactory, mResourceInstanceIdentifier, transaction); | ||
264 | auto revisionAndReplayedEntities = reader.executeInitialQuery(modifiedQuery, offset, batchsize, resultProviderCallback(query, resultProvider)); | ||
265 | SinkTrace() << "Initial query took: " << Log::TraceTime(time.elapsed()); | 275 | SinkTrace() << "Initial query took: " << Log::TraceTime(time.elapsed()); |
266 | return revisionAndReplayedEntities; | 276 | return qMakePair(entityStore->maxRevision(), replayedEntities); |
267 | } | 277 | } |
268 | 278 | ||
269 | template class QueryRunner<Sink::ApplicationDomain::Folder>; | 279 | template class QueryRunner<Sink::ApplicationDomain::Folder>; |
diff --git a/common/queryrunner.h b/common/queryrunner.h index 78aabf6..9bd4791 100644 --- a/common/queryrunner.h +++ b/common/queryrunner.h | |||
@@ -20,10 +20,10 @@ | |||
20 | #pragma once | 20 | #pragma once |
21 | 21 | ||
22 | #include <QObject> | 22 | #include <QObject> |
23 | #include "resourcecontext.h" | ||
23 | #include "resourceaccess.h" | 24 | #include "resourceaccess.h" |
24 | #include "resultprovider.h" | 25 | #include "resultprovider.h" |
25 | #include "domaintypeadaptorfactoryinterface.h" | 26 | #include "domaintypeadaptorfactoryinterface.h" |
26 | #include "storage.h" | ||
27 | #include "query.h" | 27 | #include "query.h" |
28 | #include "log.h" | 28 | #include "log.h" |
29 | 29 | ||
@@ -84,8 +84,7 @@ template <typename DomainType> | |||
84 | class QueryRunner : public QueryRunnerBase | 84 | class QueryRunner : public QueryRunnerBase |
85 | { | 85 | { |
86 | public: | 86 | public: |
87 | QueryRunner(const Sink::Query &query, const Sink::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, | 87 | QueryRunner(const Sink::Query &query, const Sink::ResourceContext &context, const QByteArray &bufferType); |
88 | const QByteArray &bufferType); | ||
89 | virtual ~QueryRunner(); | 88 | virtual ~QueryRunner(); |
90 | 89 | ||
91 | /** | 90 | /** |
@@ -97,8 +96,8 @@ public: | |||
97 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); | 96 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); |
98 | 97 | ||
99 | private: | 98 | private: |
100 | QByteArray mResourceInstanceIdentifier; | 99 | Sink::ResourceContext mResourceContext; |
101 | SINK_DEBUG_COMPONENT(mResourceInstanceIdentifier) | 100 | SINK_DEBUG_COMPONENT(mResourceContext.resourceInstanceIdentifier) |
102 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; | 101 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; |
103 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr>> mResultProvider; | 102 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr>> mResultProvider; |
104 | ResultTransformation mResultTransformation; | 103 | ResultTransformation mResultTransformation; |
diff --git a/common/remoteidmap.cpp b/common/remoteidmap.cpp index 2c3e5c7..da57cf6 100644 --- a/common/remoteidmap.cpp +++ b/common/remoteidmap.cpp | |||
@@ -27,7 +27,7 @@ using namespace Sink; | |||
27 | 27 | ||
28 | SINK_DEBUG_AREA("remoteidmap") | 28 | SINK_DEBUG_AREA("remoteidmap") |
29 | 29 | ||
30 | RemoteIdMap::RemoteIdMap(Sink::Storage::Transaction &transaction) | 30 | RemoteIdMap::RemoteIdMap(Sink::Storage::DataStore::Transaction &transaction) |
31 | : mTransaction(transaction) | 31 | : mTransaction(transaction) |
32 | { | 32 | { |
33 | 33 | ||
@@ -58,7 +58,7 @@ QByteArray RemoteIdMap::resolveRemoteId(const QByteArray &bufferType, const QByt | |||
58 | Index index("rid.mapping." + bufferType, mTransaction); | 58 | Index index("rid.mapping." + bufferType, mTransaction); |
59 | QByteArray sinkId = index.lookup(remoteId); | 59 | QByteArray sinkId = index.lookup(remoteId); |
60 | if (sinkId.isEmpty()) { | 60 | if (sinkId.isEmpty()) { |
61 | sinkId = Sink::Storage::generateUid(); | 61 | sinkId = Sink::Storage::DataStore::generateUid(); |
62 | index.add(remoteId, sinkId); | 62 | index.add(remoteId, sinkId); |
63 | Index("localid.mapping." + bufferType, mTransaction).add(sinkId, remoteId); | 63 | Index("localid.mapping." + bufferType, mTransaction).add(sinkId, remoteId); |
64 | } | 64 | } |
@@ -81,7 +81,7 @@ QByteArray RemoteIdMap::readValue(const QByteArray &key) | |||
81 | mTransaction.openDatabase("values").scan(key, [&value](const QByteArray &, const QByteArray &v) { | 81 | mTransaction.openDatabase("values").scan(key, [&value](const QByteArray &, const QByteArray &v) { |
82 | value = v; | 82 | value = v; |
83 | return false; | 83 | return false; |
84 | }, [](const Sink::Storage::Error &) { | 84 | }, [](const Sink::Storage::DataStore::Error &) { |
85 | //Ignore errors because we may not find the value | 85 | //Ignore errors because we may not find the value |
86 | }); | 86 | }); |
87 | return value; | 87 | return value; |
diff --git a/common/remoteidmap.h b/common/remoteidmap.h index bf08621..32c5efd 100644 --- a/common/remoteidmap.h +++ b/common/remoteidmap.h | |||
@@ -31,7 +31,7 @@ namespace Sink { | |||
31 | class SINK_EXPORT RemoteIdMap | 31 | class SINK_EXPORT RemoteIdMap |
32 | { | 32 | { |
33 | public: | 33 | public: |
34 | RemoteIdMap(Sink::Storage::Transaction &); | 34 | RemoteIdMap(Sink::Storage::DataStore::Transaction &); |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Records a localId to remoteId mapping | 37 | * Records a localId to remoteId mapping |
@@ -58,7 +58,7 @@ public: | |||
58 | void writeValue(const QByteArray &key, const QByteArray &value); | 58 | void writeValue(const QByteArray &key, const QByteArray &value); |
59 | 59 | ||
60 | private: | 60 | private: |
61 | Sink::Storage::Transaction &mTransaction; | 61 | Sink::Storage::DataStore::Transaction &mTransaction; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | } | 64 | } |
diff --git a/common/resource.h b/common/resource.h index d468aca..426585d 100644 --- a/common/resource.h +++ b/common/resource.h | |||
@@ -27,6 +27,7 @@ | |||
27 | namespace Sink { | 27 | namespace Sink { |
28 | class FacadeFactory; | 28 | class FacadeFactory; |
29 | class AdaptorFactoryRegistry; | 29 | class AdaptorFactoryRegistry; |
30 | class ResourceContext; | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * Resource interface | 33 | * Resource interface |
@@ -75,7 +76,7 @@ public: | |||
75 | ResourceFactory(QObject *parent); | 76 | ResourceFactory(QObject *parent); |
76 | virtual ~ResourceFactory(); | 77 | virtual ~ResourceFactory(); |
77 | 78 | ||
78 | virtual Resource *createResource(const QByteArray &instanceIdentifier) = 0; | 79 | virtual Resource *createResource(const ResourceContext &context) = 0; |
79 | virtual void registerFacades(FacadeFactory &factory) = 0; | 80 | virtual void registerFacades(FacadeFactory &factory) = 0; |
80 | virtual void registerAdaptorFactories(AdaptorFactoryRegistry ®istry) {}; | 81 | virtual void registerAdaptorFactories(AdaptorFactoryRegistry ®istry) {}; |
81 | virtual void removeDataFromDisk(const QByteArray &instanceIdentifier) = 0; | 82 | virtual void removeDataFromDisk(const QByteArray &instanceIdentifier) = 0; |
diff --git a/common/resourcecontext.h b/common/resourcecontext.h new file mode 100644 index 0000000..6058ac7 --- /dev/null +++ b/common/resourcecontext.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||
8 | * later version accepted by the membership of KDE e.V. (or its | ||
9 | * successor approved by the membership of KDE e.V.), which shall | ||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | #pragma once | ||
21 | |||
22 | #include "domaintypeadaptorfactoryinterface.h" | ||
23 | #include "applicationdomaintype.h" | ||
24 | #include "resourceaccess.h" | ||
25 | #include <QByteArray> | ||
26 | #include <QMap> | ||
27 | |||
28 | namespace Sink { | ||
29 | |||
30 | /* | ||
31 | * A context object that can be passed around so each part of the system knows in what context it works. | ||
32 | * | ||
33 | * This is necessary because we can't rely on a singleton or thread-local storage since multiple resources can be accessed from the same thread/process. | ||
34 | */ | ||
35 | struct ResourceContext { | ||
36 | const QByteArray resourceInstanceIdentifier; | ||
37 | const QByteArray resourceType; | ||
38 | QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> adaptorFactories; | ||
39 | //TODO prehaps use a weak pointer to not mess up lifetime management | ||
40 | ResourceAccessInterface::Ptr mResourceAccess; | ||
41 | |||
42 | |||
43 | ResourceContext(const QByteArray &identifier, const QByteArray &resourceType_, const QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> &factories = QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr>()) | ||
44 | : resourceInstanceIdentifier(identifier), | ||
45 | resourceType(resourceType_), | ||
46 | adaptorFactories(factories) | ||
47 | { | ||
48 | } | ||
49 | |||
50 | QByteArray instanceId() const | ||
51 | { | ||
52 | return resourceInstanceIdentifier; | ||
53 | } | ||
54 | |||
55 | DomainTypeAdaptorFactoryInterface &adaptorFactory(const QByteArray &type) const | ||
56 | { | ||
57 | auto factory = adaptorFactories.value(type); | ||
58 | Q_ASSERT(factory); | ||
59 | return *factory; | ||
60 | } | ||
61 | |||
62 | template<typename DomainType> | ||
63 | DomainTypeAdaptorFactoryInterface &adaptorFactory() | ||
64 | { | ||
65 | return adaptorFactory(ApplicationDomain::getTypeName<DomainType>()); | ||
66 | } | ||
67 | |||
68 | ResourceAccessInterface::Ptr resourceAccess() | ||
69 | { | ||
70 | if (!mResourceAccess) { | ||
71 | mResourceAccess = ResourceAccessFactory::instance().getAccess(resourceInstanceIdentifier, resourceType); | ||
72 | } | ||
73 | return mResourceAccess; | ||
74 | } | ||
75 | }; | ||
76 | |||
77 | } | ||
diff --git a/common/sourcewriteback.cpp b/common/sourcewriteback.cpp index 702d8e3..204793e 100644 --- a/common/sourcewriteback.cpp +++ b/common/sourcewriteback.cpp | |||
@@ -22,6 +22,8 @@ | |||
22 | #include "definitions.h" | 22 | #include "definitions.h" |
23 | #include "log.h" | 23 | #include "log.h" |
24 | #include "bufferutils.h" | 24 | #include "bufferutils.h" |
25 | #include "entitybuffer.h" | ||
26 | #include "entity_generated.h" | ||
25 | 27 | ||
26 | #define ENTITY_TYPE_MAIL "mail" | 28 | #define ENTITY_TYPE_MAIL "mail" |
27 | #define ENTITY_TYPE_FOLDER "folder" | 29 | #define ENTITY_TYPE_FOLDER "folder" |
@@ -30,21 +32,21 @@ SINK_DEBUG_AREA("sourcewriteback") | |||
30 | 32 | ||
31 | using namespace Sink; | 33 | using namespace Sink; |
32 | 34 | ||
33 | SourceWriteBack::SourceWriteBack(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 35 | SourceWriteBack::SourceWriteBack(const ResourceContext &context) |
34 | : ChangeReplay(resourceInstanceIdentifier), | 36 | : ChangeReplay(context), |
35 | mSyncStorage(Sink::storageLocation(), resourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadWrite), | 37 | mResourceContext(context), |
36 | mResourceType(resourceType), | 38 | mSyncStorage(Sink::storageLocation(), context.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadWrite), |
37 | mResourceInstanceIdentifier(resourceInstanceIdentifier) | 39 | mEntityStore(QSharedPointer<Storage::EntityStore>::create(mResourceContext)) |
38 | { | 40 | { |
39 | 41 | ||
40 | } | 42 | } |
41 | 43 | ||
42 | EntityStore &SourceWriteBack::store() | 44 | EntityStore &SourceWriteBack::store() |
43 | { | 45 | { |
44 | if (!mEntityStore) { | 46 | if (!mEntityStoreWrapper) { |
45 | mEntityStore = QSharedPointer<EntityStore>::create(mResourceType, mResourceInstanceIdentifier, mTransaction); | 47 | mEntityStoreWrapper = QSharedPointer<EntityStore>::create(*mEntityStore); |
46 | } | 48 | } |
47 | return *mEntityStore; | 49 | return *mEntityStoreWrapper; |
48 | } | 50 | } |
49 | 51 | ||
50 | RemoteIdMap &SourceWriteBack::syncStore() | 52 | RemoteIdMap &SourceWriteBack::syncStore() |
@@ -76,15 +78,14 @@ KAsync::Job<void> SourceWriteBack::replay(const QByteArray &type, const QByteArr | |||
76 | const auto metadataBuffer = Sink::EntityBuffer::readBuffer<Sink::Metadata>(entity.metadata()); | 78 | const auto metadataBuffer = Sink::EntityBuffer::readBuffer<Sink::Metadata>(entity.metadata()); |
77 | Q_ASSERT(metadataBuffer); | 79 | Q_ASSERT(metadataBuffer); |
78 | Q_ASSERT(!mSyncStore); | 80 | Q_ASSERT(!mSyncStore); |
79 | Q_ASSERT(!mEntityStore); | 81 | Q_ASSERT(!mEntityStoreWrapper); |
80 | Q_ASSERT(!mTransaction); | ||
81 | Q_ASSERT(!mSyncTransaction); | 82 | Q_ASSERT(!mSyncTransaction); |
82 | mTransaction = mStorage.createTransaction(Sink::Storage::ReadOnly); | 83 | mEntityStore->startTransaction(Storage::DataStore::ReadOnly); |
83 | mSyncTransaction = mSyncStorage.createTransaction(Sink::Storage::ReadWrite); | 84 | mSyncTransaction = mSyncStorage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
84 | 85 | ||
85 | // const qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; | 86 | // const qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; |
86 | const auto operation = metadataBuffer ? metadataBuffer->operation() : Sink::Operation_Creation; | 87 | const auto operation = metadataBuffer ? metadataBuffer->operation() : Sink::Operation_Creation; |
87 | const auto uid = Sink::Storage::uidFromKey(key); | 88 | const auto uid = Sink::Storage::DataStore::uidFromKey(key); |
88 | const auto modifiedProperties = metadataBuffer->modifiedProperties() ? BufferUtils::fromVector(*metadataBuffer->modifiedProperties()) : QByteArrayList(); | 89 | const auto modifiedProperties = metadataBuffer->modifiedProperties() ? BufferUtils::fromVector(*metadataBuffer->modifiedProperties()) : QByteArrayList(); |
89 | QByteArray oldRemoteId; | 90 | QByteArray oldRemoteId; |
90 | 91 | ||
@@ -133,9 +134,9 @@ KAsync::Job<void> SourceWriteBack::replay(const QByteArray &type, const QByteArr | |||
133 | SinkWarning() << "Failed to replay change: " << error.errorMessage; | 134 | SinkWarning() << "Failed to replay change: " << error.errorMessage; |
134 | } | 135 | } |
135 | mSyncStore.clear(); | 136 | mSyncStore.clear(); |
136 | mEntityStore.clear(); | 137 | mEntityStoreWrapper.clear(); |
137 | mTransaction.abort(); | ||
138 | mSyncTransaction.commit(); | 138 | mSyncTransaction.commit(); |
139 | mEntityStore->abortTransaction(); | ||
139 | }); | 140 | }); |
140 | } | 141 | } |
141 | 142 | ||
diff --git a/common/sourcewriteback.h b/common/sourcewriteback.h index 8031573..327d1ad 100644 --- a/common/sourcewriteback.h +++ b/common/sourcewriteback.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "storage.h" | 25 | #include "storage.h" |
26 | #include "entitystore.h" | 26 | #include "entitystore.h" |
27 | #include "remoteidmap.h" | 27 | #include "remoteidmap.h" |
28 | #include "metadata_generated.h" | ||
28 | 29 | ||
29 | namespace Sink { | 30 | namespace Sink { |
30 | 31 | ||
@@ -34,7 +35,7 @@ namespace Sink { | |||
34 | class SINK_EXPORT SourceWriteBack : public ChangeReplay | 35 | class SINK_EXPORT SourceWriteBack : public ChangeReplay |
35 | { | 36 | { |
36 | public: | 37 | public: |
37 | SourceWriteBack(const QByteArray &resourceType,const QByteArray &resourceInstanceIdentifier); | 38 | SourceWriteBack(const ResourceContext &resourceContext); |
38 | 39 | ||
39 | protected: | 40 | protected: |
40 | ///Base implementation calls the replay$Type calls | 41 | ///Base implementation calls the replay$Type calls |
@@ -58,12 +59,12 @@ protected: | |||
58 | private: | 59 | private: |
59 | //Read only access to main storage | 60 | //Read only access to main storage |
60 | EntityStore &store(); | 61 | EntityStore &store(); |
61 | 62 | ResourceContext mResourceContext; | |
62 | Sink::Storage mSyncStorage; | 63 | Sink::Storage::DataStore mSyncStorage; |
63 | QSharedPointer<RemoteIdMap> mSyncStore; | 64 | QSharedPointer<RemoteIdMap> mSyncStore; |
64 | QSharedPointer<EntityStore> mEntityStore; | 65 | QSharedPointer<Storage::EntityStore> mEntityStore; |
65 | Sink::Storage::Transaction mTransaction; | 66 | QSharedPointer<EntityStore> mEntityStoreWrapper; |
66 | Sink::Storage::Transaction mSyncTransaction; | 67 | Sink::Storage::DataStore::Transaction mSyncTransaction; |
67 | QByteArray mResourceType; | 68 | QByteArray mResourceType; |
68 | QByteArray mResourceInstanceIdentifier; | 69 | QByteArray mResourceInstanceIdentifier; |
69 | }; | 70 | }; |
diff --git a/common/specialpurposepreprocessor.cpp b/common/specialpurposepreprocessor.cpp index b9ad94a..a6ee373 100644 --- a/common/specialpurposepreprocessor.cpp +++ b/common/specialpurposepreprocessor.cpp | |||
@@ -11,6 +11,8 @@ static QHash<QByteArray, QString> specialPurposeFolders() | |||
11 | { | 11 | { |
12 | QHash<QByteArray, QString> hash; | 12 | QHash<QByteArray, QString> hash; |
13 | //FIXME localize | 13 | //FIXME localize |
14 | //TODO inbox | ||
15 | //TODO use standardized values | ||
14 | hash.insert("drafts", "Drafts"); | 16 | hash.insert("drafts", "Drafts"); |
15 | hash.insert("trash", "Trash"); | 17 | hash.insert("trash", "Trash"); |
16 | hash.insert("inbox", "Inbox"); | 18 | hash.insert("inbox", "Inbox"); |
@@ -45,31 +47,31 @@ QByteArray getSpecialPurposeType(const QString &name) | |||
45 | 47 | ||
46 | SpecialPurposeProcessor::SpecialPurposeProcessor(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : mResourceType(resourceType), mResourceInstanceIdentifier(resourceInstanceIdentifier) {} | 48 | SpecialPurposeProcessor::SpecialPurposeProcessor(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : mResourceType(resourceType), mResourceInstanceIdentifier(resourceInstanceIdentifier) {} |
47 | 49 | ||
48 | QByteArray SpecialPurposeProcessor::ensureFolder(Sink::Storage::Transaction &transaction, const QByteArray &specialPurpose) | 50 | QByteArray SpecialPurposeProcessor::ensureFolder(Sink::Storage::DataStore::Transaction &transaction, const QByteArray &specialPurpose) |
49 | { | 51 | { |
50 | if (!mSpecialPurposeFolders.contains(specialPurpose)) { | 52 | /* if (!mSpecialPurposeFolders.contains(specialPurpose)) { */ |
51 | //Try to find an existing drafts folder | 53 | /* //Try to find an existing drafts folder */ |
52 | Sink::EntityReader<ApplicationDomain::Folder> reader(mResourceType, mResourceInstanceIdentifier, transaction); | 54 | /* Sink::EntityReader<ApplicationDomain::Folder> reader(mResourceType, mResourceInstanceIdentifier, transaction); */ |
53 | reader.query(Sink::Query().filter<ApplicationDomain::Folder::SpecialPurpose>(Query::Comparator(specialPurpose, Query::Comparator::Contains)), | 55 | /* reader.query(Sink::Query().filter<ApplicationDomain::Folder::SpecialPurpose>(Query::Comparator(specialPurpose, Query::Comparator::Contains)), */ |
54 | [this, specialPurpose](const ApplicationDomain::Folder &f) -> bool{ | 56 | /* [this, specialPurpose](const ApplicationDomain::Folder &f) -> bool{ */ |
55 | mSpecialPurposeFolders.insert(specialPurpose, f.identifier()); | 57 | /* mSpecialPurposeFolders.insert(specialPurpose, f.identifier()); */ |
56 | return false; | 58 | /* return false; */ |
57 | }); | 59 | /* }); */ |
58 | if (!mSpecialPurposeFolders.contains(specialPurpose)) { | 60 | /* if (!mSpecialPurposeFolders.contains(specialPurpose)) { */ |
59 | SinkTrace() << "Failed to find a drafts folder, creating a new one"; | 61 | /* SinkTrace() << "Failed to find a drafts folder, creating a new one"; */ |
60 | auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier); | 62 | /* auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier); */ |
61 | folder.setSpecialPurpose(QByteArrayList() << specialPurpose); | 63 | /* folder.setSpecialPurpose(QByteArrayList() << specialPurpose); */ |
62 | folder.setName(sSpecialPurposeFolders.value(specialPurpose)); | 64 | /* folder.setName(sSpecialPurposeFolders.value(specialPurpose)); */ |
63 | folder.setIcon("folder"); | 65 | /* folder.setIcon("folder"); */ |
64 | //This processes the pipeline synchronously | 66 | /* //This processes the pipeline synchronously */ |
65 | createEntity(folder); | 67 | /* createEntity(folder); */ |
66 | mSpecialPurposeFolders.insert(specialPurpose, folder.identifier()); | 68 | /* mSpecialPurposeFolders.insert(specialPurpose, folder.identifier()); */ |
67 | } | 69 | /* } */ |
68 | } | 70 | /* } */ |
69 | return mSpecialPurposeFolders.value(specialPurpose); | 71 | return mSpecialPurposeFolders.value(specialPurpose); |
70 | } | 72 | } |
71 | 73 | ||
72 | void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) | 74 | void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) |
73 | { | 75 | { |
74 | if (newEntity.getProperty("trash").toBool()) { | 76 | if (newEntity.getProperty("trash").toBool()) { |
75 | newEntity.setProperty("folder", ensureFolder(transaction, "trash")); | 77 | newEntity.setProperty("folder", ensureFolder(transaction, "trash")); |
@@ -80,12 +82,12 @@ void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::BufferAdapto | |||
80 | } | 82 | } |
81 | } | 83 | } |
82 | 84 | ||
83 | void SpecialPurposeProcessor::newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) | 85 | void SpecialPurposeProcessor::newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) |
84 | { | 86 | { |
85 | moveToFolder(newEntity, transaction); | 87 | moveToFolder(newEntity, transaction); |
86 | } | 88 | } |
87 | 89 | ||
88 | void SpecialPurposeProcessor::modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) | 90 | void SpecialPurposeProcessor::modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) |
89 | { | 91 | { |
90 | moveToFolder(newEntity, transaction); | 92 | moveToFolder(newEntity, transaction); |
91 | } | 93 | } |
diff --git a/common/specialpurposepreprocessor.h b/common/specialpurposepreprocessor.h index a33701b..8b2d9e9 100644 --- a/common/specialpurposepreprocessor.h +++ b/common/specialpurposepreprocessor.h | |||
@@ -30,12 +30,12 @@ class SINK_EXPORT SpecialPurposeProcessor : public Sink::Preprocessor | |||
30 | public: | 30 | public: |
31 | SpecialPurposeProcessor(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier); | 31 | SpecialPurposeProcessor(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier); |
32 | 32 | ||
33 | QByteArray ensureFolder(Sink::Storage::Transaction &transaction, const QByteArray &specialPurpose); | 33 | QByteArray ensureFolder(Sink::Storage::DataStore::Transaction &transaction, const QByteArray &specialPurpose); |
34 | 34 | ||
35 | void moveToFolder(Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction); | 35 | void moveToFolder(Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction); |
36 | 36 | ||
37 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 37 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
38 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE; | 38 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE; |
39 | 39 | ||
40 | QHash<QByteArray, QByteArray> mSpecialPurposeFolders; | 40 | QHash<QByteArray, QByteArray> mSpecialPurposeFolders; |
41 | QByteArray mResourceType; | 41 | QByteArray mResourceType; |
diff --git a/common/storage.h b/common/storage.h index 4ef20d5..e368b05 100644 --- a/common/storage.h +++ b/common/storage.h | |||
@@ -27,8 +27,9 @@ | |||
27 | #include <QString> | 27 | #include <QString> |
28 | 28 | ||
29 | namespace Sink { | 29 | namespace Sink { |
30 | namespace Storage { | ||
30 | 31 | ||
31 | class SINK_EXPORT Storage | 32 | class SINK_EXPORT DataStore |
32 | { | 33 | { |
33 | public: | 34 | public: |
34 | enum AccessMode | 35 | enum AccessMode |
@@ -66,16 +67,16 @@ public: | |||
66 | /** | 67 | /** |
67 | * Write a value | 68 | * Write a value |
68 | */ | 69 | */ |
69 | bool write(const QByteArray &key, const QByteArray &value, const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()); | 70 | bool write(const QByteArray &key, const QByteArray &value, const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()); |
70 | 71 | ||
71 | /** | 72 | /** |
72 | * Remove a key | 73 | * Remove a key |
73 | */ | 74 | */ |
74 | void remove(const QByteArray &key, const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()); | 75 | void remove(const QByteArray &key, const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()); |
75 | /** | 76 | /** |
76 | * Remove a key-value pair | 77 | * Remove a key-value pair |
77 | */ | 78 | */ |
78 | void remove(const QByteArray &key, const QByteArray &value, const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()); | 79 | void remove(const QByteArray &key, const QByteArray &value, const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()); |
79 | 80 | ||
80 | /** | 81 | /** |
81 | * Read values with a given key. | 82 | * Read values with a given key. |
@@ -87,7 +88,7 @@ public: | |||
87 | * @return The number of values retrieved. | 88 | * @return The number of values retrieved. |
88 | */ | 89 | */ |
89 | int scan(const QByteArray &key, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, | 90 | int scan(const QByteArray &key, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, |
90 | const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>(), bool findSubstringKeys = false, bool skipInternalKeys = true) const; | 91 | const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>(), bool findSubstringKeys = false, bool skipInternalKeys = true) const; |
91 | 92 | ||
92 | /** | 93 | /** |
93 | * Finds the last value in a series matched by prefix. | 94 | * Finds the last value in a series matched by prefix. |
@@ -96,7 +97,7 @@ public: | |||
96 | * Note that this relies on a key scheme like $uid$revision. | 97 | * Note that this relies on a key scheme like $uid$revision. |
97 | */ | 98 | */ |
98 | void findLatest(const QByteArray &uid, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, | 99 | void findLatest(const QByteArray &uid, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, |
99 | const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()) const; | 100 | const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()) const; |
100 | 101 | ||
101 | /** | 102 | /** |
102 | * Returns true if the database contains the substring key. | 103 | * Returns true if the database contains the substring key. |
@@ -127,14 +128,14 @@ public: | |||
127 | public: | 128 | public: |
128 | Transaction(); | 129 | Transaction(); |
129 | ~Transaction(); | 130 | ~Transaction(); |
130 | bool commit(const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()); | 131 | bool commit(const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()); |
131 | void abort(); | 132 | void abort(); |
132 | 133 | ||
133 | QList<QByteArray> getDatabaseNames() const; | 134 | QList<QByteArray> getDatabaseNames() const; |
134 | bool validateNamedDatabases(); | 135 | bool validateNamedDatabases(); |
135 | 136 | ||
136 | NamedDatabase openDatabase(const QByteArray &name = QByteArray("default"), | 137 | NamedDatabase openDatabase(const QByteArray &name = QByteArray("default"), |
137 | const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>(), bool allowDuplicates = false) const; | 138 | const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>(), bool allowDuplicates = false) const; |
138 | 139 | ||
139 | Transaction(Transaction &&other); | 140 | Transaction(Transaction &&other); |
140 | Transaction &operator=(Transaction &&other); | 141 | Transaction &operator=(Transaction &&other); |
@@ -144,29 +145,29 @@ public: | |||
144 | private: | 145 | private: |
145 | Transaction(Transaction &other); | 146 | Transaction(Transaction &other); |
146 | Transaction &operator=(Transaction &other); | 147 | Transaction &operator=(Transaction &other); |
147 | friend Storage; | 148 | friend DataStore; |
148 | class Private; | 149 | class Private; |
149 | Transaction(Private *); | 150 | Transaction(Private *); |
150 | Private *d; | 151 | Private *d; |
151 | }; | 152 | }; |
152 | 153 | ||
153 | Storage(const QString &storageRoot, const QString &name, AccessMode mode = ReadOnly); | 154 | DataStore(const QString &storageRoot, const QString &name, AccessMode mode = ReadOnly); |
154 | ~Storage(); | 155 | ~DataStore(); |
155 | 156 | ||
156 | Transaction createTransaction(AccessMode mode = ReadWrite, const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>()); | 157 | Transaction createTransaction(AccessMode mode = ReadWrite, const std::function<void(const DataStore::Error &error)> &errorHandler = std::function<void(const DataStore::Error &error)>()); |
157 | 158 | ||
158 | /** | 159 | /** |
159 | * Set the default error handler. | 160 | * Set the default error handler. |
160 | */ | 161 | */ |
161 | void setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler); | 162 | void setDefaultErrorHandler(const std::function<void(const DataStore::Error &error)> &errorHandler); |
162 | std::function<void(const Storage::Error &error)> defaultErrorHandler() const; | 163 | std::function<void(const DataStore::Error &error)> defaultErrorHandler() const; |
163 | 164 | ||
164 | /** | 165 | /** |
165 | * A basic error handler that writes to std::cerr. | 166 | * A basic error handler that writes to std::cerr. |
166 | * | 167 | * |
167 | * Used if nothing else is configured. | 168 | * Used if nothing else is configured. |
168 | */ | 169 | */ |
169 | static std::function<void(const Storage::Error &error)> basicErrorHandler(); | 170 | static std::function<void(const DataStore::Error &error)> basicErrorHandler(); |
170 | 171 | ||
171 | qint64 diskUsage() const; | 172 | qint64 diskUsage() const; |
172 | void removeFromDisk() const; | 173 | void removeFromDisk() const; |
@@ -178,16 +179,16 @@ public: | |||
178 | */ | 179 | */ |
179 | static void clearEnv(); | 180 | static void clearEnv(); |
180 | 181 | ||
181 | static qint64 maxRevision(const Sink::Storage::Transaction &); | 182 | static qint64 maxRevision(const Transaction &); |
182 | static void setMaxRevision(Sink::Storage::Transaction &, qint64 revision); | 183 | static void setMaxRevision(Transaction &, qint64 revision); |
183 | 184 | ||
184 | static qint64 cleanedUpRevision(const Sink::Storage::Transaction &); | 185 | static qint64 cleanedUpRevision(const Transaction &); |
185 | static void setCleanedUpRevision(Sink::Storage::Transaction &, qint64 revision); | 186 | static void setCleanedUpRevision(Transaction &, qint64 revision); |
186 | 187 | ||
187 | static QByteArray getUidFromRevision(const Sink::Storage::Transaction &, qint64 revision); | 188 | static QByteArray getUidFromRevision(const Transaction &, qint64 revision); |
188 | static QByteArray getTypeFromRevision(const Sink::Storage::Transaction &, qint64 revision); | 189 | static QByteArray getTypeFromRevision(const Transaction &, qint64 revision); |
189 | static void recordRevision(Sink::Storage::Transaction &, qint64 revision, const QByteArray &uid, const QByteArray &type); | 190 | static void recordRevision(Transaction &, qint64 revision, const QByteArray &uid, const QByteArray &type); |
190 | static void removeRevision(Sink::Storage::Transaction &, qint64 revision); | 191 | static void removeRevision(Transaction &, qint64 revision); |
191 | 192 | ||
192 | bool exists() const; | 193 | bool exists() const; |
193 | 194 | ||
@@ -199,16 +200,17 @@ public: | |||
199 | static QByteArray uidFromKey(const QByteArray &key); | 200 | static QByteArray uidFromKey(const QByteArray &key); |
200 | static qint64 revisionFromKey(const QByteArray &key); | 201 | static qint64 revisionFromKey(const QByteArray &key); |
201 | 202 | ||
202 | static NamedDatabase mainDatabase(const Sink::Storage::Transaction &, const QByteArray &type); | 203 | static NamedDatabase mainDatabase(const Transaction &, const QByteArray &type); |
203 | 204 | ||
204 | static QByteArray generateUid(); | 205 | static QByteArray generateUid(); |
205 | 206 | ||
206 | private: | 207 | private: |
207 | std::function<void(const Storage::Error &error)> mErrorHandler; | 208 | std::function<void(const DataStore::Error &error)> mErrorHandler; |
208 | 209 | ||
209 | private: | 210 | private: |
210 | class Private; | 211 | class Private; |
211 | Private *const d; | 212 | Private *const d; |
212 | }; | 213 | }; |
213 | 214 | ||
215 | } | ||
214 | } // namespace Sink | 216 | } // namespace Sink |
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp new file mode 100644 index 0000000..9615eca --- /dev/null +++ b/common/storage/entitystore.cpp | |||
@@ -0,0 +1,338 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||
8 | * later version accepted by the membership of KDE e.V. (or its | ||
9 | * successor approved by the membership of KDE e.V.), which shall | ||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | #include "entitystore.h" | ||
21 | |||
22 | #include "entitybuffer.h" | ||
23 | #include "log.h" | ||
24 | #include "typeindex.h" | ||
25 | #include "definitions.h" | ||
26 | #include "resourcecontext.h" | ||
27 | #include "index.h" | ||
28 | |||
29 | #include "mail.h" | ||
30 | #include "folder.h" | ||
31 | #include "event.h" | ||
32 | |||
33 | using namespace Sink; | ||
34 | using namespace Sink::Storage; | ||
35 | |||
36 | SINK_DEBUG_AREA("entitystore"); | ||
37 | |||
38 | class EntityStore::Private { | ||
39 | public: | ||
40 | Private(const ResourceContext &context) : resourceContext(context) {} | ||
41 | |||
42 | ResourceContext resourceContext; | ||
43 | DataStore::Transaction transaction; | ||
44 | QHash<QByteArray, QSharedPointer<TypeIndex> > indexByType; | ||
45 | |||
46 | DataStore::Transaction &getTransaction() | ||
47 | { | ||
48 | if (transaction) { | ||
49 | return transaction; | ||
50 | } | ||
51 | |||
52 | Sink::Storage::DataStore store(Sink::storageLocation(), resourceContext.instanceId(), DataStore::ReadOnly); | ||
53 | transaction = store.createTransaction(DataStore::ReadOnly); | ||
54 | Q_ASSERT(transaction.validateNamedDatabases()); | ||
55 | return transaction; | ||
56 | } | ||
57 | |||
58 | /* template<typename T> */ | ||
59 | /* TypeIndex &typeIndex(const QByteArray &type) */ | ||
60 | /* { */ | ||
61 | /* if (indexByType.contains(type)) { */ | ||
62 | /* return *indexByType.value(type); */ | ||
63 | /* } */ | ||
64 | /* auto index = QSharedPointer<TypeIndex>::create(type); */ | ||
65 | /* ApplicationDomain::TypeImplementation<T>::configureIndex(*index); */ | ||
66 | /* indexByType.insert(type, index); */ | ||
67 | /* return *index; */ | ||
68 | /* } */ | ||
69 | |||
70 | TypeIndex &typeIndex(const QByteArray &type) | ||
71 | { | ||
72 | /* return applyType<typeIndex>(type); */ | ||
73 | if (indexByType.contains(type)) { | ||
74 | return *indexByType.value(type); | ||
75 | } | ||
76 | auto index = QSharedPointer<TypeIndex>::create(type); | ||
77 | //TODO expand for all types | ||
78 | /* TypeHelper<type>::configureIndex(*index); */ | ||
79 | // Try this: (T would i.e. become | ||
80 | // TypeHelper<ApplicationDomain::TypeImplementation>::T::configureIndex(*index); | ||
81 | if (type == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { | ||
82 | ApplicationDomain::TypeImplementation<ApplicationDomain::Folder>::configureIndex(*index); | ||
83 | } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { | ||
84 | ApplicationDomain::TypeImplementation<ApplicationDomain::Mail>::configureIndex(*index); | ||
85 | } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Event>()) { | ||
86 | ApplicationDomain::TypeImplementation<ApplicationDomain::Event>::configureIndex(*index); | ||
87 | } else { | ||
88 | Q_ASSERT(false); | ||
89 | SinkError() << "Unkonwn type " << type; | ||
90 | } | ||
91 | indexByType.insert(type, index); | ||
92 | return *index; | ||
93 | } | ||
94 | }; | ||
95 | |||
96 | EntityStore::EntityStore(const ResourceContext &context) | ||
97 | : d(new EntityStore::Private{context}) | ||
98 | { | ||
99 | |||
100 | } | ||
101 | |||
102 | void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMode) | ||
103 | { | ||
104 | Sink::Storage::DataStore store(Sink::storageLocation(), d->resourceContext.instanceId(), accessMode); | ||
105 | d->transaction = store.createTransaction(accessMode); | ||
106 | Q_ASSERT(d->transaction.validateNamedDatabases()); | ||
107 | } | ||
108 | |||
109 | void EntityStore::commitTransaction() | ||
110 | { | ||
111 | d->transaction.commit(); | ||
112 | d->transaction = Storage::DataStore::Transaction(); | ||
113 | } | ||
114 | |||
115 | void EntityStore::abortTransaction() | ||
116 | { | ||
117 | d->transaction.abort(); | ||
118 | d->transaction = Storage::DataStore::Transaction(); | ||
119 | } | ||
120 | |||
121 | QVector<QByteArray> EntityStore::fullScan(const QByteArray &type) | ||
122 | { | ||
123 | SinkTrace() << "Looking for : " << type; | ||
124 | //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. | ||
125 | QSet<QByteArray> keys; | ||
126 | DataStore::mainDatabase(d->getTransaction(), type) | ||
127 | .scan(QByteArray(), | ||
128 | [&](const QByteArray &key, const QByteArray &value) -> bool { | ||
129 | const auto uid = DataStore::uidFromKey(key); | ||
130 | if (keys.contains(uid)) { | ||
131 | //Not something that should persist if the replay works, so we keep a message for now. | ||
132 | SinkTrace() << "Multiple revisions for key: " << key; | ||
133 | } | ||
134 | keys << uid; | ||
135 | return true; | ||
136 | }, | ||
137 | [](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message; }); | ||
138 | |||
139 | SinkTrace() << "Full scan retrieved " << keys.size() << " results."; | ||
140 | return keys.toList().toVector(); | ||
141 | } | ||
142 | |||
143 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting) | ||
144 | { | ||
145 | return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction()); | ||
146 | } | ||
147 | |||
148 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value) | ||
149 | { | ||
150 | return d->typeIndex(type).lookup(property, value, d->getTransaction()); | ||
151 | } | ||
152 | |||
153 | void EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) | ||
154 | { | ||
155 | auto list = d->typeIndex(type).lookup(property, value, d->getTransaction()); | ||
156 | for (const auto &uid : list) { | ||
157 | callback(uid); | ||
158 | } | ||
159 | /* Index index(type + ".index." + property, d->transaction); */ | ||
160 | /* index.lookup(value, [&](const QByteArray &sinkId) { */ | ||
161 | /* callback(sinkId); */ | ||
162 | /* }, */ | ||
163 | /* [&](const Index::Error &error) { */ | ||
164 | /* SinkWarning() << "Error in index: " << error.message << property; */ | ||
165 | /* }); */ | ||
166 | } | ||
167 | |||
168 | void EntityStore::readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback) | ||
169 | { | ||
170 | auto db = DataStore::mainDatabase(d->getTransaction(), type); | ||
171 | db.findLatest(uid, | ||
172 | [=](const QByteArray &key, const QByteArray &value) -> bool { | ||
173 | callback(DataStore::uidFromKey(key), Sink::EntityBuffer(value.data(), value.size())); | ||
174 | return false; | ||
175 | }, | ||
176 | [&](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message << uid; }); | ||
177 | } | ||
178 | |||
179 | void EntityStore::readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &)> callback) | ||
180 | { | ||
181 | readLatest(type, uid, [&](const QByteArray &uid, const EntityBuffer &buffer) { | ||
182 | auto adaptor = d->resourceContext.adaptorFactory(type).createAdaptor(buffer.entity()); | ||
183 | callback(ApplicationDomain::ApplicationDomainType{d->resourceContext.instanceId(), uid, DataStore::maxRevision(d->getTransaction()), adaptor}); | ||
184 | }); | ||
185 | } | ||
186 | |||
187 | ApplicationDomain::ApplicationDomainType EntityStore::readLatest(const QByteArray &type, const QByteArray &uid) | ||
188 | { | ||
189 | ApplicationDomain::ApplicationDomainType dt; | ||
190 | readLatest(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { | ||
191 | dt = entity; | ||
192 | }); | ||
193 | return dt; | ||
194 | } | ||
195 | |||
196 | void EntityStore::readEntity(const QByteArray &type, const QByteArray &key, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback) | ||
197 | { | ||
198 | auto db = DataStore::mainDatabase(d->getTransaction(), type); | ||
199 | db.scan(key, | ||
200 | [=](const QByteArray &key, const QByteArray &value) -> bool { | ||
201 | callback(DataStore::uidFromKey(key), Sink::EntityBuffer(value.data(), value.size())); | ||
202 | return false; | ||
203 | }, | ||
204 | [&](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message << key; }); | ||
205 | } | ||
206 | |||
207 | void EntityStore::readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &)> callback) | ||
208 | { | ||
209 | readEntity(type, uid, [&](const QByteArray &uid, const EntityBuffer &buffer) { | ||
210 | auto adaptor = d->resourceContext.adaptorFactory(type).createAdaptor(buffer.entity()); | ||
211 | callback(ApplicationDomain::ApplicationDomainType{d->resourceContext.instanceId(), uid, DataStore::maxRevision(d->getTransaction()), adaptor}); | ||
212 | }); | ||
213 | } | ||
214 | |||
215 | ApplicationDomain::ApplicationDomainType EntityStore::readEntity(const QByteArray &type, const QByteArray &uid) | ||
216 | { | ||
217 | ApplicationDomain::ApplicationDomainType dt; | ||
218 | readEntity(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { | ||
219 | dt = entity; | ||
220 | }); | ||
221 | return dt; | ||
222 | } | ||
223 | |||
224 | |||
225 | void EntityStore::readAll(const QByteArray &type, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> &callback) | ||
226 | { | ||
227 | auto db = DataStore::mainDatabase(d->getTransaction(), type); | ||
228 | db.scan("", | ||
229 | [=](const QByteArray &key, const QByteArray &value) -> bool { | ||
230 | auto uid = DataStore::uidFromKey(key); | ||
231 | auto buffer = Sink::EntityBuffer{value.data(), value.size()}; | ||
232 | auto adaptor = d->resourceContext.adaptorFactory(type).createAdaptor(buffer.entity()); | ||
233 | callback(ApplicationDomain::ApplicationDomainType{d->resourceContext.instanceId(), uid, DataStore::maxRevision(d->getTransaction()), adaptor}); | ||
234 | return true; | ||
235 | }, | ||
236 | [&](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message; }); | ||
237 | } | ||
238 | |||
239 | void EntityStore::readRevisions(qint64 baseRevision, const QByteArray &expectedType, const std::function<void(const QByteArray &key)> &callback) | ||
240 | { | ||
241 | qint64 revisionCounter = baseRevision; | ||
242 | const qint64 topRevision = DataStore::maxRevision(d->getTransaction()); | ||
243 | // Spit out the revision keys one by one. | ||
244 | while (revisionCounter <= topRevision) { | ||
245 | const auto uid = DataStore::getUidFromRevision(d->getTransaction(), revisionCounter); | ||
246 | const auto type = DataStore::getTypeFromRevision(d->getTransaction(), revisionCounter); | ||
247 | // SinkTrace() << "Revision" << *revisionCounter << type << uid; | ||
248 | Q_ASSERT(!uid.isEmpty()); | ||
249 | Q_ASSERT(!type.isEmpty()); | ||
250 | if (type != expectedType) { | ||
251 | // Skip revision | ||
252 | revisionCounter++; | ||
253 | continue; | ||
254 | } | ||
255 | const auto key = DataStore::assembleKey(uid, revisionCounter); | ||
256 | revisionCounter++; | ||
257 | callback(key); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | void EntityStore::readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback) | ||
262 | { | ||
263 | auto db = DataStore::mainDatabase(d->getTransaction(), type); | ||
264 | qint64 latestRevision = 0; | ||
265 | db.scan(uid, | ||
266 | [&latestRevision, revision](const QByteArray &key, const QByteArray &) -> bool { | ||
267 | const auto foundRevision = Sink::Storage::DataStore::revisionFromKey(key); | ||
268 | if (foundRevision < revision && foundRevision > latestRevision) { | ||
269 | latestRevision = foundRevision; | ||
270 | } | ||
271 | return true; | ||
272 | }, | ||
273 | [](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }, true); | ||
274 | return readEntity(type, Sink::Storage::DataStore::assembleKey(uid, latestRevision), callback); | ||
275 | } | ||
276 | |||
277 | void EntityStore::readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const ApplicationDomain::ApplicationDomainType &)> callback) | ||
278 | { | ||
279 | readPrevious(type, uid, revision, [&](const QByteArray &uid, const EntityBuffer &buffer) { | ||
280 | auto adaptor = d->resourceContext.adaptorFactory(type).createAdaptor(buffer.entity()); | ||
281 | callback(ApplicationDomain::ApplicationDomainType{d->resourceContext.instanceId(), uid, DataStore::maxRevision(d->getTransaction()), adaptor}); | ||
282 | }); | ||
283 | } | ||
284 | |||
285 | ApplicationDomain::ApplicationDomainType EntityStore::readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision) | ||
286 | { | ||
287 | ApplicationDomain::ApplicationDomainType dt; | ||
288 | readPrevious(type, uid, revision, [&](const ApplicationDomain::ApplicationDomainType &entity) { | ||
289 | dt = entity; | ||
290 | }); | ||
291 | return dt; | ||
292 | } | ||
293 | |||
294 | void EntityStore::readAllUids(const QByteArray &type, const std::function<void(const QByteArray &uid)> callback) | ||
295 | { | ||
296 | //TODO use uid index instead | ||
297 | //FIXME we currently report each uid for every revision with the same uid | ||
298 | auto db = DataStore::mainDatabase(d->getTransaction(), type); | ||
299 | db.scan("", | ||
300 | [callback](const QByteArray &key, const QByteArray &) -> bool { | ||
301 | callback(Sink::Storage::DataStore::uidFromKey(key)); | ||
302 | return true; | ||
303 | }, | ||
304 | [](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Failed to read current value from storage: " << error.message; }); | ||
305 | } | ||
306 | |||
307 | bool EntityStore::contains(const QByteArray &type, const QByteArray &uid) | ||
308 | { | ||
309 | return DataStore::mainDatabase(d->getTransaction(), type).contains(uid); | ||
310 | } | ||
311 | |||
312 | qint64 EntityStore::maxRevision() | ||
313 | { | ||
314 | return DataStore::maxRevision(d->getTransaction()); | ||
315 | } | ||
316 | |||
317 | /* DataStore::Transaction getTransaction() */ | ||
318 | /* { */ | ||
319 | /* Sink::Storage::DataStore::Transaction transaction; */ | ||
320 | /* { */ | ||
321 | /* Sink::Storage::DataStore storage(Sink::storageLocation(), mResourceInstanceIdentifier); */ | ||
322 | /* if (!storage.exists()) { */ | ||
323 | /* //This is not an error if the resource wasn't started before */ | ||
324 | /* SinkLog() << "Store doesn't exist: " << mResourceInstanceIdentifier; */ | ||
325 | /* return Sink::Storage::DataStore::Transaction(); */ | ||
326 | /* } */ | ||
327 | /* storage.setDefaultErrorHandler([this](const Sink::Storage::DataStore::Error &error) { SinkWarning() << "Error during query: " << error.store << error.message; }); */ | ||
328 | /* transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly); */ | ||
329 | /* } */ | ||
330 | |||
331 | /* //FIXME this is a temporary measure to recover from a failure to open the named databases correctly. */ | ||
332 | /* //Once the actual problem is fixed it will be enough to simply crash if we open the wrong database (which we check in openDatabase already). */ | ||
333 | /* while (!transaction.validateNamedDatabases()) { */ | ||
334 | /* Sink::Storage::DataStore storage(Sink::storageLocation(), mResourceInstanceIdentifier); */ | ||
335 | /* transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly); */ | ||
336 | /* } */ | ||
337 | /* return transaction; */ | ||
338 | /* } */ | ||
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h new file mode 100644 index 0000000..de29e87 --- /dev/null +++ b/common/storage/entitystore.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||
8 | * later version accepted by the membership of KDE e.V. (or its | ||
9 | * successor approved by the membership of KDE e.V.), which shall | ||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | #pragma once | ||
21 | |||
22 | #include "sink_export.h" | ||
23 | |||
24 | #include <memory> | ||
25 | #include "domaintypeadaptorfactoryinterface.h" | ||
26 | #include "query.h" | ||
27 | #include "storage.h" | ||
28 | #include "resourcecontext.h" | ||
29 | |||
30 | namespace Sink { | ||
31 | class EntityBuffer; | ||
32 | namespace Storage { | ||
33 | |||
34 | class SINK_EXPORT EntityStore | ||
35 | { | ||
36 | public: | ||
37 | typedef QSharedPointer<EntityStore> Ptr; | ||
38 | EntityStore(const ResourceContext &resourceContext); | ||
39 | |||
40 | void add(const ApplicationDomain::ApplicationDomainType &); | ||
41 | void modify(const ApplicationDomain::ApplicationDomainType &); | ||
42 | void remove(const ApplicationDomain::ApplicationDomainType &); | ||
43 | |||
44 | void startTransaction(Sink::Storage::DataStore::AccessMode); | ||
45 | void commitTransaction(); | ||
46 | void abortTransaction(); | ||
47 | |||
48 | QVector<QByteArray> fullScan(const QByteArray &type); | ||
49 | QVector<QByteArray> indexLookup(const QByteArray &type, const Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting); | ||
50 | QVector<QByteArray> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value); | ||
51 | void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback); | ||
52 | template<typename EntityType, typename PropertyType> | ||
53 | void indexLookup(const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) { | ||
54 | return indexLookup(ApplicationDomain::getTypeName<EntityType>(), PropertyType::name, value, callback); | ||
55 | } | ||
56 | |||
57 | void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); | ||
58 | void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); | ||
59 | |||
60 | ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid); | ||
61 | |||
62 | template<typename T> | ||
63 | T readLatest(const QByteArray &uid) { | ||
64 | return T(readLatest(ApplicationDomain::getTypeName<T>(), uid)); | ||
65 | } | ||
66 | |||
67 | void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); | ||
68 | void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); | ||
69 | ApplicationDomain::ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key); | ||
70 | |||
71 | template<typename T> | ||
72 | T readEntity(const QByteArray &key) { | ||
73 | return T(readEntity(ApplicationDomain::getTypeName<T>(), key)); | ||
74 | } | ||
75 | |||
76 | |||
77 | void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); | ||
78 | void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); | ||
79 | ApplicationDomain::ApplicationDomainType readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision); | ||
80 | |||
81 | template<typename T> | ||
82 | T readPrevious(const QByteArray &uid, qint64 revision) { | ||
83 | return T(readPrevious(ApplicationDomain::getTypeName<T>(), uid, revision)); | ||
84 | } | ||
85 | |||
86 | void readAllUids(const QByteArray &type, const std::function<void(const QByteArray &uid)> callback); | ||
87 | |||
88 | void readAll(const QByteArray &type, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> &callback); | ||
89 | |||
90 | template<typename T> | ||
91 | void readAll(const std::function<void(const T &entity)> &callback) { | ||
92 | return readAll(ApplicationDomain::getTypeName<T>(), [&](const ApplicationDomain::ApplicationDomainType &entity) { | ||
93 | callback(T(entity)); | ||
94 | }); | ||
95 | } | ||
96 | |||
97 | void readRevisions(qint64 baseRevision, const QByteArray &type, const std::function<void(const QByteArray &key)> &callback); | ||
98 | |||
99 | bool contains(const QByteArray &type, const QByteArray &uid); | ||
100 | |||
101 | qint64 maxRevision(); | ||
102 | |||
103 | private: | ||
104 | class Private; | ||
105 | const QSharedPointer<Private> d; | ||
106 | }; | ||
107 | |||
108 | } | ||
109 | } | ||
diff --git a/common/storage_common.cpp b/common/storage_common.cpp index 1f2594e..60ef83d 100644 --- a/common/storage_common.cpp +++ b/common/storage_common.cpp | |||
@@ -27,26 +27,27 @@ | |||
27 | SINK_DEBUG_AREA("storage") | 27 | SINK_DEBUG_AREA("storage") |
28 | 28 | ||
29 | namespace Sink { | 29 | namespace Sink { |
30 | namespace Storage { | ||
30 | 31 | ||
31 | static const char *s_internalPrefix = "__internal"; | 32 | static const char *s_internalPrefix = "__internal"; |
32 | static const int s_internalPrefixSize = strlen(s_internalPrefix); | 33 | static const int s_internalPrefixSize = strlen(s_internalPrefix); |
33 | 34 | ||
34 | void errorHandler(const Storage::Error &error) | 35 | void errorHandler(const DataStore::Error &error) |
35 | { | 36 | { |
36 | SinkWarning() << "Database error in " << error.store << ", code " << error.code << ", message: " << error.message; | 37 | SinkWarning() << "Database error in " << error.store << ", code " << error.code << ", message: " << error.message; |
37 | } | 38 | } |
38 | 39 | ||
39 | std::function<void(const Storage::Error &error)> Storage::basicErrorHandler() | 40 | std::function<void(const DataStore::Error &error)> DataStore::basicErrorHandler() |
40 | { | 41 | { |
41 | return errorHandler; | 42 | return errorHandler; |
42 | } | 43 | } |
43 | 44 | ||
44 | void Storage::setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler) | 45 | void DataStore::setDefaultErrorHandler(const std::function<void(const DataStore::Error &error)> &errorHandler) |
45 | { | 46 | { |
46 | mErrorHandler = errorHandler; | 47 | mErrorHandler = errorHandler; |
47 | } | 48 | } |
48 | 49 | ||
49 | std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() const | 50 | std::function<void(const DataStore::Error &error)> DataStore::defaultErrorHandler() const |
50 | { | 51 | { |
51 | if (mErrorHandler) { | 52 | if (mErrorHandler) { |
52 | return mErrorHandler; | 53 | return mErrorHandler; |
@@ -54,12 +55,12 @@ std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() | |||
54 | return basicErrorHandler(); | 55 | return basicErrorHandler(); |
55 | } | 56 | } |
56 | 57 | ||
57 | void Storage::setMaxRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 58 | void DataStore::setMaxRevision(DataStore::Transaction &transaction, qint64 revision) |
58 | { | 59 | { |
59 | transaction.openDatabase().write("__internal_maxRevision", QByteArray::number(revision)); | 60 | transaction.openDatabase().write("__internal_maxRevision", QByteArray::number(revision)); |
60 | } | 61 | } |
61 | 62 | ||
62 | qint64 Storage::maxRevision(const Sink::Storage::Transaction &transaction) | 63 | qint64 DataStore::maxRevision(const DataStore::Transaction &transaction) |
63 | { | 64 | { |
64 | qint64 r = 0; | 65 | qint64 r = 0; |
65 | transaction.openDatabase().scan("__internal_maxRevision", | 66 | transaction.openDatabase().scan("__internal_maxRevision", |
@@ -68,19 +69,19 @@ qint64 Storage::maxRevision(const Sink::Storage::Transaction &transaction) | |||
68 | return false; | 69 | return false; |
69 | }, | 70 | }, |
70 | [](const Error &error) { | 71 | [](const Error &error) { |
71 | if (error.code != Sink::Storage::NotFound) { | 72 | if (error.code != DataStore::NotFound) { |
72 | SinkWarning() << "Coultn'd find the maximum revision."; | 73 | SinkWarning() << "Coultn'd find the maximum revision."; |
73 | } | 74 | } |
74 | }); | 75 | }); |
75 | return r; | 76 | return r; |
76 | } | 77 | } |
77 | 78 | ||
78 | void Storage::setCleanedUpRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 79 | void DataStore::setCleanedUpRevision(DataStore::Transaction &transaction, qint64 revision) |
79 | { | 80 | { |
80 | transaction.openDatabase().write("__internal_cleanedUpRevision", QByteArray::number(revision)); | 81 | transaction.openDatabase().write("__internal_cleanedUpRevision", QByteArray::number(revision)); |
81 | } | 82 | } |
82 | 83 | ||
83 | qint64 Storage::cleanedUpRevision(const Sink::Storage::Transaction &transaction) | 84 | qint64 DataStore::cleanedUpRevision(const DataStore::Transaction &transaction) |
84 | { | 85 | { |
85 | qint64 r = 0; | 86 | qint64 r = 0; |
86 | transaction.openDatabase().scan("__internal_cleanedUpRevision", | 87 | transaction.openDatabase().scan("__internal_cleanedUpRevision", |
@@ -89,14 +90,14 @@ qint64 Storage::cleanedUpRevision(const Sink::Storage::Transaction &transaction) | |||
89 | return false; | 90 | return false; |
90 | }, | 91 | }, |
91 | [](const Error &error) { | 92 | [](const Error &error) { |
92 | if (error.code != Sink::Storage::NotFound) { | 93 | if (error.code != DataStore::NotFound) { |
93 | SinkWarning() << "Coultn'd find the maximum revision."; | 94 | SinkWarning() << "Coultn'd find the maximum revision."; |
94 | } | 95 | } |
95 | }); | 96 | }); |
96 | return r; | 97 | return r; |
97 | } | 98 | } |
98 | 99 | ||
99 | QByteArray Storage::getUidFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) | 100 | QByteArray DataStore::getUidFromRevision(const DataStore::Transaction &transaction, qint64 revision) |
100 | { | 101 | { |
101 | QByteArray uid; | 102 | QByteArray uid; |
102 | transaction.openDatabase("revisions") | 103 | transaction.openDatabase("revisions") |
@@ -109,7 +110,7 @@ QByteArray Storage::getUidFromRevision(const Sink::Storage::Transaction &transac | |||
109 | return uid; | 110 | return uid; |
110 | } | 111 | } |
111 | 112 | ||
112 | QByteArray Storage::getTypeFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) | 113 | QByteArray DataStore::getTypeFromRevision(const DataStore::Transaction &transaction, qint64 revision) |
113 | { | 114 | { |
114 | QByteArray type; | 115 | QByteArray type; |
115 | transaction.openDatabase("revisionType") | 116 | transaction.openDatabase("revisionType") |
@@ -122,25 +123,25 @@ QByteArray Storage::getTypeFromRevision(const Sink::Storage::Transaction &transa | |||
122 | return type; | 123 | return type; |
123 | } | 124 | } |
124 | 125 | ||
125 | void Storage::recordRevision(Sink::Storage::Transaction &transaction, qint64 revision, const QByteArray &uid, const QByteArray &type) | 126 | void DataStore::recordRevision(DataStore::Transaction &transaction, qint64 revision, const QByteArray &uid, const QByteArray &type) |
126 | { | 127 | { |
127 | // TODO use integerkeys | 128 | // TODO use integerkeys |
128 | transaction.openDatabase("revisions").write(QByteArray::number(revision), uid); | 129 | transaction.openDatabase("revisions").write(QByteArray::number(revision), uid); |
129 | transaction.openDatabase("revisionType").write(QByteArray::number(revision), type); | 130 | transaction.openDatabase("revisionType").write(QByteArray::number(revision), type); |
130 | } | 131 | } |
131 | 132 | ||
132 | void Storage::removeRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 133 | void DataStore::removeRevision(DataStore::Transaction &transaction, qint64 revision) |
133 | { | 134 | { |
134 | transaction.openDatabase("revisions").remove(QByteArray::number(revision)); | 135 | transaction.openDatabase("revisions").remove(QByteArray::number(revision)); |
135 | transaction.openDatabase("revisionType").remove(QByteArray::number(revision)); | 136 | transaction.openDatabase("revisionType").remove(QByteArray::number(revision)); |
136 | } | 137 | } |
137 | 138 | ||
138 | bool Storage::isInternalKey(const char *key) | 139 | bool DataStore::isInternalKey(const char *key) |
139 | { | 140 | { |
140 | return key && strncmp(key, s_internalPrefix, s_internalPrefixSize) == 0; | 141 | return key && strncmp(key, s_internalPrefix, s_internalPrefixSize) == 0; |
141 | } | 142 | } |
142 | 143 | ||
143 | bool Storage::isInternalKey(void *key, int size) | 144 | bool DataStore::isInternalKey(void *key, int size) |
144 | { | 145 | { |
145 | if (size < 1) { | 146 | if (size < 1) { |
146 | return false; | 147 | return false; |
@@ -149,39 +150,39 @@ bool Storage::isInternalKey(void *key, int size) | |||
149 | return key && strncmp(static_cast<char *>(key), s_internalPrefix, (size > s_internalPrefixSize ? s_internalPrefixSize : size)) == 0; | 150 | return key && strncmp(static_cast<char *>(key), s_internalPrefix, (size > s_internalPrefixSize ? s_internalPrefixSize : size)) == 0; |
150 | } | 151 | } |
151 | 152 | ||
152 | bool Storage::isInternalKey(const QByteArray &key) | 153 | bool DataStore::isInternalKey(const QByteArray &key) |
153 | { | 154 | { |
154 | return key.startsWith(s_internalPrefix); | 155 | return key.startsWith(s_internalPrefix); |
155 | } | 156 | } |
156 | 157 | ||
157 | QByteArray Storage::assembleKey(const QByteArray &key, qint64 revision) | 158 | QByteArray DataStore::assembleKey(const QByteArray &key, qint64 revision) |
158 | { | 159 | { |
159 | Q_ASSERT(revision <= 9223372036854775807); | 160 | Q_ASSERT(revision <= 9223372036854775807); |
160 | Q_ASSERT(key.size() == 38); | 161 | Q_ASSERT(key.size() == 38); |
161 | return key + QByteArray::number(revision).rightJustified(19, '0', false); | 162 | return key + QByteArray::number(revision).rightJustified(19, '0', false); |
162 | } | 163 | } |
163 | 164 | ||
164 | QByteArray Storage::uidFromKey(const QByteArray &key) | 165 | QByteArray DataStore::uidFromKey(const QByteArray &key) |
165 | { | 166 | { |
166 | return key.mid(0, 38); | 167 | return key.mid(0, 38); |
167 | } | 168 | } |
168 | 169 | ||
169 | qint64 Storage::revisionFromKey(const QByteArray &key) | 170 | qint64 DataStore::revisionFromKey(const QByteArray &key) |
170 | { | 171 | { |
171 | return key.mid(39).toLongLong(); | 172 | return key.mid(39).toLongLong(); |
172 | } | 173 | } |
173 | 174 | ||
174 | QByteArray Storage::generateUid() | 175 | QByteArray DataStore::generateUid() |
175 | { | 176 | { |
176 | return QUuid::createUuid().toByteArray(); | 177 | return QUuid::createUuid().toByteArray(); |
177 | } | 178 | } |
178 | 179 | ||
179 | Storage::NamedDatabase Storage::mainDatabase(const Sink::Storage::Transaction &t, const QByteArray &type) | 180 | DataStore::NamedDatabase DataStore::mainDatabase(const DataStore::Transaction &t, const QByteArray &type) |
180 | { | 181 | { |
181 | return t.openDatabase(type + ".main"); | 182 | return t.openDatabase(type + ".main"); |
182 | } | 183 | } |
183 | 184 | ||
184 | bool Storage::NamedDatabase::contains(const QByteArray &uid) | 185 | bool DataStore::NamedDatabase::contains(const QByteArray &uid) |
185 | { | 186 | { |
186 | bool found = false; | 187 | bool found = false; |
187 | scan(uid, | 188 | scan(uid, |
@@ -189,8 +190,9 @@ bool Storage::NamedDatabase::contains(const QByteArray &uid) | |||
189 | found = true; | 190 | found = true; |
190 | return false; | 191 | return false; |
191 | }, | 192 | }, |
192 | [this](const Sink::Storage::Error &error) {}, true); | 193 | [this](const DataStore::Error &error) {}, true); |
193 | return found; | 194 | return found; |
194 | } | 195 | } |
195 | 196 | ||
197 | } | ||
196 | } // namespace Sink | 198 | } // namespace Sink |
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index 6f11af3..e418472 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp | |||
@@ -39,6 +39,7 @@ SINK_DEBUG_AREA("storage") | |||
39 | // SINK_DEBUG_COMPONENT(d->storageRoot.toLatin1() + '/' + d->name.toLatin1()) | 39 | // SINK_DEBUG_COMPONENT(d->storageRoot.toLatin1() + '/' + d->name.toLatin1()) |
40 | 40 | ||
41 | namespace Sink { | 41 | namespace Sink { |
42 | namespace Storage { | ||
42 | 43 | ||
43 | QMutex sMutex; | 44 | QMutex sMutex; |
44 | QHash<QString, MDB_env *> sEnvironments; | 45 | QHash<QString, MDB_env *> sEnvironments; |
@@ -47,17 +48,17 @@ int getErrorCode(int e) | |||
47 | { | 48 | { |
48 | switch (e) { | 49 | switch (e) { |
49 | case MDB_NOTFOUND: | 50 | case MDB_NOTFOUND: |
50 | return Storage::ErrorCodes::NotFound; | 51 | return DataStore::ErrorCodes::NotFound; |
51 | default: | 52 | default: |
52 | break; | 53 | break; |
53 | } | 54 | } |
54 | return -1; | 55 | return -1; |
55 | } | 56 | } |
56 | 57 | ||
57 | class Storage::NamedDatabase::Private | 58 | class DataStore::NamedDatabase::Private |
58 | { | 59 | { |
59 | public: | 60 | public: |
60 | Private(const QByteArray &_db, bool _allowDuplicates, const std::function<void(const Storage::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_txn *_txn) | 61 | Private(const QByteArray &_db, bool _allowDuplicates, const std::function<void(const DataStore::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_txn *_txn) |
61 | : db(_db), transaction(_txn), allowDuplicates(_allowDuplicates), defaultErrorHandler(_defaultErrorHandler), name(_name) | 62 | : db(_db), transaction(_txn), allowDuplicates(_allowDuplicates), defaultErrorHandler(_defaultErrorHandler), name(_name) |
62 | { | 63 | { |
63 | } | 64 | } |
@@ -70,10 +71,10 @@ public: | |||
70 | MDB_txn *transaction; | 71 | MDB_txn *transaction; |
71 | MDB_dbi dbi; | 72 | MDB_dbi dbi; |
72 | bool allowDuplicates; | 73 | bool allowDuplicates; |
73 | std::function<void(const Storage::Error &error)> defaultErrorHandler; | 74 | std::function<void(const DataStore::Error &error)> defaultErrorHandler; |
74 | QString name; | 75 | QString name; |
75 | 76 | ||
76 | bool openDatabase(bool readOnly, std::function<void(const Storage::Error &error)> errorHandler) | 77 | bool openDatabase(bool readOnly, std::function<void(const DataStore::Error &error)> errorHandler) |
77 | { | 78 | { |
78 | unsigned int flags = 0; | 79 | unsigned int flags = 0; |
79 | if (!readOnly) { | 80 | if (!readOnly) { |
@@ -97,20 +98,20 @@ public: | |||
97 | } | 98 | } |
98 | }; | 99 | }; |
99 | 100 | ||
100 | Storage::NamedDatabase::NamedDatabase() : d(nullptr) | 101 | DataStore::NamedDatabase::NamedDatabase() : d(nullptr) |
101 | { | 102 | { |
102 | } | 103 | } |
103 | 104 | ||
104 | Storage::NamedDatabase::NamedDatabase(NamedDatabase::Private *prv) : d(prv) | 105 | DataStore::NamedDatabase::NamedDatabase(NamedDatabase::Private *prv) : d(prv) |
105 | { | 106 | { |
106 | } | 107 | } |
107 | 108 | ||
108 | Storage::NamedDatabase::NamedDatabase(NamedDatabase &&other) : d(nullptr) | 109 | DataStore::NamedDatabase::NamedDatabase(NamedDatabase &&other) : d(nullptr) |
109 | { | 110 | { |
110 | *this = std::move(other); | 111 | *this = std::move(other); |
111 | } | 112 | } |
112 | 113 | ||
113 | Storage::NamedDatabase &Storage::NamedDatabase::operator=(Storage::NamedDatabase &&other) | 114 | DataStore::NamedDatabase &DataStore::NamedDatabase::operator=(DataStore::NamedDatabase &&other) |
114 | { | 115 | { |
115 | if (&other != this) { | 116 | if (&other != this) { |
116 | delete d; | 117 | delete d; |
@@ -120,12 +121,12 @@ Storage::NamedDatabase &Storage::NamedDatabase::operator=(Storage::NamedDatabase | |||
120 | return *this; | 121 | return *this; |
121 | } | 122 | } |
122 | 123 | ||
123 | Storage::NamedDatabase::~NamedDatabase() | 124 | DataStore::NamedDatabase::~NamedDatabase() |
124 | { | 125 | { |
125 | delete d; | 126 | delete d; |
126 | } | 127 | } |
127 | 128 | ||
128 | bool Storage::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sValue, const std::function<void(const Storage::Error &error)> &errorHandler) | 129 | bool DataStore::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sValue, const std::function<void(const DataStore::Error &error)> &errorHandler) |
129 | { | 130 | { |
130 | if (!d || !d->transaction) { | 131 | if (!d || !d->transaction) { |
131 | Error error("", ErrorCodes::GenericError, "Not open"); | 132 | Error error("", ErrorCodes::GenericError, "Not open"); |
@@ -161,12 +162,12 @@ bool Storage::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sVa | |||
161 | return !rc; | 162 | return !rc; |
162 | } | 163 | } |
163 | 164 | ||
164 | void Storage::NamedDatabase::remove(const QByteArray &k, const std::function<void(const Storage::Error &error)> &errorHandler) | 165 | void DataStore::NamedDatabase::remove(const QByteArray &k, const std::function<void(const DataStore::Error &error)> &errorHandler) |
165 | { | 166 | { |
166 | remove(k, QByteArray(), errorHandler); | 167 | remove(k, QByteArray(), errorHandler); |
167 | } | 168 | } |
168 | 169 | ||
169 | void Storage::NamedDatabase::remove(const QByteArray &k, const QByteArray &value, const std::function<void(const Storage::Error &error)> &errorHandler) | 170 | void DataStore::NamedDatabase::remove(const QByteArray &k, const QByteArray &value, const std::function<void(const DataStore::Error &error)> &errorHandler) |
170 | { | 171 | { |
171 | if (!d || !d->transaction) { | 172 | if (!d || !d->transaction) { |
172 | if (d) { | 173 | if (d) { |
@@ -195,8 +196,8 @@ void Storage::NamedDatabase::remove(const QByteArray &k, const QByteArray &value | |||
195 | } | 196 | } |
196 | } | 197 | } |
197 | 198 | ||
198 | int Storage::NamedDatabase::scan(const QByteArray &k, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, | 199 | int DataStore::NamedDatabase::scan(const QByteArray &k, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, |
199 | const std::function<void(const Storage::Error &error)> &errorHandler, bool findSubstringKeys, bool skipInternalKeys) const | 200 | const std::function<void(const DataStore::Error &error)> &errorHandler, bool findSubstringKeys, bool skipInternalKeys) const |
200 | { | 201 | { |
201 | if (!d || !d->transaction) { | 202 | if (!d || !d->transaction) { |
202 | // Not an error. We rely on this to read nothing from non-existing databases. | 203 | // Not an error. We rely on this to read nothing from non-existing databases. |
@@ -278,8 +279,8 @@ int Storage::NamedDatabase::scan(const QByteArray &k, const std::function<bool(c | |||
278 | return numberOfRetrievedValues; | 279 | return numberOfRetrievedValues; |
279 | } | 280 | } |
280 | 281 | ||
281 | void Storage::NamedDatabase::findLatest(const QByteArray &k, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, | 282 | void DataStore::NamedDatabase::findLatest(const QByteArray &k, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, |
282 | const std::function<void(const Storage::Error &error)> &errorHandler) const | 283 | const std::function<void(const DataStore::Error &error)> &errorHandler) const |
283 | { | 284 | { |
284 | if (!d || !d->transaction) { | 285 | if (!d || !d->transaction) { |
285 | // Not an error. We rely on this to read nothing from non-existing databases. | 286 | // Not an error. We rely on this to read nothing from non-existing databases. |
@@ -346,7 +347,7 @@ void Storage::NamedDatabase::findLatest(const QByteArray &k, const std::function | |||
346 | return; | 347 | return; |
347 | } | 348 | } |
348 | 349 | ||
349 | qint64 Storage::NamedDatabase::getSize() | 350 | qint64 DataStore::NamedDatabase::getSize() |
350 | { | 351 | { |
351 | if (!d || !d->transaction) { | 352 | if (!d || !d->transaction) { |
352 | return -1; | 353 | return -1; |
@@ -368,10 +369,10 @@ qint64 Storage::NamedDatabase::getSize() | |||
368 | } | 369 | } |
369 | 370 | ||
370 | 371 | ||
371 | class Storage::Transaction::Private | 372 | class DataStore::Transaction::Private |
372 | { | 373 | { |
373 | public: | 374 | public: |
374 | Private(bool _requestRead, const std::function<void(const Storage::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_env *_env) | 375 | Private(bool _requestRead, const std::function<void(const DataStore::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_env *_env) |
375 | : env(_env), transaction(nullptr), requestedRead(_requestRead), defaultErrorHandler(_defaultErrorHandler), name(_name), implicitCommit(false), error(false), modificationCounter(0) | 376 | : env(_env), transaction(nullptr), requestedRead(_requestRead), defaultErrorHandler(_defaultErrorHandler), name(_name), implicitCommit(false), error(false), modificationCounter(0) |
376 | { | 377 | { |
377 | } | 378 | } |
@@ -383,7 +384,7 @@ public: | |||
383 | MDB_txn *transaction; | 384 | MDB_txn *transaction; |
384 | MDB_dbi dbi; | 385 | MDB_dbi dbi; |
385 | bool requestedRead; | 386 | bool requestedRead; |
386 | std::function<void(const Storage::Error &error)> defaultErrorHandler; | 387 | std::function<void(const DataStore::Error &error)> defaultErrorHandler; |
387 | QString name; | 388 | QString name; |
388 | bool implicitCommit; | 389 | bool implicitCommit; |
389 | bool error; | 390 | bool error; |
@@ -406,21 +407,21 @@ public: | |||
406 | } | 407 | } |
407 | }; | 408 | }; |
408 | 409 | ||
409 | Storage::Transaction::Transaction() : d(nullptr) | 410 | DataStore::Transaction::Transaction() : d(nullptr) |
410 | { | 411 | { |
411 | } | 412 | } |
412 | 413 | ||
413 | Storage::Transaction::Transaction(Transaction::Private *prv) : d(prv) | 414 | DataStore::Transaction::Transaction(Transaction::Private *prv) : d(prv) |
414 | { | 415 | { |
415 | d->startTransaction(); | 416 | d->startTransaction(); |
416 | } | 417 | } |
417 | 418 | ||
418 | Storage::Transaction::Transaction(Transaction &&other) : d(nullptr) | 419 | DataStore::Transaction::Transaction(Transaction &&other) : d(nullptr) |
419 | { | 420 | { |
420 | *this = std::move(other); | 421 | *this = std::move(other); |
421 | } | 422 | } |
422 | 423 | ||
423 | Storage::Transaction &Storage::Transaction::operator=(Storage::Transaction &&other) | 424 | DataStore::Transaction &DataStore::Transaction::operator=(DataStore::Transaction &&other) |
424 | { | 425 | { |
425 | if (&other != this) { | 426 | if (&other != this) { |
426 | delete d; | 427 | delete d; |
@@ -430,7 +431,7 @@ Storage::Transaction &Storage::Transaction::operator=(Storage::Transaction &&oth | |||
430 | return *this; | 431 | return *this; |
431 | } | 432 | } |
432 | 433 | ||
433 | Storage::Transaction::~Transaction() | 434 | DataStore::Transaction::~Transaction() |
434 | { | 435 | { |
435 | if (d && d->transaction) { | 436 | if (d && d->transaction) { |
436 | if (d->implicitCommit && !d->error) { | 437 | if (d->implicitCommit && !d->error) { |
@@ -443,12 +444,12 @@ Storage::Transaction::~Transaction() | |||
443 | delete d; | 444 | delete d; |
444 | } | 445 | } |
445 | 446 | ||
446 | Storage::Transaction::operator bool() const | 447 | DataStore::Transaction::operator bool() const |
447 | { | 448 | { |
448 | return (d && d->transaction); | 449 | return (d && d->transaction); |
449 | } | 450 | } |
450 | 451 | ||
451 | bool Storage::Transaction::commit(const std::function<void(const Storage::Error &error)> &errorHandler) | 452 | bool DataStore::Transaction::commit(const std::function<void(const DataStore::Error &error)> &errorHandler) |
452 | { | 453 | { |
453 | if (!d || !d->transaction) { | 454 | if (!d || !d->transaction) { |
454 | return false; | 455 | return false; |
@@ -467,7 +468,7 @@ bool Storage::Transaction::commit(const std::function<void(const Storage::Error | |||
467 | return !rc; | 468 | return !rc; |
468 | } | 469 | } |
469 | 470 | ||
470 | void Storage::Transaction::abort() | 471 | void DataStore::Transaction::abort() |
471 | { | 472 | { |
472 | if (!d || !d->transaction) { | 473 | if (!d || !d->transaction) { |
473 | return; | 474 | return; |
@@ -481,7 +482,7 @@ void Storage::Transaction::abort() | |||
481 | 482 | ||
482 | //Ensure that we opened the correct database by comparing the expected identifier with the one | 483 | //Ensure that we opened the correct database by comparing the expected identifier with the one |
483 | //we write to the database on first open. | 484 | //we write to the database on first open. |
484 | static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray &db, bool readOnly) | 485 | static bool ensureCorrectDb(DataStore::NamedDatabase &database, const QByteArray &db, bool readOnly) |
485 | { | 486 | { |
486 | bool openedTheWrongDatabase = false; | 487 | bool openedTheWrongDatabase = false; |
487 | auto count = database.scan("__internal_dbname", [db, &openedTheWrongDatabase](const QByteArray &key, const QByteArray &value) ->bool { | 488 | auto count = database.scan("__internal_dbname", [db, &openedTheWrongDatabase](const QByteArray &key, const QByteArray &value) ->bool { |
@@ -491,7 +492,7 @@ static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray & | |||
491 | } | 492 | } |
492 | return false; | 493 | return false; |
493 | }, | 494 | }, |
494 | [](const Storage::Error &error) -> bool{ | 495 | [](const DataStore::Error &error) -> bool{ |
495 | return false; | 496 | return false; |
496 | }, false); | 497 | }, false); |
497 | //This is the first time we open this database in a write transaction, write the db name | 498 | //This is the first time we open this database in a write transaction, write the db name |
@@ -503,7 +504,7 @@ static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray & | |||
503 | return !openedTheWrongDatabase; | 504 | return !openedTheWrongDatabase; |
504 | } | 505 | } |
505 | 506 | ||
506 | bool Storage::Transaction::validateNamedDatabases() | 507 | bool DataStore::Transaction::validateNamedDatabases() |
507 | { | 508 | { |
508 | auto databases = getDatabaseNames(); | 509 | auto databases = getDatabaseNames(); |
509 | for (const auto &dbName : databases) { | 510 | for (const auto &dbName : databases) { |
@@ -516,28 +517,28 @@ bool Storage::Transaction::validateNamedDatabases() | |||
516 | return true; | 517 | return true; |
517 | } | 518 | } |
518 | 519 | ||
519 | Storage::NamedDatabase Storage::Transaction::openDatabase(const QByteArray &db, const std::function<void(const Storage::Error &error)> &errorHandler, bool allowDuplicates) const | 520 | DataStore::NamedDatabase DataStore::Transaction::openDatabase(const QByteArray &db, const std::function<void(const DataStore::Error &error)> &errorHandler, bool allowDuplicates) const |
520 | { | 521 | { |
521 | if (!d) { | 522 | if (!d) { |
522 | return Storage::NamedDatabase(); | 523 | return DataStore::NamedDatabase(); |
523 | } | 524 | } |
524 | Q_ASSERT(d->transaction); | 525 | Q_ASSERT(d->transaction); |
525 | // We don't now if anything changed | 526 | // We don't now if anything changed |
526 | d->implicitCommit = true; | 527 | d->implicitCommit = true; |
527 | auto p = new Storage::NamedDatabase::Private(db, allowDuplicates, d->defaultErrorHandler, d->name, d->transaction); | 528 | auto p = new DataStore::NamedDatabase::Private(db, allowDuplicates, d->defaultErrorHandler, d->name, d->transaction); |
528 | if (!p->openDatabase(d->requestedRead, errorHandler)) { | 529 | if (!p->openDatabase(d->requestedRead, errorHandler)) { |
529 | delete p; | 530 | delete p; |
530 | return Storage::NamedDatabase(); | 531 | return DataStore::NamedDatabase(); |
531 | } | 532 | } |
532 | auto database = Storage::NamedDatabase(p); | 533 | auto database = DataStore::NamedDatabase(p); |
533 | if (!ensureCorrectDb(database, db, d->requestedRead)) { | 534 | if (!ensureCorrectDb(database, db, d->requestedRead)) { |
534 | SinkWarning() << "Failed to open the database" << db; | 535 | SinkWarning() << "Failed to open the database" << db; |
535 | return Storage::NamedDatabase(); | 536 | return DataStore::NamedDatabase(); |
536 | } | 537 | } |
537 | return database; | 538 | return database; |
538 | } | 539 | } |
539 | 540 | ||
540 | QList<QByteArray> Storage::Transaction::getDatabaseNames() const | 541 | QList<QByteArray> DataStore::Transaction::getDatabaseNames() const |
541 | { | 542 | { |
542 | if (!d) { | 543 | if (!d) { |
543 | SinkWarning() << "Invalid transaction"; | 544 | SinkWarning() << "Invalid transaction"; |
@@ -574,7 +575,7 @@ QList<QByteArray> Storage::Transaction::getDatabaseNames() const | |||
574 | } | 575 | } |
575 | 576 | ||
576 | 577 | ||
577 | class Storage::Private | 578 | class DataStore::Private |
578 | { | 579 | { |
579 | public: | 580 | public: |
580 | Private(const QString &s, const QString &n, AccessMode m); | 581 | Private(const QString &s, const QString &n, AccessMode m); |
@@ -587,7 +588,7 @@ public: | |||
587 | AccessMode mode; | 588 | AccessMode mode; |
588 | }; | 589 | }; |
589 | 590 | ||
590 | Storage::Private::Private(const QString &s, const QString &n, AccessMode m) : storageRoot(s), name(n), env(0), mode(m) | 591 | DataStore::Private::Private(const QString &s, const QString &n, AccessMode m) : storageRoot(s), name(n), env(0), mode(m) |
591 | { | 592 | { |
592 | const QString fullPath(storageRoot + '/' + name); | 593 | const QString fullPath(storageRoot + '/' + name); |
593 | QFileInfo dirInfo(fullPath); | 594 | QFileInfo dirInfo(fullPath); |
@@ -639,27 +640,27 @@ Storage::Private::Private(const QString &s, const QString &n, AccessMode m) : st | |||
639 | } | 640 | } |
640 | } | 641 | } |
641 | 642 | ||
642 | Storage::Private::~Private() | 643 | DataStore::Private::~Private() |
643 | { | 644 | { |
644 | //We never close the environment (unless we remove the db), since we should only open the environment once per process (as per lmdb docs) | 645 | //We never close the environment (unless we remove the db), since we should only open the environment once per process (as per lmdb docs) |
645 | //and create storage instance from all over the place. Thus, we're not closing it here on purpose. | 646 | //and create storage instance from all over the place. Thus, we're not closing it here on purpose. |
646 | } | 647 | } |
647 | 648 | ||
648 | Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) : d(new Private(storageRoot, name, mode)) | 649 | DataStore::DataStore(const QString &storageRoot, const QString &name, AccessMode mode) : d(new Private(storageRoot, name, mode)) |
649 | { | 650 | { |
650 | } | 651 | } |
651 | 652 | ||
652 | Storage::~Storage() | 653 | DataStore::~DataStore() |
653 | { | 654 | { |
654 | delete d; | 655 | delete d; |
655 | } | 656 | } |
656 | 657 | ||
657 | bool Storage::exists() const | 658 | bool DataStore::exists() const |
658 | { | 659 | { |
659 | return (d->env != 0); | 660 | return (d->env != 0); |
660 | } | 661 | } |
661 | 662 | ||
662 | Storage::Transaction Storage::createTransaction(AccessMode type, const std::function<void(const Storage::Error &error)> &errorHandlerArg) | 663 | DataStore::Transaction DataStore::createTransaction(AccessMode type, const std::function<void(const DataStore::Error &error)> &errorHandlerArg) |
663 | { | 664 | { |
664 | auto errorHandler = errorHandlerArg ? errorHandlerArg : defaultErrorHandler(); | 665 | auto errorHandler = errorHandlerArg ? errorHandlerArg : defaultErrorHandler(); |
665 | if (!d->env) { | 666 | if (!d->env) { |
@@ -677,7 +678,7 @@ Storage::Transaction Storage::createTransaction(AccessMode type, const std::func | |||
677 | return Transaction(new Transaction::Private(requestedRead, defaultErrorHandler(), d->name, d->env)); | 678 | return Transaction(new Transaction::Private(requestedRead, defaultErrorHandler(), d->name, d->env)); |
678 | } | 679 | } |
679 | 680 | ||
680 | qint64 Storage::diskUsage() const | 681 | qint64 DataStore::diskUsage() const |
681 | { | 682 | { |
682 | QFileInfo info(d->storageRoot + '/' + d->name + "/data.mdb"); | 683 | QFileInfo info(d->storageRoot + '/' + d->name + "/data.mdb"); |
683 | if (!info.exists()) { | 684 | if (!info.exists()) { |
@@ -686,7 +687,7 @@ qint64 Storage::diskUsage() const | |||
686 | return info.size(); | 687 | return info.size(); |
687 | } | 688 | } |
688 | 689 | ||
689 | void Storage::removeFromDisk() const | 690 | void DataStore::removeFromDisk() const |
690 | { | 691 | { |
691 | const QString fullPath(d->storageRoot + '/' + d->name); | 692 | const QString fullPath(d->storageRoot + '/' + d->name); |
692 | QMutexLocker locker(&sMutex); | 693 | QMutexLocker locker(&sMutex); |
@@ -701,7 +702,7 @@ void Storage::removeFromDisk() const | |||
701 | } | 702 | } |
702 | } | 703 | } |
703 | 704 | ||
704 | void Storage::clearEnv() | 705 | void DataStore::clearEnv() |
705 | { | 706 | { |
706 | for (auto env : sEnvironments) { | 707 | for (auto env : sEnvironments) { |
707 | mdb_env_close(env); | 708 | mdb_env_close(env); |
@@ -709,4 +710,5 @@ void Storage::clearEnv() | |||
709 | sEnvironments.clear(); | 710 | sEnvironments.clear(); |
710 | } | 711 | } |
711 | 712 | ||
713 | } | ||
712 | } // namespace Sink | 714 | } // namespace Sink |
diff --git a/common/store.cpp b/common/store.cpp index 0ecdcd2..52fec2e 100644 --- a/common/store.cpp +++ b/common/store.cpp | |||
@@ -230,7 +230,7 @@ KAsync::Job<void> Store::removeDataFromDisk(const QByteArray &identifier) | |||
230 | { | 230 | { |
231 | // All databases are going to become invalid, nuke the environments | 231 | // All databases are going to become invalid, nuke the environments |
232 | // TODO: all clients should react to a notification the resource | 232 | // TODO: all clients should react to a notification the resource |
233 | Sink::Storage::clearEnv(); | 233 | Sink::Storage::DataStore::clearEnv(); |
234 | SinkTrace() << "Remove data from disk " << identifier; | 234 | SinkTrace() << "Remove data from disk " << identifier; |
235 | auto time = QSharedPointer<QTime>::create(); | 235 | auto time = QSharedPointer<QTime>::create(); |
236 | time->start(); | 236 | time->start(); |
diff --git a/common/synchronizer.cpp b/common/synchronizer.cpp index 53db82f..5ddd77c 100644 --- a/common/synchronizer.cpp +++ b/common/synchronizer.cpp | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "bufferutils.h" | 24 | #include "bufferutils.h" |
25 | #include "entitystore.h" | 25 | #include "entitystore.h" |
26 | #include "remoteidmap.h" | 26 | #include "remoteidmap.h" |
27 | #include "adaptorfactoryregistry.h" | 27 | #include "entityreader.h" |
28 | #include "createentity_generated.h" | 28 | #include "createentity_generated.h" |
29 | #include "modifyentity_generated.h" | 29 | #include "modifyentity_generated.h" |
30 | #include "deleteentity_generated.h" | 30 | #include "deleteentity_generated.h" |
@@ -33,13 +33,12 @@ SINK_DEBUG_AREA("synchronizer") | |||
33 | 33 | ||
34 | using namespace Sink; | 34 | using namespace Sink; |
35 | 35 | ||
36 | Synchronizer::Synchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 36 | Synchronizer::Synchronizer(const Sink::ResourceContext &context) |
37 | : mStorage(Sink::storageLocation(), resourceInstanceIdentifier, Sink::Storage::ReadOnly), | 37 | : mResourceContext(context), |
38 | mSyncStorage(Sink::storageLocation(), resourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadWrite), | 38 | mEntityStore(Storage::EntityStore::Ptr::create(mResourceContext)), |
39 | mResourceType(resourceType), | 39 | mSyncStorage(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::DataStore::ReadWrite) |
40 | mResourceInstanceIdentifier(resourceInstanceIdentifier) | ||
41 | { | 40 | { |
42 | SinkTrace() << "Starting synchronizer: " << resourceType << resourceInstanceIdentifier; | 41 | SinkTrace() << "Starting synchronizer: " << mResourceContext.resourceType << mResourceContext.instanceId(); |
43 | } | 42 | } |
44 | 43 | ||
45 | Synchronizer::~Synchronizer() | 44 | Synchronizer::~Synchronizer() |
@@ -59,11 +58,9 @@ void Synchronizer::enqueueCommand(int commandId, const QByteArray &data) | |||
59 | mEnqueue(commandId, data); | 58 | mEnqueue(commandId, data); |
60 | } | 59 | } |
61 | 60 | ||
62 | EntityStore &Synchronizer::store() | 61 | Storage::EntityStore &Synchronizer::store() |
63 | { | 62 | { |
64 | if (!mEntityStore) { | 63 | mEntityStore->startTransaction(Sink::Storage::DataStore::ReadOnly); |
65 | mEntityStore = QSharedPointer<EntityStore>::create(mResourceType, mResourceInstanceIdentifier, transaction()); | ||
66 | } | ||
67 | return *mEntityStore; | 64 | return *mEntityStore; |
68 | } | 65 | } |
69 | 66 | ||
@@ -75,13 +72,12 @@ RemoteIdMap &Synchronizer::syncStore() | |||
75 | return *mSyncStore; | 72 | return *mSyncStore; |
76 | } | 73 | } |
77 | 74 | ||
78 | void Synchronizer::createEntity(const QByteArray &sinkId, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject, | 75 | void Synchronizer::createEntity(const QByteArray &sinkId, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject) |
79 | DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback) | ||
80 | { | 76 | { |
81 | // These changes are coming from the source | 77 | // These changes are coming from the source |
82 | const auto replayToSource = false; | 78 | const auto replayToSource = false; |
83 | flatbuffers::FlatBufferBuilder entityFbb; | 79 | flatbuffers::FlatBufferBuilder entityFbb; |
84 | adaptorFactory.createBuffer(domainObject, entityFbb); | 80 | mResourceContext.adaptorFactory(bufferType).createBuffer(domainObject, entityFbb); |
85 | flatbuffers::FlatBufferBuilder fbb; | 81 | flatbuffers::FlatBufferBuilder fbb; |
86 | // This is the resource type and not the domain type | 82 | // This is the resource type and not the domain type |
87 | auto entityId = fbb.CreateString(sinkId.toStdString()); | 83 | auto entityId = fbb.CreateString(sinkId.toStdString()); |
@@ -89,18 +85,17 @@ void Synchronizer::createEntity(const QByteArray &sinkId, const QByteArray &buff | |||
89 | auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); | 85 | auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); |
90 | auto location = Sink::Commands::CreateCreateEntity(fbb, entityId, type, delta, replayToSource); | 86 | auto location = Sink::Commands::CreateCreateEntity(fbb, entityId, type, delta, replayToSource); |
91 | Sink::Commands::FinishCreateEntityBuffer(fbb, location); | 87 | Sink::Commands::FinishCreateEntityBuffer(fbb, location); |
92 | callback(BufferUtils::extractBuffer(fbb)); | 88 | enqueueCommand(Sink::Commands::CreateEntityCommand, BufferUtils::extractBuffer(fbb)); |
93 | } | 89 | } |
94 | 90 | ||
95 | void Synchronizer::modifyEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject, | 91 | void Synchronizer::modifyEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject) |
96 | DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback) | ||
97 | { | 92 | { |
98 | // FIXME removals | 93 | // FIXME removals |
99 | QByteArrayList deletedProperties; | 94 | QByteArrayList deletedProperties; |
100 | // These changes are coming from the source | 95 | // These changes are coming from the source |
101 | const auto replayToSource = false; | 96 | const auto replayToSource = false; |
102 | flatbuffers::FlatBufferBuilder entityFbb; | 97 | flatbuffers::FlatBufferBuilder entityFbb; |
103 | adaptorFactory.createBuffer(domainObject, entityFbb); | 98 | mResourceContext.adaptorFactory(bufferType).createBuffer(domainObject, entityFbb); |
104 | flatbuffers::FlatBufferBuilder fbb; | 99 | flatbuffers::FlatBufferBuilder fbb; |
105 | auto entityId = fbb.CreateString(sinkId.toStdString()); | 100 | auto entityId = fbb.CreateString(sinkId.toStdString()); |
106 | auto modifiedProperties = BufferUtils::toVector(fbb, domainObject.changedProperties()); | 101 | auto modifiedProperties = BufferUtils::toVector(fbb, domainObject.changedProperties()); |
@@ -110,10 +105,10 @@ void Synchronizer::modifyEntity(const QByteArray &sinkId, qint64 revision, const | |||
110 | auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); | 105 | auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); |
111 | auto location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, deletions, type, delta, replayToSource, modifiedProperties); | 106 | auto location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, deletions, type, delta, replayToSource, modifiedProperties); |
112 | Sink::Commands::FinishModifyEntityBuffer(fbb, location); | 107 | Sink::Commands::FinishModifyEntityBuffer(fbb, location); |
113 | callback(BufferUtils::extractBuffer(fbb)); | 108 | enqueueCommand(Sink::Commands::ModifyEntityCommand, BufferUtils::extractBuffer(fbb)); |
114 | } | 109 | } |
115 | 110 | ||
116 | void Synchronizer::deleteEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType, std::function<void(const QByteArray &)> callback) | 111 | void Synchronizer::deleteEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType) |
117 | { | 112 | { |
118 | // These changes are coming from the source | 113 | // These changes are coming from the source |
119 | const auto replayToSource = false; | 114 | const auto replayToSource = false; |
@@ -123,63 +118,69 @@ void Synchronizer::deleteEntity(const QByteArray &sinkId, qint64 revision, const | |||
123 | auto type = fbb.CreateString(bufferType.toStdString()); | 118 | auto type = fbb.CreateString(bufferType.toStdString()); |
124 | auto location = Sink::Commands::CreateDeleteEntity(fbb, revision, entityId, type, replayToSource); | 119 | auto location = Sink::Commands::CreateDeleteEntity(fbb, revision, entityId, type, replayToSource); |
125 | Sink::Commands::FinishDeleteEntityBuffer(fbb, location); | 120 | Sink::Commands::FinishDeleteEntityBuffer(fbb, location); |
126 | callback(BufferUtils::extractBuffer(fbb)); | 121 | enqueueCommand(Sink::Commands::DeleteEntityCommand, BufferUtils::extractBuffer(fbb)); |
127 | } | 122 | } |
128 | 123 | ||
129 | void Synchronizer::scanForRemovals(const QByteArray &bufferType, const std::function<void(const std::function<void(const QByteArray &key)> &callback)> &entryGenerator, std::function<bool(const QByteArray &remoteId)> exists) | 124 | void Synchronizer::scanForRemovals(const QByteArray &bufferType, const std::function<void(const std::function<void(const QByteArray &key)> &callback)> &entryGenerator, std::function<bool(const QByteArray &remoteId)> exists) |
130 | { | 125 | { |
131 | entryGenerator([this, bufferType, &exists](const QByteArray &key) { | 126 | entryGenerator([this, bufferType, &exists](const QByteArray &sinkId) { |
132 | auto sinkId = Sink::Storage::uidFromKey(key); | ||
133 | const auto remoteId = syncStore().resolveLocalId(bufferType, sinkId); | 127 | const auto remoteId = syncStore().resolveLocalId(bufferType, sinkId); |
134 | SinkTrace() << "Checking for removal " << key << remoteId; | 128 | SinkTrace() << "Checking for removal " << sinkId << remoteId; |
135 | // If we have no remoteId, the entity hasn't been replayed to the source yet | 129 | // If we have no remoteId, the entity hasn't been replayed to the source yet |
136 | if (!remoteId.isEmpty()) { | 130 | if (!remoteId.isEmpty()) { |
137 | if (!exists(remoteId)) { | 131 | if (!exists(remoteId)) { |
138 | SinkTrace() << "Found a removed entity: " << sinkId; | 132 | SinkTrace() << "Found a removed entity: " << sinkId; |
139 | deleteEntity(sinkId, Sink::Storage::maxRevision(transaction()), bufferType, | 133 | deleteEntity(sinkId, mEntityStore->maxRevision(), bufferType); |
140 | [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::DeleteEntityCommand, buffer); }); | ||
141 | } | 134 | } |
142 | } | 135 | } |
143 | }); | 136 | }); |
144 | } | 137 | } |
145 | 138 | ||
146 | void Synchronizer::modify(const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity) | 139 | void Synchronizer::scanForRemovals(const QByteArray &bufferType, std::function<bool(const QByteArray &remoteId)> exists) |
147 | { | 140 | { |
148 | auto mainDatabase = Storage::mainDatabase(transaction(), bufferType); | 141 | scanForRemovals(bufferType, |
149 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); | 142 | [this, &bufferType](const std::function<void(const QByteArray &)> &callback) { |
150 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(mResourceType, bufferType); | 143 | store().readAllUids(bufferType, [callback](const QByteArray &uid) { |
151 | Q_ASSERT(adaptorFactory); | 144 | callback(uid); |
152 | qint64 retrievedRevision = 0; | 145 | }); |
153 | if (auto current = EntityReaderUtils::getLatest(mainDatabase, sinkId, *adaptorFactory, retrievedRevision)) { | 146 | }, |
147 | exists | ||
148 | ); | ||
149 | } | ||
150 | |||
151 | void Synchronizer::modifyIfChanged(Storage::EntityStore &store, const QByteArray &bufferType, const QByteArray &sinkId, const Sink::ApplicationDomain::ApplicationDomainType &entity) | ||
152 | { | ||
153 | store.readLatest(bufferType, sinkId, [&, this](const Sink::ApplicationDomain::ApplicationDomainType ¤t) { | ||
154 | bool changed = false; | 154 | bool changed = false; |
155 | for (const auto &property : entity.changedProperties()) { | 155 | for (const auto &property : entity.changedProperties()) { |
156 | if (entity.getProperty(property) != current->getProperty(property)) { | 156 | if (entity.getProperty(property) != current.getProperty(property)) { |
157 | SinkTrace() << "Property changed " << sinkId << property; | 157 | SinkTrace() << "Property changed " << sinkId << property; |
158 | changed = true; | 158 | changed = true; |
159 | } | 159 | } |
160 | } | 160 | } |
161 | if (changed) { | 161 | if (changed) { |
162 | SinkTrace() << "Found a modified entity: " << remoteId; | 162 | SinkTrace() << "Found a modified entity: " << sinkId; |
163 | modifyEntity(sinkId, Sink::Storage::maxRevision(transaction()), bufferType, entity, *adaptorFactory, | 163 | modifyEntity(sinkId, store.maxRevision(), bufferType, entity); |
164 | [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::ModifyEntityCommand, buffer); }); | ||
165 | } | 164 | } |
166 | } else { | 165 | }); |
167 | SinkWarning() << "Failed to get current entity"; | 166 | } |
168 | } | 167 | |
168 | void Synchronizer::modify(const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity) | ||
169 | { | ||
170 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); | ||
171 | Storage::EntityStore store(mResourceContext); | ||
172 | modifyIfChanged(store, bufferType, sinkId, entity); | ||
169 | } | 173 | } |
170 | 174 | ||
171 | void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity) | 175 | void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity) |
172 | { | 176 | { |
173 | SinkTrace() << "Create or modify" << bufferType << remoteId; | 177 | SinkTrace() << "Create or modify" << bufferType << remoteId; |
174 | auto mainDatabase = Storage::mainDatabase(transaction(), bufferType); | 178 | Storage::EntityStore store(mResourceContext); |
175 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); | 179 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); |
176 | const auto found = mainDatabase.contains(sinkId); | 180 | const auto found = store.contains(bufferType, sinkId); |
177 | if (!found) { | 181 | if (!found) { |
178 | SinkTrace() << "Found a new entity: " << remoteId; | 182 | SinkTrace() << "Found a new entity: " << remoteId; |
179 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(mResourceType, bufferType); | 183 | createEntity(sinkId, bufferType, entity); |
180 | Q_ASSERT(adaptorFactory); | ||
181 | createEntity( | ||
182 | sinkId, bufferType, entity, *adaptorFactory, [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::CreateEntityCommand, buffer); }); | ||
183 | } else { // modification | 184 | } else { // modification |
184 | modify(bufferType, remoteId, entity); | 185 | modify(bufferType, remoteId, entity); |
185 | } | 186 | } |
@@ -190,10 +191,9 @@ void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray | |||
190 | { | 191 | { |
191 | 192 | ||
192 | SinkTrace() << "Create or modify" << bufferType << remoteId; | 193 | SinkTrace() << "Create or modify" << bufferType << remoteId; |
193 | auto mainDatabase = Storage::mainDatabase(transaction(), bufferType); | ||
194 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); | 194 | const auto sinkId = syncStore().resolveRemoteId(bufferType, remoteId); |
195 | const auto found = mainDatabase.contains(sinkId); | 195 | Storage::EntityStore store(mResourceContext); |
196 | auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(mResourceType, bufferType); | 196 | const auto found = store.contains(bufferType, sinkId); |
197 | if (!found) { | 197 | if (!found) { |
198 | if (!mergeCriteria.isEmpty()) { | 198 | if (!mergeCriteria.isEmpty()) { |
199 | Sink::Query query; | 199 | Sink::Query query; |
@@ -201,7 +201,8 @@ void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray | |||
201 | query.filter(it.key(), it.value()); | 201 | query.filter(it.key(), it.value()); |
202 | } | 202 | } |
203 | bool merge = false; | 203 | bool merge = false; |
204 | Sink::EntityReader<DomainType> reader(mResourceType, mResourceInstanceIdentifier, transaction()); | 204 | Storage::EntityStore store(mResourceContext); |
205 | Sink::EntityReader<DomainType> reader(store); | ||
205 | reader.query(query, | 206 | reader.query(query, |
206 | [this, bufferType, remoteId, &merge](const DomainType &o) -> bool{ | 207 | [this, bufferType, remoteId, &merge](const DomainType &o) -> bool{ |
207 | merge = true; | 208 | merge = true; |
@@ -211,43 +212,21 @@ void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray | |||
211 | }); | 212 | }); |
212 | if (!merge) { | 213 | if (!merge) { |
213 | SinkTrace() << "Found a new entity: " << remoteId; | 214 | SinkTrace() << "Found a new entity: " << remoteId; |
214 | createEntity( | 215 | createEntity(sinkId, bufferType, entity); |
215 | sinkId, bufferType, entity, *adaptorFactory, [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::CreateEntityCommand, buffer); }); | ||
216 | } | 216 | } |
217 | } else { | 217 | } else { |
218 | SinkTrace() << "Found a new entity: " << remoteId; | 218 | SinkTrace() << "Found a new entity: " << remoteId; |
219 | createEntity( | 219 | createEntity(sinkId, bufferType, entity); |
220 | sinkId, bufferType, entity, *adaptorFactory, [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::CreateEntityCommand, buffer); }); | ||
221 | } | 220 | } |
222 | } else { // modification | 221 | } else { // modification |
223 | qint64 retrievedRevision = 0; | 222 | modifyIfChanged(store, bufferType, sinkId, entity); |
224 | if (auto current = EntityReaderUtils::getLatest(mainDatabase, sinkId, *adaptorFactory, retrievedRevision)) { | ||
225 | bool changed = false; | ||
226 | for (const auto &property : entity.changedProperties()) { | ||
227 | if (entity.getProperty(property) != current->getProperty(property)) { | ||
228 | SinkTrace() << "Property changed " << sinkId << property; | ||
229 | changed = true; | ||
230 | } | ||
231 | } | ||
232 | if (changed) { | ||
233 | SinkTrace() << "Found a modified entity: " << remoteId; | ||
234 | modifyEntity(sinkId, Sink::Storage::maxRevision(transaction()), bufferType, entity, *adaptorFactory, | ||
235 | [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::ModifyEntityCommand, buffer); }); | ||
236 | } | ||
237 | } else { | ||
238 | SinkWarning() << "Failed to get current entity"; | ||
239 | } | ||
240 | } | 223 | } |
241 | } | 224 | } |
242 | 225 | ||
243 | template<typename DomainType> | 226 | template<typename DomainType> |
244 | void Synchronizer::modify(const DomainType &entity) | 227 | void Synchronizer::modify(const DomainType &entity) |
245 | { | 228 | { |
246 | const auto bufferType = ApplicationDomain::getTypeName<DomainType>(); | 229 | modifyEntity(entity.identifier(), entity.revision(), ApplicationDomain::getTypeName<DomainType>(), entity); |
247 | const auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(mResourceType, bufferType); | ||
248 | Q_ASSERT(adaptorFactory); | ||
249 | modifyEntity(entity.identifier(), entity.revision(), bufferType, entity, *adaptorFactory, | ||
250 | [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::ModifyEntityCommand, buffer); }); | ||
251 | } | 230 | } |
252 | 231 | ||
253 | KAsync::Job<void> Synchronizer::synchronize() | 232 | KAsync::Job<void> Synchronizer::synchronize() |
@@ -257,7 +236,6 @@ KAsync::Job<void> Synchronizer::synchronize() | |||
257 | mMessageQueue->startTransaction(); | 236 | mMessageQueue->startTransaction(); |
258 | return synchronizeWithSource().syncThen<void>([this]() { | 237 | return synchronizeWithSource().syncThen<void>([this]() { |
259 | mSyncStore.clear(); | 238 | mSyncStore.clear(); |
260 | mEntityStore.clear(); | ||
261 | mMessageQueue->commit(); | 239 | mMessageQueue->commit(); |
262 | mSyncInProgress = false; | 240 | mSyncInProgress = false; |
263 | }); | 241 | }); |
@@ -266,8 +244,7 @@ KAsync::Job<void> Synchronizer::synchronize() | |||
266 | void Synchronizer::commit() | 244 | void Synchronizer::commit() |
267 | { | 245 | { |
268 | mMessageQueue->commit(); | 246 | mMessageQueue->commit(); |
269 | mTransaction.abort(); | 247 | mEntityStore->abortTransaction(); |
270 | mEntityStore.clear(); | ||
271 | mSyncTransaction.commit(); | 248 | mSyncTransaction.commit(); |
272 | mSyncStore.clear(); | 249 | mSyncStore.clear(); |
273 | if (mSyncInProgress) { | 250 | if (mSyncInProgress) { |
@@ -275,20 +252,11 @@ void Synchronizer::commit() | |||
275 | } | 252 | } |
276 | } | 253 | } |
277 | 254 | ||
278 | Sink::Storage::Transaction &Synchronizer::transaction() | 255 | Sink::Storage::DataStore::DataStore::Transaction &Synchronizer::syncTransaction() |
279 | { | ||
280 | if (!mTransaction) { | ||
281 | SinkTrace() << "Starting transaction"; | ||
282 | mTransaction = mStorage.createTransaction(Sink::Storage::ReadOnly); | ||
283 | } | ||
284 | return mTransaction; | ||
285 | } | ||
286 | |||
287 | Sink::Storage::Transaction &Synchronizer::syncTransaction() | ||
288 | { | 256 | { |
289 | if (!mSyncTransaction) { | 257 | if (!mSyncTransaction) { |
290 | SinkTrace() << "Starting transaction"; | 258 | SinkTrace() << "Starting transaction"; |
291 | mSyncTransaction = mSyncStorage.createTransaction(Sink::Storage::ReadWrite); | 259 | mSyncTransaction = mSyncStorage.createTransaction(Sink::Storage::DataStore::DataStore::ReadWrite); |
292 | } | 260 | } |
293 | return mSyncTransaction; | 261 | return mSyncTransaction; |
294 | } | 262 | } |
diff --git a/common/synchronizer.h b/common/synchronizer.h index 5f60128..f3319f6 100644 --- a/common/synchronizer.h +++ b/common/synchronizer.h | |||
@@ -37,31 +37,28 @@ class RemoteIdMap; | |||
37 | class SINK_EXPORT Synchronizer | 37 | class SINK_EXPORT Synchronizer |
38 | { | 38 | { |
39 | public: | 39 | public: |
40 | Synchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier); | 40 | Synchronizer(const Sink::ResourceContext &resourceContext); |
41 | virtual ~Synchronizer(); | 41 | virtual ~Synchronizer(); |
42 | 42 | ||
43 | void setup(const std::function<void(int commandId, const QByteArray &data)> &enqueueCommandCallback, MessageQueue &messageQueue); | 43 | void setup(const std::function<void(int commandId, const QByteArray &data)> &enqueueCommandCallback, MessageQueue &messageQueue); |
44 | KAsync::Job<void> synchronize(); | 44 | KAsync::Job<void> synchronize(); |
45 | 45 | ||
46 | //Read only access to main storage | 46 | //Read only access to main storage |
47 | EntityStore &store(); | 47 | Storage::EntityStore &store(); |
48 | 48 | ||
49 | //Read/Write access to sync storage | 49 | //Read/Write access to sync storage |
50 | RemoteIdMap &syncStore(); | 50 | RemoteIdMap &syncStore(); |
51 | 51 | ||
52 | void commit(); | 52 | void commit(); |
53 | Sink::Storage::Transaction &transaction(); | 53 | Sink::Storage::DataStore::Transaction &syncTransaction(); |
54 | Sink::Storage::Transaction &syncTransaction(); | ||
55 | 54 | ||
56 | protected: | 55 | protected: |
57 | ///Calls the callback to enqueue the command | 56 | ///Calls the callback to enqueue the command |
58 | void enqueueCommand(int commandId, const QByteArray &data); | 57 | void enqueueCommand(int commandId, const QByteArray &data); |
59 | 58 | ||
60 | static void createEntity(const QByteArray &localId, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject, | 59 | void createEntity(const QByteArray &localId, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject); |
61 | DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback); | 60 | void modifyEntity(const QByteArray &localId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject); |
62 | static void modifyEntity(const QByteArray &localId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject, | 61 | void deleteEntity(const QByteArray &localId, qint64 revision, const QByteArray &bufferType); |
63 | DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback); | ||
64 | static void deleteEntity(const QByteArray &localId, qint64 revision, const QByteArray &bufferType, std::function<void(const QByteArray &)> callback); | ||
65 | 62 | ||
66 | /** | 63 | /** |
67 | * A synchronous algorithm to remove entities that are no longer existing. | 64 | * A synchronous algorithm to remove entities that are no longer existing. |
@@ -74,7 +71,8 @@ protected: | |||
74 | * All functions are called synchronously, and both @param entryGenerator and @param exists need to be synchronous. | 71 | * All functions are called synchronously, and both @param entryGenerator and @param exists need to be synchronous. |
75 | */ | 72 | */ |
76 | void scanForRemovals(const QByteArray &bufferType, | 73 | void scanForRemovals(const QByteArray &bufferType, |
77 | const std::function<void(const std::function<void(const QByteArray &key)> &callback)> &entryGenerator, std::function<bool(const QByteArray &remoteId)> exists); | 74 | const std::function<void(const std::function<void(const QByteArray &sinkId)> &callback)> &entryGenerator, std::function<bool(const QByteArray &remoteId)> exists); |
75 | void scanForRemovals(const QByteArray &bufferType, std::function<bool(const QByteArray &remoteId)> exists); | ||
78 | 76 | ||
79 | /** | 77 | /** |
80 | * An algorithm to create or modify the entity. | 78 | * An algorithm to create or modify the entity. |
@@ -96,14 +94,13 @@ protected: | |||
96 | virtual KAsync::Job<void> synchronizeWithSource() = 0; | 94 | virtual KAsync::Job<void> synchronizeWithSource() = 0; |
97 | 95 | ||
98 | private: | 96 | private: |
97 | void modifyIfChanged(Storage::EntityStore &store, const QByteArray &bufferType, const QByteArray &sinkId, const Sink::ApplicationDomain::ApplicationDomainType &entity); | ||
98 | |||
99 | Sink::ResourceContext mResourceContext; | ||
100 | Sink::Storage::EntityStore::Ptr mEntityStore; | ||
99 | QSharedPointer<RemoteIdMap> mSyncStore; | 101 | QSharedPointer<RemoteIdMap> mSyncStore; |
100 | QSharedPointer<EntityStore> mEntityStore; | 102 | Sink::Storage::DataStore mSyncStorage; |
101 | Sink::Storage mStorage; | 103 | Sink::Storage::DataStore::Transaction mSyncTransaction; |
102 | Sink::Storage mSyncStorage; | ||
103 | QByteArray mResourceType; | ||
104 | QByteArray mResourceInstanceIdentifier; | ||
105 | Sink::Storage::Transaction mTransaction; | ||
106 | Sink::Storage::Transaction mSyncTransaction; | ||
107 | std::function<void(int commandId, const QByteArray &data)> mEnqueue; | 104 | std::function<void(int commandId, const QByteArray &data)> mEnqueue; |
108 | MessageQueue *mMessageQueue; | 105 | MessageQueue *mMessageQueue; |
109 | bool mSyncInProgress; | 106 | bool mSyncInProgress; |
diff --git a/common/test.cpp b/common/test.cpp index 7bba125..0982293 100644 --- a/common/test.cpp +++ b/common/test.cpp | |||
@@ -104,11 +104,11 @@ public: | |||
104 | facade->mTestAccount = testAccount; | 104 | facade->mTestAccount = testAccount; |
105 | map.insert(instanceIdentifier, facade); | 105 | map.insert(instanceIdentifier, facade); |
106 | bool alwaysReturnFacade = instanceIdentifier.isEmpty(); | 106 | bool alwaysReturnFacade = instanceIdentifier.isEmpty(); |
107 | Sink::FacadeFactory::instance().registerFacade<T, TestFacade<T>>("testresource", [alwaysReturnFacade](const QByteArray &instanceIdentifier) { | 107 | Sink::FacadeFactory::instance().registerFacade<T, TestFacade<T>>("testresource", [alwaysReturnFacade](const Sink::ResourceContext &context) { |
108 | if (alwaysReturnFacade) { | 108 | if (alwaysReturnFacade) { |
109 | return map.value(QByteArray()); | 109 | return map.value(QByteArray()); |
110 | } | 110 | } |
111 | return map.value(instanceIdentifier); | 111 | return map.value(context.resourceInstanceIdentifier); |
112 | }); | 112 | }); |
113 | return facade; | 113 | return facade; |
114 | } | 114 | } |
diff --git a/common/typeindex.cpp b/common/typeindex.cpp index 816e7ee..64c2a01 100644 --- a/common/typeindex.cpp +++ b/common/typeindex.cpp | |||
@@ -66,7 +66,7 @@ QByteArray TypeIndex::indexName(const QByteArray &property, const QByteArray &so | |||
66 | template <> | 66 | template <> |
67 | void TypeIndex::addProperty<QByteArray>(const QByteArray &property) | 67 | void TypeIndex::addProperty<QByteArray>(const QByteArray &property) |
68 | { | 68 | { |
69 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::Transaction &transaction) { | 69 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) { |
70 | // SinkTrace() << "Indexing " << mType + ".index." + property << value.toByteArray(); | 70 | // SinkTrace() << "Indexing " << mType + ".index." + property << value.toByteArray(); |
71 | Index(indexName(property), transaction).add(getByteArray(value), identifier); | 71 | Index(indexName(property), transaction).add(getByteArray(value), identifier); |
72 | }; | 72 | }; |
@@ -77,7 +77,7 @@ void TypeIndex::addProperty<QByteArray>(const QByteArray &property) | |||
77 | template <> | 77 | template <> |
78 | void TypeIndex::addProperty<QString>(const QByteArray &property) | 78 | void TypeIndex::addProperty<QString>(const QByteArray &property) |
79 | { | 79 | { |
80 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::Transaction &transaction) { | 80 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) { |
81 | // SinkTrace() << "Indexing " << mType + ".index." + property << value.toByteArray(); | 81 | // SinkTrace() << "Indexing " << mType + ".index." + property << value.toByteArray(); |
82 | Index(indexName(property), transaction).add(getByteArray(value), identifier); | 82 | Index(indexName(property), transaction).add(getByteArray(value), identifier); |
83 | }; | 83 | }; |
@@ -88,7 +88,7 @@ void TypeIndex::addProperty<QString>(const QByteArray &property) | |||
88 | template <> | 88 | template <> |
89 | void TypeIndex::addProperty<QDateTime>(const QByteArray &property) | 89 | void TypeIndex::addProperty<QDateTime>(const QByteArray &property) |
90 | { | 90 | { |
91 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::Transaction &transaction) { | 91 | auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) { |
92 | //SinkTrace() << "Indexing " << mType + ".index." + property << getByteArray(value); | 92 | //SinkTrace() << "Indexing " << mType + ".index." + property << getByteArray(value); |
93 | Index(indexName(property), transaction).add(getByteArray(value), identifier); | 93 | Index(indexName(property), transaction).add(getByteArray(value), identifier); |
94 | }; | 94 | }; |
@@ -99,7 +99,7 @@ void TypeIndex::addProperty<QDateTime>(const QByteArray &property) | |||
99 | template <> | 99 | template <> |
100 | void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray &property, const QByteArray &sortProperty) | 100 | void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray &property, const QByteArray &sortProperty) |
101 | { | 101 | { |
102 | auto indexer = [=](const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::Transaction &transaction) { | 102 | auto indexer = [=](const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction) { |
103 | const auto date = sortValue.toDateTime(); | 103 | const auto date = sortValue.toDateTime(); |
104 | const auto propertyValue = getByteArray(value); | 104 | const auto propertyValue = getByteArray(value); |
105 | Index(indexName(property, sortProperty), transaction).add(propertyValue + toSortableByteArray(date), identifier); | 105 | Index(indexName(property, sortProperty), transaction).add(propertyValue + toSortableByteArray(date), identifier); |
@@ -108,7 +108,7 @@ void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray & | |||
108 | mSortedProperties.insert(property, sortProperty); | 108 | mSortedProperties.insert(property, sortProperty); |
109 | } | 109 | } |
110 | 110 | ||
111 | void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 111 | void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
112 | { | 112 | { |
113 | for (const auto &property : mProperties) { | 113 | for (const auto &property : mProperties) { |
114 | const auto value = bufferAdaptor.getProperty(property); | 114 | const auto value = bufferAdaptor.getProperty(property); |
@@ -123,7 +123,7 @@ void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain: | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 126 | void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) |
127 | { | 127 | { |
128 | for (const auto &property : mProperties) { | 128 | for (const auto &property : mProperties) { |
129 | const auto value = bufferAdaptor.getProperty(property); | 129 | const auto value = bufferAdaptor.getProperty(property); |
@@ -159,7 +159,7 @@ static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter) | |||
159 | return keys; | 159 | return keys; |
160 | } | 160 | } |
161 | 161 | ||
162 | QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::Transaction &transaction) | 162 | QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction) |
163 | { | 163 | { |
164 | QVector<QByteArray> keys; | 164 | QVector<QByteArray> keys; |
165 | for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { | 165 | for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { |
@@ -185,7 +185,7 @@ QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> | |||
185 | return keys; | 185 | return keys; |
186 | } | 186 | } |
187 | 187 | ||
188 | QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant &value, Sink::Storage::Transaction &transaction) | 188 | QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) |
189 | { | 189 | { |
190 | SinkTrace() << "Index lookup on property: " << property << mSecondaryProperties.keys() << mProperties; | 190 | SinkTrace() << "Index lookup on property: " << property << mSecondaryProperties.keys() << mProperties; |
191 | if (mProperties.contains(property)) { | 191 | if (mProperties.contains(property)) { |
@@ -218,19 +218,19 @@ QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant | |||
218 | } | 218 | } |
219 | 219 | ||
220 | template <> | 220 | template <> |
221 | void TypeIndex::index<QByteArray, QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::Transaction &transaction) | 221 | void TypeIndex::index<QByteArray, QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::DataStore::Transaction &transaction) |
222 | { | 222 | { |
223 | Index(indexName(leftName + rightName), transaction).add(getByteArray(leftValue), getByteArray(rightValue)); | 223 | Index(indexName(leftName + rightName), transaction).add(getByteArray(leftValue), getByteArray(rightValue)); |
224 | } | 224 | } |
225 | 225 | ||
226 | template <> | 226 | template <> |
227 | void TypeIndex::index<QString, QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::Transaction &transaction) | 227 | void TypeIndex::index<QString, QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::DataStore::Transaction &transaction) |
228 | { | 228 | { |
229 | Index(indexName(leftName + rightName), transaction).add(getByteArray(leftValue), getByteArray(rightValue)); | 229 | Index(indexName(leftName + rightName), transaction).add(getByteArray(leftValue), getByteArray(rightValue)); |
230 | } | 230 | } |
231 | 231 | ||
232 | template <> | 232 | template <> |
233 | QVector<QByteArray> TypeIndex::secondaryLookup<QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::Transaction &transaction) | 233 | QVector<QByteArray> TypeIndex::secondaryLookup<QByteArray>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) |
234 | { | 234 | { |
235 | QVector<QByteArray> keys; | 235 | QVector<QByteArray> keys; |
236 | Index index(indexName(leftName + rightName), transaction); | 236 | Index index(indexName(leftName + rightName), transaction); |
@@ -242,7 +242,7 @@ QVector<QByteArray> TypeIndex::secondaryLookup<QByteArray>(const QByteArray &lef | |||
242 | } | 242 | } |
243 | 243 | ||
244 | template <> | 244 | template <> |
245 | QVector<QByteArray> TypeIndex::secondaryLookup<QString>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::Transaction &transaction) | 245 | QVector<QByteArray> TypeIndex::secondaryLookup<QString>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) |
246 | { | 246 | { |
247 | QVector<QByteArray> keys; | 247 | QVector<QByteArray> keys; |
248 | Index index(indexName(leftName + rightName), transaction); | 248 | Index index(indexName(leftName + rightName), transaction); |
diff --git a/common/typeindex.h b/common/typeindex.h index 4972e95..2638577 100644 --- a/common/typeindex.h +++ b/common/typeindex.h | |||
@@ -52,29 +52,29 @@ public: | |||
52 | { | 52 | { |
53 | mSecondaryProperties.insert(Left::name, Right::name); | 53 | mSecondaryProperties.insert(Left::name, Right::name); |
54 | } | 54 | } |
55 | void add(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 55 | void add(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
56 | void remove(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction); | 56 | void remove(const QByteArray &identifier, const Sink::ApplicationDomain::BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); |
57 | 57 | ||
58 | QVector<QByteArray> query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::Transaction &transaction); | 58 | QVector<QByteArray> query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction); |
59 | QVector<QByteArray> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::Transaction &transaction); | 59 | QVector<QByteArray> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction); |
60 | 60 | ||
61 | template <typename Left, typename Right> | 61 | template <typename Left, typename Right> |
62 | QVector<QByteArray> secondaryLookup(const QVariant &value, Sink::Storage::Transaction &transaction) | 62 | QVector<QByteArray> secondaryLookup(const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) |
63 | { | 63 | { |
64 | return secondaryLookup<typename Left::Type>(Left::name, Right::name, value, transaction); | 64 | return secondaryLookup<typename Left::Type>(Left::name, Right::name, value, transaction); |
65 | } | 65 | } |
66 | 66 | ||
67 | template <typename Type> | 67 | template <typename Type> |
68 | QVector<QByteArray> secondaryLookup(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::Transaction &transaction); | 68 | QVector<QByteArray> secondaryLookup(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction); |
69 | 69 | ||
70 | template <typename Left, typename Right> | 70 | template <typename Left, typename Right> |
71 | void index(const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::Transaction &transaction) | 71 | void index(const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::DataStore::Transaction &transaction) |
72 | { | 72 | { |
73 | index<typename Left::Type, typename Right::Type>(Left::name, Right::name, leftValue, rightValue, transaction); | 73 | index<typename Left::Type, typename Right::Type>(Left::name, Right::name, leftValue, rightValue, transaction); |
74 | } | 74 | } |
75 | 75 | ||
76 | template <typename LeftType, typename RightType> | 76 | template <typename LeftType, typename RightType> |
77 | void index(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::Transaction &transaction); | 77 | void index(const QByteArray &leftName, const QByteArray &rightName, const QVariant &leftValue, const QVariant &rightValue, Sink::Storage::DataStore::Transaction &transaction); |
78 | 78 | ||
79 | 79 | ||
80 | private: | 80 | private: |
@@ -85,6 +85,6 @@ private: | |||
85 | QMap<QByteArray, QByteArray> mSortedProperties; | 85 | QMap<QByteArray, QByteArray> mSortedProperties; |
86 | //<Property, ResultProperty> | 86 | //<Property, ResultProperty> |
87 | QMap<QByteArray, QByteArray> mSecondaryProperties; | 87 | QMap<QByteArray, QByteArray> mSecondaryProperties; |
88 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, Sink::Storage::Transaction &transaction)>> mIndexer; | 88 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mIndexer; |
89 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::Transaction &transaction)>> mSortIndexer; | 89 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction)>> mSortIndexer; |
90 | }; | 90 | }; |
diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp index 120498a..4343eba 100644 --- a/examples/dummyresource/facade.cpp +++ b/examples/dummyresource/facade.cpp | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | #include "domainadaptor.h" | 22 | #include "domainadaptor.h" |
23 | 23 | ||
24 | DummyResourceFacade::DummyResourceFacade(const QByteArray &instanceIdentifier) | 24 | DummyResourceFacade::DummyResourceFacade(const Sink::ResourceContext &context) |
25 | : Sink::GenericFacade<Sink::ApplicationDomain::Event>(instanceIdentifier, QSharedPointer<DummyEventAdaptorFactory>::create()) | 25 | : Sink::GenericFacade<Sink::ApplicationDomain::Event>(context) |
26 | { | 26 | { |
27 | } | 27 | } |
28 | 28 | ||
@@ -31,8 +31,8 @@ DummyResourceFacade::~DummyResourceFacade() | |||
31 | } | 31 | } |
32 | 32 | ||
33 | 33 | ||
34 | DummyResourceMailFacade::DummyResourceMailFacade(const QByteArray &instanceIdentifier) | 34 | DummyResourceMailFacade::DummyResourceMailFacade(const Sink::ResourceContext &context) |
35 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<DummyMailAdaptorFactory>::create()) | 35 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(context) |
36 | { | 36 | { |
37 | } | 37 | } |
38 | 38 | ||
@@ -41,8 +41,8 @@ DummyResourceMailFacade::~DummyResourceMailFacade() | |||
41 | } | 41 | } |
42 | 42 | ||
43 | 43 | ||
44 | DummyResourceFolderFacade::DummyResourceFolderFacade(const QByteArray &instanceIdentifier) | 44 | DummyResourceFolderFacade::DummyResourceFolderFacade(const Sink::ResourceContext &context) |
45 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(instanceIdentifier, QSharedPointer<DummyFolderAdaptorFactory>::create()) | 45 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(context) |
46 | { | 46 | { |
47 | } | 47 | } |
48 | 48 | ||
diff --git a/examples/dummyresource/facade.h b/examples/dummyresource/facade.h index 5e0096d..1bb45fd 100644 --- a/examples/dummyresource/facade.h +++ b/examples/dummyresource/facade.h | |||
@@ -25,20 +25,20 @@ | |||
25 | class DummyResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Event> | 25 | class DummyResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Event> |
26 | { | 26 | { |
27 | public: | 27 | public: |
28 | DummyResourceFacade(const QByteArray &instanceIdentifier); | 28 | DummyResourceFacade(const Sink::ResourceContext &context); |
29 | virtual ~DummyResourceFacade(); | 29 | virtual ~DummyResourceFacade(); |
30 | }; | 30 | }; |
31 | 31 | ||
32 | class DummyResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> | 32 | class DummyResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> |
33 | { | 33 | { |
34 | public: | 34 | public: |
35 | DummyResourceMailFacade(const QByteArray &instanceIdentifier); | 35 | DummyResourceMailFacade(const Sink::ResourceContext &context); |
36 | virtual ~DummyResourceMailFacade(); | 36 | virtual ~DummyResourceMailFacade(); |
37 | }; | 37 | }; |
38 | 38 | ||
39 | class DummyResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> | 39 | class DummyResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> |
40 | { | 40 | { |
41 | public: | 41 | public: |
42 | DummyResourceFolderFacade(const QByteArray &instanceIdentifier); | 42 | DummyResourceFolderFacade(const Sink::ResourceContext &context); |
43 | virtual ~DummyResourceFolderFacade(); | 43 | virtual ~DummyResourceFolderFacade(); |
44 | }; | 44 | }; |
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 6d14721..e288be2 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp | |||
@@ -53,8 +53,8 @@ SINK_DEBUG_AREA("dummyresource") | |||
53 | class DummySynchronizer : public Sink::Synchronizer { | 53 | class DummySynchronizer : public Sink::Synchronizer { |
54 | public: | 54 | public: |
55 | 55 | ||
56 | DummySynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 56 | DummySynchronizer(const Sink::ResourceContext &context) |
57 | : Sink::Synchronizer(resourceType, resourceInstanceIdentifier) | 57 | : Sink::Synchronizer(context) |
58 | { | 58 | { |
59 | 59 | ||
60 | } | 60 | } |
@@ -129,11 +129,11 @@ class DummySynchronizer : public Sink::Synchronizer { | |||
129 | 129 | ||
130 | }; | 130 | }; |
131 | 131 | ||
132 | DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) | 132 | DummyResource::DummyResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline) |
133 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) | 133 | : Sink::GenericResource(resourceContext, pipeline) |
134 | { | 134 | { |
135 | setupSynchronizer(QSharedPointer<DummySynchronizer>::create(PLUGIN_NAME, instanceIdentifier)); | 135 | setupSynchronizer(QSharedPointer<DummySynchronizer>::create(resourceContext)); |
136 | setupChangereplay(QSharedPointer<Sink::NullChangeReplay>::create(instanceIdentifier)); | 136 | setupChangereplay(QSharedPointer<Sink::NullChangeReplay>::create(resourceContext)); |
137 | setupPreprocessors(ENTITY_TYPE_MAIL, | 137 | setupPreprocessors(ENTITY_TYPE_MAIL, |
138 | QVector<Sink::Preprocessor*>() << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); | 138 | QVector<Sink::Preprocessor*>() << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); |
139 | setupPreprocessors(ENTITY_TYPE_FOLDER, | 139 | setupPreprocessors(ENTITY_TYPE_FOLDER, |
@@ -182,9 +182,9 @@ DummyResourceFactory::DummyResourceFactory(QObject *parent) | |||
182 | 182 | ||
183 | } | 183 | } |
184 | 184 | ||
185 | Sink::Resource *DummyResourceFactory::createResource(const QByteArray &instanceIdentifier) | 185 | Sink::Resource *DummyResourceFactory::createResource(const Sink::ResourceContext &resourceContext) |
186 | { | 186 | { |
187 | return new DummyResource(instanceIdentifier); | 187 | return new DummyResource(resourceContext); |
188 | } | 188 | } |
189 | 189 | ||
190 | void DummyResourceFactory::registerFacades(Sink::FacadeFactory &factory) | 190 | void DummyResourceFactory::registerFacades(Sink::FacadeFactory &factory) |
diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h index 0a29d53..3dd82ff 100644 --- a/examples/dummyresource/resourcefactory.h +++ b/examples/dummyresource/resourcefactory.h | |||
@@ -32,7 +32,7 @@ | |||
32 | class DummyResource : public Sink::GenericResource | 32 | class DummyResource : public Sink::GenericResource |
33 | { | 33 | { |
34 | public: | 34 | public: |
35 | DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); | 35 | DummyResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); |
36 | virtual ~DummyResource(); | 36 | virtual ~DummyResource(); |
37 | 37 | ||
38 | KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE; | 38 | KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE; |
@@ -48,7 +48,7 @@ class DummyResourceFactory : public Sink::ResourceFactory | |||
48 | public: | 48 | public: |
49 | DummyResourceFactory(QObject *parent = 0); | 49 | DummyResourceFactory(QObject *parent = 0); |
50 | 50 | ||
51 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 51 | Sink::Resource *createResource(const Sink::ResourceContext &resourceContext) Q_DECL_OVERRIDE; |
52 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; | 52 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; |
53 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; | 53 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; |
54 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 54 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; |
diff --git a/examples/imapresource/facade.cpp b/examples/imapresource/facade.cpp index d338b01..2829bb1 100644 --- a/examples/imapresource/facade.cpp +++ b/examples/imapresource/facade.cpp | |||
@@ -25,8 +25,8 @@ | |||
25 | #include "domainadaptor.h" | 25 | #include "domainadaptor.h" |
26 | #include "queryrunner.h" | 26 | #include "queryrunner.h" |
27 | 27 | ||
28 | ImapResourceMailFacade::ImapResourceMailFacade(const QByteArray &instanceIdentifier) | 28 | ImapResourceMailFacade::ImapResourceMailFacade(const Sink::ResourceContext &context) |
29 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<ImapMailAdaptorFactory>::create()) | 29 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(context) |
30 | { | 30 | { |
31 | } | 31 | } |
32 | 32 | ||
@@ -34,8 +34,8 @@ ImapResourceMailFacade::~ImapResourceMailFacade() | |||
34 | { | 34 | { |
35 | } | 35 | } |
36 | 36 | ||
37 | ImapResourceFolderFacade::ImapResourceFolderFacade(const QByteArray &instanceIdentifier) | 37 | ImapResourceFolderFacade::ImapResourceFolderFacade(const Sink::ResourceContext &context) |
38 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(instanceIdentifier, QSharedPointer<ImapFolderAdaptorFactory>::create()) | 38 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(context) |
39 | { | 39 | { |
40 | } | 40 | } |
41 | 41 | ||
diff --git a/examples/imapresource/facade.h b/examples/imapresource/facade.h index 479ad96..1d24856 100644 --- a/examples/imapresource/facade.h +++ b/examples/imapresource/facade.h | |||
@@ -24,13 +24,13 @@ | |||
24 | class ImapResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> | 24 | class ImapResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> |
25 | { | 25 | { |
26 | public: | 26 | public: |
27 | ImapResourceMailFacade(const QByteArray &instanceIdentifier); | 27 | ImapResourceMailFacade(const Sink::ResourceContext &context); |
28 | virtual ~ImapResourceMailFacade(); | 28 | virtual ~ImapResourceMailFacade(); |
29 | }; | 29 | }; |
30 | 30 | ||
31 | class ImapResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> | 31 | class ImapResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> |
32 | { | 32 | { |
33 | public: | 33 | public: |
34 | ImapResourceFolderFacade(const QByteArray &instanceIdentifier); | 34 | ImapResourceFolderFacade(const Sink::ResourceContext &context); |
35 | virtual ~ImapResourceFolderFacade(); | 35 | virtual ~ImapResourceFolderFacade(); |
36 | }; | 36 | }; |
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index c72579c..0ea07bf 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -50,8 +50,8 @@ | |||
50 | #include <QtAlgorithms> | 50 | #include <QtAlgorithms> |
51 | 51 | ||
52 | #include "imapserverproxy.h" | 52 | #include "imapserverproxy.h" |
53 | #include "entityreader.h" | ||
54 | #include "mailpreprocessor.h" | 53 | #include "mailpreprocessor.h" |
54 | #include "adaptorfactoryregistry.h" | ||
55 | #include "specialpurposepreprocessor.h" | 55 | #include "specialpurposepreprocessor.h" |
56 | 56 | ||
57 | //This is the resources entity type, and not the domain type | 57 | //This is the resources entity type, and not the domain type |
@@ -92,8 +92,8 @@ static QByteArray assembleMailRid(const ApplicationDomain::Mail &mail, qint64 im | |||
92 | 92 | ||
93 | class ImapSynchronizer : public Sink::Synchronizer { | 93 | class ImapSynchronizer : public Sink::Synchronizer { |
94 | public: | 94 | public: |
95 | ImapSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 95 | ImapSynchronizer(const ResourceContext &resourceContext) |
96 | : Sink::Synchronizer(resourceType, resourceInstanceIdentifier) | 96 | : Sink::Synchronizer(resourceContext) |
97 | { | 97 | { |
98 | 98 | ||
99 | } | 99 | } |
@@ -126,17 +126,6 @@ public: | |||
126 | SinkTrace() << "Found folders " << folderList.size(); | 126 | SinkTrace() << "Found folders " << folderList.size(); |
127 | 127 | ||
128 | scanForRemovals(bufferType, | 128 | scanForRemovals(bufferType, |
129 | [this, &bufferType](const std::function<void(const QByteArray &)> &callback) { | ||
130 | //TODO Instead of iterating over all entries in the database, which can also pick up the same item multiple times, | ||
131 | //we should rather iterate over an index that contains every uid exactly once. The remoteId index would be such an index, | ||
132 | //but we currently fail to iterate over all entries in an index it seems. | ||
133 | // auto remoteIds = synchronizationTransaction.openDatabase("rid.mapping." + bufferType, std::function<void(const Sink::Storage::Error &)>(), true); | ||
134 | auto mainDatabase = Sink::Storage::mainDatabase(transaction(), bufferType); | ||
135 | mainDatabase.scan("", [&](const QByteArray &key, const QByteArray &) { | ||
136 | callback(key); | ||
137 | return true; | ||
138 | }); | ||
139 | }, | ||
140 | [&folderList](const QByteArray &remoteId) -> bool { | 129 | [&folderList](const QByteArray &remoteId) -> bool { |
141 | // folderList.contains(remoteId) | 130 | // folderList.contains(remoteId) |
142 | for (const auto &folderPath : folderList) { | 131 | for (const auto &folderPath : folderList) { |
@@ -190,18 +179,12 @@ public: | |||
190 | const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, path.toUtf8()); | 179 | const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, path.toUtf8()); |
191 | 180 | ||
192 | int count = 0; | 181 | int count = 0; |
193 | auto property = Sink::ApplicationDomain::Mail::Folder::name; | 182 | |
194 | scanForRemovals(bufferType, | 183 | scanForRemovals(bufferType, |
195 | [&](const std::function<void(const QByteArray &)> &callback) { | 184 | [&](const std::function<void(const QByteArray &)> &callback) { |
196 | Index index(bufferType + ".index." + property, transaction()); | 185 | store().indexLookup<ApplicationDomain::Mail, ApplicationDomain::Mail::Folder>(folderLocalId, callback); |
197 | index.lookup(folderLocalId, [&](const QByteArray &sinkId) { | ||
198 | callback(sinkId); | ||
199 | }, | ||
200 | [&](const Index::Error &error) { | ||
201 | SinkWarning() << "Error in index: " << error.message << property; | ||
202 | }); | ||
203 | }, | 186 | }, |
204 | [messages, path, &count](const QByteArray &remoteId) -> bool { | 187 | [&](const QByteArray &remoteId) -> bool { |
205 | if (messages.contains(uidFromMailRid(remoteId))) { | 188 | if (messages.contains(uidFromMailRid(remoteId))) { |
206 | return true; | 189 | return true; |
207 | } | 190 | } |
@@ -347,7 +330,7 @@ public: | |||
347 | class ImapWriteback : public Sink::SourceWriteBack | 330 | class ImapWriteback : public Sink::SourceWriteBack |
348 | { | 331 | { |
349 | public: | 332 | public: |
350 | ImapWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier) | 333 | ImapWriteback(const ResourceContext &resourceContext) : Sink::SourceWriteBack(resourceContext) |
351 | { | 334 | { |
352 | 335 | ||
353 | } | 336 | } |
@@ -514,10 +497,10 @@ public: | |||
514 | QByteArray mResourceInstanceIdentifier; | 497 | QByteArray mResourceInstanceIdentifier; |
515 | }; | 498 | }; |
516 | 499 | ||
517 | ImapResource::ImapResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) | 500 | ImapResource::ImapResource(const ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline) |
518 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) | 501 | : Sink::GenericResource(resourceContext, pipeline) |
519 | { | 502 | { |
520 | auto config = ResourceConfig::getConfiguration(instanceIdentifier); | 503 | auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); |
521 | mServer = config.value("server").toString(); | 504 | mServer = config.value("server").toString(); |
522 | mPort = config.value("port").toInt(); | 505 | mPort = config.value("port").toInt(); |
523 | mUser = config.value("username").toString(); | 506 | mUser = config.value("username").toString(); |
@@ -532,46 +515,45 @@ ImapResource::ImapResource(const QByteArray &instanceIdentifier, const QSharedPo | |||
532 | mPort = list.at(1).toInt(); | 515 | mPort = list.at(1).toInt(); |
533 | } | 516 | } |
534 | 517 | ||
535 | auto synchronizer = QSharedPointer<ImapSynchronizer>::create(PLUGIN_NAME, instanceIdentifier); | 518 | auto synchronizer = QSharedPointer<ImapSynchronizer>::create(resourceContext); |
536 | synchronizer->mServer = mServer; | 519 | synchronizer->mServer = mServer; |
537 | synchronizer->mPort = mPort; | 520 | synchronizer->mPort = mPort; |
538 | synchronizer->mUser = mUser; | 521 | synchronizer->mUser = mUser; |
539 | synchronizer->mPassword = mPassword; | 522 | synchronizer->mPassword = mPassword; |
540 | synchronizer->mResourceInstanceIdentifier = instanceIdentifier; | ||
541 | setupSynchronizer(synchronizer); | 523 | setupSynchronizer(synchronizer); |
542 | auto changereplay = QSharedPointer<ImapWriteback>::create(PLUGIN_NAME, instanceIdentifier); | 524 | auto changereplay = QSharedPointer<ImapWriteback>::create(resourceContext); |
543 | changereplay->mServer = mServer; | 525 | changereplay->mServer = mServer; |
544 | changereplay->mPort = mPort; | 526 | changereplay->mPort = mPort; |
545 | changereplay->mUser = mUser; | 527 | changereplay->mUser = mUser; |
546 | changereplay->mPassword = mPassword; | 528 | changereplay->mPassword = mPassword; |
547 | setupChangereplay(changereplay); | 529 | setupChangereplay(changereplay); |
548 | 530 | ||
549 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(mResourceType, mResourceInstanceIdentifier) << new MimeMessageMover << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); | 531 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MimeMessageMover << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); |
550 | setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder>); | 532 | setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder>); |
551 | } | 533 | } |
552 | 534 | ||
553 | void ImapResource::removeFromDisk(const QByteArray &instanceIdentifier) | 535 | void ImapResource::removeFromDisk(const QByteArray &instanceIdentifier) |
554 | { | 536 | { |
555 | GenericResource::removeFromDisk(instanceIdentifier); | 537 | GenericResource::removeFromDisk(instanceIdentifier); |
556 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); | 538 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
557 | } | 539 | } |
558 | 540 | ||
559 | KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) | 541 | KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) |
560 | { | 542 | { |
561 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); | 543 | auto synchronizationStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); |
562 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); | 544 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); |
563 | 545 | ||
564 | auto mainStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier, Sink::Storage::ReadOnly); | 546 | auto mainStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); |
565 | auto transaction = mainStore->createTransaction(Sink::Storage::ReadOnly); | 547 | auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); |
566 | 548 | ||
567 | auto entityStore = QSharedPointer<Sink::EntityStore>::create(mResourceType, mResourceInstanceIdentifier, transaction); | 549 | Sink::Storage::EntityStore entityStore(mResourceContext); |
568 | auto syncStore = QSharedPointer<Sink::RemoteIdMap>::create(synchronizationTransaction); | 550 | auto syncStore = QSharedPointer<Sink::RemoteIdMap>::create(synchronizationTransaction); |
569 | 551 | ||
570 | SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; | 552 | SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; |
571 | 553 | ||
572 | if (domainType == ENTITY_TYPE_MAIL) { | 554 | if (domainType == ENTITY_TYPE_MAIL) { |
573 | const auto mail = entityStore->read<Sink::ApplicationDomain::Mail>(entityId); | 555 | const auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); |
574 | const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(mail.getFolder()); | 556 | const auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(mail.getFolder()); |
575 | const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); | 557 | const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); |
576 | const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); | 558 | const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); |
577 | if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { | 559 | if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { |
@@ -635,7 +617,7 @@ KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &in | |||
635 | } | 617 | } |
636 | if (domainType == ENTITY_TYPE_FOLDER) { | 618 | if (domainType == ENTITY_TYPE_FOLDER) { |
637 | const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); | 619 | const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); |
638 | const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(entityId); | 620 | const auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId); |
639 | 621 | ||
640 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { | 622 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { |
641 | SinkLog() << "Inspecting cache integrity" << remoteId; | 623 | SinkLog() << "Inspecting cache integrity" << remoteId; |
@@ -698,9 +680,9 @@ ImapResourceFactory::ImapResourceFactory(QObject *parent) | |||
698 | 680 | ||
699 | } | 681 | } |
700 | 682 | ||
701 | Sink::Resource *ImapResourceFactory::createResource(const QByteArray &instanceIdentifier) | 683 | Sink::Resource *ImapResourceFactory::createResource(const ResourceContext &context) |
702 | { | 684 | { |
703 | return new ImapResource(instanceIdentifier); | 685 | return new ImapResource(context); |
704 | } | 686 | } |
705 | 687 | ||
706 | void ImapResourceFactory::registerFacades(Sink::FacadeFactory &factory) | 688 | void ImapResourceFactory::registerFacades(Sink::FacadeFactory &factory) |
diff --git a/examples/imapresource/imapresource.h b/examples/imapresource/imapresource.h index 236e695..684a3c9 100644 --- a/examples/imapresource/imapresource.h +++ b/examples/imapresource/imapresource.h | |||
@@ -42,7 +42,7 @@ struct Folder; | |||
42 | class ImapResource : public Sink::GenericResource | 42 | class ImapResource : public Sink::GenericResource |
43 | { | 43 | { |
44 | public: | 44 | public: |
45 | ImapResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); | 45 | ImapResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); |
46 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; | 46 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; |
47 | static void removeFromDisk(const QByteArray &instanceIdentifier); | 47 | static void removeFromDisk(const QByteArray &instanceIdentifier); |
48 | 48 | ||
@@ -62,7 +62,7 @@ class ImapResourceFactory : public Sink::ResourceFactory | |||
62 | public: | 62 | public: |
63 | ImapResourceFactory(QObject *parent = 0); | 63 | ImapResourceFactory(QObject *parent = 0); |
64 | 64 | ||
65 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 65 | Sink::Resource *createResource(const Sink::ResourceContext &resourceContext) Q_DECL_OVERRIDE; |
66 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; | 66 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; |
67 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; | 67 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; |
68 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 68 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; |
diff --git a/examples/maildirresource/facade.cpp b/examples/maildirresource/facade.cpp index 256b255..ba53c5f 100644 --- a/examples/maildirresource/facade.cpp +++ b/examples/maildirresource/facade.cpp | |||
@@ -22,11 +22,10 @@ | |||
22 | #include <QDir> | 22 | #include <QDir> |
23 | #include <QFileInfo> | 23 | #include <QFileInfo> |
24 | 24 | ||
25 | #include "domainadaptor.h" | 25 | #include "query.h" |
26 | #include "queryrunner.h" | ||
27 | 26 | ||
28 | MaildirResourceMailFacade::MaildirResourceMailFacade(const QByteArray &instanceIdentifier) | 27 | MaildirResourceMailFacade::MaildirResourceMailFacade(const Sink::ResourceContext &context) |
29 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<MaildirMailAdaptorFactory>::create()) | 28 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(context) |
30 | { | 29 | { |
31 | mResultTransformation = [](Sink::ApplicationDomain::ApplicationDomainType &value) { | 30 | mResultTransformation = [](Sink::ApplicationDomain::ApplicationDomainType &value) { |
32 | if (value.hasProperty("mimeMessage")) { | 31 | if (value.hasProperty("mimeMessage")) { |
@@ -62,8 +61,8 @@ QPair<KAsync::Job<void>, Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr> | |||
62 | } | 61 | } |
63 | 62 | ||
64 | 63 | ||
65 | MaildirResourceFolderFacade::MaildirResourceFolderFacade(const QByteArray &instanceIdentifier) | 64 | MaildirResourceFolderFacade::MaildirResourceFolderFacade(const Sink::ResourceContext &context) |
66 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(instanceIdentifier, QSharedPointer<MaildirFolderAdaptorFactory>::create()) | 65 | : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(context) |
67 | { | 66 | { |
68 | } | 67 | } |
69 | 68 | ||
diff --git a/examples/maildirresource/facade.h b/examples/maildirresource/facade.h index 38981d0..fdb693e 100644 --- a/examples/maildirresource/facade.h +++ b/examples/maildirresource/facade.h | |||
@@ -24,7 +24,7 @@ | |||
24 | class MaildirResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> | 24 | class MaildirResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> |
25 | { | 25 | { |
26 | public: | 26 | public: |
27 | MaildirResourceMailFacade(const QByteArray &instanceIdentifier); | 27 | MaildirResourceMailFacade(const Sink::ResourceContext &context); |
28 | virtual ~MaildirResourceMailFacade(); | 28 | virtual ~MaildirResourceMailFacade(); |
29 | QPair<KAsync::Job<void>, Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; | 29 | QPair<KAsync::Job<void>, Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; |
30 | }; | 30 | }; |
@@ -32,6 +32,6 @@ public: | |||
32 | class MaildirResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> | 32 | class MaildirResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder> |
33 | { | 33 | { |
34 | public: | 34 | public: |
35 | MaildirResourceFolderFacade(const QByteArray &instanceIdentifier); | 35 | MaildirResourceFolderFacade(const Sink::ResourceContext &context); |
36 | virtual ~MaildirResourceFolderFacade(); | 36 | virtual ~MaildirResourceFolderFacade(); |
37 | }; | 37 | }; |
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 1ed7fc8..b89d78c 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -85,13 +85,13 @@ class MaildirMimeMessageMover : public Sink::Preprocessor | |||
85 | public: | 85 | public: |
86 | MaildirMimeMessageMover(const QByteArray &resourceInstanceIdentifier, const QString &maildirPath) : mResourceInstanceIdentifier(resourceInstanceIdentifier), mMaildirPath(maildirPath) {} | 86 | MaildirMimeMessageMover(const QByteArray &resourceInstanceIdentifier, const QString &maildirPath) : mResourceInstanceIdentifier(resourceInstanceIdentifier), mMaildirPath(maildirPath) {} |
87 | 87 | ||
88 | QString getPath(const QByteArray &folderIdentifier, Sink::Storage::Transaction &transaction) | 88 | QString getPath(const QByteArray &folderIdentifier, Sink::Storage::DataStore::Transaction &transaction) |
89 | { | 89 | { |
90 | if (folderIdentifier.isEmpty()) { | 90 | if (folderIdentifier.isEmpty()) { |
91 | return mMaildirPath; | 91 | return mMaildirPath; |
92 | } | 92 | } |
93 | QString folderPath; | 93 | QString folderPath; |
94 | auto db = Sink::Storage::mainDatabase(transaction, ENTITY_TYPE_FOLDER); | 94 | auto db = Sink::Storage::DataStore::mainDatabase(transaction, ENTITY_TYPE_FOLDER); |
95 | db.findLatest(folderIdentifier, [&](const QByteArray &, const QByteArray &value) { | 95 | db.findLatest(folderIdentifier, [&](const QByteArray &, const QByteArray &value) { |
96 | Sink::EntityBuffer buffer(value); | 96 | Sink::EntityBuffer buffer(value); |
97 | const Sink::Entity &entity = buffer.entity(); | 97 | const Sink::Entity &entity = buffer.entity(); |
@@ -108,7 +108,7 @@ public: | |||
108 | return folderPath; | 108 | return folderPath; |
109 | } | 109 | } |
110 | 110 | ||
111 | QString moveMessage(const QString &oldPath, const QByteArray &folder, Sink::Storage::Transaction &transaction) | 111 | QString moveMessage(const QString &oldPath, const QByteArray &folder, Sink::Storage::DataStore::Transaction &transaction) |
112 | { | 112 | { |
113 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { | 113 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { |
114 | const auto path = getPath(folder, transaction); | 114 | const auto path = getPath(folder, transaction); |
@@ -141,7 +141,7 @@ public: | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 144 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
145 | { | 145 | { |
146 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); | 146 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); |
147 | if (mimeMessage.isValid()) { | 147 | if (mimeMessage.isValid()) { |
@@ -150,7 +150,7 @@ public: | |||
150 | } | 150 | } |
151 | 151 | ||
152 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 152 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
153 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 153 | Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
154 | { | 154 | { |
155 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); | 155 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); |
156 | const auto newFolder = newEntity.getProperty("folder"); | 156 | const auto newFolder = newEntity.getProperty("folder"); |
@@ -185,7 +185,7 @@ public: | |||
185 | maildir.changeEntryFlags(identifier, flags); | 185 | maildir.changeEntryFlags(identifier, flags); |
186 | } | 186 | } |
187 | 187 | ||
188 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 188 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
189 | { | 189 | { |
190 | const auto filePath = getFilePathFromMimeMessagePath(oldEntity.getProperty("mimeMessage").toString()); | 190 | const auto filePath = getFilePathFromMimeMessagePath(oldEntity.getProperty("mimeMessage").toString()); |
191 | QFile::remove(filePath); | 191 | QFile::remove(filePath); |
@@ -199,7 +199,7 @@ class FolderPreprocessor : public Sink::Preprocessor | |||
199 | public: | 199 | public: |
200 | FolderPreprocessor(const QString maildirPath) : mMaildirPath(maildirPath) {} | 200 | FolderPreprocessor(const QString maildirPath) : mMaildirPath(maildirPath) {} |
201 | 201 | ||
202 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 202 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
203 | { | 203 | { |
204 | auto folderName = newEntity.getProperty("name").toString(); | 204 | auto folderName = newEntity.getProperty("name").toString(); |
205 | const auto path = mMaildirPath + "/" + folderName; | 205 | const auto path = mMaildirPath + "/" + folderName; |
@@ -208,11 +208,11 @@ public: | |||
208 | } | 208 | } |
209 | 209 | ||
210 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 210 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
211 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 211 | Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
212 | { | 212 | { |
213 | } | 213 | } |
214 | 214 | ||
215 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 215 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
216 | { | 216 | { |
217 | } | 217 | } |
218 | QString mMaildirPath; | 218 | QString mMaildirPath; |
@@ -221,8 +221,8 @@ public: | |||
221 | 221 | ||
222 | class MaildirSynchronizer : public Sink::Synchronizer { | 222 | class MaildirSynchronizer : public Sink::Synchronizer { |
223 | public: | 223 | public: |
224 | MaildirSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 224 | MaildirSynchronizer(const Sink::ResourceContext &resourceContext) |
225 | : Sink::Synchronizer(resourceType, resourceInstanceIdentifier) | 225 | : Sink::Synchronizer(resourceContext) |
226 | { | 226 | { |
227 | 227 | ||
228 | } | 228 | } |
@@ -278,19 +278,7 @@ public: | |||
278 | const QByteArray bufferType = ENTITY_TYPE_FOLDER; | 278 | const QByteArray bufferType = ENTITY_TYPE_FOLDER; |
279 | QStringList folderList = listAvailableFolders(); | 279 | QStringList folderList = listAvailableFolders(); |
280 | SinkTrace() << "Found folders " << folderList; | 280 | SinkTrace() << "Found folders " << folderList; |
281 | |||
282 | scanForRemovals(bufferType, | 281 | scanForRemovals(bufferType, |
283 | [this, &bufferType](const std::function<void(const QByteArray &)> &callback) { | ||
284 | //TODO Instead of iterating over all entries in the database, which can also pick up the same item multiple times, | ||
285 | //we should rather iterate over an index that contains every uid exactly once. The remoteId index would be such an index, | ||
286 | //but we currently fail to iterate over all entries in an index it seems. | ||
287 | // auto remoteIds = synchronizationTransaction.openDatabase("rid.mapping." + bufferType, std::function<void(const Sink::Storage::Error &)>(), true); | ||
288 | auto mainDatabase = Sink::Storage::mainDatabase(transaction(), bufferType); | ||
289 | mainDatabase.scan("", [&](const QByteArray &key, const QByteArray &) { | ||
290 | callback(key); | ||
291 | return true; | ||
292 | }); | ||
293 | }, | ||
294 | [&folderList](const QByteArray &remoteId) -> bool { | 282 | [&folderList](const QByteArray &remoteId) -> bool { |
295 | return folderList.contains(remoteId); | 283 | return folderList.contains(remoteId); |
296 | } | 284 | } |
@@ -323,16 +311,9 @@ public: | |||
323 | 311 | ||
324 | const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, path.toUtf8()); | 312 | const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, path.toUtf8()); |
325 | 313 | ||
326 | auto property = "folder"; | ||
327 | scanForRemovals(bufferType, | 314 | scanForRemovals(bufferType, |
328 | [&](const std::function<void(const QByteArray &)> &callback) { | 315 | [&](const std::function<void(const QByteArray &)> &callback) { |
329 | Index index(bufferType + ".index." + property, transaction()); | 316 | store().indexLookup<ApplicationDomain::Mail, ApplicationDomain::Mail::Folder>(folderLocalId, callback); |
330 | index.lookup(folderLocalId, [&](const QByteArray &sinkId) { | ||
331 | callback(sinkId); | ||
332 | }, | ||
333 | [&](const Index::Error &error) { | ||
334 | SinkWarning() << "Error in index: " << error.message << property; | ||
335 | }); | ||
336 | }, | 317 | }, |
337 | [](const QByteArray &remoteId) -> bool { | 318 | [](const QByteArray &remoteId) -> bool { |
338 | return QFile(remoteId).exists(); | 319 | return QFile(remoteId).exists(); |
@@ -392,7 +373,7 @@ public: | |||
392 | class MaildirWriteback : public Sink::SourceWriteBack | 373 | class MaildirWriteback : public Sink::SourceWriteBack |
393 | { | 374 | { |
394 | public: | 375 | public: |
395 | MaildirWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier) | 376 | MaildirWriteback(const Sink::ResourceContext &resourceContext) : Sink::SourceWriteBack(resourceContext) |
396 | { | 377 | { |
397 | 378 | ||
398 | } | 379 | } |
@@ -442,24 +423,24 @@ public: | |||
442 | }; | 423 | }; |
443 | 424 | ||
444 | 425 | ||
445 | MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) | 426 | MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline) |
446 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) | 427 | : Sink::GenericResource(resourceContext, pipeline) |
447 | { | 428 | { |
448 | auto config = ResourceConfig::getConfiguration(instanceIdentifier); | 429 | auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); |
449 | mMaildirPath = QDir::cleanPath(QDir::fromNativeSeparators(config.value("path").toString())); | 430 | mMaildirPath = QDir::cleanPath(QDir::fromNativeSeparators(config.value("path").toString())); |
450 | //Chop a trailing slash if necessary | 431 | //Chop a trailing slash if necessary |
451 | if (mMaildirPath.endsWith("/")) { | 432 | if (mMaildirPath.endsWith("/")) { |
452 | mMaildirPath.chop(1); | 433 | mMaildirPath.chop(1); |
453 | } | 434 | } |
454 | 435 | ||
455 | auto synchronizer = QSharedPointer<MaildirSynchronizer>::create(PLUGIN_NAME, instanceIdentifier); | 436 | auto synchronizer = QSharedPointer<MaildirSynchronizer>::create(resourceContext); |
456 | synchronizer->mMaildirPath = mMaildirPath; | 437 | synchronizer->mMaildirPath = mMaildirPath; |
457 | setupSynchronizer(synchronizer); | 438 | setupSynchronizer(synchronizer); |
458 | auto changereplay = QSharedPointer<MaildirWriteback>::create(PLUGIN_NAME, instanceIdentifier); | 439 | auto changereplay = QSharedPointer<MaildirWriteback>::create(resourceContext); |
459 | changereplay->mMaildirPath = mMaildirPath; | 440 | changereplay->mMaildirPath = mMaildirPath; |
460 | setupChangereplay(changereplay); | 441 | setupChangereplay(changereplay); |
461 | 442 | ||
462 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(mResourceType, mResourceInstanceIdentifier) << new MaildirMimeMessageMover(mResourceInstanceIdentifier, mMaildirPath) << new MaildirMailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); | 443 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MaildirMimeMessageMover(resourceContext.instanceId(), mMaildirPath) << new MaildirMailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); |
463 | setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new FolderPreprocessor(mMaildirPath) << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder>); | 444 | setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new FolderPreprocessor(mMaildirPath) << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder>); |
464 | 445 | ||
465 | KPIM::Maildir dir(mMaildirPath, true); | 446 | KPIM::Maildir dir(mMaildirPath, true); |
@@ -480,24 +461,24 @@ MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSh | |||
480 | void MaildirResource::removeFromDisk(const QByteArray &instanceIdentifier) | 461 | void MaildirResource::removeFromDisk(const QByteArray &instanceIdentifier) |
481 | { | 462 | { |
482 | GenericResource::removeFromDisk(instanceIdentifier); | 463 | GenericResource::removeFromDisk(instanceIdentifier); |
483 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); | 464 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
484 | } | 465 | } |
485 | 466 | ||
486 | KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) | 467 | KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) |
487 | { | 468 | { |
488 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); | 469 | auto synchronizationStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); |
489 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); | 470 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); |
490 | 471 | ||
491 | auto mainStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier, Sink::Storage::ReadOnly); | 472 | auto mainStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); |
492 | auto transaction = mainStore->createTransaction(Sink::Storage::ReadOnly); | 473 | auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); |
493 | 474 | ||
494 | auto entityStore = QSharedPointer<EntityStore>::create(mResourceType, mResourceInstanceIdentifier, transaction); | 475 | Sink::Storage::EntityStore entityStore(mResourceContext); |
495 | auto syncStore = QSharedPointer<RemoteIdMap>::create(synchronizationTransaction); | 476 | auto syncStore = QSharedPointer<RemoteIdMap>::create(synchronizationTransaction); |
496 | 477 | ||
497 | SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; | 478 | SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; |
498 | 479 | ||
499 | if (domainType == ENTITY_TYPE_MAIL) { | 480 | if (domainType == ENTITY_TYPE_MAIL) { |
500 | auto mail = entityStore->read<Sink::ApplicationDomain::Mail>(entityId); | 481 | auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); |
501 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | 482 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); |
502 | 483 | ||
503 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { | 484 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { |
@@ -530,7 +511,7 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray | |||
530 | } | 511 | } |
531 | if (domainType == ENTITY_TYPE_FOLDER) { | 512 | if (domainType == ENTITY_TYPE_FOLDER) { |
532 | const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); | 513 | const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); |
533 | auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(entityId); | 514 | auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId); |
534 | 515 | ||
535 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { | 516 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { |
536 | SinkTrace() << "Inspecting cache integrity" << remoteId; | 517 | SinkTrace() << "Inspecting cache integrity" << remoteId; |
@@ -577,9 +558,9 @@ MaildirResourceFactory::MaildirResourceFactory(QObject *parent) | |||
577 | 558 | ||
578 | } | 559 | } |
579 | 560 | ||
580 | Sink::Resource *MaildirResourceFactory::createResource(const QByteArray &instanceIdentifier) | 561 | Sink::Resource *MaildirResourceFactory::createResource(const ResourceContext &context) |
581 | { | 562 | { |
582 | return new MaildirResource(instanceIdentifier); | 563 | return new MaildirResource(context); |
583 | } | 564 | } |
584 | 565 | ||
585 | void MaildirResourceFactory::registerFacades(Sink::FacadeFactory &factory) | 566 | void MaildirResourceFactory::registerFacades(Sink::FacadeFactory &factory) |
diff --git a/examples/maildirresource/maildirresource.h b/examples/maildirresource/maildirresource.h index 490e1e6..6265819 100644 --- a/examples/maildirresource/maildirresource.h +++ b/examples/maildirresource/maildirresource.h | |||
@@ -45,7 +45,7 @@ class MaildirFolderAdaptorFactory; | |||
45 | class MaildirResource : public Sink::GenericResource | 45 | class MaildirResource : public Sink::GenericResource |
46 | { | 46 | { |
47 | public: | 47 | public: |
48 | MaildirResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); | 48 | MaildirResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); |
49 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; | 49 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; |
50 | static void removeFromDisk(const QByteArray &instanceIdentifier); | 50 | static void removeFromDisk(const QByteArray &instanceIdentifier); |
51 | private: | 51 | private: |
@@ -64,7 +64,7 @@ class MaildirResourceFactory : public Sink::ResourceFactory | |||
64 | public: | 64 | public: |
65 | MaildirResourceFactory(QObject *parent = 0); | 65 | MaildirResourceFactory(QObject *parent = 0); |
66 | 66 | ||
67 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 67 | Sink::Resource *createResource(const Sink::ResourceContext &context) Q_DECL_OVERRIDE; |
68 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; | 68 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; |
69 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; | 69 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; |
70 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 70 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; |
diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp index 3ce9476..9a22c41 100644 --- a/examples/mailtransportresource/mailtransportresource.cpp +++ b/examples/mailtransportresource/mailtransportresource.cpp | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <pipeline.h> | 41 | #include <pipeline.h> |
42 | #include <mailpreprocessor.h> | 42 | #include <mailpreprocessor.h> |
43 | #include <indexupdater.h> | 43 | #include <indexupdater.h> |
44 | #include <adaptorfactoryregistry.h> | ||
44 | 45 | ||
45 | #define ENTITY_TYPE_MAIL "mail" | 46 | #define ENTITY_TYPE_MAIL "mail" |
46 | 47 | ||
@@ -52,7 +53,7 @@ using namespace Sink; | |||
52 | class MailtransportWriteback : public Sink::SourceWriteBack | 53 | class MailtransportWriteback : public Sink::SourceWriteBack |
53 | { | 54 | { |
54 | public: | 55 | public: |
55 | MailtransportWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier) | 56 | MailtransportWriteback(const Sink::ResourceContext &resourceContext) : Sink::SourceWriteBack(resourceContext) |
56 | { | 57 | { |
57 | 58 | ||
58 | } | 59 | } |
@@ -74,9 +75,9 @@ public: | |||
74 | 75 | ||
75 | class MailtransportSynchronizer : public Sink::Synchronizer { | 76 | class MailtransportSynchronizer : public Sink::Synchronizer { |
76 | public: | 77 | public: |
77 | MailtransportSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) | 78 | MailtransportSynchronizer(const Sink::ResourceContext &resourceContext) |
78 | : Sink::Synchronizer(resourceType, resourceInstanceIdentifier), | 79 | : Sink::Synchronizer(resourceContext), |
79 | mResourceInstanceIdentifier(resourceInstanceIdentifier) | 80 | mResourceInstanceIdentifier(resourceContext.instanceId()) |
80 | { | 81 | { |
81 | 82 | ||
82 | } | 83 | } |
@@ -112,10 +113,9 @@ public: | |||
112 | { | 113 | { |
113 | SinkLog() << " Synchronizing"; | 114 | SinkLog() << " Synchronizing"; |
114 | return KAsync::start<void>([this](KAsync::Future<void> future) { | 115 | return KAsync::start<void>([this](KAsync::Future<void> future) { |
115 | Sink::Query query; | ||
116 | QList<ApplicationDomain::Mail> toSend; | 116 | QList<ApplicationDomain::Mail> toSend; |
117 | SinkLog() << " Looking for mail"; | 117 | SinkLog() << " Looking for mail"; |
118 | store().reader<ApplicationDomain::Mail>().query(query, [&](const ApplicationDomain::Mail &mail) -> bool { | 118 | store().readAll<ApplicationDomain::Mail>([&](const ApplicationDomain::Mail &mail) -> bool { |
119 | SinkTrace() << "Found mail: " << mail.identifier(); | 119 | SinkTrace() << "Found mail: " << mail.identifier(); |
120 | if (!mail.getSent()) { | 120 | if (!mail.getSent()) { |
121 | toSend << mail; | 121 | toSend << mail; |
@@ -143,10 +143,10 @@ public: | |||
143 | MailtransportResource::Settings mSettings; | 143 | MailtransportResource::Settings mSettings; |
144 | }; | 144 | }; |
145 | 145 | ||
146 | MailtransportResource::MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) | 146 | MailtransportResource::MailtransportResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline) |
147 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) | 147 | : Sink::GenericResource(resourceContext, pipeline) |
148 | { | 148 | { |
149 | auto config = ResourceConfig::getConfiguration(instanceIdentifier); | 149 | auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); |
150 | mSettings = {config.value("server").toString(), | 150 | mSettings = {config.value("server").toString(), |
151 | config.value("username").toString(), | 151 | config.value("username").toString(), |
152 | config.value("cacert").toString(), | 152 | config.value("cacert").toString(), |
@@ -154,11 +154,11 @@ MailtransportResource::MailtransportResource(const QByteArray &instanceIdentifie | |||
154 | config.value("testmode").toBool() | 154 | config.value("testmode").toBool() |
155 | }; | 155 | }; |
156 | 156 | ||
157 | auto synchronizer = QSharedPointer<MailtransportSynchronizer>::create(PLUGIN_NAME, instanceIdentifier); | 157 | auto synchronizer = QSharedPointer<MailtransportSynchronizer>::create(resourceContext); |
158 | synchronizer->mSettings = mSettings; | 158 | synchronizer->mSettings = mSettings; |
159 | setupSynchronizer(synchronizer); | 159 | setupSynchronizer(synchronizer); |
160 | 160 | ||
161 | auto changereplay = QSharedPointer<MailtransportWriteback>::create(PLUGIN_NAME, instanceIdentifier); | 161 | auto changereplay = QSharedPointer<MailtransportWriteback>::create(resourceContext); |
162 | changereplay->mSettings = mSettings; | 162 | changereplay->mSettings = mSettings; |
163 | setupChangereplay(changereplay); | 163 | setupChangereplay(changereplay); |
164 | 164 | ||
@@ -168,14 +168,14 @@ MailtransportResource::MailtransportResource(const QByteArray &instanceIdentifie | |||
168 | void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier) | 168 | void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier) |
169 | { | 169 | { |
170 | GenericResource::removeFromDisk(instanceIdentifier); | 170 | GenericResource::removeFromDisk(instanceIdentifier); |
171 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); | 171 | Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
172 | } | 172 | } |
173 | 173 | ||
174 | KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) | 174 | KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) |
175 | { | 175 | { |
176 | if (domainType == ENTITY_TYPE_MAIL) { | 176 | if (domainType == ENTITY_TYPE_MAIL) { |
177 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { | 177 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { |
178 | auto path = resourceStorageLocation(mResourceInstanceIdentifier) + "/test/" + entityId; | 178 | auto path = resourceStorageLocation(mResourceContext.instanceId()) + "/test/" + entityId; |
179 | if (QFileInfo::exists(path)) { | 179 | if (QFileInfo::exists(path)) { |
180 | return KAsync::null<void>(); | 180 | return KAsync::null<void>(); |
181 | } | 181 | } |
@@ -191,14 +191,14 @@ MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) | |||
191 | 191 | ||
192 | } | 192 | } |
193 | 193 | ||
194 | Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier) | 194 | Sink::Resource *MailtransportResourceFactory::createResource(const Sink::ResourceContext &context) |
195 | { | 195 | { |
196 | return new MailtransportResource(instanceIdentifier); | 196 | return new MailtransportResource(context); |
197 | } | 197 | } |
198 | 198 | ||
199 | void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory) | 199 | void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory) |
200 | { | 200 | { |
201 | factory.registerFacade<ApplicationDomain::Mail, DefaultFacade<ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>>(PLUGIN_NAME); | 201 | factory.registerFacade<ApplicationDomain::Mail, DefaultFacade<ApplicationDomain::Mail>>(PLUGIN_NAME); |
202 | } | 202 | } |
203 | 203 | ||
204 | void MailtransportResourceFactory::registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) | 204 | void MailtransportResourceFactory::registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) |
diff --git a/examples/mailtransportresource/mailtransportresource.h b/examples/mailtransportresource/mailtransportresource.h index dcc33df..212880c 100644 --- a/examples/mailtransportresource/mailtransportresource.h +++ b/examples/mailtransportresource/mailtransportresource.h | |||
@@ -28,7 +28,7 @@ | |||
28 | class MailtransportResource : public Sink::GenericResource | 28 | class MailtransportResource : public Sink::GenericResource |
29 | { | 29 | { |
30 | public: | 30 | public: |
31 | MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); | 31 | MailtransportResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); |
32 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; | 32 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; |
33 | static void removeFromDisk(const QByteArray &instanceIdentifier); | 33 | static void removeFromDisk(const QByteArray &instanceIdentifier); |
34 | 34 | ||
@@ -52,7 +52,7 @@ class MailtransportResourceFactory : public Sink::ResourceFactory | |||
52 | public: | 52 | public: |
53 | MailtransportResourceFactory(QObject *parent = 0); | 53 | MailtransportResourceFactory(QObject *parent = 0); |
54 | 54 | ||
55 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 55 | Sink::Resource *createResource(const Sink::ResourceContext &resourceContext) Q_DECL_OVERRIDE; |
56 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; | 56 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; |
57 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; | 57 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; |
58 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 58 | void removeDataFromDisk(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; |
diff --git a/sinksh/syntax_modules/sink_stat.cpp b/sinksh/syntax_modules/sink_stat.cpp index 9f0fe44..5978c01 100644 --- a/sinksh/syntax_modules/sink_stat.cpp +++ b/sinksh/syntax_modules/sink_stat.cpp | |||
@@ -42,8 +42,8 @@ void statResources(const QStringList &resources, const State &state) | |||
42 | { | 42 | { |
43 | qint64 total = 0; | 43 | qint64 total = 0; |
44 | for (const auto &resource : resources) { | 44 | for (const auto &resource : resources) { |
45 | Sink::Storage storage(Sink::storageLocation(), resource, Sink::Storage::ReadOnly); | 45 | Sink::Storage::DataStore storage(Sink::storageLocation(), resource, Sink::Storage::DataStore::ReadOnly); |
46 | auto transaction = storage.createTransaction(Sink::Storage::ReadOnly); | 46 | auto transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly); |
47 | 47 | ||
48 | QList<QByteArray> databases = transaction.getDatabaseNames(); | 48 | QList<QByteArray> databases = transaction.getDatabaseNames(); |
49 | for (const auto &databaseName : databases) { | 49 | for (const auto &databaseName : databases) { |
@@ -57,7 +57,7 @@ void statResources(const QStringList &resources, const State &state) | |||
57 | 57 | ||
58 | QDir dir(Sink::storageLocation()); | 58 | QDir dir(Sink::storageLocation()); |
59 | for (const auto &folder : dir.entryList(QStringList() << resource + "*")) { | 59 | for (const auto &folder : dir.entryList(QStringList() << resource + "*")) { |
60 | diskUsage += Sink::Storage(Sink::storageLocation(), folder, Sink::Storage::ReadOnly).diskUsage(); | 60 | diskUsage += Sink::Storage::DataStore(Sink::storageLocation(), folder, Sink::Storage::DataStore::ReadOnly).diskUsage(); |
61 | } | 61 | } |
62 | auto size = diskUsage / 1024; | 62 | auto size = diskUsage / 1024; |
63 | state.printLine(QObject::tr("Disk usage [kb]: %1").arg(size), 1); | 63 | state.printLine(QObject::tr("Disk usage [kb]: %1").arg(size), 1); |
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp index fd3d5f0..94c78a7 100644 --- a/tests/clientapitest.cpp +++ b/tests/clientapitest.cpp | |||
@@ -22,11 +22,13 @@ public: | |||
22 | auto facade = std::make_shared<TestDummyResourceFacade<T>>(); | 22 | auto facade = std::make_shared<TestDummyResourceFacade<T>>(); |
23 | map.insert(instanceIdentifier, facade); | 23 | map.insert(instanceIdentifier, facade); |
24 | bool alwaysReturnFacade = instanceIdentifier.isEmpty(); | 24 | bool alwaysReturnFacade = instanceIdentifier.isEmpty(); |
25 | Sink::FacadeFactory::instance().registerFacade<T, TestDummyResourceFacade<T>>("dummyresource", [alwaysReturnFacade](const QByteArray &instanceIdentifier) { | 25 | Sink::FacadeFactory::instance().registerFacade<T, TestDummyResourceFacade<T>>("dummyresource", [alwaysReturnFacade](const Sink::ResourceContext &context) { |
26 | if (alwaysReturnFacade) { | 26 | if (alwaysReturnFacade) { |
27 | Q_ASSERT(map.contains(QByteArray())); | ||
27 | return map.value(QByteArray()); | 28 | return map.value(QByteArray()); |
28 | } | 29 | } |
29 | return map.value(instanceIdentifier); | 30 | Q_ASSERT(map.contains(context.instanceId())); |
31 | return map.value(context.instanceId()); | ||
30 | }); | 32 | }); |
31 | return facade; | 33 | return facade; |
32 | } | 34 | } |
diff --git a/tests/databasepopulationandfacadequerybenchmark.cpp b/tests/databasepopulationandfacadequerybenchmark.cpp index 5efe292..4e00bd4 100644 --- a/tests/databasepopulationandfacadequerybenchmark.cpp +++ b/tests/databasepopulationandfacadequerybenchmark.cpp | |||
@@ -38,13 +38,13 @@ class DatabasePopulationAndFacadeQueryBenchmark : public QObject | |||
38 | 38 | ||
39 | void populateDatabase(int count) | 39 | void populateDatabase(int count) |
40 | { | 40 | { |
41 | Sink::Storage(Sink::storageLocation(), "identifier", Sink::Storage::ReadWrite).removeFromDisk(); | 41 | Sink::Storage::DataStore(Sink::storageLocation(), "identifier", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); |
42 | // Setup | 42 | // Setup |
43 | auto domainTypeAdaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); | 43 | auto domainTypeAdaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); |
44 | { | 44 | { |
45 | Sink::Storage storage(Sink::storageLocation(), identifier, Sink::Storage::ReadWrite); | 45 | Sink::Storage::DataStore storage(Sink::storageLocation(), identifier, Sink::Storage::DataStore::ReadWrite); |
46 | auto transaction = storage.createTransaction(Sink::Storage::ReadWrite); | 46 | auto transaction = storage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
47 | auto db = Sink::Storage::mainDatabase(transaction, "event"); | 47 | auto db = Sink::Storage::DataStore::mainDatabase(transaction, "event"); |
48 | 48 | ||
49 | int bufferSizeTotal = 0; | 49 | int bufferSizeTotal = 0; |
50 | int keysSizeTotal = 0; | 50 | int keysSizeTotal = 0; |
@@ -58,15 +58,15 @@ class DatabasePopulationAndFacadeQueryBenchmark : public QObject | |||
58 | flatbuffers::FlatBufferBuilder fbb; | 58 | flatbuffers::FlatBufferBuilder fbb; |
59 | domainTypeAdaptorFactory->createBuffer(*domainObject, fbb); | 59 | domainTypeAdaptorFactory->createBuffer(*domainObject, fbb); |
60 | const auto buffer = QByteArray::fromRawData(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize()); | 60 | const auto buffer = QByteArray::fromRawData(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize()); |
61 | const auto key = Sink::Storage::generateUid(); | 61 | const auto key = Sink::Storage::DataStore::generateUid(); |
62 | db.write(key, buffer); | 62 | db.write(key, buffer); |
63 | bufferSizeTotal += buffer.size(); | 63 | bufferSizeTotal += buffer.size(); |
64 | keysSizeTotal += key.size(); | 64 | keysSizeTotal += key.size(); |
65 | } | 65 | } |
66 | transaction.commit(); | 66 | transaction.commit(); |
67 | 67 | ||
68 | transaction = storage.createTransaction(Sink::Storage::ReadOnly); | 68 | transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly); |
69 | db = Sink::Storage::mainDatabase(transaction, "event"); | 69 | db = Sink::Storage::DataStore::mainDatabase(transaction, "event"); |
70 | 70 | ||
71 | auto dataSizeTotal = count * (QByteArray("uid").size() + QByteArray("summary").size() + attachment.size()); | 71 | auto dataSizeTotal = count * (QByteArray("uid").size() + QByteArray("summary").size() + attachment.size()); |
72 | auto size = db.getSize(); | 72 | auto size = db.getSize(); |
@@ -100,7 +100,11 @@ class DatabasePopulationAndFacadeQueryBenchmark : public QObject | |||
100 | 100 | ||
101 | auto resultSet = QSharedPointer<Sink::ResultProvider<Sink::ApplicationDomain::Event::Ptr>>::create(); | 101 | auto resultSet = QSharedPointer<Sink::ResultProvider<Sink::ApplicationDomain::Event::Ptr>>::create(); |
102 | auto resourceAccess = QSharedPointer<TestResourceAccess>::create(); | 102 | auto resourceAccess = QSharedPointer<TestResourceAccess>::create(); |
103 | TestResourceFacade facade(identifier, resourceAccess); | 103 | |
104 | QMap<QByteArray, DomainTypeAdaptorFactoryInterface::Ptr> factories; | ||
105 | Sink::ResourceContext context{identifier, "test", factories}; | ||
106 | context.mResourceAccess = resourceAccess; | ||
107 | TestResourceFacade facade(context); | ||
104 | 108 | ||
105 | auto ret = facade.load(query); | 109 | auto ret = facade.load(query); |
106 | ret.first.exec().waitForFinished(); | 110 | ret.first.exec().waitForFinished(); |
@@ -118,7 +122,7 @@ class DatabasePopulationAndFacadeQueryBenchmark : public QObject | |||
118 | const auto finalRss = getCurrentRSS(); | 122 | const auto finalRss = getCurrentRSS(); |
119 | const auto rssGrowth = finalRss - startingRss; | 123 | const auto rssGrowth = finalRss - startingRss; |
120 | // Since the database is memory mapped it is attributted to the resident set size. | 124 | // Since the database is memory mapped it is attributted to the resident set size. |
121 | const auto rssWithoutDb = finalRss - Sink::Storage(Sink::storageLocation(), identifier, Sink::Storage::ReadWrite).diskUsage(); | 125 | const auto rssWithoutDb = finalRss - Sink::Storage::DataStore(Sink::storageLocation(), identifier, Sink::Storage::DataStore::ReadWrite).diskUsage(); |
122 | const auto peakRss = getPeakRSS(); | 126 | const auto peakRss = getPeakRSS(); |
123 | // How much peak deviates from final rss in percent (should be around 0) | 127 | // How much peak deviates from final rss in percent (should be around 0) |
124 | const auto percentageRssError = static_cast<double>(peakRss - finalRss) * 100.0 / static_cast<double>(finalRss); | 128 | const auto percentageRssError = static_cast<double>(peakRss - finalRss) * 100.0 / static_cast<double>(finalRss); |
diff --git a/tests/dummyresourcebenchmark.cpp b/tests/dummyresourcebenchmark.cpp index d0ecef7..a2de316 100644 --- a/tests/dummyresourcebenchmark.cpp +++ b/tests/dummyresourcebenchmark.cpp | |||
@@ -9,7 +9,6 @@ | |||
9 | #include "resourcecontrol.h" | 9 | #include "resourcecontrol.h" |
10 | #include "commands.h" | 10 | #include "commands.h" |
11 | #include "entitybuffer.h" | 11 | #include "entitybuffer.h" |
12 | #include "pipeline.h" | ||
13 | #include "log.h" | 12 | #include "log.h" |
14 | #include "resourceconfig.h" | 13 | #include "resourceconfig.h" |
15 | #include "notification_generated.h" | 14 | #include "notification_generated.h" |
@@ -151,8 +150,7 @@ private slots: | |||
151 | QTime time; | 150 | QTime time; |
152 | time.start(); | 151 | time.start(); |
153 | 152 | ||
154 | auto pipeline = QSharedPointer<Sink::Pipeline>::create("sink.dummy.instance1"); | 153 | DummyResource resource(Sink::ResourceContext{"sink.dummy.instance1", "test"}); |
155 | DummyResource resource("sink.dummy.instance1", pipeline); | ||
156 | 154 | ||
157 | flatbuffers::FlatBufferBuilder eventFbb; | 155 | flatbuffers::FlatBufferBuilder eventFbb; |
158 | eventFbb.Clear(); | 156 | eventFbb.Clear(); |
diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp index be6e3a5..0883a13 100644 --- a/tests/dummyresourcetest.cpp +++ b/tests/dummyresourcetest.cpp | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "log.h" | 13 | #include "log.h" |
14 | #include "test.h" | 14 | #include "test.h" |
15 | #include "testutils.h" | 15 | #include "testutils.h" |
16 | #include "adaptorfactoryregistry.h" | ||
16 | 17 | ||
17 | using namespace Sink; | 18 | using namespace Sink; |
18 | using namespace Sink::ApplicationDomain; | 19 | using namespace Sink::ApplicationDomain; |
@@ -28,6 +29,11 @@ class DummyResourceTest : public QObject | |||
28 | 29 | ||
29 | QTime time; | 30 | QTime time; |
30 | 31 | ||
32 | Sink::ResourceContext getContext() | ||
33 | { | ||
34 | return Sink::ResourceContext{"sink.dummy.instance1", "sink.dummy", Sink::AdaptorFactoryRegistry::instance().getFactories("sink.dummy")}; | ||
35 | } | ||
36 | |||
31 | private slots: | 37 | private slots: |
32 | void initTestCase() | 38 | void initTestCase() |
33 | { | 39 | { |
@@ -129,8 +135,7 @@ private slots: | |||
129 | 135 | ||
130 | void testResourceSync() | 136 | void testResourceSync() |
131 | { | 137 | { |
132 | auto pipeline = QSharedPointer<Sink::Pipeline>::create("sink.dummy.instance1"); | 138 | ::DummyResource resource(getContext()); |
133 | ::DummyResource resource("sink.dummy.instance1", pipeline); | ||
134 | auto job = resource.synchronizeWithSource(); | 139 | auto job = resource.synchronizeWithSource(); |
135 | // TODO pass in optional timeout? | 140 | // TODO pass in optional timeout? |
136 | auto future = job.exec(); | 141 | auto future = job.exec(); |
diff --git a/tests/dummyresourcewritebenchmark.cpp b/tests/dummyresourcewritebenchmark.cpp index 5cd7007..facd60c 100644 --- a/tests/dummyresourcewritebenchmark.cpp +++ b/tests/dummyresourcewritebenchmark.cpp | |||
@@ -9,7 +9,6 @@ | |||
9 | #include "store.h" | 9 | #include "store.h" |
10 | #include "commands.h" | 10 | #include "commands.h" |
11 | #include "entitybuffer.h" | 11 | #include "entitybuffer.h" |
12 | #include "pipeline.h" | ||
13 | #include "log.h" | 12 | #include "log.h" |
14 | #include "resourceconfig.h" | 13 | #include "resourceconfig.h" |
15 | #include "definitions.h" | 14 | #include "definitions.h" |
@@ -109,8 +108,7 @@ class DummyResourceWriteBenchmark : public QObject | |||
109 | QTime time; | 108 | QTime time; |
110 | time.start(); | 109 | time.start(); |
111 | 110 | ||
112 | auto pipeline = QSharedPointer<Sink::Pipeline>::create("sink.dummy.instance1"); | 111 | ::DummyResource resource(Sink::ResourceContext{"sink.dummy.instance1", "dummy"}); |
113 | DummyResource resource("sink.dummy.instance1", pipeline); | ||
114 | 112 | ||
115 | int bufferSize = 0; | 113 | int bufferSize = 0; |
116 | auto command = createEntityBuffer(bufferSize); | 114 | auto command = createEntityBuffer(bufferSize); |
diff --git a/tests/hawd/dataset.cpp b/tests/hawd/dataset.cpp index c023f31..fb2d7e6 100644 --- a/tests/hawd/dataset.cpp +++ b/tests/hawd/dataset.cpp | |||
@@ -215,7 +215,7 @@ QString Dataset::Row::toString(const QStringList &cols, int standardCols, const | |||
215 | 215 | ||
216 | Dataset::Dataset(const QString &name, const State &state) | 216 | Dataset::Dataset(const QString &name, const State &state) |
217 | : m_definition(state.datasetDefinition(name)), | 217 | : m_definition(state.datasetDefinition(name)), |
218 | m_storage(state.resultsPath(), name, Sink::Storage::ReadWrite), | 218 | m_storage(state.resultsPath(), name, Sink::Storage::DataStore::ReadWrite), |
219 | m_transaction(m_storage.createTransaction()), | 219 | m_transaction(m_storage.createTransaction()), |
220 | m_commitHash(state.commitHash()) | 220 | m_commitHash(state.commitHash()) |
221 | { | 221 | { |
@@ -270,13 +270,13 @@ void Dataset::eachRow(const std::function<void(const Row &row)> &resultHandler) | |||
270 | resultHandler(row); | 270 | resultHandler(row); |
271 | return true; | 271 | return true; |
272 | }, | 272 | }, |
273 | Sink::Storage::basicErrorHandler()); | 273 | Sink::Storage::DataStore::basicErrorHandler()); |
274 | } | 274 | } |
275 | 275 | ||
276 | Dataset::Row Dataset::row(qint64 key) | 276 | Dataset::Row Dataset::row(qint64 key) |
277 | { | 277 | { |
278 | if (key < 1) { | 278 | if (key < 1) { |
279 | Row row(*this, Sink::Storage::maxRevision(m_transaction)); | 279 | Row row(*this, Sink::Storage::DataStore::maxRevision(m_transaction)); |
280 | row.setCommitHash(m_commitHash); | 280 | row.setCommitHash(m_commitHash); |
281 | return row; | 281 | return row; |
282 | } | 282 | } |
@@ -287,7 +287,7 @@ Dataset::Row Dataset::row(qint64 key) | |||
287 | row.fromBinary(value); | 287 | row.fromBinary(value); |
288 | return true; | 288 | return true; |
289 | }, | 289 | }, |
290 | Sink::Storage::basicErrorHandler() | 290 | Sink::Storage::DataStore::basicErrorHandler() |
291 | ); | 291 | ); |
292 | return row; | 292 | return row; |
293 | } | 293 | } |
diff --git a/tests/hawd/dataset.h b/tests/hawd/dataset.h index 0fca8f0..bb2aae5 100644 --- a/tests/hawd/dataset.h +++ b/tests/hawd/dataset.h | |||
@@ -84,8 +84,8 @@ public: | |||
84 | 84 | ||
85 | private: | 85 | private: |
86 | DatasetDefinition m_definition; | 86 | DatasetDefinition m_definition; |
87 | Sink::Storage m_storage; | 87 | Sink::Storage::DataStore m_storage; |
88 | Sink::Storage::Transaction m_transaction; | 88 | Sink::Storage::DataStore::Transaction m_transaction; |
89 | QString m_commitHash; | 89 | QString m_commitHash; |
90 | }; | 90 | }; |
91 | 91 | ||
diff --git a/tests/indextest.cpp b/tests/indextest.cpp index 8566803..d6a28d6 100644 --- a/tests/indextest.cpp +++ b/tests/indextest.cpp | |||
@@ -16,19 +16,19 @@ class IndexTest : public QObject | |||
16 | private slots: | 16 | private slots: |
17 | void initTestCase() | 17 | void initTestCase() |
18 | { | 18 | { |
19 | Sink::Storage store("./testindex", "sink.dummy.testindex", Sink::Storage::ReadWrite); | 19 | Sink::Storage::DataStore store("./testindex", "sink.dummy.testindex", Sink::Storage::DataStore::ReadWrite); |
20 | store.removeFromDisk(); | 20 | store.removeFromDisk(); |
21 | } | 21 | } |
22 | 22 | ||
23 | void cleanup() | 23 | void cleanup() |
24 | { | 24 | { |
25 | Sink::Storage store("./testindex", "sink.dummy.testindex", Sink::Storage::ReadWrite); | 25 | Sink::Storage::DataStore store("./testindex", "sink.dummy.testindex", Sink::Storage::DataStore::ReadWrite); |
26 | store.removeFromDisk(); | 26 | store.removeFromDisk(); |
27 | } | 27 | } |
28 | 28 | ||
29 | void testIndex() | 29 | void testIndex() |
30 | { | 30 | { |
31 | Index index("./testindex", "sink.dummy.testindex", Sink::Storage::ReadWrite); | 31 | Index index("./testindex", "sink.dummy.testindex", Sink::Storage::DataStore::ReadWrite); |
32 | // The first key is specifically a substring of the second key | 32 | // The first key is specifically a substring of the second key |
33 | index.add("key", "value1"); | 33 | index.add("key", "value1"); |
34 | index.add("keyFoo", "value2"); | 34 | index.add("keyFoo", "value2"); |
diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp index 1d96819..c44b9f6 100644 --- a/tests/mailquerybenchmark.cpp +++ b/tests/mailquerybenchmark.cpp | |||
@@ -62,8 +62,7 @@ class MailQueryBenchmark : public QObject | |||
62 | { | 62 | { |
63 | TestResource::removeFromDisk(resourceIdentifier); | 63 | TestResource::removeFromDisk(resourceIdentifier); |
64 | 64 | ||
65 | auto pipeline = QSharedPointer<Sink::Pipeline>::create(resourceIdentifier); | 65 | auto pipeline = QSharedPointer<Sink::Pipeline>::create(Sink::ResourceContext{resourceIdentifier, "test"}); |
66 | pipeline->setResourceType("test"); | ||
67 | 66 | ||
68 | auto indexer = QSharedPointer<DefaultIndexUpdater<Mail>>::create(); | 67 | auto indexer = QSharedPointer<DefaultIndexUpdater<Mail>>::create(); |
69 | 68 | ||
@@ -94,10 +93,10 @@ class MailQueryBenchmark : public QObject | |||
94 | // Benchmark | 93 | // Benchmark |
95 | QTime time; | 94 | QTime time; |
96 | time.start(); | 95 | time.start(); |
97 | |||
98 | auto resultSet = QSharedPointer<Sink::ResultProvider<Mail::Ptr>>::create(); | 96 | auto resultSet = QSharedPointer<Sink::ResultProvider<Mail::Ptr>>::create(); |
99 | auto resourceAccess = QSharedPointer<TestResourceAccess>::create(); | 97 | Sink::ResourceContext context{resourceIdentifier, "test"}; |
100 | TestMailResourceFacade facade(resourceIdentifier, resourceAccess); | 98 | context.mResourceAccess = QSharedPointer<TestResourceAccess>::create(); |
99 | TestMailResourceFacade facade(context); | ||
101 | 100 | ||
102 | auto ret = facade.load(query); | 101 | auto ret = facade.load(query); |
103 | ret.first.exec().waitForFinished(); | 102 | ret.first.exec().waitForFinished(); |
@@ -115,7 +114,7 @@ class MailQueryBenchmark : public QObject | |||
115 | const auto finalRss = getCurrentRSS(); | 114 | const auto finalRss = getCurrentRSS(); |
116 | const auto rssGrowth = finalRss - startingRss; | 115 | const auto rssGrowth = finalRss - startingRss; |
117 | // Since the database is memory mapped it is attributted to the resident set size. | 116 | // Since the database is memory mapped it is attributted to the resident set size. |
118 | const auto rssWithoutDb = finalRss - Sink::Storage(Sink::storageLocation(), resourceIdentifier, Sink::Storage::ReadWrite).diskUsage(); | 117 | const auto rssWithoutDb = finalRss - Sink::Storage::DataStore(Sink::storageLocation(), resourceIdentifier, Sink::Storage::DataStore::ReadWrite).diskUsage(); |
119 | const auto peakRss = getPeakRSS(); | 118 | const auto peakRss = getPeakRSS(); |
120 | // How much peak deviates from final rss in percent (should be around 0) | 119 | // How much peak deviates from final rss in percent (should be around 0) |
121 | const auto percentageRssError = static_cast<double>(peakRss - finalRss) * 100.0 / static_cast<double>(finalRss); | 120 | const auto percentageRssError = static_cast<double>(peakRss - finalRss) * 100.0 / static_cast<double>(finalRss); |
diff --git a/tests/messagequeuetest.cpp b/tests/messagequeuetest.cpp index e79bba2..83fa23f 100644 --- a/tests/messagequeuetest.cpp +++ b/tests/messagequeuetest.cpp | |||
@@ -21,7 +21,7 @@ private slots: | |||
21 | void initTestCase() | 21 | void initTestCase() |
22 | { | 22 | { |
23 | Sink::Test::initTest(); | 23 | Sink::Test::initTest(); |
24 | Sink::Storage store(Sink::Store::storageLocation(), "sink.dummy.testqueue", Sink::Storage::ReadWrite); | 24 | Sink::Storage::DataStore store(Sink::Store::storageLocation(), "sink.dummy.testqueue", Sink::Storage::DataStore::ReadWrite); |
25 | store.removeFromDisk(); | 25 | store.removeFromDisk(); |
26 | } | 26 | } |
27 | 27 | ||
@@ -31,7 +31,7 @@ private slots: | |||
31 | 31 | ||
32 | void cleanup() | 32 | void cleanup() |
33 | { | 33 | { |
34 | Sink::Storage store(Sink::Store::storageLocation(), "sink.dummy.testqueue", Sink::Storage::ReadWrite); | 34 | Sink::Storage::DataStore store(Sink::Store::storageLocation(), "sink.dummy.testqueue", Sink::Storage::DataStore::ReadWrite); |
35 | store.removeFromDisk(); | 35 | store.removeFromDisk(); |
36 | } | 36 | } |
37 | 37 | ||
diff --git a/tests/pipelinebenchmark.cpp b/tests/pipelinebenchmark.cpp index 0c0b9e6..16806c7 100644 --- a/tests/pipelinebenchmark.cpp +++ b/tests/pipelinebenchmark.cpp | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | // class IndexUpdater : public Sink::Preprocessor { | 48 | // class IndexUpdater : public Sink::Preprocessor { |
49 | // public: | 49 | // public: |
50 | // void newEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 50 | // void newEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
51 | // { | 51 | // { |
52 | // for (int i = 0; i < 10; i++) { | 52 | // for (int i = 0; i < 10; i++) { |
53 | // Index ridIndex(QString("index.index%1").arg(i).toLatin1(), transaction); | 53 | // Index ridIndex(QString("index.index%1").arg(i).toLatin1(), transaction); |
@@ -56,11 +56,11 @@ | |||
56 | // } | 56 | // } |
57 | // | 57 | // |
58 | // void modifiedEntity(const QByteArray &key, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, const Sink::ApplicationDomain::BufferAdaptor &newEntity, | 58 | // void modifiedEntity(const QByteArray &key, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, const Sink::ApplicationDomain::BufferAdaptor &newEntity, |
59 | // Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 59 | // Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
60 | // { | 60 | // { |
61 | // } | 61 | // } |
62 | // | 62 | // |
63 | // void deletedEntity(const QByteArray &key, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 63 | // void deletedEntity(const QByteArray &key, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
64 | // { | 64 | // { |
65 | // } | 65 | // } |
66 | // }; | 66 | // }; |
@@ -83,9 +83,8 @@ class PipelineBenchmark : public QObject | |||
83 | { | 83 | { |
84 | TestResource::removeFromDisk(resourceIdentifier); | 84 | TestResource::removeFromDisk(resourceIdentifier); |
85 | 85 | ||
86 | auto pipeline = QSharedPointer<Sink::Pipeline>::create(resourceIdentifier); | 86 | auto pipeline = QSharedPointer<Sink::Pipeline>::create(Sink::ResourceContext{resourceIdentifier, "test"}); |
87 | pipeline->setPreprocessors("mail", preprocessors); | 87 | pipeline->setPreprocessors("mail", preprocessors); |
88 | pipeline->setResourceType("test"); | ||
89 | 88 | ||
90 | QTime time; | 89 | QTime time; |
91 | time.start(); | 90 | time.start(); |
@@ -112,7 +111,7 @@ class PipelineBenchmark : public QObject | |||
112 | // Print memory layout, RSS is what is in memory | 111 | // Print memory layout, RSS is what is in memory |
113 | // std::system("exec pmap -x \"$PPID\""); | 112 | // std::system("exec pmap -x \"$PPID\""); |
114 | // | 113 | // |
115 | std::cout << "Size: " << Sink::Storage(Sink::storageLocation(), resourceIdentifier, Sink::Storage::ReadOnly).diskUsage() / 1024 << " [kb]" << std::endl; | 114 | std::cout << "Size: " << Sink::Storage::DataStore(Sink::storageLocation(), resourceIdentifier, Sink::Storage::DataStore::ReadOnly).diskUsage() / 1024 << " [kb]" << std::endl; |
116 | std::cout << "Time: " << allProcessedTime << " [ms]" << std::endl; | 115 | std::cout << "Time: " << allProcessedTime << " [ms]" << std::endl; |
117 | 116 | ||
118 | HAWD::Dataset dataset("pipeline", mHawdState); | 117 | HAWD::Dataset dataset("pipeline", mHawdState); |
diff --git a/tests/pipelinetest.cpp b/tests/pipelinetest.cpp index 7216f62..112453e 100644 --- a/tests/pipelinetest.cpp +++ b/tests/pipelinetest.cpp | |||
@@ -23,14 +23,14 @@ | |||
23 | 23 | ||
24 | static void removeFromDisk(const QString &name) | 24 | static void removeFromDisk(const QString &name) |
25 | { | 25 | { |
26 | Sink::Storage store(Sink::Store::storageLocation(), name, Sink::Storage::ReadWrite); | 26 | Sink::Storage::DataStore store(Sink::Store::storageLocation(), name, Sink::Storage::DataStore::ReadWrite); |
27 | store.removeFromDisk(); | 27 | store.removeFromDisk(); |
28 | } | 28 | } |
29 | 29 | ||
30 | static QList<QByteArray> getKeys(const QByteArray &dbEnv, const QByteArray &name) | 30 | static QList<QByteArray> getKeys(const QByteArray &dbEnv, const QByteArray &name) |
31 | { | 31 | { |
32 | Sink::Storage store(Sink::storageLocation(), dbEnv, Sink::Storage::ReadOnly); | 32 | Sink::Storage::DataStore store(Sink::storageLocation(), dbEnv, Sink::Storage::DataStore::ReadOnly); |
33 | auto transaction = store.createTransaction(Sink::Storage::ReadOnly); | 33 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadOnly); |
34 | auto db = transaction.openDatabase(name, nullptr, false); | 34 | auto db = transaction.openDatabase(name, nullptr, false); |
35 | QList<QByteArray> result; | 35 | QList<QByteArray> result; |
36 | db.scan("", [&](const QByteArray &key, const QByteArray &value) { | 36 | db.scan("", [&](const QByteArray &key, const QByteArray &value) { |
@@ -42,8 +42,8 @@ static QList<QByteArray> getKeys(const QByteArray &dbEnv, const QByteArray &name | |||
42 | 42 | ||
43 | static QByteArray getEntity(const QByteArray &dbEnv, const QByteArray &name, const QByteArray &uid) | 43 | static QByteArray getEntity(const QByteArray &dbEnv, const QByteArray &name, const QByteArray &uid) |
44 | { | 44 | { |
45 | Sink::Storage store(Sink::storageLocation(), dbEnv, Sink::Storage::ReadOnly); | 45 | Sink::Storage::DataStore store(Sink::storageLocation(), dbEnv, Sink::Storage::DataStore::ReadOnly); |
46 | auto transaction = store.createTransaction(Sink::Storage::ReadOnly); | 46 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadOnly); |
47 | auto db = transaction.openDatabase(name, nullptr, false); | 47 | auto db = transaction.openDatabase(name, nullptr, false); |
48 | QByteArray result; | 48 | QByteArray result; |
49 | db.scan(uid, [&](const QByteArray &key, const QByteArray &value) { | 49 | db.scan(uid, [&](const QByteArray &key, const QByteArray &value) { |
@@ -152,20 +152,20 @@ QByteArray deleteEntityCommand(const QByteArray &uid, qint64 revision) | |||
152 | class TestProcessor : public Sink::Preprocessor | 152 | class TestProcessor : public Sink::Preprocessor |
153 | { | 153 | { |
154 | public: | 154 | public: |
155 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 155 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
156 | { | 156 | { |
157 | newUids << uid; | 157 | newUids << uid; |
158 | newRevisions << revision; | 158 | newRevisions << revision; |
159 | } | 159 | } |
160 | 160 | ||
161 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 161 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
162 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 162 | Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
163 | { | 163 | { |
164 | modifiedUids << uid; | 164 | modifiedUids << uid; |
165 | modifiedRevisions << revision; | 165 | modifiedRevisions << revision; |
166 | } | 166 | } |
167 | 167 | ||
168 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 168 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::DataStore::Transaction &transaction) Q_DECL_OVERRIDE |
169 | { | 169 | { |
170 | deletedUids << uid; | 170 | deletedUids << uid; |
171 | deletedRevisions << revision; | 171 | deletedRevisions << revision; |
@@ -203,8 +203,7 @@ private slots: | |||
203 | flatbuffers::FlatBufferBuilder entityFbb; | 203 | flatbuffers::FlatBufferBuilder entityFbb; |
204 | auto command = createEntityCommand(createEvent(entityFbb)); | 204 | auto command = createEntityCommand(createEvent(entityFbb)); |
205 | 205 | ||
206 | Sink::Pipeline pipeline("sink.pipelinetest.instance1"); | 206 | Sink::Pipeline pipeline(Sink::ResourceContext{"sink.pipelinetest.instance1", "test"}); |
207 | pipeline.setResourceType("test"); | ||
208 | 207 | ||
209 | pipeline.startTransaction(); | 208 | pipeline.startTransaction(); |
210 | pipeline.newEntity(command.constData(), command.size()); | 209 | pipeline.newEntity(command.constData(), command.size()); |
@@ -220,8 +219,7 @@ private slots: | |||
220 | flatbuffers::FlatBufferBuilder entityFbb; | 219 | flatbuffers::FlatBufferBuilder entityFbb; |
221 | auto command = createEntityCommand(createEvent(entityFbb, "summary", "description")); | 220 | auto command = createEntityCommand(createEvent(entityFbb, "summary", "description")); |
222 | 221 | ||
223 | Sink::Pipeline pipeline("sink.pipelinetest.instance1"); | 222 | Sink::Pipeline pipeline(Sink::ResourceContext{"sink.pipelinetest.instance1", "test"}); |
224 | pipeline.setResourceType("test"); | ||
225 | 223 | ||
226 | auto adaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); | 224 | auto adaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); |
227 | 225 | ||
@@ -234,7 +232,7 @@ private slots: | |||
234 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); | 232 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); |
235 | QCOMPARE(keys.size(), 1); | 233 | QCOMPARE(keys.size(), 1); |
236 | const auto key = keys.first(); | 234 | const auto key = keys.first(); |
237 | const auto uid = Sink::Storage::uidFromKey(key); | 235 | const auto uid = Sink::Storage::DataStore::uidFromKey(key); |
238 | 236 | ||
239 | // Execute the modification | 237 | // Execute the modification |
240 | entityFbb.Clear(); | 238 | entityFbb.Clear(); |
@@ -244,7 +242,7 @@ private slots: | |||
244 | pipeline.commit(); | 242 | pipeline.commit(); |
245 | 243 | ||
246 | // Ensure we've got the new revision with the modification | 244 | // Ensure we've got the new revision with the modification |
247 | auto buffer = getEntity("sink.pipelinetest.instance1", "event.main", Sink::Storage::assembleKey(uid, 2)); | 245 | auto buffer = getEntity("sink.pipelinetest.instance1", "event.main", Sink::Storage::DataStore::assembleKey(uid, 2)); |
248 | QVERIFY(!buffer.isEmpty()); | 246 | QVERIFY(!buffer.isEmpty()); |
249 | Sink::EntityBuffer entityBuffer(buffer.data(), buffer.size()); | 247 | Sink::EntityBuffer entityBuffer(buffer.data(), buffer.size()); |
250 | auto adaptor = adaptorFactory->createAdaptor(entityBuffer.entity()); | 248 | auto adaptor = adaptorFactory->createAdaptor(entityBuffer.entity()); |
@@ -269,8 +267,7 @@ private slots: | |||
269 | flatbuffers::FlatBufferBuilder entityFbb; | 267 | flatbuffers::FlatBufferBuilder entityFbb; |
270 | auto command = createEntityCommand(createEvent(entityFbb)); | 268 | auto command = createEntityCommand(createEvent(entityFbb)); |
271 | 269 | ||
272 | Sink::Pipeline pipeline("sink.pipelinetest.instance1"); | 270 | Sink::Pipeline pipeline(Sink::ResourceContext{"sink.pipelinetest.instance1", "test"}); |
273 | pipeline.setResourceType("test"); | ||
274 | 271 | ||
275 | auto adaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); | 272 | auto adaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create(); |
276 | 273 | ||
@@ -282,7 +279,7 @@ private slots: | |||
282 | // Get uid of written entity | 279 | // Get uid of written entity |
283 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); | 280 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); |
284 | QCOMPARE(keys.size(), 1); | 281 | QCOMPARE(keys.size(), 1); |
285 | const auto uid = Sink::Storage::uidFromKey(keys.first()); | 282 | const auto uid = Sink::Storage::DataStore::uidFromKey(keys.first()); |
286 | 283 | ||
287 | 284 | ||
288 | // Create another operation inbetween | 285 | // Create another operation inbetween |
@@ -302,7 +299,7 @@ private slots: | |||
302 | pipeline.commit(); | 299 | pipeline.commit(); |
303 | 300 | ||
304 | // Ensure we've got the new revision with the modification | 301 | // Ensure we've got the new revision with the modification |
305 | auto buffer = getEntity("sink.pipelinetest.instance1", "event.main", Sink::Storage::assembleKey(uid, 3)); | 302 | auto buffer = getEntity("sink.pipelinetest.instance1", "event.main", Sink::Storage::DataStore::assembleKey(uid, 3)); |
306 | QVERIFY(!buffer.isEmpty()); | 303 | QVERIFY(!buffer.isEmpty()); |
307 | Sink::EntityBuffer entityBuffer(buffer.data(), buffer.size()); | 304 | Sink::EntityBuffer entityBuffer(buffer.data(), buffer.size()); |
308 | auto adaptor = adaptorFactory->createAdaptor(entityBuffer.entity()); | 305 | auto adaptor = adaptorFactory->createAdaptor(entityBuffer.entity()); |
@@ -313,8 +310,7 @@ private slots: | |||
313 | { | 310 | { |
314 | flatbuffers::FlatBufferBuilder entityFbb; | 311 | flatbuffers::FlatBufferBuilder entityFbb; |
315 | auto command = createEntityCommand(createEvent(entityFbb)); | 312 | auto command = createEntityCommand(createEvent(entityFbb)); |
316 | Sink::Pipeline pipeline("sink.pipelinetest.instance1"); | 313 | Sink::Pipeline pipeline(Sink::ResourceContext{"sink.pipelinetest.instance1", "test"}); |
317 | pipeline.setResourceType("test"); | ||
318 | 314 | ||
319 | // Create the initial revision | 315 | // Create the initial revision |
320 | pipeline.startTransaction(); | 316 | pipeline.startTransaction(); |
@@ -324,7 +320,7 @@ private slots: | |||
324 | auto result = getKeys("sink.pipelinetest.instance1", "event.main"); | 320 | auto result = getKeys("sink.pipelinetest.instance1", "event.main"); |
325 | QCOMPARE(result.size(), 1); | 321 | QCOMPARE(result.size(), 1); |
326 | 322 | ||
327 | const auto uid = Sink::Storage::uidFromKey(result.first()); | 323 | const auto uid = Sink::Storage::DataStore::uidFromKey(result.first()); |
328 | 324 | ||
329 | // Delete entity | 325 | // Delete entity |
330 | auto deleteCommand = deleteEntityCommand(uid, 1); | 326 | auto deleteCommand = deleteEntityCommand(uid, 1); |
@@ -350,8 +346,7 @@ private slots: | |||
350 | 346 | ||
351 | auto testProcessor = new TestProcessor; | 347 | auto testProcessor = new TestProcessor; |
352 | 348 | ||
353 | Sink::Pipeline pipeline("sink.pipelinetest.instance1"); | 349 | Sink::Pipeline pipeline(Sink::ResourceContext{"sink.pipelinetest.instance1", "test"}); |
354 | pipeline.setResourceType("test"); | ||
355 | pipeline.setPreprocessors("event", QVector<Sink::Preprocessor *>() << testProcessor); | 350 | pipeline.setPreprocessors("event", QVector<Sink::Preprocessor *>() << testProcessor); |
356 | pipeline.startTransaction(); | 351 | pipeline.startTransaction(); |
357 | // pipeline.setAdaptorFactory("event", QSharedPointer<TestEventAdaptorFactory>::create()); | 352 | // pipeline.setAdaptorFactory("event", QSharedPointer<TestEventAdaptorFactory>::create()); |
@@ -363,21 +358,21 @@ private slots: | |||
363 | QCOMPARE(testProcessor->newUids.size(), 1); | 358 | QCOMPARE(testProcessor->newUids.size(), 1); |
364 | QCOMPARE(testProcessor->newRevisions.size(), 1); | 359 | QCOMPARE(testProcessor->newRevisions.size(), 1); |
365 | // Key doesn't contain revision and is just the uid | 360 | // Key doesn't contain revision and is just the uid |
366 | QCOMPARE(testProcessor->newUids.at(0), Sink::Storage::uidFromKey(testProcessor->newUids.at(0))); | 361 | QCOMPARE(testProcessor->newUids.at(0), Sink::Storage::DataStore::uidFromKey(testProcessor->newUids.at(0))); |
367 | } | 362 | } |
368 | pipeline.commit(); | 363 | pipeline.commit(); |
369 | entityFbb.Clear(); | 364 | entityFbb.Clear(); |
370 | pipeline.startTransaction(); | 365 | pipeline.startTransaction(); |
371 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); | 366 | auto keys = getKeys("sink.pipelinetest.instance1", "event.main"); |
372 | QCOMPARE(keys.size(), 1); | 367 | QCOMPARE(keys.size(), 1); |
373 | const auto uid = Sink::Storage::uidFromKey(keys.first()); | 368 | const auto uid = Sink::Storage::DataStore::uidFromKey(keys.first()); |
374 | { | 369 | { |
375 | auto modifyCommand = modifyEntityCommand(createEvent(entityFbb, "summary2"), uid, 1); | 370 | auto modifyCommand = modifyEntityCommand(createEvent(entityFbb, "summary2"), uid, 1); |
376 | pipeline.modifiedEntity(modifyCommand.constData(), modifyCommand.size()); | 371 | pipeline.modifiedEntity(modifyCommand.constData(), modifyCommand.size()); |
377 | QCOMPARE(testProcessor->modifiedUids.size(), 1); | 372 | QCOMPARE(testProcessor->modifiedUids.size(), 1); |
378 | QCOMPARE(testProcessor->modifiedRevisions.size(), 1); | 373 | QCOMPARE(testProcessor->modifiedRevisions.size(), 1); |
379 | // Key doesn't contain revision and is just the uid | 374 | // Key doesn't contain revision and is just the uid |
380 | QCOMPARE(testProcessor->modifiedUids.at(0), Sink::Storage::uidFromKey(testProcessor->modifiedUids.at(0))); | 375 | QCOMPARE(testProcessor->modifiedUids.at(0), Sink::Storage::DataStore::uidFromKey(testProcessor->modifiedUids.at(0))); |
381 | } | 376 | } |
382 | pipeline.commit(); | 377 | pipeline.commit(); |
383 | entityFbb.Clear(); | 378 | entityFbb.Clear(); |
@@ -389,7 +384,7 @@ private slots: | |||
389 | QCOMPARE(testProcessor->deletedUids.size(), 1); | 384 | QCOMPARE(testProcessor->deletedUids.size(), 1); |
390 | QCOMPARE(testProcessor->deletedSummaries.size(), 1); | 385 | QCOMPARE(testProcessor->deletedSummaries.size(), 1); |
391 | // Key doesn't contain revision and is just the uid | 386 | // Key doesn't contain revision and is just the uid |
392 | QCOMPARE(testProcessor->deletedUids.at(0), Sink::Storage::uidFromKey(testProcessor->deletedUids.at(0))); | 387 | QCOMPARE(testProcessor->deletedUids.at(0), Sink::Storage::DataStore::uidFromKey(testProcessor->deletedUids.at(0))); |
393 | QCOMPARE(testProcessor->deletedSummaries.at(0), QByteArray("summary2")); | 388 | QCOMPARE(testProcessor->deletedSummaries.at(0), QByteArray("summary2")); |
394 | } | 389 | } |
395 | } | 390 | } |
diff --git a/tests/querytest.cpp b/tests/querytest.cpp index c5c251a..9ae3c74 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp | |||
@@ -64,7 +64,7 @@ private slots: | |||
64 | // Setup | 64 | // Setup |
65 | { | 65 | { |
66 | Mail mail("sink.dummy.instance1"); | 66 | Mail mail("sink.dummy.instance1"); |
67 | Sink::Store::create<Mail>(mail).exec().waitForFinished(); | 67 | VERIFYEXEC(Sink::Store::create<Mail>(mail)); |
68 | } | 68 | } |
69 | 69 | ||
70 | // Test | 70 | // Test |
diff --git a/tests/storagebenchmark.cpp b/tests/storagebenchmark.cpp index a1ddcc9..906844e 100644 --- a/tests/storagebenchmark.cpp +++ b/tests/storagebenchmark.cpp | |||
@@ -62,7 +62,7 @@ private slots: | |||
62 | 62 | ||
63 | void cleanupTestCase() | 63 | void cleanupTestCase() |
64 | { | 64 | { |
65 | Sink::Storage store(testDataPath, dbName); | 65 | Sink::Storage::DataStore store(testDataPath, dbName); |
66 | store.removeFromDisk(); | 66 | store.removeFromDisk(); |
67 | } | 67 | } |
68 | 68 | ||
@@ -70,7 +70,7 @@ private slots: | |||
70 | { | 70 | { |
71 | auto event = createEvent(); | 71 | auto event = createEvent(); |
72 | 72 | ||
73 | QScopedPointer<Sink::Storage> store(new Sink::Storage(testDataPath, dbName, Sink::Storage::ReadWrite)); | 73 | QScopedPointer<Sink::Storage::DataStore> store(new Sink::Storage::DataStore(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite)); |
74 | 74 | ||
75 | const char *keyPrefix = "key"; | 75 | const char *keyPrefix = "key"; |
76 | 76 | ||
@@ -78,12 +78,12 @@ private slots: | |||
78 | time.start(); | 78 | time.start(); |
79 | // Test db write time | 79 | // Test db write time |
80 | { | 80 | { |
81 | auto transaction = store->createTransaction(Sink::Storage::ReadWrite); | 81 | auto transaction = store->createTransaction(Sink::Storage::DataStore::ReadWrite); |
82 | for (int i = 0; i < count; i++) { | 82 | for (int i = 0; i < count; i++) { |
83 | transaction.openDatabase().write(keyPrefix + QByteArray::number(i), event); | 83 | transaction.openDatabase().write(keyPrefix + QByteArray::number(i), event); |
84 | if ((i % 10000) == 0) { | 84 | if ((i % 10000) == 0) { |
85 | transaction.commit(); | 85 | transaction.commit(); |
86 | transaction = store->createTransaction(Sink::Storage::ReadWrite); | 86 | transaction = store->createTransaction(Sink::Storage::DataStore::ReadWrite); |
87 | } | 87 | } |
88 | } | 88 | } |
89 | transaction.commit(); | 89 | transaction.commit(); |
@@ -105,7 +105,7 @@ private slots: | |||
105 | 105 | ||
106 | // Db read time | 106 | // Db read time |
107 | { | 107 | { |
108 | auto transaction = store->createTransaction(Sink::Storage::ReadOnly); | 108 | auto transaction = store->createTransaction(Sink::Storage::DataStore::ReadOnly); |
109 | auto db = transaction.openDatabase(); | 109 | auto db = transaction.openDatabase(); |
110 | for (int i = 0; i < count; i++) { | 110 | for (int i = 0; i < count; i++) { |
111 | db.scan(keyPrefix + QByteArray::number(i), [](const QByteArray &key, const QByteArray &value) -> bool { return true; }); | 111 | db.scan(keyPrefix + QByteArray::number(i), [](const QByteArray &key, const QByteArray &value) -> bool { return true; }); |
@@ -126,7 +126,7 @@ private slots: | |||
126 | 126 | ||
127 | void testSizes() | 127 | void testSizes() |
128 | { | 128 | { |
129 | Sink::Storage store(testDataPath, dbName); | 129 | Sink::Storage::DataStore store(testDataPath, dbName); |
130 | qDebug() << "Database size [kb]: " << store.diskUsage() / 1024; | 130 | qDebug() << "Database size [kb]: " << store.diskUsage() / 1024; |
131 | 131 | ||
132 | QFileInfo fileInfo(filePath); | 132 | QFileInfo fileInfo(filePath); |
@@ -135,11 +135,11 @@ private slots: | |||
135 | 135 | ||
136 | void testScan() | 136 | void testScan() |
137 | { | 137 | { |
138 | QScopedPointer<Sink::Storage> store(new Sink::Storage(testDataPath, dbName, Sink::Storage::ReadOnly)); | 138 | QScopedPointer<Sink::Storage::DataStore> store(new Sink::Storage::DataStore(testDataPath, dbName, Sink::Storage::DataStore::ReadOnly)); |
139 | 139 | ||
140 | QBENCHMARK { | 140 | QBENCHMARK { |
141 | int hit = 0; | 141 | int hit = 0; |
142 | store->createTransaction(Sink::Storage::ReadOnly) | 142 | store->createTransaction(Sink::Storage::DataStore::ReadOnly) |
143 | .openDatabase() | 143 | .openDatabase() |
144 | .scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { | 144 | .scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { |
145 | if (key == "key10000") { | 145 | if (key == "key10000") { |
@@ -154,8 +154,8 @@ private slots: | |||
154 | 154 | ||
155 | void testKeyLookup() | 155 | void testKeyLookup() |
156 | { | 156 | { |
157 | QScopedPointer<Sink::Storage> store(new Sink::Storage(testDataPath, dbName, Sink::Storage::ReadOnly)); | 157 | QScopedPointer<Sink::Storage::DataStore> store(new Sink::Storage::DataStore(testDataPath, dbName, Sink::Storage::DataStore::ReadOnly)); |
158 | auto transaction = store->createTransaction(Sink::Storage::ReadOnly); | 158 | auto transaction = store->createTransaction(Sink::Storage::DataStore::ReadOnly); |
159 | auto db = transaction.openDatabase(); | 159 | auto db = transaction.openDatabase(); |
160 | 160 | ||
161 | QBENCHMARK { | 161 | QBENCHMARK { |
@@ -170,8 +170,8 @@ private slots: | |||
170 | 170 | ||
171 | void testFindLatest() | 171 | void testFindLatest() |
172 | { | 172 | { |
173 | QScopedPointer<Sink::Storage> store(new Sink::Storage(testDataPath, dbName, Sink::Storage::ReadOnly)); | 173 | QScopedPointer<Sink::Storage::DataStore> store(new Sink::Storage::DataStore(testDataPath, dbName, Sink::Storage::DataStore::ReadOnly)); |
174 | auto transaction = store->createTransaction(Sink::Storage::ReadOnly); | 174 | auto transaction = store->createTransaction(Sink::Storage::DataStore::ReadOnly); |
175 | auto db = transaction.openDatabase(); | 175 | auto db = transaction.openDatabase(); |
176 | 176 | ||
177 | QBENCHMARK { | 177 | QBENCHMARK { |
diff --git a/tests/storagetest.cpp b/tests/storagetest.cpp index aa12ec1..5a517c7 100644 --- a/tests/storagetest.cpp +++ b/tests/storagetest.cpp | |||
@@ -21,14 +21,14 @@ private: | |||
21 | 21 | ||
22 | void populate(int count) | 22 | void populate(int count) |
23 | { | 23 | { |
24 | Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadWrite); | 24 | Sink::Storage::DataStore storage(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
25 | auto transaction = storage.createTransaction(Sink::Storage::ReadWrite); | 25 | auto transaction = storage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
26 | for (int i = 0; i < count; i++) { | 26 | for (int i = 0; i < count; i++) { |
27 | // This should perhaps become an implementation detail of the db? | 27 | // This should perhaps become an implementation detail of the db? |
28 | if (i % 10000 == 0) { | 28 | if (i % 10000 == 0) { |
29 | if (i > 0) { | 29 | if (i > 0) { |
30 | transaction.commit(); | 30 | transaction.commit(); |
31 | transaction = storage.createTransaction(Sink::Storage::ReadWrite); | 31 | transaction = storage.createTransaction(Sink::Storage::DataStore::ReadWrite); |
32 | } | 32 | } |
33 | } | 33 | } |
34 | transaction.openDatabase().write(keyPrefix + QByteArray::number(i), keyPrefix + QByteArray::number(i)); | 34 | transaction.openDatabase().write(keyPrefix + QByteArray::number(i), keyPrefix + QByteArray::number(i)); |
@@ -36,12 +36,12 @@ private: | |||
36 | transaction.commit(); | 36 | transaction.commit(); |
37 | } | 37 | } |
38 | 38 | ||
39 | bool verify(Sink::Storage &storage, int i) | 39 | bool verify(Sink::Storage::DataStore &storage, int i) |
40 | { | 40 | { |
41 | bool success = true; | 41 | bool success = true; |
42 | bool keyMatch = true; | 42 | bool keyMatch = true; |
43 | const auto reference = keyPrefix + QByteArray::number(i); | 43 | const auto reference = keyPrefix + QByteArray::number(i); |
44 | storage.createTransaction(Sink::Storage::ReadOnly) | 44 | storage.createTransaction(Sink::Storage::DataStore::ReadOnly) |
45 | .openDatabase() | 45 | .openDatabase() |
46 | .scan(keyPrefix + QByteArray::number(i), | 46 | .scan(keyPrefix + QByteArray::number(i), |
47 | [&keyMatch, &reference](const QByteArray &key, const QByteArray &value) -> bool { | 47 | [&keyMatch, &reference](const QByteArray &key, const QByteArray &value) -> bool { |
@@ -51,7 +51,7 @@ private: | |||
51 | } | 51 | } |
52 | return keyMatch; | 52 | return keyMatch; |
53 | }, | 53 | }, |
54 | [&success](const Sink::Storage::Error &error) { | 54 | [&success](const Sink::Storage::DataStore::Error &error) { |
55 | qDebug() << error.message; | 55 | qDebug() << error.message; |
56 | success = false; | 56 | success = false; |
57 | }); | 57 | }); |
@@ -63,20 +63,20 @@ private slots: | |||
63 | { | 63 | { |
64 | testDataPath = "./testdb"; | 64 | testDataPath = "./testdb"; |
65 | dbName = "test"; | 65 | dbName = "test"; |
66 | Sink::Storage storage(testDataPath, dbName); | 66 | Sink::Storage::DataStore storage(testDataPath, dbName); |
67 | storage.removeFromDisk(); | 67 | storage.removeFromDisk(); |
68 | } | 68 | } |
69 | 69 | ||
70 | void cleanup() | 70 | void cleanup() |
71 | { | 71 | { |
72 | Sink::Storage storage(testDataPath, dbName); | 72 | Sink::Storage::DataStore storage(testDataPath, dbName); |
73 | storage.removeFromDisk(); | 73 | storage.removeFromDisk(); |
74 | } | 74 | } |
75 | 75 | ||
76 | void testCleanup() | 76 | void testCleanup() |
77 | { | 77 | { |
78 | populate(1); | 78 | populate(1); |
79 | Sink::Storage storage(testDataPath, dbName); | 79 | Sink::Storage::DataStore storage(testDataPath, dbName); |
80 | storage.removeFromDisk(); | 80 | storage.removeFromDisk(); |
81 | QFileInfo info(testDataPath + "/" + dbName); | 81 | QFileInfo info(testDataPath + "/" + dbName); |
82 | QVERIFY(!info.exists()); | 82 | QVERIFY(!info.exists()); |
@@ -90,7 +90,7 @@ private slots: | |||
90 | 90 | ||
91 | // ensure we can read everything back correctly | 91 | // ensure we can read everything back correctly |
92 | { | 92 | { |
93 | Sink::Storage storage(testDataPath, dbName); | 93 | Sink::Storage::DataStore storage(testDataPath, dbName); |
94 | for (int i = 0; i < count; i++) { | 94 | for (int i = 0; i < count; i++) { |
95 | QVERIFY(verify(storage, i)); | 95 | QVERIFY(verify(storage, i)); |
96 | } | 96 | } |
@@ -105,8 +105,8 @@ private slots: | |||
105 | // ensure we can scan for values | 105 | // ensure we can scan for values |
106 | { | 106 | { |
107 | int hit = 0; | 107 | int hit = 0; |
108 | Sink::Storage store(testDataPath, dbName); | 108 | Sink::Storage::DataStore store(testDataPath, dbName); |
109 | store.createTransaction(Sink::Storage::ReadOnly) | 109 | store.createTransaction(Sink::Storage::DataStore::ReadOnly) |
110 | .openDatabase() | 110 | .openDatabase() |
111 | .scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { | 111 | .scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { |
112 | if (key == "key50") { | 112 | if (key == "key50") { |
@@ -121,8 +121,8 @@ private slots: | |||
121 | { | 121 | { |
122 | int hit = 0; | 122 | int hit = 0; |
123 | bool foundInvalidValue = false; | 123 | bool foundInvalidValue = false; |
124 | Sink::Storage store(testDataPath, dbName); | 124 | Sink::Storage::DataStore store(testDataPath, dbName); |
125 | store.createTransaction(Sink::Storage::ReadOnly) | 125 | store.createTransaction(Sink::Storage::DataStore::ReadOnly) |
126 | .openDatabase() | 126 | .openDatabase() |
127 | .scan("key50", [&](const QByteArray &key, const QByteArray &value) -> bool { | 127 | .scan("key50", [&](const QByteArray &key, const QByteArray &value) -> bool { |
128 | if (key != "key50") { | 128 | if (key != "key50") { |
@@ -139,10 +139,10 @@ private slots: | |||
139 | void testNestedOperations() | 139 | void testNestedOperations() |
140 | { | 140 | { |
141 | populate(3); | 141 | populate(3); |
142 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 142 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
143 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 143 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
144 | transaction.openDatabase().scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { | 144 | transaction.openDatabase().scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { |
145 | transaction.openDatabase().remove(key, [](const Sink::Storage::Error &) { QVERIFY(false); }); | 145 | transaction.openDatabase().remove(key, [](const Sink::Storage::DataStore::Error &) { QVERIFY(false); }); |
146 | return false; | 146 | return false; |
147 | }); | 147 | }); |
148 | } | 148 | } |
@@ -150,11 +150,11 @@ private slots: | |||
150 | void testNestedTransactions() | 150 | void testNestedTransactions() |
151 | { | 151 | { |
152 | populate(3); | 152 | populate(3); |
153 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 153 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
154 | store.createTransaction(Sink::Storage::ReadOnly) | 154 | store.createTransaction(Sink::Storage::DataStore::ReadOnly) |
155 | .openDatabase() | 155 | .openDatabase() |
156 | .scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { | 156 | .scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { |
157 | store.createTransaction(Sink::Storage::ReadWrite).openDatabase().remove(key, [](const Sink::Storage::Error &) { QVERIFY(false); }); | 157 | store.createTransaction(Sink::Storage::DataStore::ReadWrite).openDatabase().remove(key, [](const Sink::Storage::DataStore::Error &) { QVERIFY(false); }); |
158 | return false; | 158 | return false; |
159 | }); | 159 | }); |
160 | } | 160 | } |
@@ -163,9 +163,9 @@ private slots: | |||
163 | { | 163 | { |
164 | bool gotResult = false; | 164 | bool gotResult = false; |
165 | bool gotError = false; | 165 | bool gotError = false; |
166 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 166 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
167 | auto transaction = store.createTransaction(Sink::Storage::ReadOnly); | 167 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadOnly); |
168 | auto db = transaction.openDatabase("default", [&](const Sink::Storage::Error &error) { | 168 | auto db = transaction.openDatabase("default", [&](const Sink::Storage::DataStore::Error &error) { |
169 | qDebug() << error.message; | 169 | qDebug() << error.message; |
170 | gotError = true; | 170 | gotError = true; |
171 | }); | 171 | }); |
@@ -174,7 +174,7 @@ private slots: | |||
174 | gotResult = true; | 174 | gotResult = true; |
175 | return false; | 175 | return false; |
176 | }, | 176 | }, |
177 | [&](const Sink::Storage::Error &error) { | 177 | [&](const Sink::Storage::DataStore::Error &error) { |
178 | qDebug() << error.message; | 178 | qDebug() << error.message; |
179 | gotError = true; | 179 | gotError = true; |
180 | }); | 180 | }); |
@@ -199,8 +199,8 @@ private slots: | |||
199 | const int concurrencyLevel = 20; | 199 | const int concurrencyLevel = 20; |
200 | for (int num = 0; num < concurrencyLevel; num++) { | 200 | for (int num = 0; num < concurrencyLevel; num++) { |
201 | futures << QtConcurrent::run([this, count, &error]() { | 201 | futures << QtConcurrent::run([this, count, &error]() { |
202 | Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadOnly); | 202 | Sink::Storage::DataStore storage(testDataPath, dbName, Sink::Storage::DataStore::ReadOnly); |
203 | Sink::Storage storage2(testDataPath, dbName + "2", Sink::Storage::ReadOnly); | 203 | Sink::Storage::DataStore storage2(testDataPath, dbName + "2", Sink::Storage::DataStore::ReadOnly); |
204 | for (int i = 0; i < count; i++) { | 204 | for (int i = 0; i < count; i++) { |
205 | if (!verify(storage, i)) { | 205 | if (!verify(storage, i)) { |
206 | error = true; | 206 | error = true; |
@@ -216,9 +216,9 @@ private slots: | |||
216 | } | 216 | } |
217 | 217 | ||
218 | { | 218 | { |
219 | Sink::Storage storage(testDataPath, dbName); | 219 | Sink::Storage::DataStore storage(testDataPath, dbName); |
220 | storage.removeFromDisk(); | 220 | storage.removeFromDisk(); |
221 | Sink::Storage storage2(testDataPath, dbName + "2"); | 221 | Sink::Storage::DataStore storage2(testDataPath, dbName + "2"); |
222 | storage2.removeFromDisk(); | 222 | storage2.removeFromDisk(); |
223 | } | 223 | } |
224 | } | 224 | } |
@@ -227,8 +227,8 @@ private slots: | |||
227 | { | 227 | { |
228 | bool gotResult = false; | 228 | bool gotResult = false; |
229 | bool gotError = false; | 229 | bool gotError = false; |
230 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 230 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
231 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 231 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
232 | auto db = transaction.openDatabase("default", nullptr, false); | 232 | auto db = transaction.openDatabase("default", nullptr, false); |
233 | db.write("key", "value"); | 233 | db.write("key", "value"); |
234 | db.write("key", "value"); | 234 | db.write("key", "value"); |
@@ -238,7 +238,7 @@ private slots: | |||
238 | gotResult = true; | 238 | gotResult = true; |
239 | return true; | 239 | return true; |
240 | }, | 240 | }, |
241 | [&](const Sink::Storage::Error &error) { | 241 | [&](const Sink::Storage::DataStore::Error &error) { |
242 | qDebug() << error.message; | 242 | qDebug() << error.message; |
243 | gotError = true; | 243 | gotError = true; |
244 | }); | 244 | }); |
@@ -252,8 +252,8 @@ private slots: | |||
252 | { | 252 | { |
253 | bool gotResult = false; | 253 | bool gotResult = false; |
254 | bool gotError = false; | 254 | bool gotError = false; |
255 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 255 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
256 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 256 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
257 | auto db = transaction.openDatabase("default", nullptr, true); | 257 | auto db = transaction.openDatabase("default", nullptr, true); |
258 | db.write("key", "value1"); | 258 | db.write("key", "value1"); |
259 | db.write("key", "value2"); | 259 | db.write("key", "value2"); |
@@ -262,7 +262,7 @@ private slots: | |||
262 | gotResult = true; | 262 | gotResult = true; |
263 | return true; | 263 | return true; |
264 | }, | 264 | }, |
265 | [&](const Sink::Storage::Error &error) { | 265 | [&](const Sink::Storage::DataStore::Error &error) { |
266 | qDebug() << error.message; | 266 | qDebug() << error.message; |
267 | gotError = true; | 267 | gotError = true; |
268 | }); | 268 | }); |
@@ -275,15 +275,15 @@ private slots: | |||
275 | { | 275 | { |
276 | bool gotResult = false; | 276 | bool gotResult = false; |
277 | bool gotError = false; | 277 | bool gotError = false; |
278 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadOnly); | 278 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadOnly); |
279 | int numValues = store.createTransaction(Sink::Storage::ReadOnly) | 279 | int numValues = store.createTransaction(Sink::Storage::DataStore::ReadOnly) |
280 | .openDatabase("test") | 280 | .openDatabase("test") |
281 | .scan("", | 281 | .scan("", |
282 | [&](const QByteArray &key, const QByteArray &value) -> bool { | 282 | [&](const QByteArray &key, const QByteArray &value) -> bool { |
283 | gotResult = true; | 283 | gotResult = true; |
284 | return false; | 284 | return false; |
285 | }, | 285 | }, |
286 | [&](const Sink::Storage::Error &error) { | 286 | [&](const Sink::Storage::DataStore::Error &error) { |
287 | qDebug() << error.message; | 287 | qDebug() << error.message; |
288 | gotError = true; | 288 | gotError = true; |
289 | }); | 289 | }); |
@@ -295,10 +295,10 @@ private slots: | |||
295 | void testWriteToNamedDb() | 295 | void testWriteToNamedDb() |
296 | { | 296 | { |
297 | bool gotError = false; | 297 | bool gotError = false; |
298 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 298 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
299 | store.createTransaction(Sink::Storage::ReadWrite) | 299 | store.createTransaction(Sink::Storage::DataStore::ReadWrite) |
300 | .openDatabase("test") | 300 | .openDatabase("test") |
301 | .write("key1", "value1", [&](const Sink::Storage::Error &error) { | 301 | .write("key1", "value1", [&](const Sink::Storage::DataStore::Error &error) { |
302 | qDebug() << error.message; | 302 | qDebug() << error.message; |
303 | gotError = true; | 303 | gotError = true; |
304 | }); | 304 | }); |
@@ -308,10 +308,10 @@ private slots: | |||
308 | void testWriteDuplicatesToNamedDb() | 308 | void testWriteDuplicatesToNamedDb() |
309 | { | 309 | { |
310 | bool gotError = false; | 310 | bool gotError = false; |
311 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 311 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
312 | store.createTransaction(Sink::Storage::ReadWrite) | 312 | store.createTransaction(Sink::Storage::DataStore::ReadWrite) |
313 | .openDatabase("test", nullptr, true) | 313 | .openDatabase("test", nullptr, true) |
314 | .write("key1", "value1", [&](const Sink::Storage::Error &error) { | 314 | .write("key1", "value1", [&](const Sink::Storage::DataStore::Error &error) { |
315 | qDebug() << error.message; | 315 | qDebug() << error.message; |
316 | gotError = true; | 316 | gotError = true; |
317 | }); | 317 | }); |
@@ -321,8 +321,8 @@ private slots: | |||
321 | // By default we want only exact matches | 321 | // By default we want only exact matches |
322 | void testSubstringKeys() | 322 | void testSubstringKeys() |
323 | { | 323 | { |
324 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 324 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
325 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 325 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
326 | auto db = transaction.openDatabase("test", nullptr, true); | 326 | auto db = transaction.openDatabase("test", nullptr, true); |
327 | db.write("sub", "value1"); | 327 | db.write("sub", "value1"); |
328 | db.write("subsub", "value2"); | 328 | db.write("subsub", "value2"); |
@@ -333,8 +333,8 @@ private slots: | |||
333 | 333 | ||
334 | void testFindSubstringKeys() | 334 | void testFindSubstringKeys() |
335 | { | 335 | { |
336 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 336 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
337 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 337 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
338 | auto db = transaction.openDatabase("test", nullptr, false); | 338 | auto db = transaction.openDatabase("test", nullptr, false); |
339 | db.write("sub", "value1"); | 339 | db.write("sub", "value1"); |
340 | db.write("subsub", "value2"); | 340 | db.write("subsub", "value2"); |
@@ -346,8 +346,8 @@ private slots: | |||
346 | 346 | ||
347 | void testFindSubstringKeysWithDuplicatesEnabled() | 347 | void testFindSubstringKeysWithDuplicatesEnabled() |
348 | { | 348 | { |
349 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 349 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
350 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 350 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
351 | auto db = transaction.openDatabase("test", nullptr, true); | 351 | auto db = transaction.openDatabase("test", nullptr, true); |
352 | db.write("sub", "value1"); | 352 | db.write("sub", "value1"); |
353 | db.write("subsub", "value2"); | 353 | db.write("subsub", "value2"); |
@@ -359,8 +359,8 @@ private slots: | |||
359 | 359 | ||
360 | void testKeySorting() | 360 | void testKeySorting() |
361 | { | 361 | { |
362 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 362 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
363 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 363 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
364 | auto db = transaction.openDatabase("test", nullptr, false); | 364 | auto db = transaction.openDatabase("test", nullptr, false); |
365 | db.write("sub_2", "value2"); | 365 | db.write("sub_2", "value2"); |
366 | db.write("sub_1", "value1"); | 366 | db.write("sub_1", "value1"); |
@@ -380,8 +380,8 @@ private slots: | |||
380 | // Ensure we don't retrieve a key that is greater than the current key. We only want equal keys. | 380 | // Ensure we don't retrieve a key that is greater than the current key. We only want equal keys. |
381 | void testKeyRange() | 381 | void testKeyRange() |
382 | { | 382 | { |
383 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 383 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
384 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 384 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
385 | auto db = transaction.openDatabase("test", nullptr, true); | 385 | auto db = transaction.openDatabase("test", nullptr, true); |
386 | db.write("sub1", "value1"); | 386 | db.write("sub1", "value1"); |
387 | int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; }); | 387 | int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; }); |
@@ -391,8 +391,8 @@ private slots: | |||
391 | 391 | ||
392 | void testFindLatest() | 392 | void testFindLatest() |
393 | { | 393 | { |
394 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 394 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
395 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 395 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
396 | auto db = transaction.openDatabase("test", nullptr, false); | 396 | auto db = transaction.openDatabase("test", nullptr, false); |
397 | db.write("sub1", "value1"); | 397 | db.write("sub1", "value1"); |
398 | db.write("sub2", "value2"); | 398 | db.write("sub2", "value2"); |
@@ -406,8 +406,8 @@ private slots: | |||
406 | 406 | ||
407 | void testFindLatestInSingle() | 407 | void testFindLatestInSingle() |
408 | { | 408 | { |
409 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 409 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
410 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 410 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
411 | auto db = transaction.openDatabase("test", nullptr, false); | 411 | auto db = transaction.openDatabase("test", nullptr, false); |
412 | db.write("sub2", "value2"); | 412 | db.write("sub2", "value2"); |
413 | QByteArray result; | 413 | QByteArray result; |
@@ -418,8 +418,8 @@ private slots: | |||
418 | 418 | ||
419 | void testFindLast() | 419 | void testFindLast() |
420 | { | 420 | { |
421 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 421 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
422 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 422 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
423 | auto db = transaction.openDatabase("test", nullptr, false); | 423 | auto db = transaction.openDatabase("test", nullptr, false); |
424 | db.write("sub2", "value2"); | 424 | db.write("sub2", "value2"); |
425 | db.write("wub3", "value3"); | 425 | db.write("wub3", "value3"); |
@@ -431,23 +431,23 @@ private slots: | |||
431 | 431 | ||
432 | void testRecordRevision() | 432 | void testRecordRevision() |
433 | { | 433 | { |
434 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 434 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
435 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 435 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
436 | Sink::Storage::recordRevision(transaction, 1, "uid", "type"); | 436 | Sink::Storage::DataStore::recordRevision(transaction, 1, "uid", "type"); |
437 | QCOMPARE(Sink::Storage::getTypeFromRevision(transaction, 1), QByteArray("type")); | 437 | QCOMPARE(Sink::Storage::DataStore::getTypeFromRevision(transaction, 1), QByteArray("type")); |
438 | QCOMPARE(Sink::Storage::getUidFromRevision(transaction, 1), QByteArray("uid")); | 438 | QCOMPARE(Sink::Storage::DataStore::getUidFromRevision(transaction, 1), QByteArray("uid")); |
439 | } | 439 | } |
440 | 440 | ||
441 | void testRecordRevisionSorting() | 441 | void testRecordRevisionSorting() |
442 | { | 442 | { |
443 | Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); | 443 | Sink::Storage::DataStore store(testDataPath, dbName, Sink::Storage::DataStore::ReadWrite); |
444 | auto transaction = store.createTransaction(Sink::Storage::ReadWrite); | 444 | auto transaction = store.createTransaction(Sink::Storage::DataStore::ReadWrite); |
445 | QByteArray result; | 445 | QByteArray result; |
446 | auto db = transaction.openDatabase("test", nullptr, false); | 446 | auto db = transaction.openDatabase("test", nullptr, false); |
447 | const auto uid = "{c5d06a9f-1534-4c52-b8ea-415db68bdadf}"; | 447 | const auto uid = "{c5d06a9f-1534-4c52-b8ea-415db68bdadf}"; |
448 | //Ensure we can sort 1 and 10 properly (by default string comparison 10 comes before 6) | 448 | //Ensure we can sort 1 and 10 properly (by default string comparison 10 comes before 6) |
449 | db.write(Sink::Storage::assembleKey(uid, 6), "value1"); | 449 | db.write(Sink::Storage::DataStore::assembleKey(uid, 6), "value1"); |
450 | db.write(Sink::Storage::assembleKey(uid, 10), "value2"); | 450 | db.write(Sink::Storage::DataStore::assembleKey(uid, 10), "value2"); |
451 | db.findLatest(uid, [&](const QByteArray &key, const QByteArray &value) { result = value; }); | 451 | db.findLatest(uid, [&](const QByteArray &key, const QByteArray &value) { result = value; }); |
452 | QCOMPARE(result, QByteArray("value2")); | 452 | QCOMPARE(result, QByteArray("value2")); |
453 | } | 453 | } |
diff --git a/tests/testimplementations.h b/tests/testimplementations.h index d188c0c..cf7a3da 100644 --- a/tests/testimplementations.h +++ b/tests/testimplementations.h | |||
@@ -83,8 +83,8 @@ public slots: | |||
83 | class TestResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Event> | 83 | class TestResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Event> |
84 | { | 84 | { |
85 | public: | 85 | public: |
86 | TestResourceFacade(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess) | 86 | TestResourceFacade(const Sink::ResourceContext &resourceContext) |
87 | : Sink::GenericFacade<Sink::ApplicationDomain::Event>(instanceIdentifier, QSharedPointer<TestEventAdaptorFactory>::create(), resourceAccess) | 87 | : Sink::GenericFacade<Sink::ApplicationDomain::Event>(resourceContext) |
88 | { | 88 | { |
89 | } | 89 | } |
90 | virtual ~TestResourceFacade() | 90 | virtual ~TestResourceFacade() |
@@ -95,8 +95,8 @@ public: | |||
95 | class TestMailResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> | 95 | class TestMailResourceFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail> |
96 | { | 96 | { |
97 | public: | 97 | public: |
98 | TestMailResourceFacade(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess) | 98 | TestMailResourceFacade(const Sink::ResourceContext &resourceContext) |
99 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<TestMailAdaptorFactory>::create(), resourceAccess) | 99 | : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(resourceContext) |
100 | { | 100 | { |
101 | } | 101 | } |
102 | virtual ~TestMailResourceFacade() | 102 | virtual ~TestMailResourceFacade() |
@@ -107,7 +107,7 @@ public: | |||
107 | class TestResource : public Sink::GenericResource | 107 | class TestResource : public Sink::GenericResource |
108 | { | 108 | { |
109 | public: | 109 | public: |
110 | TestResource(const QByteArray &instanceIdentifier, QSharedPointer<Sink::Pipeline> pipeline) : Sink::GenericResource("test", instanceIdentifier, pipeline) | 110 | TestResource(const Sink::ResourceContext &resourceContext, QSharedPointer<Sink::Pipeline> pipeline) : Sink::GenericResource(resourceContext, pipeline) |
111 | { | 111 | { |
112 | } | 112 | } |
113 | 113 | ||