diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-04 08:25:18 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-04 08:25:18 +0200 |
commit | d6a01b3f82d626856001356c0875aa738a0346ac (patch) | |
tree | d77a6000e9d53be7844d72697496efa093b5f8ad /common/typeindex.cpp | |
parent | 48ba18c92eede967afc4cf8894a3b06fd6a3c179 (diff) | |
download | sink-d6a01b3f82d626856001356c0875aa738a0346ac.tar.gz sink-d6a01b3f82d626856001356c0875aa738a0346ac.zip |
Support for subqueries.
This allows us to match properties from a subquery.
Unfortunately this also means that DataStoreQuery needs access to all
type implementations to issue the subquery (for potentially another type).
Diffstat (limited to 'common/typeindex.cpp')
-rw-r--r-- | common/typeindex.cpp | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/common/typeindex.cpp b/common/typeindex.cpp index 272237c..816e7ee 100644 --- a/common/typeindex.cpp +++ b/common/typeindex.cpp | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | SINK_DEBUG_AREA("typeindex") | 25 | SINK_DEBUG_AREA("typeindex") |
26 | 26 | ||
27 | using namespace Sink; | ||
28 | |||
27 | static QByteArray getByteArray(const QVariant &value) | 29 | static QByteArray getByteArray(const QVariant &value) |
28 | { | 30 | { |
29 | if (value.type() == QVariant::DateTime) { | 31 | if (value.type() == QVariant::DateTime) { |
@@ -138,16 +140,32 @@ void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDoma | |||
138 | } | 140 | } |
139 | } | 141 | } |
140 | 142 | ||
143 | static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter) | ||
144 | { | ||
145 | QVector<QByteArray> keys; | ||
146 | QByteArrayList lookupKeys; | ||
147 | if (filter.comparator == Query::Comparator::Equals) { | ||
148 | lookupKeys << getByteArray(filter.value); | ||
149 | } else if (filter.comparator == Query::Comparator::In) { | ||
150 | lookupKeys = filter.value.value<QByteArrayList>(); | ||
151 | } else { | ||
152 | Q_ASSERT(false); | ||
153 | } | ||
154 | |||
155 | for (const auto &lookupKey : lookupKeys) { | ||
156 | index.lookup(lookupKey, [&](const QByteArray &value) { keys << value; }, | ||
157 | [lookupKey](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << lookupKey; }, true); | ||
158 | } | ||
159 | return keys; | ||
160 | } | ||
161 | |||
141 | QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::Transaction &transaction) | 162 | QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::Transaction &transaction) |
142 | { | 163 | { |
143 | QVector<QByteArray> keys; | 164 | QVector<QByteArray> keys; |
144 | for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { | 165 | for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { |
145 | if (query.hasFilter(it.key()) && query.sortProperty == it.value()) { | 166 | if (query.hasFilter(it.key()) && query.sortProperty == it.value()) { |
146 | Index index(indexName(it.key(), it.value()), transaction); | 167 | Index index(indexName(it.key(), it.value()), transaction); |
147 | const auto lookupKey = getByteArray(query.getFilter(it.key()).value); | 168 | keys << indexLookup(index, query.getFilter(it.key())); |
148 | SinkTrace() << "looking for " << lookupKey; | ||
149 | index.lookup(lookupKey, [&](const QByteArray &value) { keys << value; }, | ||
150 | [it](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << it.key() << it.value(); }, true); | ||
151 | appliedFilters << it.key(); | 169 | appliedFilters << it.key(); |
152 | appliedSorting = it.value(); | 170 | appliedSorting = it.value(); |
153 | SinkTrace() << "Index lookup on " << it.key() << it.value() << " found " << keys.size() << " keys."; | 171 | SinkTrace() << "Index lookup on " << it.key() << it.value() << " found " << keys.size() << " keys."; |
@@ -157,9 +175,7 @@ QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> | |||
157 | for (const auto &property : mProperties) { | 175 | for (const auto &property : mProperties) { |
158 | if (query.hasFilter(property)) { | 176 | if (query.hasFilter(property)) { |
159 | Index index(indexName(property), transaction); | 177 | Index index(indexName(property), transaction); |
160 | const auto lookupKey = getByteArray(query.getFilter(property).value); | 178 | keys << indexLookup(index, query.getFilter(property)); |
161 | index.lookup( | ||
162 | lookupKey, [&](const QByteArray &value) { keys << value; }, [property](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << property; }); | ||
163 | appliedFilters << property; | 179 | appliedFilters << property; |
164 | SinkTrace() << "Index lookup on " << property << " found " << keys.size() << " keys."; | 180 | SinkTrace() << "Index lookup on " << property << " found " << keys.size() << " keys."; |
165 | return keys; | 181 | return keys; |
@@ -177,7 +193,7 @@ QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant | |||
177 | Index index(indexName(property), transaction); | 193 | Index index(indexName(property), transaction); |
178 | const auto lookupKey = getByteArray(value); | 194 | const auto lookupKey = getByteArray(value); |
179 | index.lookup( | 195 | index.lookup( |
180 | lookupKey, [&](const QByteArray &value) { keys << value; }, [property](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << property; }); | 196 | lookupKey, [&, this](const QByteArray &value) { keys << value; }, [property, this](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << property; }); |
181 | SinkTrace() << "Index lookup on " << property << " found " << keys.size() << " keys."; | 197 | SinkTrace() << "Index lookup on " << property << " found " << keys.size() << " keys."; |
182 | return keys; | 198 | return keys; |
183 | } else if (mSecondaryProperties.contains(property)) { | 199 | } else if (mSecondaryProperties.contains(property)) { |
@@ -189,7 +205,7 @@ QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant | |||
189 | Index index(indexName(property + resultProperty), transaction); | 205 | Index index(indexName(property + resultProperty), transaction); |
190 | const auto lookupKey = getByteArray(value); | 206 | const auto lookupKey = getByteArray(value); |
191 | index.lookup( | 207 | index.lookup( |
192 | lookupKey, [&](const QByteArray &value) { secondaryKeys << value; }, [property](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << property; }); | 208 | lookupKey, [&, this](const QByteArray &value) { secondaryKeys << value; }, [property, this](const Index::Error &error) { SinkWarning() << "Error in index: " << error.message << property; }); |
193 | SinkTrace() << "Looked up secondary keys: " << secondaryKeys; | 209 | SinkTrace() << "Looked up secondary keys: " << secondaryKeys; |
194 | for (const auto &secondary : secondaryKeys) { | 210 | for (const auto &secondary : secondaryKeys) { |
195 | keys += lookup(resultProperty, secondary, transaction); | 211 | keys += lookup(resultProperty, secondary, transaction); |