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#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "IDBDatabaseInfo.h"
31#include "IDBError.h"
32#include "IDBGetAllResult.h"
33#include "IDBGetResult.h"
34#include "IDBKeyData.h"
35#include "IDBResourceIdentifier.h"
36#include "IDBTransactionInfo.h"
37#include "ThreadSafeDataBuffer.h"
38
39namespace WebCore {
40
41class ThreadSafeDataBuffer;
42
43enum class IDBResultType {
44 Error,
45 OpenDatabaseSuccess,
46 OpenDatabaseUpgradeNeeded,
47 DeleteDatabaseSuccess,
48 CreateObjectStoreSuccess,
49 DeleteObjectStoreSuccess,
50 ClearObjectStoreSuccess,
51 PutOrAddSuccess,
52 GetRecordSuccess,
53 GetAllRecordsSuccess,
54 GetCountSuccess,
55 DeleteRecordSuccess,
56 CreateIndexSuccess,
57 DeleteIndexSuccess,
58 OpenCursorSuccess,
59 IterateCursorSuccess,
60 RenameObjectStoreSuccess,
61 RenameIndexSuccess,
62};
63
64namespace IDBServer {
65class UniqueIDBDatabaseConnection;
66class UniqueIDBDatabaseTransaction;
67}
68
69class IDBResultData {
70public:
71 static IDBResultData error(const IDBResourceIdentifier&, const IDBError&);
72 static IDBResultData openDatabaseSuccess(const IDBResourceIdentifier&, IDBServer::UniqueIDBDatabaseConnection&);
73 static IDBResultData openDatabaseUpgradeNeeded(const IDBResourceIdentifier&, IDBServer::UniqueIDBDatabaseTransaction&);
74 static IDBResultData deleteDatabaseSuccess(const IDBResourceIdentifier&, const IDBDatabaseInfo&);
75 static IDBResultData createObjectStoreSuccess(const IDBResourceIdentifier&);
76 static IDBResultData deleteObjectStoreSuccess(const IDBResourceIdentifier&);
77 static IDBResultData renameObjectStoreSuccess(const IDBResourceIdentifier&);
78 static IDBResultData clearObjectStoreSuccess(const IDBResourceIdentifier&);
79 static IDBResultData createIndexSuccess(const IDBResourceIdentifier&);
80 static IDBResultData deleteIndexSuccess(const IDBResourceIdentifier&);
81 static IDBResultData renameIndexSuccess(const IDBResourceIdentifier&);
82 static IDBResultData putOrAddSuccess(const IDBResourceIdentifier&, const IDBKeyData&);
83 static IDBResultData getRecordSuccess(const IDBResourceIdentifier&, const IDBGetResult&);
84 static IDBResultData getAllRecordsSuccess(const IDBResourceIdentifier&, const IDBGetAllResult&);
85 static IDBResultData getCountSuccess(const IDBResourceIdentifier&, uint64_t count);
86 static IDBResultData deleteRecordSuccess(const IDBResourceIdentifier&);
87 static IDBResultData openCursorSuccess(const IDBResourceIdentifier&, const IDBGetResult&);
88 static IDBResultData iterateCursorSuccess(const IDBResourceIdentifier&, const IDBGetResult&);
89
90 WEBCORE_EXPORT IDBResultData(const IDBResultData&);
91 IDBResultData& operator=(IDBResultData&&) = default;
92
93 enum IsolatedCopyTag { IsolatedCopy };
94 IDBResultData(const IDBResultData&, IsolatedCopyTag);
95 IDBResultData isolatedCopy() const;
96
97 IDBResultType type() const { return m_type; }
98 IDBResourceIdentifier requestIdentifier() const { return m_requestIdentifier; }
99
100 const IDBError& error() const { return m_error; }
101 uint64_t databaseConnectionIdentifier() const { return m_databaseConnectionIdentifier; }
102
103 const IDBDatabaseInfo& databaseInfo() const;
104 const IDBTransactionInfo& transactionInfo() const;
105
106 const IDBKeyData* resultKey() const { return m_resultKey.get(); }
107 uint64_t resultInteger() const { return m_resultInteger; }
108
109 WEBCORE_EXPORT const IDBGetResult& getResult() const;
110 WEBCORE_EXPORT IDBGetResult& getResultRef();
111 WEBCORE_EXPORT const IDBGetAllResult& getAllResult() const;
112
113 WEBCORE_EXPORT IDBResultData();
114 template<class Encoder> void encode(Encoder&) const;
115 template<class Decoder> static Optional<IDBResultData> decode(Decoder&);
116
117private:
118 IDBResultData(const IDBResourceIdentifier&);
119 IDBResultData(IDBResultType, const IDBResourceIdentifier&);
120
121 static void isolatedCopy(const IDBResultData& source, IDBResultData& destination);
122
123 IDBResultType m_type { IDBResultType::Error };
124 IDBResourceIdentifier m_requestIdentifier;
125
126 IDBError m_error;
127 uint64_t m_databaseConnectionIdentifier { 0 };
128 std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
129 std::unique_ptr<IDBTransactionInfo> m_transactionInfo;
130 std::unique_ptr<IDBKeyData> m_resultKey;
131 std::unique_ptr<IDBGetResult> m_getResult;
132 std::unique_ptr<IDBGetAllResult> m_getAllResult;
133 uint64_t m_resultInteger { 0 };
134};
135
136template<class Encoder>
137void IDBResultData::encode(Encoder& encoder) const
138{
139 encoder << m_requestIdentifier << m_error << m_databaseConnectionIdentifier << m_resultInteger;
140
141 encoder.encodeEnum(m_type);
142
143 encoder << !!m_databaseInfo;
144 if (m_databaseInfo)
145 encoder << *m_databaseInfo;
146
147 encoder << !!m_transactionInfo;
148 if (m_transactionInfo)
149 encoder << *m_transactionInfo;
150
151 encoder << !!m_resultKey;
152 if (m_resultKey)
153 encoder << *m_resultKey;
154
155 encoder << !!m_getResult;
156 if (m_getResult)
157 encoder << *m_getResult;
158
159 encoder << !!m_getAllResult;
160 if (m_getAllResult)
161 encoder << *m_getAllResult;
162}
163
164template<class Decoder> Optional<IDBResultData> IDBResultData::decode(Decoder& decoder)
165{
166 IDBResultData result;
167 if (!decoder.decode(result.m_requestIdentifier))
168 return WTF::nullopt;
169
170 if (!decoder.decode(result.m_error))
171 return WTF::nullopt;
172
173 if (!decoder.decode(result.m_databaseConnectionIdentifier))
174 return WTF::nullopt;
175
176 if (!decoder.decode(result.m_resultInteger))
177 return WTF::nullopt;
178
179 if (!decoder.decodeEnum(result.m_type))
180 return WTF::nullopt;
181
182 bool hasObject;
183
184 if (!decoder.decode(hasObject))
185 return WTF::nullopt;
186 if (hasObject) {
187 auto object = std::make_unique<IDBDatabaseInfo>();
188 if (!decoder.decode(*object))
189 return WTF::nullopt;
190 result.m_databaseInfo = WTFMove(object);
191 }
192
193 if (!decoder.decode(hasObject))
194 return WTF::nullopt;
195 if (hasObject) {
196 auto object = std::make_unique<IDBTransactionInfo>();
197 if (!decoder.decode(*object))
198 return WTF::nullopt;
199 result.m_transactionInfo = WTFMove(object);
200 }
201
202 if (!decoder.decode(hasObject))
203 return WTF::nullopt;
204 if (hasObject) {
205 auto object = std::make_unique<IDBKeyData>();
206 Optional<IDBKeyData> optional;
207 decoder >> optional;
208 if (!optional)
209 return WTF::nullopt;
210 *object = WTFMove(*optional);
211 result.m_resultKey = WTFMove(object);
212 }
213
214 if (!decoder.decode(hasObject))
215 return WTF::nullopt;
216 if (hasObject) {
217 auto object = std::make_unique<IDBGetResult>();
218 if (!decoder.decode(*object))
219 return WTF::nullopt;
220 result.m_getResult = WTFMove(object);
221 }
222
223 if (!decoder.decode(hasObject))
224 return WTF::nullopt;
225 if (hasObject) {
226 auto object = std::make_unique<IDBGetAllResult>();
227 if (!decoder.decode(*object))
228 return WTF::nullopt;
229 result.m_getAllResult = WTFMove(object);
230 }
231
232 return result;
233}
234
235} // namespace WebCore
236
237#endif // ENABLE(INDEXED_DATABASE)
238