diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/CMakeLists.txt | 2 | ||||
-rw-r--r-- | common/domain/mail.cpp | 99 | ||||
-rw-r--r-- | common/indexer.cpp | 39 | ||||
-rw-r--r-- | common/indexer.h | 49 | ||||
-rw-r--r-- | common/mail/threadindexer.cpp | 140 | ||||
-rw-r--r-- | common/mail/threadindexer.h | 36 | ||||
-rw-r--r-- | common/typeindex.cpp | 8 | ||||
-rw-r--r-- | common/typeindex.h | 9 |
8 files changed, 286 insertions, 96 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e329d93..b5efb62 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt | |||
@@ -75,6 +75,8 @@ set(command_SRCS | |||
75 | specialpurposepreprocessor.cpp | 75 | specialpurposepreprocessor.cpp |
76 | datastorequery.cpp | 76 | datastorequery.cpp |
77 | storage/entitystore.cpp | 77 | storage/entitystore.cpp |
78 | indexer.cpp | ||
79 | mail/threadindexer.cpp | ||
78 | ${storage_SRCS}) | 80 | ${storage_SRCS}) |
79 | 81 | ||
80 | add_library(${PROJECT_NAME} SHARED ${command_SRCS}) | 82 | add_library(${PROJECT_NAME} SHARED ${command_SRCS}) |
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp index 9d58767..4b33f06 100644 --- a/common/domain/mail.cpp +++ b/common/domain/mail.cpp | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "entitybuffer.h" | 35 | #include "entitybuffer.h" |
36 | #include "datastorequery.h" | 36 | #include "datastorequery.h" |
37 | #include "entity_generated.h" | 37 | #include "entity_generated.h" |
38 | #include "mail/threadindexer.h" | ||
38 | 39 | ||
39 | #include "mail_generated.h" | 40 | #include "mail_generated.h" |
40 | 41 | ||
@@ -59,6 +60,8 @@ void TypeImplementation<Mail>::configureIndex(TypeIndex &index) | |||
59 | index.addProperty<QByteArray>(Mail::ParentMessageId::name); | 60 | index.addProperty<QByteArray>(Mail::ParentMessageId::name); |
60 | 61 | ||
61 | index.addProperty<Mail::MessageId>(); | 62 | index.addProperty<Mail::MessageId>(); |
63 | |||
64 | index.addSecondaryPropertyIndexer<Mail::MessageId, Mail::ThreadId, ThreadIndexer>(); | ||
62 | index.addSecondaryProperty<Mail::MessageId, Mail::ThreadId>(); | 65 | index.addSecondaryProperty<Mail::MessageId, Mail::ThreadId>(); |
63 | index.addSecondaryProperty<Mail::ThreadId, Mail::MessageId>(); | 66 | index.addSecondaryProperty<Mail::ThreadId, Mail::MessageId>(); |
64 | } | 67 | } |
@@ -74,102 +77,6 @@ static TypeIndex &getIndex() | |||
74 | return *index; | 77 | return *index; |
75 | } | 78 | } |
76 | 79 | ||
77 | static QString stripOffPrefixes(const QString &subject) | ||
78 | { | ||
79 | //TODO this hardcoded list is probably not good enough (especially regarding internationalization) | ||
80 | //TODO this whole routine, including internationalized re/fwd ... should go into some library. | ||
81 | //We'll require the same for generating reply/forward subjects in kube | ||
82 | static QStringList defaultReplyPrefixes = QStringList() << QLatin1String("Re\\s*:") | ||
83 | << QLatin1String("Re\\[\\d+\\]:") | ||
84 | << QLatin1String("Re\\d+:"); | ||
85 | |||
86 | static QStringList defaultForwardPrefixes = QStringList() << QLatin1String("Fwd:") | ||
87 | << QLatin1String("FW:"); | ||
88 | |||
89 | QStringList replyPrefixes; // = GlobalSettings::self()->replyPrefixes(); | ||
90 | if (replyPrefixes.isEmpty()) { | ||
91 | replyPrefixes = defaultReplyPrefixes; | ||
92 | } | ||
93 | |||
94 | QStringList forwardPrefixes; // = GlobalSettings::self()->forwardPrefixes(); | ||
95 | if (forwardPrefixes.isEmpty()) { | ||
96 | forwardPrefixes = defaultReplyPrefixes; | ||
97 | } | ||
98 | |||
99 | const QStringList prefixRegExps = replyPrefixes + forwardPrefixes; | ||
100 | |||
101 | // construct a big regexp that | ||
102 | // 1. is anchored to the beginning of str (sans whitespace) | ||
103 | // 2. matches at least one of the part regexps in prefixRegExps | ||
104 | const QString bigRegExp = QString::fromLatin1("^(?:\\s+|(?:%1))+\\s*").arg(prefixRegExps.join(QLatin1String(")|(?:"))); | ||
105 | |||
106 | static QString regExpPattern; | ||
107 | static QRegExp regExp; | ||
108 | |||
109 | regExp.setCaseSensitivity(Qt::CaseInsensitive); | ||
110 | if (regExpPattern != bigRegExp) { | ||
111 | // the prefixes have changed, so update the regexp | ||
112 | regExpPattern = bigRegExp; | ||
113 | regExp.setPattern(regExpPattern); | ||
114 | } | ||
115 | |||
116 | if(regExp.isValid()) { | ||
117 | QString tmp = subject; | ||
118 | if (regExp.indexIn( tmp ) == 0) { | ||
119 | return tmp.remove(0, regExp.matchedLength()); | ||
120 | } | ||
121 | } else { | ||
122 | SinkWarning() << "bigRegExp = \"" | ||
123 | << bigRegExp << "\"\n" | ||
124 | << "prefix regexp is invalid!"; | ||
125 | } | ||
126 | |||
127 | return subject; | ||
128 | } | ||
129 | |||
130 | |||
131 | static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction) | ||
132 | { | ||
133 | auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name); | ||
134 | auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name); | ||
135 | auto subject = bufferAdaptor.getProperty(Mail::Subject::name); | ||
136 | |||
137 | auto normalizedSubject = stripOffPrefixes(subject.toString()).toUtf8(); | ||
138 | |||
139 | QVector<QByteArray> thread; | ||
140 | |||
141 | //a child already registered our thread. | ||
142 | thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId, transaction); | ||
143 | |||
144 | //If parent is already available, add to thread of parent | ||
145 | if (thread.isEmpty() && parentMessageId.isValid()) { | ||
146 | thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(parentMessageId, transaction); | ||
147 | SinkTrace() << "Found parent"; | ||
148 | } | ||
149 | if (thread.isEmpty()) { | ||
150 | //Try to lookup the thread by subject: | ||
151 | thread = getIndex().secondaryLookup<Mail::Subject, Mail::ThreadId>(normalizedSubject, transaction); | ||
152 | if (thread.isEmpty()) { | ||
153 | SinkTrace() << "Created a new thread "; | ||
154 | thread << QUuid::createUuid().toByteArray(); | ||
155 | } else { | ||
156 | } | ||
157 | } | ||
158 | |||
159 | //We should have found the thread by now | ||
160 | if (!thread.isEmpty()) { | ||
161 | if (parentMessageId.isValid()) { | ||
162 | //Register parent with thread for when it becomes available | ||
163 | getIndex().index<Mail::MessageId, Mail::ThreadId>(parentMessageId, thread.first(), transaction); | ||
164 | } | ||
165 | getIndex().index<Mail::MessageId, Mail::ThreadId>(messageId, thread.first(), transaction); | ||
166 | getIndex().index<Mail::ThreadId, Mail::MessageId>(thread.first(), messageId, transaction); | ||
167 | getIndex().index<Mail::Subject, Mail::ThreadId>(normalizedSubject, thread.first(), transaction); | ||
168 | } else { | ||
169 | SinkWarning() << "Couldn't find a thread for: " << messageId; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplementation<Mail>::initializeReadPropertyMapper() | 80 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplementation<Mail>::initializeReadPropertyMapper() |
174 | { | 81 | { |
175 | auto propertyMapper = QSharedPointer<ReadPropertyMapper<Buffer> >::create(); | 82 | auto propertyMapper = QSharedPointer<ReadPropertyMapper<Buffer> >::create(); |
diff --git a/common/indexer.cpp b/common/indexer.cpp new file mode 100644 index 0000000..1b223b3 --- /dev/null +++ b/common/indexer.cpp | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | #include "indexer.h" | ||
20 | |||
21 | using namespace Sink; | ||
22 | |||
23 | void Indexer::setup(TypeIndex *index, Storage::DataStore::Transaction *transaction) | ||
24 | { | ||
25 | mTypeIndex = index; | ||
26 | mTransaction = transaction; | ||
27 | } | ||
28 | |||
29 | Storage::DataStore::Transaction &Indexer::transaction() | ||
30 | { | ||
31 | Q_ASSERT(mTransaction); | ||
32 | return *mTransaction; | ||
33 | } | ||
34 | |||
35 | TypeIndex &Indexer::index() | ||
36 | { | ||
37 | Q_ASSERT(mTypeIndex); | ||
38 | return *mTypeIndex; | ||
39 | } | ||
diff --git a/common/indexer.h b/common/indexer.h new file mode 100644 index 0000000..7e148d1 --- /dev/null +++ b/common/indexer.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | #pragma once | ||
20 | |||
21 | #include "storage.h" | ||
22 | #include <QSharedPointer> | ||
23 | |||
24 | class TypeIndex; | ||
25 | namespace Sink { | ||
26 | namespace ApplicationDomain { | ||
27 | class ApplicationDomainType; | ||
28 | } | ||
29 | |||
30 | class Indexer | ||
31 | { | ||
32 | public: | ||
33 | typedef QSharedPointer<Indexer> Ptr; | ||
34 | virtual void add(const ApplicationDomain::ApplicationDomainType &entity) = 0; | ||
35 | virtual void modify(const ApplicationDomain::ApplicationDomainType &old, const ApplicationDomain::ApplicationDomainType &entity) = 0; | ||
36 | virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) = 0; | ||
37 | |||
38 | protected: | ||
39 | Storage::DataStore::Transaction &transaction(); | ||
40 | TypeIndex &index(); | ||
41 | |||
42 | private: | ||
43 | friend class ::TypeIndex; | ||
44 | void setup(TypeIndex *, Storage::DataStore::Transaction *); | ||
45 | Storage::DataStore::Transaction *mTransaction; | ||
46 | TypeIndex *mTypeIndex; | ||
47 | }; | ||
48 | |||
49 | } | ||
diff --git a/common/mail/threadindexer.cpp b/common/mail/threadindexer.cpp new file mode 100644 index 0000000..4a18625 --- /dev/null +++ b/common/mail/threadindexer.cpp | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | #include "threadindexer.h" | ||
20 | |||
21 | #include "typeindex.h" | ||
22 | #include "log.h" | ||
23 | |||
24 | SINK_DEBUG_AREA("threadindex") | ||
25 | |||
26 | using namespace Sink; | ||
27 | using namespace Sink::ApplicationDomain; | ||
28 | |||
29 | static QString stripOffPrefixes(const QString &subject) | ||
30 | { | ||
31 | //TODO this hardcoded list is probably not good enough (especially regarding internationalization) | ||
32 | //TODO this whole routine, including internationalized re/fwd ... should go into some library. | ||
33 | //We'll require the same for generating reply/forward subjects in kube | ||
34 | static QStringList defaultReplyPrefixes = QStringList() << QLatin1String("Re\\s*:") | ||
35 | << QLatin1String("Re\\[\\d+\\]:") | ||
36 | << QLatin1String("Re\\d+:"); | ||
37 | |||
38 | static QStringList defaultForwardPrefixes = QStringList() << QLatin1String("Fwd:") | ||
39 | << QLatin1String("FW:"); | ||
40 | |||
41 | QStringList replyPrefixes; // = GlobalSettings::self()->replyPrefixes(); | ||
42 | if (replyPrefixes.isEmpty()) { | ||
43 | replyPrefixes = defaultReplyPrefixes; | ||
44 | } | ||
45 | |||
46 | QStringList forwardPrefixes; // = GlobalSettings::self()->forwardPrefixes(); | ||
47 | if (forwardPrefixes.isEmpty()) { | ||
48 | forwardPrefixes = defaultReplyPrefixes; | ||
49 | } | ||
50 | |||
51 | const QStringList prefixRegExps = replyPrefixes + forwardPrefixes; | ||
52 | |||
53 | // construct a big regexp that | ||
54 | // 1. is anchored to the beginning of str (sans whitespace) | ||
55 | // 2. matches at least one of the part regexps in prefixRegExps | ||
56 | const QString bigRegExp = QString::fromLatin1("^(?:\\s+|(?:%1))+\\s*").arg(prefixRegExps.join(QLatin1String(")|(?:"))); | ||
57 | |||
58 | static QString regExpPattern; | ||
59 | static QRegExp regExp; | ||
60 | |||
61 | regExp.setCaseSensitivity(Qt::CaseInsensitive); | ||
62 | if (regExpPattern != bigRegExp) { | ||
63 | // the prefixes have changed, so update the regexp | ||
64 | regExpPattern = bigRegExp; | ||
65 | regExp.setPattern(regExpPattern); | ||
66 | } | ||
67 | |||
68 | if(regExp.isValid()) { | ||
69 | QString tmp = subject; | ||
70 | if (regExp.indexIn( tmp ) == 0) { | ||
71 | return tmp.remove(0, regExp.matchedLength()); | ||
72 | } | ||
73 | } else { | ||
74 | SinkWarning() << "bigRegExp = \"" | ||
75 | << bigRegExp << "\"\n" | ||
76 | << "prefix regexp is invalid!"; | ||
77 | } | ||
78 | |||
79 | return subject; | ||
80 | } | ||
81 | |||
82 | |||
83 | void ThreadIndexer::updateThreadingIndex(const QByteArray &identifier, const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) | ||
84 | { | ||
85 | auto messageId = entity.getProperty(Mail::MessageId::name); | ||
86 | auto parentMessageId = entity.getProperty(Mail::ParentMessageId::name); | ||
87 | auto subject = entity.getProperty(Mail::Subject::name); | ||
88 | |||
89 | auto normalizedSubject = stripOffPrefixes(subject.toString()).toUtf8(); | ||
90 | |||
91 | QVector<QByteArray> thread; | ||
92 | |||
93 | //a child already registered our thread. | ||
94 | thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId, transaction); | ||
95 | |||
96 | //If parent is already available, add to thread of parent | ||
97 | if (thread.isEmpty() && parentMessageId.isValid()) { | ||
98 | thread = index().secondaryLookup<Mail::MessageId, Mail::ThreadId>(parentMessageId, transaction); | ||
99 | SinkTrace() << "Found parent"; | ||
100 | } | ||
101 | if (thread.isEmpty()) { | ||
102 | //Try to lookup the thread by subject: | ||
103 | thread = index().secondaryLookup<Mail::Subject, Mail::ThreadId>(normalizedSubject, transaction); | ||
104 | if (thread.isEmpty()) { | ||
105 | SinkTrace() << "Created a new thread "; | ||
106 | thread << QUuid::createUuid().toByteArray(); | ||
107 | } else { | ||
108 | } | ||
109 | } | ||
110 | |||
111 | //We should have found the thread by now | ||
112 | if (!thread.isEmpty()) { | ||
113 | if (parentMessageId.isValid()) { | ||
114 | //Register parent with thread for when it becomes available | ||
115 | index().index<Mail::MessageId, Mail::ThreadId>(parentMessageId, thread.first(), transaction); | ||
116 | } | ||
117 | index().index<Mail::MessageId, Mail::ThreadId>(messageId, thread.first(), transaction); | ||
118 | index().index<Mail::ThreadId, Mail::MessageId>(thread.first(), messageId, transaction); | ||
119 | index().index<Mail::Subject, Mail::ThreadId>(normalizedSubject, thread.first(), transaction); | ||
120 | } else { | ||
121 | SinkWarning() << "Couldn't find a thread for: " << messageId; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | |||
126 | void ThreadIndexer::add(const ApplicationDomain::ApplicationDomainType &entity) | ||
127 | { | ||
128 | updateThreadingIndex(entity.identifier(), entity, transaction()); | ||
129 | } | ||
130 | |||
131 | void ThreadIndexer::modify(const ApplicationDomain::ApplicationDomainType &old, const ApplicationDomain::ApplicationDomainType &entity) | ||
132 | { | ||
133 | |||
134 | } | ||
135 | |||
136 | void ThreadIndexer::remove(const ApplicationDomain::ApplicationDomainType &entity) | ||
137 | { | ||
138 | |||
139 | } | ||
140 | |||
diff --git a/common/mail/threadindexer.h b/common/mail/threadindexer.h new file mode 100644 index 0000000..064ae71 --- /dev/null +++ b/common/mail/threadindexer.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | #pragma once | ||
20 | |||
21 | #include "indexer.h" | ||
22 | |||
23 | namespace Sink { | ||
24 | |||
25 | class ThreadIndexer : public Indexer | ||
26 | { | ||
27 | public: | ||
28 | typedef QSharedPointer<ThreadIndexer> Ptr; | ||
29 | virtual void add(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE; | ||
30 | virtual void modify(const ApplicationDomain::ApplicationDomainType &old, const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE; | ||
31 | virtual void remove(const ApplicationDomain::ApplicationDomainType &entity) Q_DECL_OVERRIDE; | ||
32 | private: | ||
33 | void updateThreadingIndex(const QByteArray &identifier, const ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); | ||
34 | }; | ||
35 | |||
36 | } | ||
diff --git a/common/typeindex.cpp b/common/typeindex.cpp index 7920efc..8f5de4f 100644 --- a/common/typeindex.cpp +++ b/common/typeindex.cpp | |||
@@ -121,6 +121,10 @@ void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain: | |||
121 | auto indexer = mSortIndexer.value(it.key() + it.value()); | 121 | auto indexer = mSortIndexer.value(it.key() + it.value()); |
122 | indexer(identifier, value, sortValue, transaction); | 122 | indexer(identifier, value, sortValue, transaction); |
123 | } | 123 | } |
124 | for (const auto &indexer : mCustomIndexer) { | ||
125 | indexer->setup(this, &transaction); | ||
126 | indexer->add(entity); | ||
127 | } | ||
124 | } | 128 | } |
125 | 129 | ||
126 | void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) | 130 | void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) |
@@ -138,6 +142,10 @@ void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDoma | |||
138 | Index(indexName(it.key(), it.value()), transaction).remove(propertyValue.toByteArray() + sortValue.toByteArray(), identifier); | 142 | Index(indexName(it.key(), it.value()), transaction).remove(propertyValue.toByteArray() + sortValue.toByteArray(), identifier); |
139 | } | 143 | } |
140 | } | 144 | } |
145 | for (const auto &indexer : mCustomIndexer) { | ||
146 | indexer->setup(this, &transaction); | ||
147 | indexer->remove(entity); | ||
148 | } | ||
141 | } | 149 | } |
142 | 150 | ||
143 | static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter) | 151 | static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter) |
diff --git a/common/typeindex.h b/common/typeindex.h index e11e673..041e04a 100644 --- a/common/typeindex.h +++ b/common/typeindex.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "storage.h" | 22 | #include "storage.h" |
23 | #include "query.h" | 23 | #include "query.h" |
24 | #include "log.h" | 24 | #include "log.h" |
25 | #include "indexer.h" | ||
25 | #include <QByteArray> | 26 | #include <QByteArray> |
26 | 27 | ||
27 | class TypeIndex | 28 | class TypeIndex |
@@ -51,6 +52,13 @@ public: | |||
51 | { | 52 | { |
52 | mSecondaryProperties.insert(Left::name, Right::name); | 53 | mSecondaryProperties.insert(Left::name, Right::name); |
53 | } | 54 | } |
55 | |||
56 | template <typename Left, typename Right, typename CustomIndexer> | ||
57 | void addSecondaryPropertyIndexer() | ||
58 | { | ||
59 | mCustomIndexer << CustomIndexer::Ptr::create(); | ||
60 | } | ||
61 | |||
54 | void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); | 62 | void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); |
55 | void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); | 63 | void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); |
56 | 64 | ||
@@ -84,6 +92,7 @@ private: | |||
84 | QMap<QByteArray, QByteArray> mSortedProperties; | 92 | QMap<QByteArray, QByteArray> mSortedProperties; |
85 | //<Property, ResultProperty> | 93 | //<Property, ResultProperty> |
86 | QMap<QByteArray, QByteArray> mSecondaryProperties; | 94 | QMap<QByteArray, QByteArray> mSecondaryProperties; |
95 | QList<Sink::Indexer::Ptr> mCustomIndexer; | ||
87 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mIndexer; | 96 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)>> mIndexer; |
88 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction)>> mSortIndexer; | 97 | QHash<QByteArray, std::function<void(const QByteArray &identifier, const QVariant &value, const QVariant &sortValue, Sink::Storage::DataStore::Transaction &transaction)>> mSortIndexer; |
89 | }; | 98 | }; |