diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2014-12-11 00:44:44 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2014-12-11 00:44:44 +0100 |
commit | fdd74a41929b4343902f1d1dfcd5116534a79f4f (patch) | |
tree | 312524c2f1a8431742d6a2575dc3c497b66cc795 | |
parent | fbd35044dc343dbd17d475b860c6019077271efc (diff) | |
download | sink-fdd74a41929b4343902f1d1dfcd5116534a79f4f.tar.gz sink-fdd74a41929b4343902f1d1dfcd5116534a79f4f.zip |
Dummyresourcefacade test.
Huzaa, we can read a value!
-rw-r--r-- | client/CMakeLists.txt | 9 | ||||
-rw-r--r-- | client/clientapi.h | 10 | ||||
-rw-r--r-- | dummyresource/CMakeLists.txt | 2 | ||||
-rw-r--r-- | dummyresource/facade.cpp | 52 | ||||
-rw-r--r-- | dummyresource/facade.h | 2 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tests/dummyresourcefacadetest.cpp | 73 |
7 files changed, 134 insertions, 18 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index a0ebe3a..8001d5f 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt | |||
@@ -3,12 +3,15 @@ project(akonadi2_client) | |||
3 | include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) | 3 | include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) |
4 | 4 | ||
5 | set(akonadi2client_SRCS | 5 | set(akonadi2client_SRCS |
6 | main.cpp | ||
7 | resourceaccess.cpp | 6 | resourceaccess.cpp |
8 | ) | 7 | ) |
9 | 8 | ||
10 | add_executable(${PROJECT_NAME} ${akonadi2client_SRCS}) | 9 | add_library(${PROJECT_NAME}_lib ${akonadi2client_SRCS}) |
11 | target_link_libraries(${PROJECT_NAME} akonadi2common) | 10 | target_link_libraries(${PROJECT_NAME}_lib akonadi2common) |
11 | qt5_use_modules(${PROJECT_NAME}_lib Widgets Network) | ||
12 | |||
13 | add_executable(${PROJECT_NAME} main.cpp) | ||
14 | target_link_libraries(${PROJECT_NAME} akonadi2_client_lib akonadi2common) | ||
12 | qt5_use_modules(${PROJECT_NAME} Widgets Network) | 15 | qt5_use_modules(${PROJECT_NAME} Widgets Network) |
13 | install(TARGETS ${PROJECT_NAME} DESTINATION bin) | 16 | install(TARGETS ${PROJECT_NAME} DESTINATION bin) |
14 | 17 | ||
diff --git a/client/clientapi.h b/client/clientapi.h index 59efe32..592fa48 100644 --- a/client/clientapi.h +++ b/client/clientapi.h | |||
@@ -185,8 +185,14 @@ using namespace async; | |||
185 | class Query | 185 | class Query |
186 | { | 186 | { |
187 | public: | 187 | public: |
188 | //Resources to search | 188 | //Could also be a propertyFilter |
189 | QSet<QString> resources; | 189 | QStringList resources; |
190 | //Could also be a propertyFilter | ||
191 | QStringList ids; | ||
192 | //Filters to apply | ||
193 | QHash<QString, QVariant> propertyFilter; | ||
194 | //Properties to retrieve | ||
195 | QSet<QString> requestedProperties; | ||
190 | }; | 196 | }; |
191 | 197 | ||
192 | 198 | ||
diff --git a/dummyresource/CMakeLists.txt b/dummyresource/CMakeLists.txt index e814f41..8fa2eee 100644 --- a/dummyresource/CMakeLists.txt +++ b/dummyresource/CMakeLists.txt | |||
@@ -6,7 +6,7 @@ generate_flatbuffers(dummycalendar) | |||
6 | 6 | ||
7 | #Client plugin | 7 | #Client plugin |
8 | add_library(${PROJECT_NAME}_facade SHARED facade.cpp) | 8 | add_library(${PROJECT_NAME}_facade SHARED facade.cpp) |
9 | target_link_libraries(${PROJECT_NAME}_facade akonadi2common) | 9 | target_link_libraries(${PROJECT_NAME}_facade akonadi2common akonadi2_client_lib) |
10 | qt5_use_modules(${PROJECT_NAME}_facade Widgets Network) | 10 | qt5_use_modules(${PROJECT_NAME}_facade Widgets Network) |
11 | #install(TARGETS ${PROJECT_NAME}_facade DESTINATION bin) | 11 | #install(TARGETS ${PROJECT_NAME}_facade DESTINATION bin) |
12 | 12 | ||
diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp index bfe1de4..44056f8 100644 --- a/dummyresource/facade.cpp +++ b/dummyresource/facade.cpp | |||
@@ -10,8 +10,7 @@ using namespace flatbuffers; | |||
10 | 10 | ||
11 | DummyResourceFacade::DummyResourceFacade() | 11 | DummyResourceFacade::DummyResourceFacade() |
12 | : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(), | 12 | : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(), |
13 | mResourceAccess(new ResourceAccess("dummyresource")), | 13 | mResourceAccess(/* new ResourceAccess("dummyresource") */) |
14 | mStorage(new Storage(Akonadi2::Store::storageLocation(), "dummyresource")) | ||
15 | { | 14 | { |
16 | // connect(mResourceAccess.data(), &ResourceAccess::ready, this, onReadyChanged); | 15 | // connect(mResourceAccess.data(), &ResourceAccess::ready, this, onReadyChanged); |
17 | } | 16 | } |
@@ -47,7 +46,10 @@ void DummyResourceFacade::remove(const Akonadi2::Domain::Event &domainObject) | |||
47 | //=> perhaps do heap allocate and use smart pointer? | 46 | //=> perhaps do heap allocate and use smart pointer? |
48 | class DummyEventAdaptor : public Akonadi2::Domain::Event { | 47 | class DummyEventAdaptor : public Akonadi2::Domain::Event { |
49 | public: | 48 | public: |
50 | DummyEventAdaptor(const QString &resource, const QString &identifier, qint64 revision):Akonadi2::Domain::Event(resource, identifier, revision){}; | 49 | DummyEventAdaptor(const QString &resource, const QString &identifier, qint64 revision) |
50 | :Akonadi2::Domain::Event(resource, identifier, revision) | ||
51 | { | ||
52 | } | ||
51 | 53 | ||
52 | //TODO | 54 | //TODO |
53 | // void setProperty(const QString &key, const QVariant &value) | 55 | // void setProperty(const QString &key, const QVariant &value) |
@@ -75,15 +77,45 @@ public: | |||
75 | void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback) | 77 | void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback) |
76 | { | 78 | { |
77 | qDebug() << "load called"; | 79 | qDebug() << "load called"; |
78 | //TODO only read values matching the query | ||
79 | auto storage = QSharedPointer<Storage>::create(Akonadi2::Store::storageLocation(), "dummyresource"); | 80 | auto storage = QSharedPointer<Storage>::create(Akonadi2::Store::storageLocation(), "dummyresource"); |
80 | storage->read("", [resultCallback, storage](void *data, int size) -> bool { | 81 | |
82 | //Compose some functions to make query matching fast. | ||
83 | //This way we can process the query once, and convert all values into something that can be compared quickly | ||
84 | std::function<bool(const std::string &key, DummyEvent const *buffer)> preparedQuery; | ||
85 | if (!query.ids.isEmpty()) { | ||
86 | //Match by id | ||
87 | //TODO: for id's a direct lookup would be way faster | ||
88 | |||
89 | //We convert the id's to std::string so we don't have to convert each key during the scan. (This runs only once, and the query will be run for every key) | ||
90 | //Probably a premature optimization, but perhaps a useful technique to be investigated. | ||
91 | QVector<std::string> ids; | ||
92 | for (const auto &id : query.ids) { | ||
93 | ids << id.toStdString(); | ||
94 | } | ||
95 | preparedQuery = [ids](const std::string &key, DummyEvent const *buffer) { | ||
96 | if (ids.contains(key)) { | ||
97 | return true; | ||
98 | } | ||
99 | return false; | ||
100 | }; | ||
101 | } else { | ||
102 | //Match everything | ||
103 | preparedQuery = [](const std::string &key, DummyEvent const *buffer) { | ||
104 | return true; | ||
105 | }; | ||
106 | } | ||
107 | |||
108 | //Because we have no indexes yet, we always do a full scan | ||
109 | storage->scan("", [=](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool { | ||
81 | //TODO read second buffer as well | 110 | //TODO read second buffer as well |
82 | auto eventBuffer = GetDummyEvent(data); | 111 | auto eventBuffer = GetDummyEvent(dataValue); |
83 | auto event = QSharedPointer<DummyEventAdaptor>::create("dummyresource", "key", 0); | 112 | if (preparedQuery && preparedQuery(std::string(static_cast<char*>(keyValue), keySize), eventBuffer)) { |
84 | event->buffer = eventBuffer; | 113 | //TODO read the revision from the generic portion of the buffer |
85 | event->storage = storage; | 114 | auto event = QSharedPointer<DummyEventAdaptor>::create("dummyresource", QString::fromUtf8(static_cast<char*>(keyValue), keySize), 0); |
86 | resultCallback(event); | 115 | event->buffer = eventBuffer; |
116 | event->storage = storage; | ||
117 | resultCallback(event); | ||
118 | } | ||
87 | return true; | 119 | return true; |
88 | }); | 120 | }); |
89 | } | 121 | } |
diff --git a/dummyresource/facade.h b/dummyresource/facade.h index 310ef77..56889aa 100644 --- a/dummyresource/facade.h +++ b/dummyresource/facade.h | |||
@@ -13,10 +13,8 @@ public: | |||
13 | virtual void create(const Akonadi2::Domain::Event &domainObject); | 13 | virtual void create(const Akonadi2::Domain::Event &domainObject); |
14 | virtual void modify(const Akonadi2::Domain::Event &domainObject); | 14 | virtual void modify(const Akonadi2::Domain::Event &domainObject); |
15 | virtual void remove(const Akonadi2::Domain::Event &domainObject); | 15 | virtual void remove(const Akonadi2::Domain::Event &domainObject); |
16 | // virtual void load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event &)> &resultCallback); | ||
17 | virtual void load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback); | 16 | virtual void load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback); |
18 | 17 | ||
19 | private: | 18 | private: |
20 | QSharedPointer<ResourceAccess> mResourceAccess; | 19 | QSharedPointer<ResourceAccess> mResourceAccess; |
21 | QSharedPointer<Storage> mStorage; | ||
22 | }; | 20 | }; |
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9ee3f5e..95aba64 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt | |||
@@ -14,4 +14,8 @@ endmacro(manual_tests) | |||
14 | manual_tests ( | 14 | manual_tests ( |
15 | storagebenchmark | 15 | storagebenchmark |
16 | storagetest | 16 | storagetest |
17 | dummyresourcefacadetest | ||
17 | ) | 18 | ) |
19 | |||
20 | target_link_libraries(dummyresourcefacadetest akonadi2_dummyresource_facade) | ||
21 | |||
diff --git a/tests/dummyresourcefacadetest.cpp b/tests/dummyresourcefacadetest.cpp new file mode 100644 index 0000000..26daa23 --- /dev/null +++ b/tests/dummyresourcefacadetest.cpp | |||
@@ -0,0 +1,73 @@ | |||
1 | #include <QtTest> | ||
2 | |||
3 | #include <iostream> | ||
4 | |||
5 | #include <QDebug> | ||
6 | #include <QString> | ||
7 | #include <QtConcurrent/QtConcurrentRun> | ||
8 | |||
9 | #include "common/storage.h" | ||
10 | #include "dummyresource/facade.h" | ||
11 | |||
12 | class DummyResourceFacadeTest : public QObject | ||
13 | { | ||
14 | Q_OBJECT | ||
15 | private: | ||
16 | QString testDataPath; | ||
17 | QString dbName; | ||
18 | const char *keyPrefix = "key"; | ||
19 | |||
20 | void populate(int count) | ||
21 | { | ||
22 | Storage storage(testDataPath, dbName, Storage::ReadWrite); | ||
23 | for (int i = 0; i < count; i++) { | ||
24 | storage.write(keyPrefix + std::to_string(i), keyPrefix + std::to_string(i)); | ||
25 | } | ||
26 | storage.commitTransaction(); | ||
27 | } | ||
28 | |||
29 | private Q_SLOTS: | ||
30 | void initTestCase() | ||
31 | { | ||
32 | testDataPath = Akonadi2::Store::storageLocation(); | ||
33 | dbName = "dummyresource"; | ||
34 | Akonadi2::FacadeFactory::instance().registerFacade<Akonadi2::Domain::Event, DummyResourceFacade>("dummyresource", []() { | ||
35 | return new DummyResourceFacade(); | ||
36 | }); | ||
37 | } | ||
38 | |||
39 | void cleanupTestCase() | ||
40 | { | ||
41 | Storage storage(testDataPath, dbName); | ||
42 | storage.removeFromDisk(); | ||
43 | } | ||
44 | |||
45 | void testScan() | ||
46 | { | ||
47 | const int count = 100; | ||
48 | populate(count); | ||
49 | |||
50 | Akonadi2::Query query; | ||
51 | query.ids << "key50"; | ||
52 | query.resources << "dummyresource"; | ||
53 | |||
54 | auto result = Akonadi2::Store::load<Akonadi2::Domain::Event>(query); | ||
55 | bool complete = false; | ||
56 | QVector<Akonadi2::Domain::Event::Ptr> results; | ||
57 | result->onAdded([&results](const Akonadi2::Domain::Event::Ptr &e) { | ||
58 | results << e; | ||
59 | }); | ||
60 | result->onComplete([&complete]() { | ||
61 | complete = true; | ||
62 | }); | ||
63 | QTRY_VERIFY(complete); | ||
64 | QCOMPARE(results.size(), 1); | ||
65 | |||
66 | Storage storage(testDataPath, dbName); | ||
67 | storage.removeFromDisk(); | ||
68 | } | ||
69 | |||
70 | }; | ||
71 | |||
72 | QTEST_MAIN(DummyResourceFacadeTest) | ||
73 | #include "dummyresourcefacadetest.moc" | ||