summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/domain/applicationdomaintype.cpp26
-rw-r--r--common/domain/applicationdomaintype.h30
-rw-r--r--common/propertymapper.cpp19
3 files changed, 66 insertions, 9 deletions
diff --git a/common/domain/applicationdomaintype.cpp b/common/domain/applicationdomaintype.cpp
index 105ae56..1e54622 100644
--- a/common/domain/applicationdomaintype.cpp
+++ b/common/domain/applicationdomaintype.cpp
@@ -31,6 +31,25 @@ 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)
35{
36 auto propertiesToCopy = properties;
37 if (properties.isEmpty()) {
38 propertiesToCopy = buffer.availableProperties();
39 }
40 for (const auto &property : propertiesToCopy) {
41 const auto value = buffer.getProperty(property);
42 if (copyBlobs && value.canConvert<BLOB>()) {
43 auto oldPath = value.value<BLOB>().value;
44 auto newPath = oldPath + "copy";
45 QFile::copy(oldPath, newPath);
46 memoryAdaptor.setProperty(property, QVariant::fromValue(BLOB{newPath}));
47 } else {
48 memoryAdaptor.setProperty(property, value);
49 }
50 }
51}
52
34ApplicationDomainType::ApplicationDomainType() 53ApplicationDomainType::ApplicationDomainType()
35 :mAdaptor(new MemoryBufferAdaptor()) 54 :mAdaptor(new MemoryBufferAdaptor())
36{ 55{
@@ -85,9 +104,6 @@ bool ApplicationDomainType::hasProperty(const QByteArray &key) const
85QVariant ApplicationDomainType::getProperty(const QByteArray &key) const 104QVariant ApplicationDomainType::getProperty(const QByteArray &key) const
86{ 105{
87 Q_ASSERT(mAdaptor); 106 Q_ASSERT(mAdaptor);
88 if (!mAdaptor->availableProperties().contains(key)) {
89 return QVariant();
90 }
91 return mAdaptor->getProperty(key); 107 return mAdaptor->getProperty(key);
92} 108}
93 109
@@ -111,7 +127,7 @@ void ApplicationDomainType::setProperty(const QByteArray &key, const Application
111 127
112QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const 128QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const
113{ 129{
114 const auto path = getProperty(key).toByteArray(); 130 const auto path = getProperty(key).value<BLOB>().value;
115 QFile file(path); 131 QFile file(path);
116 if (!file.open(QIODevice::ReadOnly)) { 132 if (!file.open(QIODevice::ReadOnly)) {
117 SinkError() << "Failed to open the file: " << file.errorString() << path; 133 SinkError() << "Failed to open the file: " << file.errorString() << path;
@@ -131,7 +147,7 @@ void ApplicationDomainType::setBlobProperty(const QByteArray &key, const QByteAr
131 file.write(value); 147 file.write(value);
132 //Ensure that the file is written to disk immediately 148 //Ensure that the file is written to disk immediately
133 file.close(); 149 file.close();
134 setProperty(key, path); 150 setProperty(key, QVariant::fromValue(BLOB{path}));
135} 151}
136 152
137void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset) 153void ApplicationDomainType::setChangedProperties(const QSet<QByteArray> &changeset)
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h
index d6bbdd4..621a512 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -63,12 +63,12 @@
63#define SINK_BLOB_PROPERTY(NAME, LOWERCASENAME) \ 63#define SINK_BLOB_PROPERTY(NAME, LOWERCASENAME) \
64 struct NAME { \ 64 struct NAME { \
65 static constexpr const char *name = #LOWERCASENAME; \ 65 static constexpr const char *name = #LOWERCASENAME; \
66 typedef QString Type; \ 66 typedef BLOB Type; \
67 }; \ 67 }; \
68 void set##NAME(const QByteArray &value) { setBlobProperty(NAME::name, value); } \ 68 void set##NAME(const QByteArray &value) { setBlobProperty(NAME::name, value); } \
69 void set##NAME##Path(const QString &path) { setProperty(NAME::name, QVariant::fromValue(path)); } \ 69 void set##NAME##Path(const QString &path) { setProperty(NAME::name, QVariant::fromValue(BLOB{path})); } \
70 QByteArray get##NAME() const { return getBlobProperty(NAME::name); } \ 70 QByteArray get##NAME() const { return getBlobProperty(NAME::name); } \
71 QString get##NAME##Path() const { return getProperty(NAME::name).value<QString>(); } \ 71 QString get##NAME##Path() const { return getProperty(NAME::name).value<BLOB>().value; } \
72 72
73#define SINK_REFERENCE_PROPERTY(TYPE, NAME, LOWERCASENAME) \ 73#define SINK_REFERENCE_PROPERTY(TYPE, NAME, LOWERCASENAME) \
74 struct NAME { \ 74 struct NAME { \
@@ -98,6 +98,12 @@ struct SINK_EXPORT Progress {
98 98
99}; 99};
100 100
101struct BLOB {
102 QString value;
103};
104
105void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList<QByteArray> &properties, bool copyBlobs);
106
101/** 107/**
102 * The domain type interface has two purposes: 108 * The domain type interface has two purposes:
103 * * provide a unified interface to read buffers (for zero-copy reading) 109 * * provide a unified interface to read buffers (for zero-copy reading)
@@ -115,14 +121,29 @@ public:
115 ApplicationDomainType(const ApplicationDomainType &other); 121 ApplicationDomainType(const ApplicationDomainType &other);
116 ApplicationDomainType& operator=(const ApplicationDomainType &other); 122 ApplicationDomainType& operator=(const ApplicationDomainType &other);
117 123
124 /**
125 * Returns an in memory representation of the same entity.
126 */
118 template <typename DomainType> 127 template <typename DomainType>
119 static typename DomainType::Ptr getInMemoryRepresentation(const ApplicationDomainType &domainType, const QList<QByteArray> properties = QList<QByteArray>()) 128 static typename DomainType::Ptr getInMemoryRepresentation(const ApplicationDomainType &domainType, const QList<QByteArray> properties = QList<QByteArray>())
120 { 129 {
121 auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(*(domainType.mAdaptor), properties); 130 auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create(*(domainType.mAdaptor), properties);
122 //The identifier still internal refers to the memory-mapped pointer, we need to copy the memory or it will become invalid 131 //mIdentifier internally still refers to the memory-mapped memory, we need to copy the memory or it will become invalid
123 return QSharedPointer<DomainType>::create(domainType.mResourceInstanceIdentifier, QByteArray(domainType.mIdentifier.constData(), domainType.mIdentifier.size()), domainType.mRevision, memoryAdaptor); 132 return QSharedPointer<DomainType>::create(domainType.mResourceInstanceIdentifier, QByteArray(domainType.mIdentifier.constData(), domainType.mIdentifier.size()), domainType.mRevision, memoryAdaptor);
124 } 133 }
125 134
135 /**
136 * Returns an in memory copy without id and resource set.
137 */
138 template <typename DomainType>
139 static typename DomainType::Ptr getInMemoryCopy(const ApplicationDomainType &domainType, const QList<QByteArray> properties = QList<QByteArray>())
140 {
141 auto memoryAdaptor = QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create();
142 Q_ASSERT(domainType.mAdaptor);
143 copyBuffer(*(domainType.mAdaptor), *memoryAdaptor, properties, true);
144 return QSharedPointer<DomainType>::create(QByteArray{}, QByteArray{}, 0, memoryAdaptor);
145 }
146
126 static QByteArray generateUid(); 147 static QByteArray generateUid();
127 148
128 template <class DomainType> 149 template <class DomainType>
@@ -430,3 +451,4 @@ Q_DECLARE_METATYPE(Sink::ApplicationDomain::Identity::Ptr)
430Q_DECLARE_METATYPE(Sink::ApplicationDomain::Mail::Contact) 451Q_DECLARE_METATYPE(Sink::ApplicationDomain::Mail::Contact)
431Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error) 452Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error)
432Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress) 453Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress)
454Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB)
diff --git a/common/propertymapper.cpp b/common/propertymapper.cpp
index 754c874..249221a 100644
--- a/common/propertymapper.cpp
+++ b/common/propertymapper.cpp
@@ -33,6 +33,15 @@ flatbuffers::uoffset_t variantToProperty<QString>(const QVariant &property, flat
33} 33}
34 34
35template <> 35template <>
36flatbuffers::uoffset_t variantToProperty<Sink::ApplicationDomain::BLOB>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb)
37{
38 if (property.isValid()) {
39 return fbb.CreateString(property.value<Sink::ApplicationDomain::BLOB>().value.toStdString()).o;
40 }
41 return 0;
42}
43
44template <>
36flatbuffers::uoffset_t variantToProperty<QByteArray>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) 45flatbuffers::uoffset_t variantToProperty<QByteArray>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb)
37{ 46{
38 if (property.isValid()) { 47 if (property.isValid()) {
@@ -111,6 +120,16 @@ QVariant propertyToVariant<QString>(const flatbuffers::String *property)
111} 120}
112 121
113template <> 122template <>
123QVariant propertyToVariant<Sink::ApplicationDomain::BLOB>(const flatbuffers::String *property)
124{
125 if (property) {
126 // We have to copy the memory, otherwise it would become eventually invalid
127 return QVariant::fromValue(Sink::ApplicationDomain::BLOB{QString::fromStdString(property->c_str())});
128 }
129 return QVariant();
130}
131
132template <>
114QVariant propertyToVariant<QByteArray>(const flatbuffers::String *property) 133QVariant propertyToVariant<QByteArray>(const flatbuffers::String *property)
115{ 134{
116 if (property) { 135 if (property) {