641223617e9e47376fa4e98c49af2e4223281f5f
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / UniqueIDBDatabaseTransaction.cpp
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 #include "config.h"
27 #include "UniqueIDBDatabaseTransaction.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBError.h"
32 #include "IDBResultData.h"
33 #include "IDBServer.h"
34 #include "Logging.h"
35 #include "UniqueIDBDatabase.h"
36
37 namespace WebCore {
38 namespace IDBServer {
39
40 Ref<UniqueIDBDatabaseTransaction> UniqueIDBDatabaseTransaction::create(UniqueIDBDatabaseConnection& connection, const IDBTransactionInfo& info)
41 {
42     return adoptRef(*new UniqueIDBDatabaseTransaction(connection, info));
43 }
44
45 UniqueIDBDatabaseTransaction::UniqueIDBDatabaseTransaction(UniqueIDBDatabaseConnection& connection, const IDBTransactionInfo& info)
46     : m_databaseConnection(connection)
47     , m_transactionInfo(info)
48 {
49     if (m_transactionInfo.mode() == IDBTransactionMode::Versionchange)
50         m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_databaseConnection->database().info());
51
52     m_databaseConnection->database().server().registerTransaction(*this);
53 }
54
55 UniqueIDBDatabaseTransaction::~UniqueIDBDatabaseTransaction()
56 {
57     m_databaseConnection->database().transactionDestroyed(*this);
58     m_databaseConnection->database().server().unregisterTransaction(*this);
59 }
60
61 IDBDatabaseInfo* UniqueIDBDatabaseTransaction::originalDatabaseInfo() const
62 {
63     ASSERT(m_transactionInfo.mode() == IDBTransactionMode::Versionchange);
64     return m_originalDatabaseInfo.get();
65 }
66
67 void UniqueIDBDatabaseTransaction::abort()
68 {
69     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort");
70
71     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
72     m_databaseConnection->database().abortTransaction(*this, [this, protectedThis](const IDBError& error) {
73         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort (callback)");
74         m_databaseConnection->didAbortTransaction(*this, error);
75     });
76 }
77
78 void UniqueIDBDatabaseTransaction::abortWithoutCallback()
79 {
80     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abortWithoutCallback");
81
82     m_databaseConnection->abortTransactionWithoutCallback(*this);
83 }
84
85 bool UniqueIDBDatabaseTransaction::isVersionChange() const
86 {
87     return m_transactionInfo.mode() == IDBTransactionMode::Versionchange;
88 }
89
90 bool UniqueIDBDatabaseTransaction::isReadOnly() const
91 {
92     return m_transactionInfo.mode() == IDBTransactionMode::Readonly;
93 }   
94
95 void UniqueIDBDatabaseTransaction::commit()
96 {
97     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit");
98
99     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
100     m_databaseConnection->database().commitTransaction(*this, [this, protectedThis](const IDBError& error) {
101         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit (callback)");
102         m_databaseConnection->didCommitTransaction(*this, error);
103     });
104 }
105
106 void UniqueIDBDatabaseTransaction::createObjectStore(const IDBRequestData& requestData, const IDBObjectStoreInfo& info)
107 {
108     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createObjectStore");
109
110     ASSERT(isVersionChange());
111     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
112
113     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
114     m_databaseConnection->database().createObjectStore(*this, info, [this, protectedThis, requestData](const IDBError& error) {
115         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createObjectStore (callback)");
116         if (error.isNull())
117             m_databaseConnection->didCreateObjectStore(IDBResultData::createObjectStoreSuccess(requestData.requestIdentifier()));
118         else
119             m_databaseConnection->didCreateObjectStore(IDBResultData::error(requestData.requestIdentifier(), error));
120     });
121 }
122
123 void UniqueIDBDatabaseTransaction::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
124 {
125     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore");
126
127     ASSERT(isVersionChange());
128     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
129
130     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
131     m_databaseConnection->database().deleteObjectStore(*this, objectStoreName, [this, protectedThis, requestData](const IDBError& error) {
132         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore (callback)");
133         if (error.isNull())
134             m_databaseConnection->didDeleteObjectStore(IDBResultData::deleteObjectStoreSuccess(requestData.requestIdentifier()));
135         else
136             m_databaseConnection->didDeleteObjectStore(IDBResultData::error(requestData.requestIdentifier(), error));
137     });
138 }
139
140 void UniqueIDBDatabaseTransaction::renameObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& newName)
141 {
142     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameObjectStore");
143
144     ASSERT(isVersionChange());
145     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
146
147     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
148     m_databaseConnection->database().renameObjectStore(*this, objectStoreIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
149         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameObjectStore (callback)");
150         if (error.isNull())
151             m_databaseConnection->didRenameObjectStore(IDBResultData::renameObjectStoreSuccess(requestData.requestIdentifier()));
152         else
153             m_databaseConnection->didRenameObjectStore(IDBResultData::error(requestData.requestIdentifier(), error));
154     });
155 }
156
157 void UniqueIDBDatabaseTransaction::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
158 {
159     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::clearObjectStore");
160
161     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
162
163     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
164     m_databaseConnection->database().clearObjectStore(*this, objectStoreIdentifier, [this, protectedThis, requestData](const IDBError& error) {
165         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::clearObjectStore (callback)");
166         if (error.isNull())
167             m_databaseConnection->didClearObjectStore(IDBResultData::clearObjectStoreSuccess(requestData.requestIdentifier()));
168         else
169             m_databaseConnection->didClearObjectStore(IDBResultData::error(requestData.requestIdentifier(), error));
170     });
171 }
172
173 void UniqueIDBDatabaseTransaction::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
174 {
175     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex");
176
177     ASSERT(isVersionChange());
178     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
179
180     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
181     m_databaseConnection->database().createIndex(*this, info, [this, protectedThis, requestData](const IDBError& error) {
182         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
183         if (error.isNull())
184             m_databaseConnection->didCreateIndex(IDBResultData::createIndexSuccess(requestData.requestIdentifier()));
185         else
186             m_databaseConnection->didCreateIndex(IDBResultData::error(requestData.requestIdentifier(), error));
187     });
188 }
189
190 void UniqueIDBDatabaseTransaction::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
191 {
192     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteIndex");
193
194     ASSERT(isVersionChange());
195     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
196
197     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
198     m_databaseConnection->database().deleteIndex(*this, objectStoreIdentifier, indexName, [this, protectedThis, requestData](const IDBError& error) {
199         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
200         if (error.isNull())
201             m_databaseConnection->didDeleteIndex(IDBResultData::deleteIndexSuccess(requestData.requestIdentifier()));
202         else
203             m_databaseConnection->didDeleteIndex(IDBResultData::error(requestData.requestIdentifier(), error));
204     });
205 }
206
207 void UniqueIDBDatabaseTransaction::renameIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
208 {
209     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameIndex");
210
211     ASSERT(isVersionChange());
212     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
213
214     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
215     m_databaseConnection->database().renameIndex(*this, objectStoreIdentifier, indexIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
216         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameIndex (callback)");
217         if (error.isNull())
218             m_databaseConnection->didRenameIndex(IDBResultData::renameIndexSuccess(requestData.requestIdentifier()));
219         else
220             m_databaseConnection->didRenameIndex(IDBResultData::error(requestData.requestIdentifier(), error));
221     });
222 }
223
224
225 void UniqueIDBDatabaseTransaction::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
226 {
227     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd");
228
229     ASSERT(!isReadOnly());
230     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
231
232     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
233     m_databaseConnection->database().putOrAdd(requestData, keyData, value, overwriteMode, [this, protectedThis, requestData](const IDBError& error, const IDBKeyData& key) {
234         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd (callback)");
235
236         if (error.isNull())
237             m_databaseConnection->connectionToClient().didPutOrAdd(IDBResultData::putOrAddSuccess(requestData.requestIdentifier(), key));
238         else
239             m_databaseConnection->connectionToClient().didPutOrAdd(IDBResultData::error(requestData.requestIdentifier(), error));
240     });
241 }
242
243 void UniqueIDBDatabaseTransaction::getRecord(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData)
244 {
245     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getRecord");
246
247     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
248
249     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
250     m_databaseConnection->database().getRecord(requestData, getRecordData, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
251         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getRecord (callback)");
252
253         if (error.isNull())
254             m_databaseConnection->connectionToClient().didGetRecord(IDBResultData::getRecordSuccess(requestData.requestIdentifier(), result));
255         else
256             m_databaseConnection->connectionToClient().didGetRecord(IDBResultData::error(requestData.requestIdentifier(), error));
257     });
258 }
259
260 void UniqueIDBDatabaseTransaction::getAllRecords(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData)
261 {
262     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getAllRecords");
263
264     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
265
266     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
267     m_databaseConnection->database().getAllRecords(requestData, getAllRecordsData, [this, protectedThis, requestData](const IDBError& error, const IDBGetAllResult& result) {
268         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getAllRecords (callback)");
269
270         if (error.isNull())
271             m_databaseConnection->connectionToClient().didGetAllRecords(IDBResultData::getAllRecordsSuccess(requestData.requestIdentifier(), result));
272         else
273             m_databaseConnection->connectionToClient().didGetAllRecords(IDBResultData::error(requestData.requestIdentifier(), error));
274     });
275 }
276
277 void UniqueIDBDatabaseTransaction::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
278 {
279     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getCount");
280
281     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
282
283     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
284     m_databaseConnection->database().getCount(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error, uint64_t count) {
285         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getCount (callback)");
286
287         if (error.isNull())
288             m_databaseConnection->connectionToClient().didGetCount(IDBResultData::getCountSuccess(requestData.requestIdentifier(), count));
289         else
290             m_databaseConnection->connectionToClient().didGetCount(IDBResultData::error(requestData.requestIdentifier(), error));
291     });
292 }
293
294 void UniqueIDBDatabaseTransaction::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
295 {
296     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteRecord");
297
298     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
299
300     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
301     m_databaseConnection->database().deleteRecord(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error) {
302         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteRecord (callback)");
303
304         if (error.isNull())
305             m_databaseConnection->connectionToClient().didDeleteRecord(IDBResultData::deleteRecordSuccess(requestData.requestIdentifier()));
306         else
307             m_databaseConnection->connectionToClient().didDeleteRecord(IDBResultData::error(requestData.requestIdentifier(), error));
308     });
309 }
310
311 void UniqueIDBDatabaseTransaction::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
312 {
313     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::openCursor");
314
315     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
316
317     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
318     m_databaseConnection->database().openCursor(requestData, info, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
319         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::openCursor (callback)");
320
321         if (error.isNull())
322             m_databaseConnection->connectionToClient().didOpenCursor(IDBResultData::openCursorSuccess(requestData.requestIdentifier(), result));
323         else
324             m_databaseConnection->connectionToClient().didOpenCursor(IDBResultData::error(requestData.requestIdentifier(), error));
325     });
326 }
327
328 void UniqueIDBDatabaseTransaction::iterateCursor(const IDBRequestData& requestData, const IDBKeyData& key, unsigned long count)
329 {
330     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::iterateCursor");
331
332     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
333
334     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
335     m_databaseConnection->database().iterateCursor(requestData, key, count, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
336         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::iterateCursor (callback)");
337
338         if (error.isNull())
339             m_databaseConnection->connectionToClient().didIterateCursor(IDBResultData::iterateCursorSuccess(requestData.requestIdentifier(), result));
340         else
341             m_databaseConnection->connectionToClient().didIterateCursor(IDBResultData::error(requestData.requestIdentifier(), error));
342     });
343 }
344
345 const Vector<uint64_t>& UniqueIDBDatabaseTransaction::objectStoreIdentifiers()
346 {
347     if (!m_objectStoreIdentifiers.isEmpty())
348         return m_objectStoreIdentifiers;
349
350     auto& info = m_databaseConnection->database().info();
351     for (auto objectStoreName : info.objectStoreNames()) {
352         auto objectStoreInfo = info.infoForExistingObjectStore(objectStoreName);
353         ASSERT(objectStoreInfo);
354         if (!objectStoreInfo)
355             continue;
356
357         if (m_transactionInfo.objectStores().contains(objectStoreName))
358             m_objectStoreIdentifiers.append(objectStoreInfo->identifier());
359     }
360
361     return m_objectStoreIdentifiers;
362 }
363
364 void UniqueIDBDatabaseTransaction::didActivateInBackingStore(const IDBError& error)
365 {
366     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::didActivateInBackingStore");
367
368     m_databaseConnection->connectionToClient().didStartTransaction(m_transactionInfo.identifier(), error);
369 }
370
371 } // namespace IDBServer
372 } // namespace WebCore
373
374 #endif // ENABLE(INDEXED_DATABASE)