1 /*
2  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
3  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
4  */
5 
6 
7 
8 #ifndef DOMAIN_QUERYRESULT_H
9 #define DOMAIN_QUERYRESULT_H
10 
11 #include <algorithm>
12 
13 #include "queryresultinterface.h"
14 #include "queryresultprovider.h"
15 
16 namespace Domain {
17 
18 
19 template<typename InputType, typename OutputType = InputType>
20 class QueryResult : public QueryResultInputImpl<InputType>, public QueryResultInterface<OutputType>
21 {
22 public:
23     typedef QSharedPointer<QueryResult<InputType, OutputType>> Ptr;
24     typedef QWeakPointer<QueryResult<InputType, OutputType>> WeakPtr;
25     typedef std::function<void(OutputType, int)> ChangeHandler;
26 
create(const typename QueryResultProvider<InputType>::Ptr & provider)27     static Ptr create(const typename QueryResultProvider<InputType>::Ptr &provider)
28     {
29         Ptr result(new QueryResult<InputType, OutputType>(provider));
30         QueryResultInputImpl<InputType>::registerResult(provider, result);
31         return result;
32     }
33 
copy(const typename QueryResultInputImpl<InputType>::Ptr & other)34     static Ptr copy(const typename QueryResultInputImpl<InputType>::Ptr &other)
35     {
36         if (!other)
37             return Ptr();
38 
39         auto provider = QueryResultInputImpl<InputType>::retrieveProvider(other);
40         return create(provider);
41     }
42 
data()43     QList<OutputType> data() const override
44     {
45         return dataImpl<OutputType>();
46     }
47 
addPreInsertHandler(const ChangeHandler & handler)48     void addPreInsertHandler(const ChangeHandler &handler) override
49     {
50         QueryResultInputImpl<InputType>::m_preInsertHandlers << handler;
51     }
52 
addPostInsertHandler(const ChangeHandler & handler)53     void addPostInsertHandler(const ChangeHandler &handler) override
54     {
55         QueryResultInputImpl<InputType>::m_postInsertHandlers << handler;
56     }
57 
addPreRemoveHandler(const ChangeHandler & handler)58     void addPreRemoveHandler(const ChangeHandler &handler) override
59     {
60         QueryResultInputImpl<InputType>::m_preRemoveHandlers << handler;
61     }
62 
addPostRemoveHandler(const ChangeHandler & handler)63     void addPostRemoveHandler(const ChangeHandler &handler) override
64     {
65         QueryResultInputImpl<InputType>::m_postRemoveHandlers << handler;
66     }
67 
addPreReplaceHandler(const ChangeHandler & handler)68     void addPreReplaceHandler(const ChangeHandler &handler) override
69     {
70         QueryResultInputImpl<InputType>::m_preReplaceHandlers << handler;
71     }
72 
addPostReplaceHandler(const ChangeHandler & handler)73     void addPostReplaceHandler(const ChangeHandler &handler) override
74     {
75         QueryResultInputImpl<InputType>::m_postReplaceHandlers << handler;
76     }
77 
78 private:
QueryResult(const typename QueryResultProvider<InputType>::Ptr & provider)79     explicit QueryResult(const typename QueryResultProvider<InputType>::Ptr &provider)
80         : QueryResultInputImpl<InputType>(provider)
81     {
82     }
83 
84     template<typename T>
85     typename std::enable_if<std::is_same<InputType, T>::value, QList<InputType>>::type
dataImpl()86     dataImpl() const
87     {
88         auto provider = QueryResultInputImpl<InputType>::m_provider;
89         return provider->data();
90     }
91 
92     template<typename T>
93     typename std::enable_if<!std::is_same<InputType, T>::value, QList<T>>::type
dataImpl()94     dataImpl() const
95     {
96         auto provider = QueryResultInputImpl<InputType>::m_provider;
97         QList<InputType> inputData = provider->data();
98         QList<OutputType> outputData;
99         std::transform(inputData.constBegin(), inputData.constEnd(),
100                        std::back_inserter(outputData),
101                        [] (const InputType &input) { return OutputType(input); });
102         return outputData;
103     }
104 };
105 
106 }
107 
108 #endif // DOMAIN_QUERYRESULT_H
109