diff options
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 | ||