diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-06-17 00:57:24 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-06-17 00:57:24 +0200 |
commit | 4eb94786232aee936cd6371824764705c9359538 (patch) | |
tree | c5347ae86c4088676f78d59d647c9a30e636b53b /examples/dummyresource/facade.cpp | |
parent | 7819a02582fea02cd6da56aa4526492d281df07a (diff) | |
download | sink-4eb94786232aee936cd6371824764705c9359538.tar.gz sink-4eb94786232aee936cd6371824764705c9359538.zip |
An almost generic query implementation.
With equality filter on arbitrary properties as a bonus.
Diffstat (limited to 'examples/dummyresource/facade.cpp')
-rw-r--r-- | examples/dummyresource/facade.cpp | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp index 9d4f64b..002b836 100644 --- a/examples/dummyresource/facade.cpp +++ b/examples/dummyresource/facade.cpp | |||
@@ -74,7 +74,7 @@ static void scan(const QSharedPointer<Akonadi2::Storage> &storage, const QByteAr | |||
74 | }); | 74 | }); |
75 | } | 75 | } |
76 | 76 | ||
77 | void DummyResourceFacade::readValue(const QSharedPointer<Akonadi2::Storage> &storage, const QByteArray &key, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback) | 77 | static void readValue(const QSharedPointer<Akonadi2::Storage> &storage, const QByteArray &key, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback, const QSharedPointer<DomainTypeAdaptorFactoryInterface<Akonadi2::ApplicationDomain::Event> > &adaptorFactory) |
78 | { | 78 | { |
79 | scan(storage, key, [=](const QByteArray &key, const Akonadi2::Entity &entity, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local, Akonadi2::Metadata const *metadataBuffer) { | 79 | scan(storage, key, [=](const QByteArray &key, const Akonadi2::Entity &entity, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local, Akonadi2::Metadata const *metadataBuffer) { |
80 | qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; | 80 | qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; |
@@ -82,19 +82,21 @@ void DummyResourceFacade::readValue(const QSharedPointer<Akonadi2::Storage> &sto | |||
82 | //Not i.e. for tags that are stored as flags in each entity of an imap store. | 82 | //Not i.e. for tags that are stored as flags in each entity of an imap store. |
83 | //additional properties that don't have a 1:1 mapping (such as separately stored tags), | 83 | //additional properties that don't have a 1:1 mapping (such as separately stored tags), |
84 | //could be added to the adaptor | 84 | //could be added to the adaptor |
85 | auto event = QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("org.kde.dummy.instance1", key, revision, mDomainTypeAdaptorFactory->createAdaptor(entity)); | 85 | auto event = QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("org.kde.dummy.instance1", key, revision, adaptorFactory->createAdaptor(entity)); |
86 | resultCallback(event); | 86 | resultCallback(event); |
87 | return true; | 87 | return true; |
88 | }); | 88 | }); |
89 | } | 89 | } |
90 | 90 | ||
91 | static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::Storage> &storage) | 91 | static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::Storage> &storage, const QSharedPointer<DomainTypeAdaptorFactoryInterface<Akonadi2::ApplicationDomain::Event> > &adaptorFactory) |
92 | { | 92 | { |
93 | QSet<QByteArray> appliedFilters; | 93 | QSet<QByteArray> appliedFilters; |
94 | ResultSet resultSet = Akonadi2::ApplicationDomain::TypeImplementation<Akonadi2::ApplicationDomain::Event>::queryIndexes(query, "org.kde.dummy.instance1", appliedFilters); | 94 | ResultSet resultSet = Akonadi2::ApplicationDomain::TypeImplementation<Akonadi2::ApplicationDomain::Event>::queryIndexes(query, "org.kde.dummy.instance1", appliedFilters); |
95 | const auto remainingFilters = query.propertyFilter.keys().toSet() - appliedFilters; | 95 | const auto remainingFilters = query.propertyFilter.keys().toSet() - appliedFilters; |
96 | 96 | ||
97 | if (resultSet.isEmpty()) { | 97 | //We do a full scan if there were no indexes available to create the initial set. |
98 | //TODO use a result set with an iterator, to read values on demand | ||
99 | if (appliedFilters.isEmpty()) { | ||
98 | QVector<QByteArray> keys; | 100 | QVector<QByteArray> keys; |
99 | scan(storage, QByteArray(), [=, &keys](const QByteArray &key, const Akonadi2::Entity &entity, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local, Akonadi2::Metadata const *metadataBuffer) { | 101 | scan(storage, QByteArray(), [=, &keys](const QByteArray &key, const Akonadi2::Entity &entity, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local, Akonadi2::Metadata const *metadataBuffer) { |
100 | keys << key; | 102 | keys << key; |
@@ -103,9 +105,34 @@ static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer | |||
103 | resultSet = ResultSet(keys); | 105 | resultSet = ResultSet(keys); |
104 | } | 106 | } |
105 | 107 | ||
106 | return resultSet; | 108 | auto filter = [remainingFilters, query](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &event) -> bool { |
109 | for (const auto &filterProperty : remainingFilters) { | ||
110 | //TODO implement other comparison operators than equality | ||
111 | if (event->getProperty(filterProperty) != query.propertyFilter.value(filterProperty)) { | ||
112 | return false; | ||
113 | } | ||
114 | } | ||
115 | return true; | ||
116 | }; | ||
117 | |||
118 | auto resultSetPtr = QSharedPointer<ResultSet>::create(resultSet); | ||
119 | |||
120 | //Read through the source values and return whatever matches the filter | ||
121 | std::function<bool(std::function<void(const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &)>)> generator = [resultSetPtr, storage, adaptorFactory, filter](std::function<void(const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &)> callback) -> bool { | ||
122 | while (resultSetPtr->next()) { | ||
123 | Akonadi2::ApplicationDomain::Event::Ptr event; | ||
124 | readValue(storage, resultSetPtr->id(), [filter, callback](const Akonadi2::ApplicationDomain::Event::Ptr &event) { | ||
125 | if (filter(event)) { | ||
126 | callback(event); | ||
127 | } | ||
128 | }, adaptorFactory); | ||
129 | } | ||
130 | return false; | ||
131 | }; | ||
132 | return ResultSet(generator); | ||
107 | } | 133 | } |
108 | 134 | ||
135 | //TODO generalize | ||
109 | KAsync::Job<qint64> DummyResourceFacade::load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr> > &resultProvider, qint64 oldRevision, qint64 newRevision) | 136 | KAsync::Job<qint64> DummyResourceFacade::load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr> > &resultProvider, qint64 oldRevision, qint64 newRevision) |
110 | { | 137 | { |
111 | return KAsync::start<qint64>([=]() { | 138 | return KAsync::start<qint64>([=]() { |
@@ -118,17 +145,14 @@ KAsync::Job<qint64> DummyResourceFacade::load(const Akonadi2::Query &query, cons | |||
118 | //TODO start transaction on indexes as well | 145 | //TODO start transaction on indexes as well |
119 | const qint64 revision = storage->maxRevision(); | 146 | const qint64 revision = storage->maxRevision(); |
120 | 147 | ||
121 | auto resultSet = getResultSet(query, storage); | 148 | auto resultSet = getResultSet(query, storage, mDomainTypeAdaptorFactory); |
122 | 149 | ||
123 | // TODO only emit changes and don't replace everything | 150 | // TODO only emit changes and don't replace everything |
124 | resultProvider->clear(); | 151 | resultProvider->clear(); |
125 | auto resultCallback = std::bind(&Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr>::add, resultProvider, std::placeholders::_1); | 152 | auto resultCallback = std::bind(&Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr>::add, resultProvider, std::placeholders::_1); |
126 | while (resultSet.next()) { | 153 | while(resultSet.next([resultCallback](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &value) -> bool { |
127 | readValue(storage, resultSet.id(), [resultCallback](const Akonadi2::ApplicationDomain::Event::Ptr &event) { | 154 | resultCallback(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<Akonadi2::ApplicationDomain::Event>(value)); |
128 | //We create an in-memory copy because the result provider will store the value, and the result we get back is only valid during the callback | 155 | })){}; |
129 | resultCallback(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<Akonadi2::ApplicationDomain::Event>(event)); | ||
130 | }); | ||
131 | } | ||
132 | storage->abortTransaction(); | 156 | storage->abortTransaction(); |
133 | return revision; | 157 | return revision; |
134 | }); | 158 | }); |