summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2014-12-11 00:44:44 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2014-12-11 00:44:44 +0100
commitfdd74a41929b4343902f1d1dfcd5116534a79f4f (patch)
tree312524c2f1a8431742d6a2575dc3c497b66cc795
parentfbd35044dc343dbd17d475b860c6019077271efc (diff)
downloadsink-fdd74a41929b4343902f1d1dfcd5116534a79f4f.tar.gz
sink-fdd74a41929b4343902f1d1dfcd5116534a79f4f.zip
Dummyresourcefacade test.
Huzaa, we can read a value!
-rw-r--r--client/CMakeLists.txt9
-rw-r--r--client/clientapi.h10
-rw-r--r--dummyresource/CMakeLists.txt2
-rw-r--r--dummyresource/facade.cpp52
-rw-r--r--dummyresource/facade.h2
-rw-r--r--tests/CMakeLists.txt4
-rw-r--r--tests/dummyresourcefacadetest.cpp73
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)
3include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 3include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
4 4
5set(akonadi2client_SRCS 5set(akonadi2client_SRCS
6 main.cpp
7 resourceaccess.cpp 6 resourceaccess.cpp
8) 7)
9 8
10add_executable(${PROJECT_NAME} ${akonadi2client_SRCS}) 9add_library(${PROJECT_NAME}_lib ${akonadi2client_SRCS})
11target_link_libraries(${PROJECT_NAME} akonadi2common) 10target_link_libraries(${PROJECT_NAME}_lib akonadi2common)
11qt5_use_modules(${PROJECT_NAME}_lib Widgets Network)
12
13add_executable(${PROJECT_NAME} main.cpp)
14target_link_libraries(${PROJECT_NAME} akonadi2_client_lib akonadi2common)
12qt5_use_modules(${PROJECT_NAME} Widgets Network) 15qt5_use_modules(${PROJECT_NAME} Widgets Network)
13install(TARGETS ${PROJECT_NAME} DESTINATION bin) 16install(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;
185class Query 185class Query
186{ 186{
187public: 187public:
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
8add_library(${PROJECT_NAME}_facade SHARED facade.cpp) 8add_library(${PROJECT_NAME}_facade SHARED facade.cpp)
9target_link_libraries(${PROJECT_NAME}_facade akonadi2common) 9target_link_libraries(${PROJECT_NAME}_facade akonadi2common akonadi2_client_lib)
10qt5_use_modules(${PROJECT_NAME}_facade Widgets Network) 10qt5_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
11DummyResourceFacade::DummyResourceFacade() 11DummyResourceFacade::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?
48class DummyEventAdaptor : public Akonadi2::Domain::Event { 47class DummyEventAdaptor : public Akonadi2::Domain::Event {
49public: 48public:
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:
75void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback) 77void 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
19private: 18private:
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)
14manual_tests ( 14manual_tests (
15 storagebenchmark 15 storagebenchmark
16 storagetest 16 storagetest
17 dummyresourcefacadetest
17) 18)
19
20target_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
12class DummyResourceFacadeTest : public QObject
13{
14 Q_OBJECT
15private:
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
29private 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
72QTEST_MAIN(DummyResourceFacadeTest)
73#include "dummyresourcefacadetest.moc"