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 "IDBConnectionToServer.h"
28
29#if ENABLE(INDEXED_DATABASE)
30
31#include "IDBConnectionProxy.h"
32#include "IDBDatabase.h"
33#include "IDBGetRecordData.h"
34#include "IDBKeyRangeData.h"
35#include "IDBOpenDBRequest.h"
36#include "IDBRequestData.h"
37#include "IDBResultData.h"
38#include "Logging.h"
39#include "SecurityOrigin.h"
40#include "TransactionOperation.h"
41#include <wtf/MainThread.h>
42
43namespace WebCore {
44namespace IDBClient {
45
46Ref<IDBConnectionToServer> IDBConnectionToServer::create(IDBConnectionToServerDelegate& delegate)
47{
48 return adoptRef(*new IDBConnectionToServer(delegate));
49}
50
51IDBConnectionToServer::IDBConnectionToServer(IDBConnectionToServerDelegate& delegate)
52 : m_delegate(makeWeakPtr(delegate))
53 , m_proxy(std::make_unique<IDBConnectionProxy>(*this))
54{
55}
56
57uint64_t IDBConnectionToServer::identifier() const
58{
59 return m_delegate->identifier();
60}
61
62IDBConnectionProxy& IDBConnectionToServer::proxy()
63{
64 ASSERT(m_proxy);
65 return *m_proxy;
66}
67
68void IDBConnectionToServer::callResultFunctionWithErrorLater(ResultFunction function, const IDBResourceIdentifier& requestIdentifier)
69{
70 callOnMainThread([this, protectedThis = makeRef(*this), function, requestIdentifier]() {
71 (this->*function)(IDBResultData::error(requestIdentifier, IDBError::serverConnectionLostError()));
72 });
73}
74
75void IDBConnectionToServer::deleteDatabase(const IDBRequestData& request)
76{
77 LOG(IndexedDB, "IDBConnectionToServer::deleteDatabase - %s", request.databaseIdentifier().debugString().utf8().data());
78
79 if (m_serverConnectionIsValid)
80 m_delegate->deleteDatabase(request);
81 else
82 callResultFunctionWithErrorLater(&IDBConnectionToServer::didDeleteDatabase, request.requestIdentifier());
83}
84
85void IDBConnectionToServer::didDeleteDatabase(const IDBResultData& resultData)
86{
87 LOG(IndexedDB, "IDBConnectionToServer::didDeleteDatabase");
88 m_proxy->didDeleteDatabase(resultData);
89}
90
91void IDBConnectionToServer::openDatabase(const IDBRequestData& request)
92{
93 LOG(IndexedDB, "IDBConnectionToServer::openDatabase - %s (%s) (%" PRIu64 ")", request.databaseIdentifier().debugString().utf8().data(), request.requestIdentifier().loggingString().utf8().data(), request.requestedVersion());
94
95 if (m_serverConnectionIsValid)
96 m_delegate->openDatabase(request);
97 else
98 callResultFunctionWithErrorLater(&IDBConnectionToServer::didOpenDatabase, request.requestIdentifier());
99}
100
101void IDBConnectionToServer::didOpenDatabase(const IDBResultData& resultData)
102{
103 LOG(IndexedDB, "IDBConnectionToServer::didOpenDatabase");
104 m_proxy->didOpenDatabase(resultData);
105}
106
107void IDBConnectionToServer::createObjectStore(const IDBRequestData& requestData, const IDBObjectStoreInfo& info)
108{
109 LOG(IndexedDB, "IDBConnectionToServer::createObjectStore");
110 ASSERT(isMainThread());
111
112 if (m_serverConnectionIsValid)
113 m_delegate->createObjectStore(requestData, info);
114 else
115 callResultFunctionWithErrorLater(&IDBConnectionToServer::didCreateObjectStore, requestData.requestIdentifier());
116}
117
118void IDBConnectionToServer::didCreateObjectStore(const IDBResultData& resultData)
119{
120 LOG(IndexedDB, "IDBConnectionToServer::didCreateObjectStore");
121 m_proxy->completeOperation(resultData);
122}
123
124void IDBConnectionToServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
125{
126 LOG(IndexedDB, "IDBConnectionToServer::deleteObjectStore");
127 ASSERT(isMainThread());
128
129 if (m_serverConnectionIsValid)
130 m_delegate->deleteObjectStore(requestData, objectStoreName);
131 else
132 callResultFunctionWithErrorLater(&IDBConnectionToServer::didDeleteObjectStore, requestData.requestIdentifier());
133}
134
135void IDBConnectionToServer::didDeleteObjectStore(const IDBResultData& resultData)
136{
137 LOG(IndexedDB, "IDBConnectionToServer::didDeleteObjectStore");
138 m_proxy->completeOperation(resultData);
139}
140
141void IDBConnectionToServer::renameObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& newName)
142{
143 LOG(IndexedDB, "IDBConnectionToServer::renameObjectStore");
144 ASSERT(isMainThread());
145
146 if (m_serverConnectionIsValid)
147 m_delegate->renameObjectStore(requestData, objectStoreIdentifier, newName);
148 else
149 callResultFunctionWithErrorLater(&IDBConnectionToServer::didRenameObjectStore, requestData.requestIdentifier());
150}
151
152void IDBConnectionToServer::didRenameObjectStore(const IDBResultData& resultData)
153{
154 LOG(IndexedDB, "IDBConnectionToServer::didRenameObjectStore");
155 m_proxy->completeOperation(resultData);
156}
157
158void IDBConnectionToServer::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
159{
160 LOG(IndexedDB, "IDBConnectionToServer::clearObjectStore");
161 ASSERT(isMainThread());
162
163 if (m_serverConnectionIsValid)
164 m_delegate->clearObjectStore(requestData, objectStoreIdentifier);
165 else
166 callResultFunctionWithErrorLater(&IDBConnectionToServer::didClearObjectStore, requestData.requestIdentifier());
167}
168
169void IDBConnectionToServer::didClearObjectStore(const IDBResultData& resultData)
170{
171 LOG(IndexedDB, "IDBConnectionToServer::didClearObjectStore");
172 m_proxy->completeOperation(resultData);
173}
174
175void IDBConnectionToServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
176{
177 LOG(IndexedDB, "IDBConnectionToServer::createIndex");
178 ASSERT(isMainThread());
179
180 if (m_serverConnectionIsValid)
181 m_delegate->createIndex(requestData, info);
182 else
183 callResultFunctionWithErrorLater(&IDBConnectionToServer::didCreateIndex, requestData.requestIdentifier());
184}
185
186void IDBConnectionToServer::didCreateIndex(const IDBResultData& resultData)
187{
188 LOG(IndexedDB, "IDBConnectionToServer::didCreateIndex");
189 m_proxy->completeOperation(resultData);
190}
191
192void IDBConnectionToServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
193{
194 LOG(IndexedDB, "IDBConnectionToServer::deleteIndex");
195 ASSERT(isMainThread());
196
197 if (m_serverConnectionIsValid)
198 m_delegate->deleteIndex(requestData, objectStoreIdentifier, indexName);
199 else
200 callResultFunctionWithErrorLater(&IDBConnectionToServer::didDeleteIndex, requestData.requestIdentifier());
201}
202
203void IDBConnectionToServer::didDeleteIndex(const IDBResultData& resultData)
204{
205 LOG(IndexedDB, "IDBConnectionToServer::didDeleteIndex");
206 m_proxy->completeOperation(resultData);
207}
208
209void IDBConnectionToServer::renameIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
210{
211 LOG(IndexedDB, "IDBConnectionToServer::renameIndex");
212 ASSERT(isMainThread());
213
214 if (m_serverConnectionIsValid)
215 m_delegate->renameIndex(requestData, objectStoreIdentifier, indexIdentifier, newName);
216 else
217 callResultFunctionWithErrorLater(&IDBConnectionToServer::didRenameIndex, requestData.requestIdentifier());
218}
219
220void IDBConnectionToServer::didRenameIndex(const IDBResultData& resultData)
221{
222 LOG(IndexedDB, "IDBConnectionToServer::didRenameIndex");
223 m_proxy->completeOperation(resultData);
224}
225
226void IDBConnectionToServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& key, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
227{
228 LOG(IndexedDB, "IDBConnectionToServer::putOrAdd");
229 ASSERT(isMainThread());
230
231 if (m_serverConnectionIsValid)
232 m_delegate->putOrAdd(requestData, key, value, overwriteMode);
233 else
234 callResultFunctionWithErrorLater(&IDBConnectionToServer::didPutOrAdd, requestData.requestIdentifier());
235}
236
237void IDBConnectionToServer::didPutOrAdd(const IDBResultData& resultData)
238{
239 LOG(IndexedDB, "IDBConnectionToServer::didPutOrAdd");
240 m_proxy->completeOperation(resultData);
241}
242
243void IDBConnectionToServer::getRecord(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData)
244{
245 LOG(IndexedDB, "IDBConnectionToServer::getRecord");
246 ASSERT(isMainThread());
247 ASSERT(!getRecordData.keyRangeData.isNull);
248
249 if (m_serverConnectionIsValid)
250 m_delegate->getRecord(requestData, getRecordData);
251 else
252 callResultFunctionWithErrorLater(&IDBConnectionToServer::didGetRecord, requestData.requestIdentifier());
253}
254
255void IDBConnectionToServer::didGetRecord(const IDBResultData& resultData)
256{
257 LOG(IndexedDB, "IDBConnectionToServer::didGetRecord");
258 m_proxy->completeOperation(resultData);
259}
260
261void IDBConnectionToServer::getAllRecords(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData)
262{
263 LOG(IndexedDB, "IDBConnectionToServer::getAllRecords");
264 ASSERT(isMainThread());
265
266 if (m_serverConnectionIsValid)
267 m_delegate->getAllRecords(requestData, getAllRecordsData);
268 else
269 callResultFunctionWithErrorLater(&IDBConnectionToServer::didGetAllRecords, requestData.requestIdentifier());
270}
271
272void IDBConnectionToServer::didGetAllRecords(const IDBResultData& resultData)
273{
274 LOG(IndexedDB, "IDBConnectionToServer::didGetAllRecords");
275 m_proxy->completeOperation(resultData);
276}
277
278void IDBConnectionToServer::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
279{
280 LOG(IndexedDB, "IDBConnectionToServer::getCount");
281 ASSERT(isMainThread());
282 ASSERT(!keyRangeData.isNull);
283
284 if (m_serverConnectionIsValid)
285 m_delegate->getCount(requestData, keyRangeData);
286 else
287 callResultFunctionWithErrorLater(&IDBConnectionToServer::didGetCount, requestData.requestIdentifier());
288}
289
290void IDBConnectionToServer::didGetCount(const IDBResultData& resultData)
291{
292 LOG(IndexedDB, "IDBConnectionToServer::didGetCount");
293 m_proxy->completeOperation(resultData);
294}
295
296void IDBConnectionToServer::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
297{
298 LOG(IndexedDB, "IDBConnectionToServer::deleteRecord");
299 ASSERT(isMainThread());
300 ASSERT(!keyRangeData.isNull);
301
302 if (m_serverConnectionIsValid)
303 m_delegate->deleteRecord(requestData, keyRangeData);
304 else
305 callResultFunctionWithErrorLater(&IDBConnectionToServer::didDeleteRecord, requestData.requestIdentifier());
306}
307
308void IDBConnectionToServer::didDeleteRecord(const IDBResultData& resultData)
309{
310 LOG(IndexedDB, "IDBConnectionToServer::didDeleteRecord");
311 m_proxy->completeOperation(resultData);
312}
313
314void IDBConnectionToServer::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
315{
316 LOG(IndexedDB, "IDBConnectionToServer::openCursor");
317 ASSERT(isMainThread());
318
319 if (m_serverConnectionIsValid)
320 m_delegate->openCursor(requestData, info);
321 else
322 callResultFunctionWithErrorLater(&IDBConnectionToServer::didOpenCursor, requestData.requestIdentifier());
323}
324
325void IDBConnectionToServer::didOpenCursor(const IDBResultData& resultData)
326{
327 LOG(IndexedDB, "IDBConnectionToServer::didOpenCursor");
328 m_proxy->completeOperation(resultData);
329}
330
331void IDBConnectionToServer::iterateCursor(const IDBRequestData& requestData, const IDBIterateCursorData& data)
332{
333 LOG(IndexedDB, "IDBConnectionToServer::iterateCursor");
334 ASSERT(isMainThread());
335
336 if (m_serverConnectionIsValid)
337 m_delegate->iterateCursor(requestData, data);
338 else
339 callResultFunctionWithErrorLater(&IDBConnectionToServer::didIterateCursor, requestData.requestIdentifier());
340}
341
342void IDBConnectionToServer::didIterateCursor(const IDBResultData& resultData)
343{
344 LOG(IndexedDB, "IDBConnectionToServer::didIterateCursor");
345 m_proxy->completeOperation(resultData);
346}
347
348void IDBConnectionToServer::establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo& info)
349{
350 LOG(IndexedDB, "IDBConnectionToServer::establishTransaction");
351 ASSERT(isMainThread());
352
353 if (m_serverConnectionIsValid)
354 m_delegate->establishTransaction(databaseConnectionIdentifier, info);
355}
356
357void IDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier)
358{
359 LOG(IndexedDB, "IDBConnectionToServer::commitTransaction");
360 ASSERT(isMainThread());
361
362 if (m_serverConnectionIsValid)
363 m_delegate->commitTransaction(transactionIdentifier);
364 else {
365 callOnMainThread([this, protectedThis = makeRef(*this), transactionIdentifier] {
366 didCommitTransaction(transactionIdentifier, IDBError::serverConnectionLostError());
367 });
368 }
369}
370
371void IDBConnectionToServer::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
372{
373 LOG(IndexedDB, "IDBConnectionToServer::didCommitTransaction");
374 ASSERT(isMainThread());
375
376 m_proxy->didCommitTransaction(transactionIdentifier, error);
377}
378
379void IDBConnectionToServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
380{
381 LOG(IndexedDB, "IDBConnectionToServer::didFinishHandlingVersionChangeTransaction");
382 ASSERT(isMainThread());
383
384 if (m_serverConnectionIsValid)
385 m_delegate->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
386}
387
388void IDBConnectionToServer::abortTransaction(const IDBResourceIdentifier& transactionIdentifier)
389{
390 LOG(IndexedDB, "IDBConnectionToServer::abortTransaction");
391 ASSERT(isMainThread());
392
393 if (m_serverConnectionIsValid)
394 m_delegate->abortTransaction(transactionIdentifier);
395 else {
396 callOnMainThread([this, protectedThis = makeRef(*this), transactionIdentifier] {
397 didAbortTransaction(transactionIdentifier, IDBError::serverConnectionLostError());
398 });
399 }
400}
401
402void IDBConnectionToServer::didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
403{
404 LOG(IndexedDB, "IDBConnectionToServer::didAbortTransaction");
405 ASSERT(isMainThread());
406
407 m_proxy->didAbortTransaction(transactionIdentifier, error);
408}
409
410void IDBConnectionToServer::fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
411{
412 LOG(IndexedDB, "IDBConnectionToServer::fireVersionChangeEvent");
413 ASSERT(isMainThread());
414
415 m_proxy->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
416}
417
418void IDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
419{
420 LOG(IndexedDB, "IDBConnectionToServer::didFireVersionChangeEvent");
421 ASSERT(isMainThread());
422
423 if (m_serverConnectionIsValid)
424 m_delegate->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
425}
426
427void IDBConnectionToServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
428{
429 LOG(IndexedDB, "IDBConnectionToServer::didStartTransaction");
430 ASSERT(isMainThread());
431
432 m_proxy->didStartTransaction(transactionIdentifier, error);
433}
434
435void IDBConnectionToServer::didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError& error)
436{
437 LOG(IndexedDB, "IDBConnectionToServer::didCloseFromServer");
438 ASSERT(isMainThread());
439
440 m_proxy->didCloseFromServer(databaseConnectionIdentifier, error);
441}
442
443void IDBConnectionToServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
444{
445 LOG(IndexedDB, "IDBConnectionToServer::confirmDidCloseFromServer");
446 ASSERT(isMainThread());
447
448 if (m_serverConnectionIsValid)
449 m_delegate->confirmDidCloseFromServer(databaseConnectionIdentifier);
450}
451
452void IDBConnectionToServer::connectionToServerLost(const IDBError& error)
453{
454 LOG(IndexedDB, "IDBConnectionToServer::connectionToServerLost");
455 ASSERT(isMainThread());
456 ASSERT(m_serverConnectionIsValid);
457
458 m_serverConnectionIsValid = false;
459 m_proxy->connectionToServerLost(error);
460}
461
462void IDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
463{
464 LOG(IndexedDB, "IDBConnectionToServer::didStartTransaction");
465 ASSERT(isMainThread());
466
467 m_proxy->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
468}
469
470void IDBConnectionToServer::openDBRequestCancelled(const IDBRequestData& requestData)
471{
472 LOG(IndexedDB, "IDBConnectionToServer::openDBRequestCancelled");
473 ASSERT(isMainThread());
474
475 if (m_serverConnectionIsValid)
476 m_delegate->openDBRequestCancelled(requestData);
477}
478
479void IDBConnectionToServer::databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier)
480{
481 LOG(IndexedDB, "IDBConnectionToServer::databaseConnectionPendingClose");
482 ASSERT(isMainThread());
483
484 if (m_serverConnectionIsValid)
485 m_delegate->databaseConnectionPendingClose(databaseConnectionIdentifier);
486}
487
488void IDBConnectionToServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
489{
490 LOG(IndexedDB, "IDBConnectionToServer::databaseConnectionClosed");
491 ASSERT(isMainThread());
492
493 if (m_serverConnectionIsValid)
494 m_delegate->databaseConnectionClosed(databaseConnectionIdentifier);
495}
496
497void IDBConnectionToServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
498{
499 LOG(IndexedDB, "IDBConnectionToServer::abortOpenAndUpgradeNeeded");
500 ASSERT(isMainThread());
501
502 if (m_serverConnectionIsValid)
503 m_delegate->abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
504}
505
506void IDBConnectionToServer::getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, Function<void (const Vector<String>&)>&& callback)
507{
508 static uint64_t callbackID = 0;
509
510 m_getAllDatabaseNamesCallbacks.add(++callbackID, WTFMove(callback));
511
512 if (m_serverConnectionIsValid)
513 m_delegate->getAllDatabaseNames(mainFrameOrigin.data(), openingOrigin.data(), callbackID);
514 else {
515 callOnMainThread([this, protectedThis = makeRef(*this), callbackID = callbackID] {
516 didGetAllDatabaseNames(callbackID, { });
517 });
518 }
519}
520
521void IDBConnectionToServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
522{
523 auto callback = m_getAllDatabaseNamesCallbacks.take(callbackID);
524 ASSERT(callback);
525
526 callback(databaseNames);
527}
528
529} // namespace IDBClient
530} // namespace WebCore
531
532#endif // ENABLE(INDEXED_DATABASE)
533