diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/domain/applicationdomaintype.cpp | 35 | ||||
-rw-r--r-- | common/domain/applicationdomaintype.h | 61 | ||||
-rw-r--r-- | common/propertymapper.cpp | 19 | ||||
-rw-r--r-- | common/query.h | 11 | ||||
-rw-r--r-- | common/queryrunner.cpp | 6 | ||||
-rw-r--r-- | common/specialpurposepreprocessor.cpp | 20 | ||||
-rw-r--r-- | common/storage/entitystore.cpp | 3 | ||||
-rw-r--r-- | common/typeindex.cpp | 6 |
8 files changed, 130 insertions, 31 deletions
diff --git a/common/domain/applicationdomaintype.cpp b/common/domain/applicationdomaintype.cpp index a655871..f00f3ed 100644 --- a/common/domain/applicationdomaintype.cpp +++ b/common/domain/applicationdomaintype.cpp | |||
@@ -31,7 +31,16 @@ namespace ApplicationDomain { | |||
31 | 31 | ||
32 | constexpr const char *Mail::ThreadId::name; | 32 | constexpr const char *Mail::ThreadId::name; |
33 | 33 | ||
34 | void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs) | 34 | int foo = [] { |
35 | QMetaType::registerEqualsComparator<Reference>(); | ||
36 | QMetaType::registerDebugStreamOperator<Reference>(); | ||
37 | QMetaType::registerConverter<Reference, QByteArray>(); | ||
38 | QMetaType::registerDebugStreamOperator<BLOB>(); | ||
39 | QMetaType::registerDebugStreamOperator<Mail::Contact>(); | ||
40 | return 0; | ||
41 | }(); | ||
42 | |||
43 | void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs, bool pruneReferences) | ||
35 | { | 44 | { |
36 | auto propertiesToCopy = properties; | 45 | auto propertiesToCopy = properties; |
37 | if (properties.isEmpty()) { | 46 | if (properties.isEmpty()) { |
@@ -44,6 +53,8 @@ void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::Applicatio | |||
44 | auto newPath = oldPath + "copy"; | 53 | auto newPath = oldPath + "copy"; |
45 | QFile::copy(oldPath, newPath); | 54 | QFile::copy(oldPath, newPath); |
46 | memoryAdaptor.setProperty(property, QVariant::fromValue(BLOB{newPath})); | 55 | memoryAdaptor.setProperty(property, QVariant::fromValue(BLOB{newPath})); |
56 | } else if (pruneReferences && value.canConvert<Reference>()) { | ||
57 | continue; | ||
47 | } else { | 58 | } else { |
48 | memoryAdaptor.setProperty(property, value); | 59 | memoryAdaptor.setProperty(property, value); |
49 | } | 60 | } |
@@ -51,14 +62,16 @@ void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::Applicatio | |||
51 | } | 62 | } |
52 | 63 | ||
53 | ApplicationDomainType::ApplicationDomainType() | 64 | ApplicationDomainType::ApplicationDomainType() |
54 | :mAdaptor(new MemoryBufferAdaptor()) | 65 | :mAdaptor(new MemoryBufferAdaptor()), |
66 | mChangeSet(new QSet<QByteArray>()) | ||
55 | { | 67 | { |
56 | 68 | ||
57 | } | 69 | } |
58 | 70 | ||
59 | ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceIdentifier) | 71 | ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceIdentifier) |
60 | :mAdaptor(new MemoryBufferAdaptor()), | 72 | :mAdaptor(new MemoryBufferAdaptor()), |
61 | mResourceInstanceIdentifier(resourceInstanceIdentifier) | 73 | mResourceInstanceIdentifier(resourceInstanceIdentifier), |
74 | mChangeSet(new QSet<QByteArray>()) | ||
62 | { | 75 | { |
63 | 76 | ||
64 | } | 77 | } |
@@ -67,11 +80,13 @@ ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceI | |||
67 | : mAdaptor(adaptor), | 80 | : mAdaptor(adaptor), |
68 | mResourceInstanceIdentifier(resourceInstanceIdentifier), | 81 | mResourceInstanceIdentifier(resourceInstanceIdentifier), |
69 | mIdentifier(identifier), | 82 | mIdentifier(identifier), |
70 | mRevision(revision) | 83 | mRevision(revision), |
84 | mChangeSet(new QSet<QByteArray>()) | ||
71 | { | 85 | { |
72 | } | 86 | } |
73 | 87 | ||
74 | ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) | 88 | ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) |
89 | : mChangeSet(new QSet<QByteArray>()) | ||
75 | { | 90 | { |
76 | *this = other; | 91 | *this = other; |
77 | } | 92 | } |
@@ -79,7 +94,9 @@ ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) | |||
79 | ApplicationDomainType& ApplicationDomainType::operator=(const ApplicationDomainType &other) | 94 | ApplicationDomainType& ApplicationDomainType::operator=(const ApplicationDomainType &other) |
80 | { | 95 | { |
81 | mAdaptor = other.mAdaptor; | 96 | mAdaptor = other.mAdaptor; |
82 | mChangeSet = other.mChangeSet; | 97 | if (other.mChangeSet) { |
98 | *mChangeSet = *other.mChangeSet; | ||
99 | } | ||
83 | mResourceInstanceIdentifier = other.mResourceInstanceIdentifier; | 100 | mResourceInstanceIdentifier = other.mResourceInstanceIdentifier; |
84 | mIdentifier = other.mIdentifier; | 101 | mIdentifier = other.mIdentifier; |
85 | mRevision = other.mRevision; | 102 | mRevision = other.mRevision; |
@@ -110,7 +127,7 @@ QVariant ApplicationDomainType::getProperty(const QByteArray &key) const | |||
110 | void ApplicationDomainType::setProperty(const QByteArray &key, const QVariant &value) | 127 | void ApplicationDomainType::setProperty(const QByteArray &key, const QVariant &value) |
111 | { | 128 | { |
112 | Q_ASSERT(mAdaptor); | 129 | Q_ASSERT(mAdaptor); |
113 | mChangeSet.insert(key); | 130 | mChangeSet->insert(key); |
114 | mAdaptor->setProperty(key, value); | 131 | mAdaptor->setProperty(key, value); |
115 | } | 132 | } |
116 | 133 | ||
@@ -122,7 +139,7 @@ void ApplicationDomainType::setResource(const QByteArray &identifier) | |||
122 | void ApplicationDomainType::setProperty(const QByteArray &key, const ApplicationDomainType &value) | 139 | void ApplicationDomainType::setProperty(const QByteArray &key, const ApplicationDomainType &value) |
123 | { | 140 | { |
124 | Q_ASSERT(!value.identifier().isEmpty()); | 141 | Q_ASSERT(!value.identifier().isEmpty()); |
125 | setProperty(key, value.identifier()); | 142 | setProperty(key, QVariant::fromValue(Reference{value.identifier()})); |
126 | } | 143 | } |
127 | 144 | ||
128 | QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const | 145 | QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const |
@@ -152,12 +169,12 @@ void ApplicationDomainType::setBlobProperty(const QByteArray &key, const QByteAr | |||
152 | 169 | ||
153 | void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset) | 170 | void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset) |
154 | { | 171 | { |
155 | mChangeSet = changeset; | 172 | *mChangeSet = changeset; |
156 | } | 173 | } |
157 | 174 | ||
158 | QByteArrayList ApplicationDomainType::changedProperties() const | 175 | QByteArrayList ApplicationDomainType::changedProperties() const |
159 | { | 176 | { |
160 | return mChangeSet.toList(); | 177 | return mChangeSet->toList(); |
161 | } | 178 | } |
162 | 179 | ||
163 | QByteArrayList ApplicationDomainType::availableProperties() const | 180 | QByteArrayList ApplicationDomainType::availableProperties() const |
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index 21e42cf..1c0f208 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h | |||
@@ -73,12 +73,12 @@ | |||
73 | #define SINK_REFERENCE_PROPERTY(TYPE, NAME, LOWERCASENAME) \ | 73 | #define SINK_REFERENCE_PROPERTY(TYPE, NAME, LOWERCASENAME) \ |
74 | struct NAME { \ | 74 | struct NAME { \ |
75 | static constexpr const char *name = #LOWERCASENAME; \ | 75 | static constexpr const char *name = #LOWERCASENAME; \ |
76 | typedef QByteArray Type; \ | 76 | typedef Reference Type; \ |
77 | typedef ApplicationDomain::TYPE ReferenceType; \ | 77 | typedef ApplicationDomain::TYPE ReferenceType; \ |
78 | }; \ | 78 | }; \ |
79 | void set##NAME(const ApplicationDomain::TYPE &value) { setProperty(NAME::name, value); } \ | 79 | void set##NAME(const ApplicationDomain::TYPE &value) { setProperty(NAME::name, value); } \ |
80 | void set##NAME(const QByteArray &value) { setProperty(NAME::name, QVariant::fromValue(value)); } \ | 80 | void set##NAME(const QByteArray &value) { setProperty(NAME::name, QVariant::fromValue(Reference{value})); } \ |
81 | QByteArray get##NAME() const { return getProperty(NAME::name).value<QByteArray>(); } \ | 81 | QByteArray get##NAME() const { return getProperty(NAME::name).value<Reference>().value; } \ |
82 | 82 | ||
83 | #define SINK_INDEX_PROPERTY(TYPE, NAME, LOWERCASENAME) \ | 83 | #define SINK_INDEX_PROPERTY(TYPE, NAME, LOWERCASENAME) \ |
84 | struct NAME { \ | 84 | struct NAME { \ |
@@ -102,7 +102,27 @@ struct BLOB { | |||
102 | QString value; | 102 | QString value; |
103 | }; | 103 | }; |
104 | 104 | ||
105 | void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs); | 105 | /** |
106 | * Internal type. | ||
107 | * | ||
108 | * Represents a reference to another entity in the same resource. | ||
109 | */ | ||
110 | struct Reference { | ||
111 | Reference() = default; | ||
112 | Reference(const Reference &) = default; | ||
113 | Reference(const QByteArray &id) : value(id) {}; | ||
114 | Reference(const char *id) : value(id) {}; | ||
115 | ~Reference() = default; | ||
116 | bool operator==(const Reference &other) const { | ||
117 | return value == other.value; | ||
118 | } | ||
119 | operator QByteArray() const { | ||
120 | return value; | ||
121 | } | ||
122 | QByteArray value; | ||
123 | }; | ||
124 | |||
125 | void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs, bool pruneReferences); | ||
106 | 126 | ||
107 | /** | 127 | /** |
108 | * The domain type interface has two purposes: | 128 | * The domain type interface has two purposes: |
@@ -121,6 +141,14 @@ public: | |||
121 | ApplicationDomainType(const ApplicationDomainType &other); | 141 | ApplicationDomainType(const ApplicationDomainType &other); |
122 | ApplicationDomainType& operator=(const ApplicationDomainType &other); | 142 | ApplicationDomainType& operator=(const ApplicationDomainType &other); |
123 | 143 | ||
144 | template <typename DomainType> | ||
145 | DomainType cast() { | ||
146 | static_assert(std::is_base_of<ApplicationDomainType, DomainType>::value, "You can only cast to base classes of ApplicationDomainType."); | ||
147 | DomainType t = *this; | ||
148 | t.mChangeSet = mChangeSet; | ||
149 | return t; | ||
150 | } | ||
151 | |||
124 | /** | 152 | /** |
125 | * Returns an in memory representation of the same entity. | 153 | * Returns an in memory representation of the same entity. |
126 | */ | 154 | */ |
@@ -140,7 +168,7 @@ public: | |||
140 | { | 168 | { |
141 | auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(); | 169 | auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(); |
142 | Q_ASSERT(domainType.mAdaptor); | 170 | Q_ASSERT(domainType.mAdaptor); |
143 | copyBuffer(*(domainType.mAdaptor), *memoryAdaptor, properties, true); | 171 | copyBuffer(*(domainType.mAdaptor), *memoryAdaptor, properties, true, true); |
144 | return QSharedPointer<DomainType>::create(QByteArray{}, QByteArray{}, 0, memoryAdaptor); | 172 | return QSharedPointer<DomainType>::create(QByteArray{}, QByteArray{}, 0, memoryAdaptor); |
145 | } | 173 | } |
146 | 174 | ||
@@ -195,7 +223,7 @@ public: | |||
195 | private: | 223 | private: |
196 | friend QDebug operator<<(QDebug, const ApplicationDomainType &); | 224 | friend QDebug operator<<(QDebug, const ApplicationDomainType &); |
197 | QSharedPointer<BufferAdaptor> mAdaptor; | 225 | QSharedPointer<BufferAdaptor> mAdaptor; |
198 | QSet<QByteArray> mChangeSet; | 226 | QSharedPointer<QSet<QByteArray>> mChangeSet; |
199 | /* | 227 | /* |
200 | * Each domain object needs to store the resource, identifier, revision triple so we can link back to the storage location. | 228 | * Each domain object needs to store the resource, identifier, revision triple so we can link back to the storage location. |
201 | */ | 229 | */ |
@@ -223,6 +251,19 @@ inline QDebug operator<< (QDebug d, const ApplicationDomainType &type) | |||
223 | return d; | 251 | return d; |
224 | } | 252 | } |
225 | 253 | ||
254 | inline QDebug operator<< (QDebug d, const Reference &ref) | ||
255 | { | ||
256 | d << ref.value; | ||
257 | return d; | ||
258 | } | ||
259 | |||
260 | inline QDebug operator<< (QDebug d, const BLOB &blob) | ||
261 | { | ||
262 | d << blob.value; | ||
263 | return d; | ||
264 | } | ||
265 | |||
266 | |||
226 | struct SINK_EXPORT SinkAccount : public ApplicationDomainType { | 267 | struct SINK_EXPORT SinkAccount : public ApplicationDomainType { |
227 | typedef QSharedPointer<SinkAccount> Ptr; | 268 | typedef QSharedPointer<SinkAccount> Ptr; |
228 | explicit SinkAccount(const QByteArray &resourceInstanceIdentifier, const QByteArray &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> &adaptor); | 269 | explicit SinkAccount(const QByteArray &resourceInstanceIdentifier, const QByteArray &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> &adaptor); |
@@ -318,6 +359,13 @@ struct SINK_EXPORT Mail : public Entity { | |||
318 | SINK_INDEX_PROPERTY(QByteArray, ThreadId, threadId); | 359 | SINK_INDEX_PROPERTY(QByteArray, ThreadId, threadId); |
319 | }; | 360 | }; |
320 | 361 | ||
362 | inline QDebug operator<< (QDebug d, const Mail::Contact &c) | ||
363 | { | ||
364 | d << "Contact(" << c.name << ", " << c.emailAddress << ")"; | ||
365 | return d; | ||
366 | } | ||
367 | |||
368 | |||
321 | /** | 369 | /** |
322 | * The status of an account or resource. | 370 | * The status of an account or resource. |
323 | * | 371 | * |
@@ -454,3 +502,4 @@ Q_DECLARE_METATYPE(Sink::ApplicationDomain::Mail::Contact) | |||
454 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error) | 502 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error) |
455 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress) | 503 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress) |
456 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB) | 504 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB) |
505 | Q_DECLARE_METATYPE(Sink::ApplicationDomain::Reference) | ||
diff --git a/common/propertymapper.cpp b/common/propertymapper.cpp index 249221a..4cfe154 100644 --- a/common/propertymapper.cpp +++ b/common/propertymapper.cpp | |||
@@ -42,6 +42,15 @@ flatbuffers::uoffset_t variantToProperty<Sink::ApplicationDomain::BLOB>(const QV | |||
42 | } | 42 | } |
43 | 43 | ||
44 | template <> | 44 | template <> |
45 | flatbuffers::uoffset_t variantToProperty<Sink::ApplicationDomain::Reference>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) | ||
46 | { | ||
47 | if (property.isValid()) { | ||
48 | return fbb.CreateString(property.value<Sink::ApplicationDomain::Reference>().value.toStdString()).o; | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | template <> | ||
45 | flatbuffers::uoffset_t variantToProperty<QByteArray>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) | 54 | flatbuffers::uoffset_t variantToProperty<QByteArray>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) |
46 | { | 55 | { |
47 | if (property.isValid()) { | 56 | if (property.isValid()) { |
@@ -130,6 +139,16 @@ QVariant propertyToVariant<Sink::ApplicationDomain::BLOB>(const flatbuffers::Str | |||
130 | } | 139 | } |
131 | 140 | ||
132 | template <> | 141 | template <> |
142 | QVariant propertyToVariant<Sink::ApplicationDomain::Reference>(const flatbuffers::String *property) | ||
143 | { | ||
144 | if (property) { | ||
145 | // We have to copy the memory, otherwise it would become eventually invalid | ||
146 | return QVariant::fromValue(Sink::ApplicationDomain::Reference{QString::fromStdString(property->c_str()).toUtf8()}); | ||
147 | } | ||
148 | return QVariant(); | ||
149 | } | ||
150 | |||
151 | template <> | ||
133 | QVariant propertyToVariant<QByteArray>(const flatbuffers::String *property) | 152 | QVariant propertyToVariant<QByteArray>(const flatbuffers::String *property) |
134 | { | 153 | { |
135 | if (property) { | 154 | if (property) { |
diff --git a/common/query.h b/common/query.h index b69639b..c265f92 100644 --- a/common/query.h +++ b/common/query.h | |||
@@ -325,16 +325,17 @@ public: | |||
325 | } | 325 | } |
326 | 326 | ||
327 | template <typename T> | 327 | template <typename T> |
328 | Query &filter(const QVariant &value) | 328 | Query &filter(const typename T::Type &value) |
329 | { | 329 | { |
330 | filter(T::name, value); | 330 | filter(T::name, QVariant::fromValue(value)); |
331 | return *this; | 331 | return *this; |
332 | } | 332 | } |
333 | 333 | ||
334 | template <typename T> | 334 | template <typename T> |
335 | Query &containsFilter(const QVariant &value) | 335 | Query &containsFilter(const QByteArray &value) |
336 | { | 336 | { |
337 | QueryBase::filter(T::name, QueryBase::Comparator(value, QueryBase::Comparator::Contains)); | 337 | static_assert(std::is_same<typename T::Type, QByteArrayList>::value, "The contains filter is only implemented for QByteArray in QByteArrayList"); |
338 | QueryBase::filter(T::name, QueryBase::Comparator(QVariant::fromValue(value), QueryBase::Comparator::Contains)); | ||
338 | return *this; | 339 | return *this; |
339 | } | 340 | } |
340 | 341 | ||
@@ -366,7 +367,7 @@ public: | |||
366 | template <typename T> | 367 | template <typename T> |
367 | Query &filter(const ApplicationDomain::Entity &value) | 368 | Query &filter(const ApplicationDomain::Entity &value) |
368 | { | 369 | { |
369 | filter(T::name, QVariant::fromValue(value.identifier())); | 370 | filter(T::name, QVariant::fromValue(ApplicationDomain::Reference{value.identifier()})); |
370 | return *this; | 371 | return *this; |
371 | } | 372 | } |
372 | 373 | ||
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index cf56268..d6a90de 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp | |||
@@ -224,15 +224,15 @@ QPair<qint64, qint64> QueryWorker<DomainType>::executeInitialQuery( | |||
224 | if (!query.parentProperty().isEmpty()) { | 224 | if (!query.parentProperty().isEmpty()) { |
225 | if (parent) { | 225 | if (parent) { |
226 | SinkTrace() << "Running initial query for parent:" << parent->identifier(); | 226 | SinkTrace() << "Running initial query for parent:" << parent->identifier(); |
227 | modifiedQuery.filter(query.parentProperty(), Query::Comparator(parent->identifier())); | 227 | modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant::fromValue(Sink::ApplicationDomain::Reference{parent->identifier()}))); |
228 | } else { | 228 | } else { |
229 | SinkTrace() << "Running initial query for toplevel"; | 229 | SinkTrace() << "Running initial query for toplevel"; |
230 | modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant())); | 230 | modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant{})); |
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | auto entityStore = EntityStore{mResourceContext}; | 234 | auto entityStore = EntityStore{mResourceContext}; |
235 | auto preparedQuery = DataStoreQuery{query, ApplicationDomain::getTypeName<DomainType>(), entityStore}; | 235 | auto preparedQuery = DataStoreQuery{modifiedQuery, ApplicationDomain::getTypeName<DomainType>(), entityStore}; |
236 | auto resultSet = preparedQuery.execute(); | 236 | auto resultSet = preparedQuery.execute(); |
237 | 237 | ||
238 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); | 238 | SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); |
diff --git a/common/specialpurposepreprocessor.cpp b/common/specialpurposepreprocessor.cpp index ce1a218..e73e4ce 100644 --- a/common/specialpurposepreprocessor.cpp +++ b/common/specialpurposepreprocessor.cpp | |||
@@ -59,7 +59,7 @@ QByteArray SpecialPurposeProcessor::ensureFolder(const QByteArray &specialPurpos | |||
59 | }); | 59 | }); |
60 | 60 | ||
61 | if (!mSpecialPurposeFolders.contains(specialPurpose)) { | 61 | if (!mSpecialPurposeFolders.contains(specialPurpose)) { |
62 | SinkTrace() << "Failed to find a drafts folder, creating a new one"; | 62 | SinkTrace() << "Failed to find a " << specialPurpose << " folder, creating a new one"; |
63 | auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier); | 63 | auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier); |
64 | folder.setSpecialPurpose(QByteArrayList() << specialPurpose); | 64 | folder.setSpecialPurpose(QByteArrayList() << specialPurpose); |
65 | folder.setName(sSpecialPurposeFolders.value(specialPurpose)); | 65 | folder.setName(sSpecialPurposeFolders.value(specialPurpose)); |
@@ -74,15 +74,21 @@ QByteArray SpecialPurposeProcessor::ensureFolder(const QByteArray &specialPurpos | |||
74 | 74 | ||
75 | void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity) | 75 | void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity) |
76 | { | 76 | { |
77 | if (newEntity.getProperty(ApplicationDomain::Mail::Trash::name).toBool()) { | 77 | using namespace Sink::ApplicationDomain; |
78 | newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::trash)); | 78 | auto mail = newEntity.cast<Mail>(); |
79 | if (mail.getTrash()) { | ||
80 | auto f = ensureFolder(ApplicationDomain::SpecialPurpose::Mail::trash); | ||
81 | SinkTrace() << "Setting trash folder: " << f; | ||
82 | mail.setFolder(f); | ||
79 | return; | 83 | return; |
80 | } | 84 | } |
81 | if (newEntity.getProperty(ApplicationDomain::Mail::Draft::name).toBool()) { | 85 | if (mail.getDraft()) { |
82 | newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::drafts)); | 86 | mail.setFolder(ensureFolder(ApplicationDomain::SpecialPurpose::Mail::drafts)); |
87 | return; | ||
83 | } | 88 | } |
84 | if (newEntity.getProperty(ApplicationDomain::Mail::Sent::name).toBool()) { | 89 | if (mail.getSent()) { |
85 | newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::sent)); | 90 | mail.setFolder(ensureFolder(ApplicationDomain::SpecialPurpose::Mail::sent)); |
91 | return; | ||
86 | } | 92 | } |
87 | } | 93 | } |
88 | 94 | ||
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 7414f49..999bb2c 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp | |||
@@ -205,9 +205,10 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic | |||
205 | auto metadataBuffer = metadataBuilder.Finish(); | 205 | auto metadataBuffer = metadataBuilder.Finish(); |
206 | FinishMetadataBuffer(metadataFbb, metadataBuffer); | 206 | FinishMetadataBuffer(metadataFbb, metadataBuffer); |
207 | } | 207 | } |
208 | SinkTrace() << "Modified entity: " << newEntity; | ||
209 | SinkTrace() << "Changed properties: " << changeset + newEntity.changedProperties(); | ||
208 | 210 | ||
209 | newEntity.setChangedProperties(newEntity.availableProperties().toSet()); | 211 | newEntity.setChangedProperties(newEntity.availableProperties().toSet()); |
210 | SinkTrace() << "Modified entity " << newEntity; | ||
211 | 212 | ||
212 | flatbuffers::FlatBufferBuilder fbb; | 213 | flatbuffers::FlatBufferBuilder fbb; |
213 | d->resourceContext.adaptorFactory(type).createBuffer(newEntity, fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize()); | 214 | d->resourceContext.adaptorFactory(type).createBuffer(newEntity, fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize()); |
diff --git a/common/typeindex.cpp b/common/typeindex.cpp index b0494f3..9d71463 100644 --- a/common/typeindex.cpp +++ b/common/typeindex.cpp | |||
@@ -34,6 +34,12 @@ static QByteArray getByteArray(const QVariant &value) | |||
34 | return "nodate"; | 34 | return "nodate"; |
35 | } | 35 | } |
36 | } | 36 | } |
37 | if (value.canConvert<Sink::ApplicationDomain::Reference>()) { | ||
38 | const auto ba = value.value<Sink::ApplicationDomain::Reference>().value; | ||
39 | if (!ba.isEmpty()) { | ||
40 | return ba; | ||
41 | } | ||
42 | } | ||
37 | if (value.isValid() && !value.toByteArray().isEmpty()) { | 43 | if (value.isValid() && !value.toByteArray().isEmpty()) { |
38 | return value.toByteArray(); | 44 | return value.toByteArray(); |
39 | } | 45 | } |