Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement...
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / IDBResultData.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 #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
39 namespace WebCore {
40
41 class ThreadSafeDataBuffer;
42
43 enum 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
64 namespace IDBServer {
65 class UniqueIDBDatabaseConnection;
66 class UniqueIDBDatabaseTransaction;
67 }
68
69 class IDBResultData {
70 public:
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
117 private:
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
136 template<class Encoder>
137 void 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
164 template<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)