summaryrefslogtreecommitdiffstats
path: root/common/storage/entitystore.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-12-09 16:31:30 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-12-09 16:31:30 +0100
commit9f6751df8e6f483b112c2b24c0bc725924f17356 (patch)
treedf312279bacc53e5bb6b6181fc25282ce5b0dd8e /common/storage/entitystore.cpp
parent9c8e4612403fc2accc26ac2b49670394972f1293 (diff)
downloadsink-9f6751df8e6f483b112c2b24c0bc725924f17356.tar.gz
sink-9f6751df8e6f483b112c2b24c0bc725924f17356.zip
Move the BLOB property handling to the entitystore.
This is really part of the storage, and will help us to cleanly implement features like moving properties into a temporary place when reading in a clean way as well.
Diffstat (limited to 'common/storage/entitystore.cpp')
-rw-r--r--common/storage/entitystore.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 999bb2c..d8b1121 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -19,6 +19,9 @@
19 */ 19 */
20#include "entitystore.h" 20#include "entitystore.h"
21 21
22#include <QDir>
23#include <QFile>
24
22#include "entitybuffer.h" 25#include "entitybuffer.h"
23#include "log.h" 26#include "log.h"
24#include "typeindex.h" 27#include "typeindex.h"
@@ -90,6 +93,11 @@ public:
90 return ApplicationDomain::ApplicationDomainType{resourceContext.instanceId(), uid, revision, adaptor}; 93 return ApplicationDomain::ApplicationDomainType{resourceContext.instanceId(), uid, revision, adaptor};
91 } 94 }
92 95
96 QString entityBlobStoragePath(const QByteArray &id)
97 {
98 return Sink::resourceStorageLocation(resourceContext.instanceId()) + "/blob/" + id;
99 }
100
93}; 101};
94 102
95EntityStore::EntityStore(const ResourceContext &context) 103EntityStore::EntityStore(const ResourceContext &context)
@@ -120,6 +128,38 @@ void EntityStore::abortTransaction()
120 d->transaction = Storage::DataStore::Transaction(); 128 d->transaction = Storage::DataStore::Transaction();
121} 129}
122 130
131void EntityStore::copyBlobs(ApplicationDomain::ApplicationDomainType &entity, qint64 newRevision)
132{
133 const auto directory = d->entityBlobStoragePath(entity.identifier());
134 if (!QDir().mkpath(directory)) {
135 SinkWarning() << "Failed to create the directory: " << directory;
136 }
137
138 for (const auto &property : entity.changedProperties()) {
139 const auto value = entity.getProperty(property);
140 if (value.canConvert<ApplicationDomain::BLOB>()) {
141 const auto blob = value.value<ApplicationDomain::BLOB>();
142 bool blobIsExternal = blob.isExternal;
143 //Any blob that is not part of the storage yet has to be moved there.
144 if (blob.isExternal) {
145 auto oldPath = blob.value;
146 auto filePath = directory + QString("/%1%2.blob").arg(QString::number(newRevision)).arg(QString::fromLatin1(property));
147 //In case we hit the same revision again due to a rollback.
148 QFile::remove(filePath);
149 QFile origFile(oldPath);
150 if (!origFile.open(QIODevice::ReadWrite)) {
151 SinkWarning() << "Failed to open the original file with write rights: " << origFile.errorString();
152 }
153 if (!origFile.rename(filePath)) {
154 SinkWarning() << "Failed to move the file from: " << oldPath << " to " << filePath << ". " << origFile.errorString();
155 }
156 origFile.close();
157 entity.setProperty(property, QVariant::fromValue(ApplicationDomain::BLOB{filePath}));
158 }
159 }
160 }
161}
162
123bool EntityStore::add(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &entity_, bool replayToSource, const PreprocessCreation &preprocess) 163bool EntityStore::add(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &entity_, bool replayToSource, const PreprocessCreation &preprocess)
124{ 164{
125 if (entity_.identifier().isEmpty()) { 165 if (entity_.identifier().isEmpty()) {
@@ -138,6 +178,8 @@ bool EntityStore::add(const QByteArray &type, const ApplicationDomain::Applicati
138 //The maxRevision may have changed meanwhile if the entity created sub-entities 178 //The maxRevision may have changed meanwhile if the entity created sub-entities
139 const qint64 newRevision = maxRevision() + 1; 179 const qint64 newRevision = maxRevision() + 1;
140 180
181 copyBlobs(entity, newRevision);
182
141 // Add metadata buffer 183 // Add metadata buffer
142 flatbuffers::FlatBufferBuilder metadataFbb; 184 flatbuffers::FlatBufferBuilder metadataFbb;
143 auto metadataBuilder = MetadataBuilder(metadataFbb); 185 auto metadataBuilder = MetadataBuilder(metadataFbb);
@@ -192,6 +234,8 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic
192 234
193 const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; 235 const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1;
194 236
237 copyBlobs(newEntity, newRevision);
238
195 // Add metadata buffer 239 // Add metadata buffer
196 flatbuffers::FlatBufferBuilder metadataFbb; 240 flatbuffers::FlatBufferBuilder metadataFbb;
197 { 241 {
@@ -297,6 +341,13 @@ void EntityStore::cleanupRevision(qint64 revision)
297 DataStore::removeRevision(d->transaction, rev); 341 DataStore::removeRevision(d->transaction, rev);
298 DataStore::mainDatabase(d->transaction, bufferType).remove(key); 342 DataStore::mainDatabase(d->transaction, bufferType).remove(key);
299 } 343 }
344 if (metadata->operation() == Operation_Removal) {
345 const auto directory = d->entityBlobStoragePath(uid);
346 QDir dir(directory);
347 if (!dir.removeRecursively()) {
348 SinkError() << "Failed to cleanup: " << directory;
349 }
350 }
300 } 351 }
301 352
302 return true; 353 return true;