summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/domain/applicationdomaintype.cpp35
-rw-r--r--common/domain/applicationdomaintype.h61
-rw-r--r--common/propertymapper.cpp19
-rw-r--r--common/query.h11
-rw-r--r--common/queryrunner.cpp6
-rw-r--r--common/specialpurposepreprocessor.cpp20
-rw-r--r--common/storage/entitystore.cpp3
-rw-r--r--common/typeindex.cpp6
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
32constexpr const char *Mail::ThreadId::name; 32constexpr const char *Mail::ThreadId::name;
33 33
34void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs) 34int 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
43void 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
53ApplicationDomainType::ApplicationDomainType() 64ApplicationDomainType::ApplicationDomainType()
54 :mAdaptor(new MemoryBufferAdaptor()) 65 :mAdaptor(new MemoryBufferAdaptor()),
66 mChangeSet(new QSet<QByteArray>())
55{ 67{
56 68
57} 69}
58 70
59ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceIdentifier) 71ApplicationDomainType::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
74ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) 88ApplicationDomainType::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)
79ApplicationDomainType& ApplicationDomainType::operator=(const ApplicationDomainType &other) 94ApplicationDomainType& 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
110void ApplicationDomainType::setProperty(const QByteArray &key, const QVariant &value) 127void 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)
122void ApplicationDomainType::setProperty(const QByteArray &key, const ApplicationDomainType &value) 139void 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
128QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const 145QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const
@@ -152,12 +169,12 @@ void ApplicationDomainType::setBlobProperty(const QByteArray &key, const QByteAr
152 169
153void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset) 170void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset)
154{ 171{
155 mChangeSet = changeset; 172 *mChangeSet = changeset;
156} 173}
157 174
158QByteArrayList ApplicationDomainType::changedProperties() const 175QByteArrayList ApplicationDomainType::changedProperties() const
159{ 176{
160 return mChangeSet.toList(); 177 return mChangeSet->toList();
161} 178}
162 179
163QByteArrayList ApplicationDomainType::availableProperties() const 180QByteArrayList 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
105void 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 */
110struct 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
125void 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:
195private: 223private:
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
254inline QDebug operator<< (QDebug d, const Reference &ref)
255{
256 d << ref.value;
257 return d;
258}
259
260inline QDebug operator<< (QDebug d, const BLOB &blob)
261{
262 d << blob.value;
263 return d;
264}
265
266
226struct SINK_EXPORT SinkAccount : public ApplicationDomainType { 267struct 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
362inline 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)
454Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error) 502Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error)
455Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress) 503Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress)
456Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB) 504Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB)
505Q_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
44template <> 44template <>
45flatbuffers::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
53template <>
45flatbuffers::uoffset_t variantToProperty<QByteArray>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) 54flatbuffers::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
132template <> 141template <>
142QVariant 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
151template <>
133QVariant propertyToVariant<QByteArray>(const flatbuffers::String *property) 152QVariant 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
75void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity) 75void 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 }