diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-12-09 16:31:30 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-12-09 16:31:30 +0100 |
commit | 9f6751df8e6f483b112c2b24c0bc725924f17356 (patch) | |
tree | df312279bacc53e5bb6b6181fc25282ce5b0dd8e /common/storage/entitystore.cpp | |
parent | 9c8e4612403fc2accc26ac2b49670394972f1293 (diff) | |
download | sink-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.cpp | 51 |
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 | ||
95 | EntityStore::EntityStore(const ResourceContext &context) | 103 | EntityStore::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 | ||
131 | void 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 | |||
123 | bool EntityStore::add(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &entity_, bool replayToSource, const PreprocessCreation &preprocess) | 163 | bool 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; |