Modern IDB: Pipe through cursor functions from client to server.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / client / TransactionOperation.h
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef TransactionOperation_h
27 #define TransactionOperation_h
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBRequestImpl.h"
32 #include "IDBResourceIdentifier.h"
33 #include "IDBTransactionImpl.h"
34
35 namespace WebCore {
36
37 class IDBResultData;
38
39 namespace IndexedDB {
40 enum class IndexRecordType;
41 }
42
43 namespace IDBClient {
44
45 class TransactionOperation : public RefCounted<TransactionOperation> {
46 public:
47     void perform()
48     {
49         m_performFunction();
50     }
51
52     void completed(const IDBResultData& data)
53     {
54         m_completeFunction(data);
55         m_transaction->operationDidComplete(*this);
56     }
57
58     const IDBResourceIdentifier& identifier() const { return m_identifier; }
59     IDBResourceIdentifier transactionIdentifier() const { return m_transaction->info().identifier(); }
60     uint64_t objectStoreIdentifier() const { return m_objectStoreIdentifier; }
61     uint64_t indexIdentifier() const { return m_indexIdentifier; }
62     IDBTransaction& transaction() { return m_transaction.get(); }
63     IndexedDB::IndexRecordType indexRecordType() const { return m_indexRecordType; }
64
65 protected:
66     TransactionOperation(IDBTransaction& transaction)
67         : m_transaction(transaction)
68         , m_identifier(transaction.serverConnection())
69     {
70     }
71
72     TransactionOperation(IDBTransaction&, IDBRequest&);
73
74     Ref<IDBTransaction> m_transaction;
75     IDBResourceIdentifier m_identifier;
76     uint64_t m_objectStoreIdentifier { 0 };
77     uint64_t m_indexIdentifier { 0 };
78     IndexedDB::IndexRecordType m_indexRecordType;
79     std::function<void ()> m_performFunction;
80     std::function<void (const IDBResultData&)> m_completeFunction;
81 };
82
83 template <typename... Arguments>
84 class TransactionOperationImpl final : public TransactionOperation {
85 public:
86     TransactionOperationImpl(IDBTransaction& transaction, void (IDBTransaction::*completeMethod)(const IDBResultData&), void (IDBTransaction::*performMethod)(TransactionOperation&, Arguments...), Arguments&&... arguments)
87         : TransactionOperation(transaction)
88     {
89         relaxAdoptionRequirement();
90         RefPtr<TransactionOperation> self(this);
91         m_performFunction = [self, this, performMethod, arguments...] {
92             (&m_transaction.get()->*performMethod)(*this, arguments...);
93         };
94
95         m_completeFunction = [self, this, completeMethod](const IDBResultData& resultData) {
96             if (completeMethod)
97                 (&m_transaction.get()->*completeMethod)(resultData);
98         };
99     }
100
101     TransactionOperationImpl(IDBTransaction& transaction, IDBRequest& request, void (IDBTransaction::*completeMethod)(IDBRequest&, const IDBResultData&), void (IDBTransaction::*performMethod)(TransactionOperation&, Arguments...), Arguments&&... arguments)
102         : TransactionOperation(transaction, request)
103     {
104         relaxAdoptionRequirement();
105
106         RefPtr<TransactionOperation> self(this);
107         m_performFunction = [self, this, performMethod, arguments...] {
108             (&m_transaction.get()->*performMethod)(*this, arguments...);
109         };
110
111         RefPtr<IDBRequest> refRequest(&request);
112         m_completeFunction = [self, this, refRequest, completeMethod](const IDBResultData& resultData) {
113             if (completeMethod)
114                 (&m_transaction.get()->*completeMethod)(*refRequest, resultData);
115         };
116     }
117 };
118
119 inline RefPtr<TransactionOperation> createTransactionOperation(
120     IDBTransaction& transaction,
121     void (IDBTransaction::*complete)(const IDBResultData&),
122     void (IDBTransaction::*perform)(TransactionOperation&))
123 {
124     auto operation = new TransactionOperationImpl<>(transaction, complete, perform);
125     return adoptRef(operation);
126 }
127
128 template<typename MP1, typename P1>
129 RefPtr<TransactionOperation> createTransactionOperation(
130     IDBTransaction& transaction,
131     void (IDBTransaction::*complete)(const IDBResultData&),
132     void (IDBTransaction::*perform)(TransactionOperation&, MP1),
133     const P1& parameter1)
134 {
135     auto operation = new TransactionOperationImpl<MP1>(transaction, complete, perform, parameter1);
136     return adoptRef(operation);
137 }
138
139 template<typename MP1, typename P1>
140 RefPtr<TransactionOperation> createTransactionOperation(
141     IDBTransaction& transaction,
142     IDBRequest& request,
143     void (IDBTransaction::*complete)(IDBRequest&, const IDBResultData&),
144     void (IDBTransaction::*perform)(TransactionOperation&, MP1),
145     const P1& parameter1)
146 {
147     auto operation = new TransactionOperationImpl<MP1>(transaction, request, complete, perform, parameter1);
148     return adoptRef(operation);
149 }
150
151 template<typename MP1, typename P1, typename MP2, typename P2>
152 RefPtr<TransactionOperation> createTransactionOperation(
153     IDBTransaction& transaction,
154     IDBRequest& request,
155     void (IDBTransaction::*complete)(IDBRequest&, const IDBResultData&),
156     void (IDBTransaction::*perform)(TransactionOperation&, MP1, MP2),
157     const P1& parameter1,
158     const P2& parameter2)
159 {
160     auto operation = new TransactionOperationImpl<MP1, MP2>(transaction, request, complete, perform, parameter1, parameter2);
161     return adoptRef(operation);
162 }
163
164 template<typename MP1, typename MP2, typename MP3, typename P1, typename P2, typename P3>
165 RefPtr<TransactionOperation> createTransactionOperation(
166     IDBTransaction& transaction,
167     IDBRequest& request,
168     void (IDBTransaction::*complete)(IDBRequest&, const IDBResultData&),
169     void (IDBTransaction::*perform)(TransactionOperation&, MP1, MP2, MP3),
170     const P1& parameter1,
171     const P2& parameter2,
172     const P3& parameter3)
173 {
174     auto operation = new TransactionOperationImpl<MP1, MP2, MP3>(transaction, request, complete, perform, parameter1, parameter2, parameter3);
175     return adoptRef(operation);
176 }
177
178 } // namespace IDBClient
179 } // namespace WebCore
180
181 #endif // ENABLE(INDEXED_DATABASE)
182 #endif // TransactionOperation_h