summaryrefslogtreecommitdiffstats
path: root/common/clientapi.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-07-24 17:26:25 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-07-27 23:22:10 +0200
commit7ae8c8719497ec7556f532bab061d3758976f792 (patch)
tree8ace2300cebcf6926c7053e3f23a5f68c304ad98 /common/clientapi.h
parent4430eabdfeddf02c20424508a2a4207b6b4a764e (diff)
downloadsink-7ae8c8719497ec7556f532bab061d3758976f792.tar.gz
sink-7ae8c8719497ec7556f532bab061d3758976f792.zip
Mode FacadeFactory to separate file, mutex protected it, and loaded
resource The factory is potentially used from several queries simultaneously, so it's now mutex protected. Additionally we try to load the plugins directly in the factory.
Diffstat (limited to 'common/clientapi.h')
-rw-r--r--common/clientapi.h94
1 files changed, 1 insertions, 93 deletions
diff --git a/common/clientapi.h b/common/clientapi.h
index 4644ae1..d860305 100644
--- a/common/clientapi.h
+++ b/common/clientapi.h
@@ -35,6 +35,7 @@
35#include "resultprovider.h" 35#include "resultprovider.h"
36#include "domain/applicationdomaintype.h" 36#include "domain/applicationdomaintype.h"
37#include "resourceconfig.h" 37#include "resourceconfig.h"
38#include "facadefactory.h"
38#include "log.h" 39#include "log.h"
39 40
40namespace async { 41namespace async {
@@ -82,98 +83,6 @@ public:
82}; 83};
83 84
84 85
85/**
86 * Interface for the store facade.
87 *
88 * All methods are synchronous.
89 * Facades are stateful (they hold connections to resources and database).
90 *
91 * TODO: would it make sense to split the write, read and notification parts? (we could potentially save some connections)
92 */
93template<class DomainType>
94class StoreFacade {
95public:
96 virtual ~StoreFacade(){};
97 QByteArray type() const { return ApplicationDomain::getTypeName<DomainType>(); }
98 virtual KAsync::Job<void> create(const DomainType &domainObject) = 0;
99 virtual KAsync::Job<void> modify(const DomainType &domainObject) = 0;
100 virtual KAsync::Job<void> remove(const DomainType &domainObject) = 0;
101 virtual KAsync::Job<void> load(const Query &query, const QSharedPointer<ResultProvider<typename DomainType::Ptr> > &resultProvider) = 0;
102};
103
104
105/**
106 * Facade factory that returns a store facade implementation, by loading a plugin and providing the relevant implementation.
107 *
108 * If we were to provide default implementations for certain capabilities. Here would be the place to do so.
109 */
110
111class FacadeFactory {
112public:
113 typedef std::function<std::shared_ptr<void>(const QByteArray &)> FactoryFunction;
114
115 void registerStaticFacades();
116
117 //FIXME: proper singleton implementation
118 static FacadeFactory &instance()
119 {
120 static FacadeFactory factory;
121 return factory;
122 }
123
124 static QByteArray key(const QByteArray &resource, const QByteArray &type)
125 {
126 return resource + type;
127 }
128
129 template<class DomainType, class Facade>
130 void registerFacade(const QByteArray &resource)
131 {
132 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
133 mFacadeRegistry.insert(key(resource, typeName), [](const QByteArray &instanceIdentifier){ return std::make_shared<Facade>(instanceIdentifier); });
134 }
135
136 /*
137 * Allows the registrar to register a specific instance.
138 *
139 * Primarily for testing.
140 */
141 template<class DomainType, class Facade>
142 void registerFacade(const QByteArray &resource, const FactoryFunction &customFactoryFunction)
143 {
144 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
145 mFacadeRegistry.insert(key(resource, typeName), customFactoryFunction);
146 }
147
148 /*
149 * Can be used to clear the factory.
150 *
151 * Primarily for testing.
152 */
153 void resetFactory()
154 {
155 mFacadeRegistry.clear();
156 }
157
158 template<class DomainType>
159 std::shared_ptr<StoreFacade<DomainType> > getFacade(const QByteArray &resource, const QByteArray &instanceIdentifier)
160 {
161 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
162 if (auto factoryFunction = mFacadeRegistry.value(key(resource, typeName))) {
163 return std::static_pointer_cast<StoreFacade<DomainType> >(factoryFunction(instanceIdentifier));
164 }
165 qWarning() << "Failed to find facade for resource: " << resource << " and type: " << typeName;
166 return std::shared_ptr<StoreFacade<DomainType> >();
167 }
168
169private:
170 FacadeFactory()
171 {
172 registerStaticFacades();
173 }
174
175 QHash<QByteArray, FactoryFunction> mFacadeRegistry;
176};
177 86
178/** 87/**
179 * Store interface used in the client API. 88 * Store interface used in the client API.
@@ -231,7 +140,6 @@ public:
231 // Query all resources and aggregate results 140 // Query all resources and aggregate results
232 KAsync::iterate(getResources(query.resources)) 141 KAsync::iterate(getResources(query.resources))
233 .template each<void, QByteArray>([query, resultSet](const QByteArray &resource, KAsync::Future<void> &future) { 142 .template each<void, QByteArray>([query, resultSet](const QByteArray &resource, KAsync::Future<void> &future) {
234 //TODO pass resource identifier to factory
235 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceName(resource), resource); 143 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceName(resource), resource);
236 if (facade) { 144 if (facade) {
237 facade->load(query, resultSet).template then<void>([&future](){future.setFinished();}).exec(); 145 facade->load(query, resultSet).template then<void>([&future](){future.setFinished();}).exec();