diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/index.cpp | 8 | ||||
-rw-r--r-- | common/index.h | 1 | ||||
-rw-r--r-- | common/indexer.h | 5 | ||||
-rw-r--r-- | common/mail/threadindexer.cpp | 22 | ||||
-rw-r--r-- | common/mail/threadindexer.h | 3 | ||||
-rw-r--r-- | common/storage/entitystore.cpp | 3 | ||||
-rw-r--r-- | common/typeindex.cpp | 151 | ||||
-rw-r--r-- | common/typeindex.h | 24 |
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 | ||
5 | Index::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 | |||
5 | Index::Index(const QString &storageRoot, const QString &name, Sink::Storage::DataStore::AccessMode mode) | 13 | Index::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 @@ | |||
25 | using namespace Sink; | 25 | using namespace Sink; |
26 | using namespace Sink::ApplicationDomain; | 26 | using namespace Sink::ApplicationDomain; |
27 | 27 | ||
28 | void ThreadIndexer::updateThreadingIndex(const QByteArray &identifier, const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) | 28 | void 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 | ||
96 | void ThreadIndexer::add(const ApplicationDomain::ApplicationDomainType &entity) | 97 | void ThreadIndexer::add(const ApplicationDomain::ApplicationDomainType &entity) |
97 | { | 98 | { |
98 | updateThreadingIndex(entity.identifier(), entity, transaction()); | 99 | updateThreadingIndex(entity, transaction()); |
100 | } | ||
101 | |||
102 | void 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 | ||
101 | void ThreadIndexer::remove(const ApplicationDomain::ApplicationDomainType &entity) | 108 | void 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 | |||
27 | public: | 27 | public: |
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(); |
32 | private: | 33 | private: |
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 | ||
123 | template <> | 123 | static void update(TypeIndex::Action action, const QByteArray &indexName, const QByteArray &key, const QByteArray &value, Sink::Storage::DataStore::Transaction &transaction) |
124 | void 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 | ||
138 | template <> | 136 | void TypeIndex::addProperty(const QByteArray &property) |
139 | void 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 | |||
152 | template <> | ||
153 | void 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 | ||
167 | template <> | 145 | template <> |
168 | void 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 | |||
182 | template <> | ||
183 | void TypeIndex::addProperty<ApplicationDomain::Reference>(const QByteArray &property) | ||
184 | { | ||
185 | addProperty<QByteArray>(property); | ||
186 | } | ||
187 | |||
188 | template <> | ||
189 | void TypeIndex::addSortedProperty<QDateTime>(const QByteArray &property) | 146 | void 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) | |||
204 | template <> | 156 | template <> |
205 | void TypeIndex::addPropertyWithSorting<QByteArray, QDateTime>(const QByteArray &property, const QByteArray &sortProperty) | 157 | void 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 <> | |||
227 | void TypeIndex::addSampledPeriodIndex<QDateTime, QDateTime>( | 175 | void 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 | ||
261 | void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) | 210 | void 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 | ||
310 | void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) | 251 | void 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 | |||
260 | void 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 | ||
315 | void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) | 270 | void 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 | ||
320 | static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter, | 279 | static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter, |
@@ -540,11 +499,5 @@ QVector<QByteArray> TypeIndex::secondaryLookup<QByteArray>(const QByteArray &lef | |||
540 | template <> | 499 | template <> |
541 | QVector<QByteArray> TypeIndex::secondaryLookup<QString>(const QByteArray &leftName, const QByteArray &rightName, const QVariant &value) | 500 | QVector<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 | |||
36 | public: | 36 | public: |
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 | ||
122 | private: | 134 | private: |
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 | }; |