diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-15 11:09:31 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-15 11:09:31 +0100 |
commit | d4b10a3de396eebc6c815093e9e1725ece270e9e (patch) | |
tree | baa77406ae79bedee9b74b836789c3370b1fa934 | |
parent | ec902175d53d371b03d8e754d917e196cd15aafa (diff) | |
download | sink-d4b10a3de396eebc6c815093e9e1725ece270e9e.tar.gz sink-d4b10a3de396eebc6c815093e9e1725ece270e9e.zip |
Working folder tree query
-rw-r--r-- | common/domain/folder.cpp | 28 | ||||
-rw-r--r-- | common/modelresult.h | 5 | ||||
-rw-r--r-- | examples/dummyresource/resourcefactory.cpp | 6 | ||||
-rw-r--r-- | tests/querytest.cpp | 98 |
4 files changed, 102 insertions, 35 deletions
diff --git a/common/domain/folder.cpp b/common/domain/folder.cpp index 50f73c2..82f6c1f 100644 --- a/common/domain/folder.cpp +++ b/common/domain/folder.cpp | |||
@@ -37,15 +37,43 @@ using namespace Akonadi2::ApplicationDomain; | |||
37 | ResultSet TypeImplementation<Folder>::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier, QSet<QByteArray> &appliedFilters, Akonadi2::Storage::Transaction &transaction) | 37 | ResultSet TypeImplementation<Folder>::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier, QSet<QByteArray> &appliedFilters, Akonadi2::Storage::Transaction &transaction) |
38 | { | 38 | { |
39 | QVector<QByteArray> keys; | 39 | QVector<QByteArray> keys; |
40 | if (query.propertyFilter.contains("parent")) { | ||
41 | Index index("folder.index.parent", transaction); | ||
42 | auto lookupKey = query.propertyFilter.value("parent").toByteArray(); | ||
43 | if (lookupKey.isEmpty()) { | ||
44 | lookupKey = "toplevel"; | ||
45 | } | ||
46 | index.lookup(lookupKey, [&](const QByteArray &value) { | ||
47 | keys << value; | ||
48 | }, | ||
49 | [](const Index::Error &error) { | ||
50 | Warning() << "Error in uid index: " << error.message; | ||
51 | }); | ||
52 | appliedFilters << "parent"; | ||
53 | } | ||
54 | Trace() << "Index lookup found " << keys.size() << " keys."; | ||
40 | return ResultSet(keys); | 55 | return ResultSet(keys); |
41 | } | 56 | } |
42 | 57 | ||
43 | void TypeImplementation<Folder>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) | 58 | void TypeImplementation<Folder>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) |
44 | { | 59 | { |
60 | const auto parent = bufferAdaptor.getProperty("parent"); | ||
61 | Trace() << "indexing " << identifier << " with parent " << parent.toByteArray(); | ||
62 | if (parent.isValid()) { | ||
63 | Index("folder.index.parent", transaction).add(parent.toByteArray(), identifier); | ||
64 | } else { | ||
65 | Index("folder.index.parent", transaction).add("toplevel", identifier); | ||
66 | } | ||
45 | } | 67 | } |
46 | 68 | ||
47 | void TypeImplementation<Folder>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) | 69 | void TypeImplementation<Folder>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) |
48 | { | 70 | { |
71 | const auto parent = bufferAdaptor.getProperty("parent"); | ||
72 | if (parent.isValid()) { | ||
73 | Index("folder.index.parent", transaction).remove(parent.toByteArray(), identifier); | ||
74 | } else { | ||
75 | Index("folder.index.parent", transaction).remove("toplevel", identifier); | ||
76 | } | ||
49 | } | 77 | } |
50 | 78 | ||
51 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Folder>::Buffer> > TypeImplementation<Folder>::initializeReadPropertyMapper() | 79 | QSharedPointer<ReadPropertyMapper<TypeImplementation<Folder>::Buffer> > TypeImplementation<Folder>::initializeReadPropertyMapper() |
diff --git a/common/modelresult.h b/common/modelresult.h index eabb868..8ca6daa 100644 --- a/common/modelresult.h +++ b/common/modelresult.h | |||
@@ -116,7 +116,7 @@ public: | |||
116 | return; | 116 | return; |
117 | } | 117 | } |
118 | auto parent = createIndexFromId(id); | 118 | auto parent = createIndexFromId(id); |
119 | qDebug() << "Added entity " << childId; | 119 | qDebug() << "Added entity " << childId << value->identifier(); |
120 | const auto keys = mTree[id]; | 120 | const auto keys = mTree[id]; |
121 | int index = 0; | 121 | int index = 0; |
122 | for (; index < keys.size(); index++) { | 122 | for (; index < keys.size(); index++) { |
@@ -166,7 +166,6 @@ public: | |||
166 | 166 | ||
167 | void fetchEntities(const QModelIndex &parent) | 167 | void fetchEntities(const QModelIndex &parent) |
168 | { | 168 | { |
169 | qDebug() << "Fetching entities"; | ||
170 | const auto id = getIdentifier(parent); | 169 | const auto id = getIdentifier(parent); |
171 | mEntityChildrenFetched[id] = true; | 170 | mEntityChildrenFetched[id] = true; |
172 | QByteArray parentIdentifier; | 171 | QByteArray parentIdentifier; |
@@ -178,7 +177,7 @@ public: | |||
178 | Q_ASSERT(object); | 177 | Q_ASSERT(object); |
179 | parentIdentifier = object->identifier(); | 178 | parentIdentifier = object->identifier(); |
180 | } | 179 | } |
181 | Trace() << "Loading entities"; | 180 | Trace() << "Loading child entities of: " << parentIdentifier; |
182 | loadEntities(parentIdentifier); | 181 | loadEntities(parentIdentifier); |
183 | } | 182 | } |
184 | 183 | ||
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index edb3b42..bed1d71 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp | |||
@@ -114,6 +114,12 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared | |||
114 | mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, QVector<Akonadi2::Preprocessor*>() << mailIndexer); | 114 | mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, QVector<Akonadi2::Preprocessor*>() << mailIndexer); |
115 | mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); | 115 | mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); |
116 | } | 116 | } |
117 | { | ||
118 | auto folderFactory = QSharedPointer<DummyFolderAdaptorFactory>::create(); | ||
119 | auto folderIndexer = new IndexUpdater<Akonadi2::ApplicationDomain::Folder>("folder.index.rid", ENTITY_TYPE_FOLDER); | ||
120 | mPipeline->setPreprocessors(ENTITY_TYPE_FOLDER, QVector<Akonadi2::Preprocessor*>() << folderIndexer); | ||
121 | mPipeline->setAdaptorFactory(ENTITY_TYPE_FOLDER, folderFactory); | ||
122 | } | ||
117 | } | 123 | } |
118 | 124 | ||
119 | void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) | 125 | void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) |
diff --git a/tests/querytest.cpp b/tests/querytest.cpp index e4f1d0d..677dbac 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp | |||
@@ -90,38 +90,72 @@ private Q_SLOTS: | |||
90 | QTRY_COMPARE(model->rowCount(), 1); | 90 | QTRY_COMPARE(model->rowCount(), 1); |
91 | } | 91 | } |
92 | 92 | ||
93 | // void testTree() | 93 | void testFolder() |
94 | // { | 94 | { |
95 | // //Setup | 95 | //Setup |
96 | // { | 96 | { |
97 | // Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); | 97 | Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); |
98 | // Akonadi2::Store::create<Akonadi2::ApplicationDomain::Folder>(folder).exec().waitForFinished(); | 98 | Akonadi2::Store::create<Akonadi2::ApplicationDomain::Folder>(folder).exec().waitForFinished(); |
99 | // | 99 | } |
100 | // Akonadi2::Query query; | 100 | |
101 | // query.resources << "org.kde.dummy.instance1"; | 101 | //Test |
102 | // query.syncOnDemand = false; | 102 | Akonadi2::Query query; |
103 | // query.processAll = true; | 103 | query.resources << "org.kde.dummy.instance1"; |
104 | // | 104 | query.syncOnDemand = false; |
105 | // auto model = new ModelResult<Akonadi2::ApplicationDomain::Folder>(query, QList<QByteArray>() << "summary" << "uid"); | 105 | query.processAll = false; |
106 | // QTRY_COMPARE(model->rowCount(), 1); | 106 | query.liveQuery = true; |
107 | // | 107 | |
108 | // auto folderEntity = model->index(0, 0).data(ModelResult<Akonadi2::ApplicationDomain::Folder>::DomainObjectRole).value<Akonadi2::ApplicationDomain::Folder>(); | 108 | //We fetch before the data is available and rely on the live query mechanism to deliver the actual data |
109 | // | 109 | auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query); |
110 | // Akonadi2::ApplicationDomain::Folder subfolder("org.kde.dummy.instance1"); | 110 | model->fetchMore(QModelIndex()); |
111 | // subfolder.setProperty("parent", folderEntity.identifier()); | 111 | QTRY_COMPARE(model->rowCount(), 1); |
112 | // Akonadi2::Store::create<Akonadi2::ApplicationDomain::Folder>(subfolder).exec().waitForFinished(); | 112 | auto folderEntity = model->index(0, 0).data(ModelResult<Akonadi2::ApplicationDomain::Folder, Akonadi2::ApplicationDomain::Folder::Ptr>::DomainObjectRole).value<Akonadi2::ApplicationDomain::Folder::Ptr>(); |
113 | // } | 113 | QVERIFY(!folderEntity->identifier().isEmpty()); |
114 | // | 114 | } |
115 | // //Test | 115 | |
116 | // Akonadi2::Query query; | 116 | void testFolderTree() |
117 | // query.resources << "org.kde.dummy.instance1"; | 117 | { |
118 | // query.syncOnDemand = false; | 118 | //Setup |
119 | // query.processAll = true; | 119 | { |
120 | // | 120 | Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); |
121 | // auto model = new ModelResult<Akonadi2::ApplicationDomain::Folder>(query, QList<QByteArray>() << "summary" << "uid"); | 121 | Akonadi2::Store::create<Akonadi2::ApplicationDomain::Folder>(folder).exec().waitForFinished(); |
122 | // QTRY_COMPARE(model->rowCount(), 1); | 122 | |
123 | // QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); | 123 | Akonadi2::Query query; |
124 | // } | 124 | query.resources << "org.kde.dummy.instance1"; |
125 | query.syncOnDemand = false; | ||
126 | query.processAll = true; | ||
127 | |||
128 | //Ensure all local data is processed | ||
129 | Akonadi2::Store::synchronize(query).exec().waitForFinished(); | ||
130 | |||
131 | auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query); | ||
132 | model->fetchMore(QModelIndex()); | ||
133 | QTRY_COMPARE(model->rowCount(), 1); | ||
134 | |||
135 | auto folderEntity = model->index(0, 0).data(ModelResult<Akonadi2::ApplicationDomain::Folder, Akonadi2::ApplicationDomain::Folder::Ptr>::DomainObjectRole).value<Akonadi2::ApplicationDomain::Folder::Ptr>(); | ||
136 | QVERIFY(!folderEntity->identifier().isEmpty()); | ||
137 | |||
138 | Akonadi2::ApplicationDomain::Folder subfolder("org.kde.dummy.instance1"); | ||
139 | subfolder.setProperty("parent", folderEntity->identifier()); | ||
140 | Akonadi2::Store::create<Akonadi2::ApplicationDomain::Folder>(subfolder).exec().waitForFinished(); | ||
141 | } | ||
142 | |||
143 | //Test | ||
144 | Akonadi2::Query query; | ||
145 | query.resources << "org.kde.dummy.instance1"; | ||
146 | query.syncOnDemand = false; | ||
147 | query.processAll = true; | ||
148 | |||
149 | //Ensure all local data is processed | ||
150 | Akonadi2::Store::synchronize(query).exec().waitForFinished(); | ||
151 | |||
152 | //We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data | ||
153 | auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query); | ||
154 | model->fetchMore(QModelIndex()); | ||
155 | QTRY_COMPARE(model->rowCount(), 1); | ||
156 | model->fetchMore(model->index(0, 0)); | ||
157 | QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); | ||
158 | } | ||
125 | }; | 159 | }; |
126 | 160 | ||
127 | QTEST_MAIN(QueryTest) | 161 | QTEST_MAIN(QueryTest) |