summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/index.cpp8
-rw-r--r--common/index.h1
-rw-r--r--common/indexer.h5
-rw-r--r--common/mail/threadindexer.cpp22
-rw-r--r--common/mail/threadindexer.h3
-rw-r--r--common/storage/entitystore.cpp3
-rw-r--r--common/typeindex.cpp151
-rw-r--r--common/typeindex.h24
8 files changed, 103 insertions, 114 deletions
diff --git a/common/index.cpp b/common/index.cpp
index 13ca6ed..86a2dd5 100644
--- a/common/index.cpp
+++ b/common/index.cpp
@@ -2,6 +2,14 @@
2 2
3#include "log.h" 3#include "log.h"
4 4
5Index::Index(const QString &storageRoot, const QString &dbName, const QString &indexName, Sink::Storage::DataStore::AccessMode mode)
6 : mTransaction(Sink::Storage::DataStore(storageRoot, dbName, mode).createTransaction(mode)),
7 mDb(mTransaction.openDatabase(indexName.toLatin1(), std::function<void(const Sink::Storage::DataStore::Error &)>(), true)),
8 mName(indexName),
9 mLogCtx("index." + indexName.toLatin1())
10{
11}
12
5Index::Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode) 13Index::Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode)
6 : mTransaction(Sink::Storage::DataStore(storageRoot, name, mode).createTransaction(mode)), 14 : mTransaction(Sink::Storage::DataStore(storageRoot, name, mode).createTransaction(mode)),
7 mDb(mTransaction.openDatabase(name.toLatin1(), std::function<void(const Sink::Storage::DataStore::Error &)>(), true)), 15 mDb(mTransaction.openDatabase(name.toLatin1(), std::function<void(const Sink::Storage::DataStore::Error &)>(), true)),
diff --git a/common/index.h b/common/index.h
index 043cc90..492319e 100644
--- a/common/index.h
+++ b/common/index.h
@@ -29,6 +29,7 @@ public:
29 int code; 29 int code;
30 }; 30 };
31 31
32 Index(const QString &storageRoot, const QString &dbName, const QString &indexName, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly);
32 Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly); 33 Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly);
33 Index(const QString &storageRoot, const Sink::Storage::DbLayout &layout, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly); 34 Index(const QString &storageRoot, const Sink::Storage::DbLayout &layout, Sink::Storage::DataStore::AccessMode mode = Sink::Storage::DataStore::ReadOnly);
34 Index(const QByteArray &name, Sink::Storage::DataStore::Transaction &); 35 Index(const QByteArray &name, Sink::Storage::DataStore::Transaction &);
diff --git a/common/indexer.h b/common/indexer.h
index f0b32f5..b5b5422 100644
--- a/common/indexer.h
+++ b/common/indexer.h
@@ -33,6 +33,11 @@ public:
33 virtual ~Indexer() = default; 33 virtual ~Indexer() = default;
34 typedef QSharedPointer<Indexer> Ptr; 34 typedef QSharedPointer<Indexer> Ptr;
35 virtual void add(const ApplicationDomain::ApplicationDomainType &entity) = 0; 35 virtual void add(const ApplicationDomain::ApplicationDomainType &entity) = 0;
36 virtual void modify(const ApplicationDomain::ApplicationDomainType &oldEntity, const ApplicationDomain::ApplicationDomainType &newEntity)
37 {
38 remove(oldEntity);
39 add(newEntity);
40 }
36 virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) = 0; 41 virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) = 0;
37 virtual void commitTransaction() {}; 42 virtual void commitTransaction() {};
38 virtual void abortTransaction() {}; 43 virtual void abortTransaction() {};
diff --git a/common/mail/threadindexer.cpp b/common/mail/threadindexer.cpp
index fb47118..c1d1aa8 100644
--- a/common/mail/threadindexer.cpp
+++ b/common/mail/threadindexer.cpp
@@ -25,24 +25,25 @@
25using namespace Sink; 25using namespace Sink;
26using namespace Sink::ApplicationDomain; 26using namespace Sink::ApplicationDomain;
27 27
28void ThreadIndexer::updateThreadingIndex(const QByteArray &identifier, const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) 28void ThreadIndexer::updateThreadingIndex(const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction)
29{ 29{
30 auto messageId = entity.getProperty(Mail::MessageId::name); 30 auto messageId = entity.getProperty(Mail::MessageId::name);
31 auto parentMessageId = entity.getProperty(Mail::ParentMessageId::name); 31 auto parentMessageId = entity.getProperty(Mail::ParentMessageId::name);
32 if (messageId.toByteArray().isEmpty()) { 32 if (messageId.toByteArray().isEmpty()) {
33 SinkWarning() << "Found an email without messageId. This is illegal and threading will break. Entity id: " << identifier; 33 SinkWarning() << "Found an email without messageId. This is illegal and threading will break. Entity id: " << entity.identifier();
34 } 34 }
35 35
36 QVector<QByteArray> thread; 36 SinkTrace() << "Indexing thread. Entity: " << entity.identifier() << "Messageid: " << messageId << "ParentMessageId: " << parentMessageId;
37 37
38 //check if a child already registered our thread. 38 //check if a child already registered our thread.
39 thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); 39 QVector<QByteArray> thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId);
40 40
41 if (!thread.isEmpty()) { 41 if (!thread.isEmpty() && parentMessageId.isValid()) {
42 //A child already registered our thread so we merge the childs thread 42 //A child already registered our thread so we merge the childs thread
43 //* check if we have a parent thread, if not just continue as usual 43 //* check if we have a parent thread, if not just continue as usual
44 //* get all messages that have the same threadid as the child 44 //* get all messages that have the same threadid as the child
45 //* switch all to the parents thread 45 //* switch all to the parents thread
46 Q_ASSERT(!parentMessageId.toByteArray().isEmpty());
46 auto parentThread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(parentMessageId); 47 auto parentThread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(parentMessageId);
47 if (!parentThread.isEmpty()) { 48 if (!parentThread.isEmpty()) {
48 auto childThreadId = thread.first(); 49 auto childThreadId = thread.first();
@@ -95,13 +96,22 @@ void ThreadIndexer::updateThreadingIndex(const QByteArray &identifier, const App
95 96
96void ThreadIndexer::add(const ApplicationDomain::ApplicationDomainType &entity) 97void ThreadIndexer::add(const ApplicationDomain::ApplicationDomainType &entity)
97{ 98{
98 updateThreadingIndex(entity.identifier(), entity, transaction()); 99 updateThreadingIndex(entity, transaction());
100}
101
102void ThreadIndexer::modify(const ApplicationDomain::ApplicationDomainType &oldEntity, const ApplicationDomain::ApplicationDomainType &newEntity)
103{
104 //FIXME Implement to support thread changes.
105 //Emails are immutable (for everything threading relevant), so we don't care about it so far.
99} 106}
100 107
101void ThreadIndexer::remove(const ApplicationDomain::ApplicationDomainType &entity) 108void ThreadIndexer::remove(const ApplicationDomain::ApplicationDomainType &entity)
102{ 109{
103 auto messageId = entity.getProperty(Mail::MessageId::name); 110 auto messageId = entity.getProperty(Mail::MessageId::name);
104 auto thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); 111 auto thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId);
112 if (thread.isEmpty()) {
113 SinkWarning() << "Failed to find the threadId for the entity " << entity.identifier() << messageId;
114 }
105 index().unindex<Mail::MessageId, Mail::ThreadId>(messageId.toByteArray(), thread.first(), transaction()); 115 index().unindex<Mail::MessageId, Mail::ThreadId>(messageId.toByteArray(), thread.first(), transaction());
106 index().unindex<Mail::ThreadId, Mail::MessageId>(thread.first(), messageId.toByteArray(), transaction()); 116 index().unindex<Mail::ThreadId, Mail::MessageId>(thread.first(), messageId.toByteArray(), transaction());
107} 117}
diff --git a/common/mail/threadindexer.h b/common/mail/threadindexer.h
index b2e939a..747ba77 100644
--- a/common/mail/threadindexer.h
+++ b/common/mail/threadindexer.h
@@ -27,10 +27,11 @@ class ThreadIndexer : public Indexer
27public: 27public:
28 typedef QSharedPointer<ThreadIndexer> Ptr; 28 typedef QSharedPointer<ThreadIndexer> Ptr;
29 virtual void add(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE; 29 virtual void add(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE;
30 virtual void modify(const ApplicationDomain::ApplicationDomainType &oldEntity, const ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE;
30 virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE; 31 virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE;
31 static QMap<QByteArray, int> databases(); 32 static QMap<QByteArray, int> databases();
32private: 33private:
33 void updateThreadingIndex(const QByteArray &identifier, const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); 34 void updateThreadingIndex(const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction);
34}; 35};
35 36
36} 37}
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 18c788a..c5b5ffc 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -283,8 +283,7 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomainType &cu
283{ 283{
284 SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity; 284 SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity;
285 285
286 d->typeIndex(type).remove(current.identifier(), current, d->transaction, d->resourceContext.instanceId()); 286 d->typeIndex(type).modify(newEntity.identifier(), current, newEntity, d->transaction, d->resourceContext.instanceId());
287 d->typeIndex(type).add(newEntity.identifier(), newEntity, d->transaction, d->resourceContext.instanceId());
288 287
289 const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1; 288 const qint64 newRevision = DataStore::maxRevision(d->transaction) + 1;
290 289
diff --git a/common/typeindex.cpp b/common/typeindex.cpp
index 6aa3796..b18791f 100644
--- a/common/typeindex.cpp
+++ b/common/typeindex.cpp
@@ -120,82 +120,34 @@ static unsigned int bucketOf(const QVariant &value)
120 } 120 }
121} 121}
122 122
123template <> 123static void update(TypeIndex::Action action, const QByteArray &indexName, const QByteArray &key, const QByteArray &value, Sink::Storage::DataStore::Transaction &transaction)
124void TypeIndex::addProperty<QByteArray>(const QByteArray &property) 124{
125{ 125 Index index(indexName, transaction);
126 auto indexer = [this, property](bool add, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) { 126 switch (action) {
127 // SinkTraceCtx(mLogCtx) << "Indexing " << mType + ".index." + property << value.toByteArray(); 127 case TypeIndex::Add:
128 if (add) { 128 index.add(key, value);
129 Index(indexName(property), transaction).add(getByteArray(value), identifier); 129 break;
130 } else { 130 case TypeIndex::Remove:
131 Index(indexName(property), transaction).remove(getByteArray(value), identifier); 131 index.remove(key, value);
132 } 132 break;
133 }; 133 }
134 mIndexer.insert(property, indexer);
135 mProperties << property;
136} 134}
137 135
138template <> 136void TypeIndex::addProperty(const QByteArray &property)
139void TypeIndex::addProperty<bool>(const QByteArray &property)
140{ 137{
141 auto indexer = [this, property](bool add, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) { 138 auto indexer = [=](Action action, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) {
142 if (add) { 139 update(action, indexName(property), getByteArray(value), identifier, transaction);
143 Index(indexName(property), transaction).add(getByteArray(value), identifier);
144 } else {
145 Index(indexName(property), transaction).remove(getByteArray(value), identifier);
146 }
147 };
148 mIndexer.insert(property, indexer);
149 mProperties << property;
150}
151
152template <>
153void TypeIndex::addProperty<QString>(const QByteArray &property)
154{
155 auto indexer = [this, property](bool add, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) {
156 // SinkTraceCtx(mLogCtx) << "Indexing " << mType + ".index." + property << value.toByteArray();
157 if (add) {
158 Index(indexName(property), transaction).add(getByteArray(value), identifier);
159 } else {
160 Index(indexName(property), transaction).remove(getByteArray(value), identifier);
161 }
162 }; 140 };
163 mIndexer.insert(property, indexer); 141 mIndexer.insert(property, indexer);
164 mProperties << property; 142 mProperties << property;
165} 143}
166 144
167template <> 145template <>
168void TypeIndex::addProperty<QDateTime>(const QByteArray &property)
169{
170 auto indexer = [this, property](bool add, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) {
171 //SinkTraceCtx(mLogCtx) << "Indexing " << mType + ".index." + property << getByteArray(value);
172 if (add) {
173 Index(indexName(property), transaction).add(getByteArray(value), identifier);
174 } else {
175 Index(indexName(property), transaction).remove(getByteArray(value), identifier);
176 }
177 };
178 mIndexer.insert(property, indexer);
179 mProperties << property;
180}
181
182template <>
183void TypeIndex::addProperty<ApplicationDomain::Reference>(const QByteArray &property)
184{
185 addProperty<QByteArray>(property);
186}
187
188template <>
189void TypeIndex::addSortedProperty<QDateTime>(const QByteArray &property) 146void TypeIndex::addSortedProperty<QDateTime>(const QByteArray &property)
190{ 147{
191 auto indexer = [this, property](bool add, const QByteArray &identifier, const QVariant &value, 148 auto indexer = [=](Action action, const QByteArray &identifier, const QVariant &value,
192 Sink::Storage::DataStore::Transaction &transaction) { 149 Sink::Storage::DataStore::Transaction &transaction) {
193 const auto sortableDate = toSortableByteArray(value); 150 update(action, sortedIndexName(property), toSortableByteArray(value), identifier, transaction);
194 if (add) {
195 Index(sortedIndexName(property), transaction).add(sortableDate, identifier);
196 } else {
197 Index(sortedIndexName(property), transaction).remove(sortableDate, identifier);
198 }
199 }; 151 };
200 mSortIndexer.insert(property, indexer); 152 mSortIndexer.insert(property, indexer);
201 mSortedProperties << property; 153 mSortedProperties << property;
@@ -204,14 +156,10 @@ void TypeIndex::addSortedProperty<QDateTime>(const QByteArray &property)
204template <> 156template <>
205void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray &property, const QByteArray &sortProperty) 157void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray &property, const QByteArray &sortProperty)
206{ 158{
207 auto indexer = [=](bool add, const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction) { 159 auto indexer = [=](Action action, const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction) {
208 const auto date = sortValue.toDateTime(); 160 const auto date = sortValue.toDateTime();
209 const auto propertyValue = getByteArray(value); 161 const auto propertyValue = getByteArray(value);
210 if (add) { 162 update(action, indexName(property, sortProperty), propertyValue + toSortableByteArray(date), identifier, transaction);
211 Index(indexName(property, sortProperty), transaction).add(propertyValue + toSortableByteArray(date), identifier);
212 } else {
213 Index(indexName(property, sortProperty), transaction).remove(propertyValue + toSortableByteArray(date), identifier);
214 }
215 }; 163 };
216 mGroupedSortIndexer.insert(property + sortProperty, indexer); 164 mGroupedSortIndexer.insert(property + sortProperty, indexer);
217 mGroupedSortedProperties.insert(property, sortProperty); 165 mGroupedSortedProperties.insert(property, sortProperty);
@@ -227,7 +175,7 @@ template <>
227void TypeIndex::addSampledPeriodIndex<QDateTime, QDateTime>( 175void TypeIndex::addSampledPeriodIndex<QDateTime, QDateTime>(
228 const QByteArray &beginProperty, const QByteArray &endProperty) 176 const QByteArray &beginProperty, const QByteArray &endProperty)
229{ 177{
230 auto indexer = [=](bool add, const QByteArray &identifier, const QVariant &begin, 178 auto indexer = [=](Action action, const QByteArray &identifier, const QVariant &begin,
231 const QVariant &end, Sink::Storage::DataStore::Transaction &transaction) { 179 const QVariant &end, Sink::Storage::DataStore::Transaction &transaction) {
232 SinkTraceCtx(mLogCtx) << "Adding entity to sampled period index"; 180 SinkTraceCtx(mLogCtx) << "Adding entity to sampled period index";
233 const auto beginDate = begin.toDateTime(); 181 const auto beginDate = begin.toDateTime();
@@ -244,12 +192,13 @@ void TypeIndex::addSampledPeriodIndex<QDateTime, QDateTime>(
244 Index index(sampledPeriodIndexName(beginProperty, endProperty), transaction); 192 Index index(sampledPeriodIndexName(beginProperty, endProperty), transaction);
245 for (auto bucket = beginBucket; bucket <= endBucket; ++bucket) { 193 for (auto bucket = beginBucket; bucket <= endBucket; ++bucket) {
246 QByteArray bucketKey = padNumber(bucket); 194 QByteArray bucketKey = padNumber(bucket);
247 if (add) { 195 switch (action) {
248 SinkTraceCtx(mLogCtx) << "Adding entity to bucket:" << bucketKey; 196 case TypeIndex::Add:
249 index.add(bucketKey, identifier); 197 index.add(bucketKey, identifier);
250 } else { 198 break;
251 SinkTraceCtx(mLogCtx) << "Removing entity from bucket:" << bucketKey; 199 case TypeIndex::Remove:
252 index.remove(bucketKey, identifier); 200 index.remove(bucketKey, identifier);
201 break;
253 } 202 }
254 } 203 }
255 }; 204 };
@@ -258,37 +207,29 @@ void TypeIndex::addSampledPeriodIndex<QDateTime, QDateTime>(
258 mSampledPeriodIndexer.insert({ beginProperty, endProperty }, indexer); 207 mSampledPeriodIndexer.insert({ beginProperty, endProperty }, indexer);
259} 208}
260 209
261void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) 210void TypeIndex::updateIndex(Action action, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
262{ 211{
263 for (const auto &property : mProperties) { 212 for (const auto &property : mProperties) {
264 const auto value = entity.getProperty(property); 213 const auto value = entity.getProperty(property);
265 auto indexer = mIndexer.value(property); 214 auto indexer = mIndexer.value(property);
266 indexer(add, identifier, value, transaction); 215 indexer(action, identifier, value, transaction);
267 } 216 }
268 for (const auto &properties : mSampledPeriodProperties) { 217 for (const auto &properties : mSampledPeriodProperties) {
269 const auto beginValue = entity.getProperty(properties.first); 218 const auto beginValue = entity.getProperty(properties.first);
270 const auto endValue = entity.getProperty(properties.second); 219 const auto endValue = entity.getProperty(properties.second);
271 auto indexer = mSampledPeriodIndexer.value(properties); 220 auto indexer = mSampledPeriodIndexer.value(properties);
272 indexer(add, identifier, beginValue, endValue, transaction); 221 indexer(action, identifier, beginValue, endValue, transaction);
273 } 222 }
274 for (const auto &property : mSortedProperties) { 223 for (const auto &property : mSortedProperties) {
275 const auto value = entity.getProperty(property); 224 const auto value = entity.getProperty(property);
276 auto indexer = mSortIndexer.value(property); 225 auto indexer = mSortIndexer.value(property);
277 indexer(add, identifier, value, transaction); 226 indexer(action, identifier, value, transaction);
278 } 227 }
279 for (auto it = mGroupedSortedProperties.constBegin(); it != mGroupedSortedProperties.constEnd(); it++) { 228 for (auto it = mGroupedSortedProperties.constBegin(); it != mGroupedSortedProperties.constEnd(); it++) {
280 const auto value = entity.getProperty(it.key()); 229 const auto value = entity.getProperty(it.key());
281 const auto sortValue = entity.getProperty(it.value()); 230 const auto sortValue = entity.getProperty(it.value());
282 auto indexer = mGroupedSortIndexer.value(it.key() + it.value()); 231 auto indexer = mGroupedSortIndexer.value(it.key() + it.value());
283 indexer(add, identifier, value, sortValue, transaction); 232 indexer(action, identifier, value, sortValue, transaction);
284 }
285 for (const auto &indexer : mCustomIndexer) {
286 indexer->setup(this, &transaction, resourceInstanceId);
287 if (add) {
288 indexer->add(entity);
289 } else {
290 indexer->remove(entity);
291 }
292 } 233 }
293 234
294} 235}
@@ -309,12 +250,30 @@ void TypeIndex::abortTransaction()
309 250
310void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) 251void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
311{ 252{
312 updateIndex(true, identifier, entity, transaction, resourceInstanceId); 253 updateIndex(Add, identifier, entity, transaction, resourceInstanceId);
254 for (const auto &indexer : mCustomIndexer) {
255 indexer->setup(this, &transaction, resourceInstanceId);
256 indexer->add(entity);
257 }
258}
259
260void TypeIndex::modify(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, const Sink::ApplicationDomain::ApplicationDomainType &newEntity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
261{
262 updateIndex(Remove, identifier, oldEntity, transaction, resourceInstanceId);
263 updateIndex(Add, identifier, newEntity, transaction, resourceInstanceId);
264 for (const auto &indexer : mCustomIndexer) {
265 indexer->setup(this, &transaction, resourceInstanceId);
266 indexer->modify(oldEntity, newEntity);
267 }
313} 268}
314 269
315void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) 270void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
316{ 271{
317 updateIndex(false, identifier, entity, transaction, resourceInstanceId); 272 updateIndex(Remove, identifier, entity, transaction, resourceInstanceId);
273 for (const auto &indexer : mCustomIndexer) {
274 indexer->setup(this, &transaction, resourceInstanceId);
275 indexer->remove(entity);
276 }
318} 277}
319 278
320static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter, 279static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter,
@@ -540,11 +499,5 @@ QVector<QByteArray> TypeIndex::secondaryLookup<QByteArray>(const QByteArray &lef
540template <> 499template <>
541QVector<QByteArray> TypeIndex::secondaryLookup<QString>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value) 500QVector<QByteArray> TypeIndex::secondaryLookup<QString>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value)
542{ 501{
543 QVector<QByteArray> keys; 502 return secondaryLookup<QByteArray>(leftName, rightName, value);
544 Index index(indexName(leftName + rightName), *mTransaction);
545 const auto lookupKey = getByteArray(value);
546 index.lookup(
547 lookupKey, [&](const QByteArray &value) { keys << QByteArray{value.constData(), value.size()}; }, [=](const Index::Error &error) { SinkWarning() << "Lookup error in secondary index: " << error.message << value << lookupKey; });
548
549 return keys;
550} 503}
diff --git a/common/typeindex.h b/common/typeindex.h
index a8c0e10..4e5a555 100644
--- a/common/typeindex.h
+++ b/common/typeindex.h
@@ -36,8 +36,15 @@ class TypeIndex
36public: 36public:
37 TypeIndex(const QByteArray &type, const Sink::Log::Context &); 37 TypeIndex(const QByteArray &type, const Sink::Log::Context &);
38 38
39 template <typename T>
40 void addProperty(const QByteArray &property); 39 void addProperty(const QByteArray &property);
40
41 //FIXME We currently simply serialize based on the QVariant we get and ignore the index type
42 template <typename T>
43 void addProperty(const QByteArray &property)
44 {
45 addProperty(property);
46 }
47
41 template <typename T> 48 template <typename T>
42 void addSortedProperty(const QByteArray &property); 49 void addSortedProperty(const QByteArray &property);
43 template <typename T, typename S> 50 template <typename T, typename S>
@@ -83,6 +90,7 @@ public:
83 } 90 }
84 91
85 void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 92 void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
93 void modify(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, const Sink::ApplicationDomain::ApplicationDomainType &newEntity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
86 void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 94 void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
87 95
88 QVector<QByteArray> query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 96 QVector<QByteArray> query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
@@ -118,10 +126,14 @@ public:
118 void commitTransaction(); 126 void commitTransaction();
119 void abortTransaction(); 127 void abortTransaction();
120 128
129 enum Action {
130 Add,
131 Remove
132 };
121 133
122private: 134private:
123 friend class Sink::Storage::EntityStore; 135 friend class Sink::Storage::EntityStore;
124 void updateIndex(bool add, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 136 void updateIndex(Action action, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
125 QByteArray indexName(const QByteArray &property, const QByteArray &sortProperty = QByteArray()) const; 137 QByteArray indexName(const QByteArray &property, const QByteArray &sortProperty = QByteArray()) const;
126 QByteArray sortedIndexName(const QByteArray &property) const; 138 QByteArray sortedIndexName(const QByteArray &property) const;
127 QByteArray sampledPeriodIndexName(const QByteArray &rangeBeginProperty, const QByteArray &rangeEndProperty) const; 139 QByteArray sampledPeriodIndexName(const QByteArray &rangeBeginProperty, const QByteArray &rangeEndProperty) const;
@@ -135,8 +147,8 @@ private:
135 QSet<QPair<QByteArray, QByteArray>> mSampledPeriodProperties; 147 QSet<QPair<QByteArray, QByteArray>> mSampledPeriodProperties;
136 QList<Sink::Indexer::Ptr> mCustomIndexer; 148 QList<Sink::Indexer::Ptr> mCustomIndexer;
137 Sink::Storage::DataStore::Transaction *mTransaction; 149 Sink::Storage::DataStore::Transaction *mTransaction;
138 QHash<QByteArray, std::function<void(bool, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mIndexer; 150 QHash<QByteArray, std::function<void(Action, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mIndexer;
139 QHash<QByteArray, std::function<void(bool, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mSortIndexer; 151 QHash<QByteArray, std::function<void(Action, const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mSortIndexer;
140 QHash<QByteArray, std::function<void(bool, const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction)>> mGroupedSortIndexer; 152 QHash<QByteArray, std::function<void(Action, const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction)>> mGroupedSortIndexer;
141 QHash<QPair<QByteArray, QByteArray>, std::function<void(bool, const QByteArray &identifier, const QVariant &begin, const QVariant &end, Sink::Storage::DataStore::Transaction &transaction)>> mSampledPeriodIndexer; 153 QHash<QPair<QByteArray, QByteArray>, std::function<void(Action, const QByteArray &identifier, const QVariant &begin, const QVariant &end, Sink::Storage::DataStore::Transaction &transaction)>> mSampledPeriodIndexer;
142}; 154};