From c81fe1578e4151e230ffa08a6c5b26b535593ee7 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 17 May 2018 20:24:51 +0200 Subject: Copy the entity when we return it. Otherwise we easily end up copying it and then have an entity that points into nowhere. Callback -> no copy, no callback -> copy. --- common/entitybuffer.h | 11 +++++++++++ common/storage/entitystore.cpp | 8 ++++---- common/storage/entitystore.h | 10 ++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/common/entitybuffer.h b/common/entitybuffer.h index 4162605..d73a138 100644 --- a/common/entitybuffer.h +++ b/common/entitybuffer.h @@ -12,7 +12,18 @@ struct Entity; class SINK_EXPORT EntityBuffer { public: + /** + * Creates an entity buffer from @param dataValue. + * + * Note that @param dataValue will need to remain valid and the data is not copied. + */ EntityBuffer(const void *dataValue, int size); + + /** + * Creates an entity buffer from @param data. + * + * Note that @param data will need to remain valid and the data is not copied. + */ EntityBuffer(const QByteArray &data); const uint8_t *resourceBuffer(); const uint8_t *metadataBuffer(); diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 638be6e..4560b13 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp @@ -249,7 +249,7 @@ bool EntityStore::add(const QByteArray &type, ApplicationDomain::ApplicationDoma ApplicationDomain::ApplicationDomainType EntityStore::applyDiff(const QByteArray &type, const ApplicationDomain::ApplicationDomainType ¤t, const ApplicationDomain::ApplicationDomainType &diff, const QByteArrayList &deletions) const { - auto newEntity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(current, current.availableProperties()); + auto newEntity = *ApplicationDomainType::getInMemoryRepresentation(current, current.availableProperties()); SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity; @@ -512,7 +512,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readLatest(const QByteArra { ApplicationDomain::ApplicationDomainType dt; readLatest(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { - dt = entity; + dt = *ApplicationDomainType::getInMemoryRepresentation(entity, entity.availableProperties()); }); return dt; } @@ -539,7 +539,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readEntity(const QByteArra { ApplicationDomain::ApplicationDomainType dt; readEntity(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { - dt = entity; + dt = *ApplicationDomainType::getInMemoryRepresentation(entity, entity.availableProperties()); }); return dt; } @@ -601,7 +601,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readPrevious(const QByteAr { ApplicationDomain::ApplicationDomainType dt; readPrevious(type, uid, revision, [&](const ApplicationDomain::ApplicationDomainType &entity) { - dt = entity; + dt = *ApplicationDomainType::getInMemoryRepresentation(entity, entity.availableProperties()); }); return dt; } diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h index 003a2ca..c89c095 100644 --- a/common/storage/entitystore.h +++ b/common/storage/entitystore.h @@ -39,6 +39,8 @@ public: EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &); ~EntityStore() = default; + using ApplicationDomainType = ApplicationDomain::ApplicationDomainType; + void initialize(); //Only the pipeline may call the following functions outside of tests @@ -63,10 +65,14 @@ public: return indexLookup(ApplicationDomain::getTypeName(), PropertyType::name, value, callback); } + ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end. void readLatest(const QByteArray &type, const QByteArray &uid, const std::function callback); + ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end. void readLatest(const QByteArray &type, const QByteArray &uid, const std::function callback); + ///Returns an entity and operation. Note that the memory only remains valid until the next operation or transaction end. void readLatest(const QByteArray &type, const QByteArray &uid, const std::function callback); + ///Returns a copy ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid); template @@ -74,8 +80,11 @@ public: return T(readLatest(ApplicationDomain::getTypeName(), uid)); } + ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end. void readEntity(const QByteArray &type, const QByteArray &uid, const std::function callback); + ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end. void readEntity(const QByteArray &type, const QByteArray &uid, const std::function callback); + ///Returns a copy ApplicationDomain::ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key); template @@ -86,6 +95,7 @@ public: void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function callback); void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function callback); + ///Returns a copy ApplicationDomain::ApplicationDomainType readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision); template -- cgit v1.2.3