diff options
Diffstat (limited to 'common/storage')
-rw-r--r-- | common/storage/entitystore.cpp | 53 | ||||
-rw-r--r-- | common/storage/entitystore.h | 4 |
2 files changed, 33 insertions, 24 deletions
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 6d48c10..6fc82de 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp | |||
@@ -41,11 +41,12 @@ SINK_DEBUG_AREA("entitystore"); | |||
41 | 41 | ||
42 | class EntityStore::Private { | 42 | class EntityStore::Private { |
43 | public: | 43 | public: |
44 | Private(const ResourceContext &context) : resourceContext(context) {} | 44 | Private(const ResourceContext &context, const Sink::Log::Context &ctx) : resourceContext(context), logCtx(ctx.subContext("entitystore")) {} |
45 | 45 | ||
46 | ResourceContext resourceContext; | 46 | ResourceContext resourceContext; |
47 | DataStore::Transaction transaction; | 47 | DataStore::Transaction transaction; |
48 | QHash<QByteArray, QSharedPointer<TypeIndex> > indexByType; | 48 | QHash<QByteArray, QSharedPointer<TypeIndex> > indexByType; |
49 | Sink::Log::Context logCtx; | ||
49 | 50 | ||
50 | bool exists() | 51 | bool exists() |
51 | { | 52 | { |
@@ -76,7 +77,7 @@ public: | |||
76 | if (indexByType.contains(type)) { | 77 | if (indexByType.contains(type)) { |
77 | return *indexByType.value(type); | 78 | return *indexByType.value(type); |
78 | } | 79 | } |
79 | auto index = QSharedPointer<TypeIndex>::create(type); | 80 | auto index = QSharedPointer<TypeIndex>::create(type, logCtx); |
80 | TypeHelper<ConfigureHelper>{type}.template operator()<void>(*index); | 81 | TypeHelper<ConfigureHelper>{type}.template operator()<void>(*index); |
81 | indexByType.insert(type, index); | 82 | indexByType.insert(type, index); |
82 | return *index; | 83 | return *index; |
@@ -103,15 +104,15 @@ public: | |||
103 | 104 | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | EntityStore::EntityStore(const ResourceContext &context) | 107 | EntityStore::EntityStore(const ResourceContext &context, const Log::Context &ctx) |
107 | : d(new EntityStore::Private{context}) | 108 | : d(new EntityStore::Private{context, ctx}) |
108 | { | 109 | { |
109 | 110 | ||
110 | } | 111 | } |
111 | 112 | ||
112 | void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMode) | 113 | void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMode) |
113 | { | 114 | { |
114 | SinkTrace() << "Starting transaction"; | 115 | SinkTraceCtx(d->logCtx) << "Starting transaction"; |
115 | Sink::Storage::DataStore store(Sink::storageLocation(), d->resourceContext.instanceId(), accessMode); | 116 | Sink::Storage::DataStore store(Sink::storageLocation(), d->resourceContext.instanceId(), accessMode); |
116 | d->transaction = store.createTransaction(accessMode); | 117 | d->transaction = store.createTransaction(accessMode); |
117 | Q_ASSERT(d->transaction.validateNamedDatabases()); | 118 | Q_ASSERT(d->transaction.validateNamedDatabases()); |
@@ -119,14 +120,14 @@ void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMo | |||
119 | 120 | ||
120 | void EntityStore::commitTransaction() | 121 | void EntityStore::commitTransaction() |
121 | { | 122 | { |
122 | SinkTrace() << "Committing transaction"; | 123 | SinkTraceCtx(d->logCtx) << "Committing transaction"; |
123 | d->transaction.commit(); | 124 | d->transaction.commit(); |
124 | d->transaction = Storage::DataStore::Transaction(); | 125 | d->transaction = Storage::DataStore::Transaction(); |
125 | } | 126 | } |
126 | 127 | ||
127 | void EntityStore::abortTransaction() | 128 | void EntityStore::abortTransaction() |
128 | { | 129 | { |
129 | SinkTrace() << "Aborting transaction"; | 130 | SinkTraceCtx(d->logCtx) << "Aborting transaction"; |
130 | d->transaction.abort(); | 131 | d->transaction.abort(); |
131 | d->transaction = Storage::DataStore::Transaction(); | 132 | d->transaction = Storage::DataStore::Transaction(); |
132 | } | 133 | } |
@@ -172,7 +173,7 @@ bool EntityStore::add(const QByteArray &type, const ApplicationDomain::Applicati | |||
172 | auto entity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(entity_, entity_.availableProperties()); | 173 | auto entity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(entity_, entity_.availableProperties()); |
173 | entity.setChangedProperties(entity.availableProperties().toSet()); | 174 | entity.setChangedProperties(entity.availableProperties().toSet()); |
174 | 175 | ||
175 | SinkTrace() << "New entity " << entity; | 176 | SinkTraceCtx(d->logCtx) << "New entity " << entity; |
176 | 177 | ||
177 | preprocess(entity); | 178 | preprocess(entity); |
178 | d->typeIndex(type).add(entity.identifier(), entity, d->transaction); | 179 | d->typeIndex(type).add(entity.identifier(), entity, d->transaction); |
@@ -199,7 +200,7 @@ bool EntityStore::add(const QByteArray &type, const ApplicationDomain::Applicati | |||
199 | [&](const DataStore::Error &error) { SinkWarning() << "Failed to write entity" << entity.identifier() << newRevision; }); | 200 | [&](const DataStore::Error &error) { SinkWarning() << "Failed to write entity" << entity.identifier() << newRevision; }); |
200 | DataStore::setMaxRevision(d->transaction, newRevision); | 201 | DataStore::setMaxRevision(d->transaction, newRevision); |
201 | DataStore::recordRevision(d->transaction, newRevision, entity.identifier(), type); | 202 | DataStore::recordRevision(d->transaction, newRevision, entity.identifier(), type); |
202 | SinkTrace() << "Wrote entity: " << entity.identifier() << type << newRevision; | 203 | SinkTraceCtx(d->logCtx) << "Wrote entity: " << entity.identifier() << type << newRevision; |
203 | return true; | 204 | return true; |
204 | } | 205 | } |
205 | 206 | ||
@@ -214,6 +215,8 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic | |||
214 | 215 | ||
215 | auto newEntity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(current, current.availableProperties()); | 216 | auto newEntity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(current, current.availableProperties()); |
216 | 217 | ||
218 | SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity; | ||
219 | |||
217 | // Apply diff | 220 | // Apply diff |
218 | //SinkTrace() << "Applying changed properties: " << changeset; | 221 | //SinkTrace() << "Applying changed properties: " << changeset; |
219 | for (const auto &property : changeset) { | 222 | for (const auto &property : changeset) { |
@@ -251,8 +254,7 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic | |||
251 | auto metadataBuffer = metadataBuilder.Finish(); | 254 | auto metadataBuffer = metadataBuilder.Finish(); |
252 | FinishMetadataBuffer(metadataFbb, metadataBuffer); | 255 | FinishMetadataBuffer(metadataFbb, metadataBuffer); |
253 | } | 256 | } |
254 | SinkTrace() << "Modified entity: " << newEntity; | 257 | SinkTraceCtx(d->logCtx) << "Changed properties: " << changeset + newEntity.changedProperties(); |
255 | SinkTrace() << "Changed properties: " << changeset + newEntity.changedProperties(); | ||
256 | 258 | ||
257 | newEntity.setChangedProperties(newEntity.availableProperties().toSet()); | 259 | newEntity.setChangedProperties(newEntity.availableProperties().toSet()); |
258 | 260 | ||
@@ -264,7 +266,7 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic | |||
264 | [&](const DataStore::Error &error) { SinkWarning() << "Failed to write entity" << newEntity.identifier() << newRevision; }); | 266 | [&](const DataStore::Error &error) { SinkWarning() << "Failed to write entity" << newEntity.identifier() << newRevision; }); |
265 | DataStore::setMaxRevision(d->transaction, newRevision); | 267 | DataStore::setMaxRevision(d->transaction, newRevision); |
266 | DataStore::recordRevision(d->transaction, newRevision, newEntity.identifier(), type); | 268 | DataStore::recordRevision(d->transaction, newRevision, newEntity.identifier(), type); |
267 | SinkTrace() << "Wrote modified entity: " << newEntity.identifier() << type << newRevision; | 269 | SinkTraceCtx(d->logCtx) << "Wrote modified entity: " << newEntity.identifier() << type << newRevision; |
268 | return true; | 270 | return true; |
269 | } | 271 | } |
270 | 272 | ||
@@ -300,7 +302,7 @@ bool EntityStore::remove(const QByteArray &type, const QByteArray &uid, bool rep | |||
300 | preprocess(current); | 302 | preprocess(current); |
301 | d->typeIndex(type).remove(current.identifier(), current, d->transaction); | 303 | d->typeIndex(type).remove(current.identifier(), current, d->transaction); |
302 | 304 | ||
303 | SinkTrace() << "Removed entity " << current; | 305 | SinkTraceCtx(d->logCtx) << "Removed entity " << current; |
304 | 306 | ||
305 | const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; | 307 | const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; |
306 | 308 | ||
@@ -328,7 +330,7 @@ void EntityStore::cleanupRevision(qint64 revision) | |||
328 | { | 330 | { |
329 | const auto uid = DataStore::getUidFromRevision(d->transaction, revision); | 331 | const auto uid = DataStore::getUidFromRevision(d->transaction, revision); |
330 | const auto bufferType = DataStore::getTypeFromRevision(d->transaction, revision); | 332 | const auto bufferType = DataStore::getTypeFromRevision(d->transaction, revision); |
331 | SinkTrace() << "Cleaning up revision " << revision << uid << bufferType; | 333 | SinkTraceCtx(d->logCtx) << "Cleaning up revision " << revision << uid << bufferType; |
332 | DataStore::mainDatabase(d->transaction, bufferType) | 334 | DataStore::mainDatabase(d->transaction, bufferType) |
333 | .scan(uid, | 335 | .scan(uid, |
334 | [&](const QByteArray &key, const QByteArray &data) -> bool { | 336 | [&](const QByteArray &key, const QByteArray &data) -> bool { |
@@ -369,7 +371,7 @@ bool EntityStore::cleanupRevisions(qint64 revision) | |||
369 | const auto firstRevisionToCleanup = lastCleanRevision + 1; | 371 | const auto firstRevisionToCleanup = lastCleanRevision + 1; |
370 | bool cleanupIsNecessary = firstRevisionToCleanup <= revision; | 372 | bool cleanupIsNecessary = firstRevisionToCleanup <= revision; |
371 | if (cleanupIsNecessary) { | 373 | if (cleanupIsNecessary) { |
372 | SinkTrace() << "Cleaning up from " << firstRevisionToCleanup << " to " << revision; | 374 | SinkTraceCtx(d->logCtx) << "Cleaning up from " << firstRevisionToCleanup << " to " << revision; |
373 | for (qint64 rev = firstRevisionToCleanup; rev <= revision; rev++) { | 375 | for (qint64 rev = firstRevisionToCleanup; rev <= revision; rev++) { |
374 | cleanupRevision(revision); | 376 | cleanupRevision(revision); |
375 | } | 377 | } |
@@ -382,9 +384,9 @@ bool EntityStore::cleanupRevisions(qint64 revision) | |||
382 | 384 | ||
383 | QVector<QByteArray> EntityStore::fullScan(const QByteArray &type) | 385 | QVector<QByteArray> EntityStore::fullScan(const QByteArray &type) |
384 | { | 386 | { |
385 | SinkTrace() << "Looking for : " << type; | 387 | SinkTraceCtx(d->logCtx) << "Looking for : " << type; |
386 | if (!d->exists()) { | 388 | if (!d->exists()) { |
387 | SinkTrace() << "Database is not existing: " << type; | 389 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; |
388 | return QVector<QByteArray>(); | 390 | return QVector<QByteArray>(); |
389 | } | 391 | } |
390 | //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. | 392 | //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. |
@@ -395,21 +397,21 @@ QVector<QByteArray> EntityStore::fullScan(const QByteArray &type) | |||
395 | const auto uid = DataStore::uidFromKey(key); | 397 | const auto uid = DataStore::uidFromKey(key); |
396 | if (keys.contains(uid)) { | 398 | if (keys.contains(uid)) { |
397 | //Not something that should persist if the replay works, so we keep a message for now. | 399 | //Not something that should persist if the replay works, so we keep a message for now. |
398 | SinkTrace() << "Multiple revisions for key: " << key; | 400 | SinkTraceCtx(d->logCtx) << "Multiple revisions for key: " << key; |
399 | } | 401 | } |
400 | keys << uid; | 402 | keys << uid; |
401 | return true; | 403 | return true; |
402 | }, | 404 | }, |
403 | [](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message; }); | 405 | [](const DataStore::Error &error) { SinkWarning() << "Error during query: " << error.message; }); |
404 | 406 | ||
405 | SinkTrace() << "Full scan retrieved " << keys.size() << " results."; | 407 | SinkTraceCtx(d->logCtx) << "Full scan retrieved " << keys.size() << " results."; |
406 | return keys.toList().toVector(); | 408 | return keys.toList().toVector(); |
407 | } | 409 | } |
408 | 410 | ||
409 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting) | 411 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting) |
410 | { | 412 | { |
411 | if (!d->exists()) { | 413 | if (!d->exists()) { |
412 | SinkTrace() << "Database is not existing: " << type; | 414 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; |
413 | return QVector<QByteArray>(); | 415 | return QVector<QByteArray>(); |
414 | } | 416 | } |
415 | return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction()); | 417 | return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction()); |
@@ -418,7 +420,7 @@ QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const Query | |||
418 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value) | 420 | QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value) |
419 | { | 421 | { |
420 | if (!d->exists()) { | 422 | if (!d->exists()) { |
421 | SinkTrace() << "Database is not existing: " << type; | 423 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; |
422 | return QVector<QByteArray>(); | 424 | return QVector<QByteArray>(); |
423 | } | 425 | } |
424 | return d->typeIndex(type).lookup(property, value, d->getTransaction()); | 426 | return d->typeIndex(type).lookup(property, value, d->getTransaction()); |
@@ -427,7 +429,7 @@ QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QByte | |||
427 | void EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) | 429 | void EntityStore::indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback) |
428 | { | 430 | { |
429 | if (!d->exists()) { | 431 | if (!d->exists()) { |
430 | SinkTrace() << "Database is not existing: " << type; | 432 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; |
431 | return; | 433 | return; |
432 | } | 434 | } |
433 | auto list = d->typeIndex(type).lookup(property, value, d->getTransaction()); | 435 | auto list = d->typeIndex(type).lookup(property, value, d->getTransaction()); |
@@ -595,7 +597,7 @@ bool EntityStore::contains(const QByteArray &type, const QByteArray &uid) | |||
595 | qint64 EntityStore::maxRevision() | 597 | qint64 EntityStore::maxRevision() |
596 | { | 598 | { |
597 | if (!d->exists()) { | 599 | if (!d->exists()) { |
598 | SinkTrace() << "Database is not existing."; | 600 | SinkTraceCtx(d->logCtx) << "Database is not existing."; |
599 | return 0; | 601 | return 0; |
600 | } | 602 | } |
601 | return DataStore::maxRevision(d->getTransaction()); | 603 | return DataStore::maxRevision(d->getTransaction()); |
@@ -623,3 +625,8 @@ qint64 EntityStore::maxRevision() | |||
623 | /* } */ | 625 | /* } */ |
624 | /* return transaction; */ | 626 | /* return transaction; */ |
625 | /* } */ | 627 | /* } */ |
628 | |||
629 | Sink::Log::Context EntityStore::logContext() const | ||
630 | { | ||
631 | return d->logCtx; | ||
632 | } | ||
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h index c626ebc..b8e1065 100644 --- a/common/storage/entitystore.h +++ b/common/storage/entitystore.h | |||
@@ -36,7 +36,7 @@ class SINK_EXPORT EntityStore | |||
36 | { | 36 | { |
37 | public: | 37 | public: |
38 | typedef QSharedPointer<EntityStore> Ptr; | 38 | typedef QSharedPointer<EntityStore> Ptr; |
39 | EntityStore(const ResourceContext &resourceContext); | 39 | EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &); |
40 | 40 | ||
41 | typedef std::function<void(const ApplicationDomain::ApplicationDomainType &, ApplicationDomain::ApplicationDomainType &)> PreprocessModification; | 41 | typedef std::function<void(const ApplicationDomain::ApplicationDomainType &, ApplicationDomain::ApplicationDomainType &)> PreprocessModification; |
42 | typedef std::function<void(ApplicationDomain::ApplicationDomainType &)> PreprocessCreation; | 42 | typedef std::function<void(ApplicationDomain::ApplicationDomainType &)> PreprocessCreation; |
@@ -109,6 +109,8 @@ public: | |||
109 | 109 | ||
110 | qint64 maxRevision(); | 110 | qint64 maxRevision(); |
111 | 111 | ||
112 | Sink::Log::Context logContext() const; | ||
113 | |||
112 | private: | 114 | private: |
113 | void copyBlobs(ApplicationDomain::ApplicationDomainType &entity, qint64 newRevision); | 115 | void copyBlobs(ApplicationDomain::ApplicationDomainType &entity, qint64 newRevision); |
114 | class Private; | 116 | class Private; |