2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "WebIDBServerConnection.h"
30 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
32 #include "AsyncRequest.h"
33 #include "DataReference.h"
34 #include "DatabaseProcessIDBConnectionMessages.h"
35 #include "DatabaseToWebProcessConnectionMessages.h"
37 #include "SecurityOriginData.h"
38 #include "WebProcess.h"
39 #include "WebToDatabaseProcessConnection.h"
40 #include <WebCore/IDBDatabaseMetadata.h>
41 #include <WebCore/SecurityOrigin.h>
43 using namespace WebCore;
47 static uint64_t generateServerConnectionIdentifier()
49 ASSERT(isMainThread());
50 static uint64_t identifier = 0;
54 PassRefPtr<WebIDBServerConnection> WebIDBServerConnection::create(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
56 RefPtr<WebIDBServerConnection> result = adoptRef(new WebIDBServerConnection(databaseName, openingOrigin, mainFrameOrigin));
57 WebProcess::shared().webToDatabaseProcessConnection()->registerWebIDBServerConnection(*result);
58 return result.release();
61 WebIDBServerConnection::WebIDBServerConnection(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
62 : m_serverConnectionIdentifier(generateServerConnectionIdentifier())
63 , m_databaseName(databaseName)
64 , m_openingOrigin(*openingOrigin.isolatedCopy())
65 , m_mainFrameOrigin(*mainFrameOrigin.isolatedCopy())
67 send(Messages::DatabaseToWebProcessConnection::EstablishIDBConnection(m_serverConnectionIdentifier));
68 send(Messages::DatabaseProcessIDBConnection::EstablishConnection(databaseName, SecurityOriginData::fromSecurityOrigin(&openingOrigin), SecurityOriginData::fromSecurityOrigin(&mainFrameOrigin)));
71 WebIDBServerConnection::~WebIDBServerConnection()
73 WebProcess::shared().webToDatabaseProcessConnection()->removeWebIDBServerConnection(*this);
75 for (const auto& it : m_serverRequests)
76 it.value->requestAborted();
79 bool WebIDBServerConnection::isClosed()
81 // FIXME: Return real value here.
85 void WebIDBServerConnection::deleteDatabase(const String& name, BoolCallbackFunction successCallback)
89 void WebIDBServerConnection::getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction completionCallback)
91 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<const IDBDatabaseMetadata&, bool>::create(completionCallback);
93 serverRequest->setAbortHandler([completionCallback]() {
94 IDBDatabaseMetadata metadata;
95 completionCallback(metadata, false);
98 uint64_t requestID = serverRequest->requestID();
99 ASSERT(!m_serverRequests.contains(requestID));
100 m_serverRequests.add(requestID, serverRequest.release());
102 LOG(IDB, "WebProcess getOrEstablishIDBDatabaseMetadata request ID %llu", requestID);
104 send(Messages::DatabaseProcessIDBConnection::GetOrEstablishIDBDatabaseMetadata(requestID));
107 void WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata(uint64_t requestID, bool success, const IDBDatabaseMetadata& metadata)
109 LOG(IDB, "WebProcess didGetOrEstablishIDBDatabaseMetadata request ID %llu", requestID);
111 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
116 serverRequest->completeRequest(metadata, success);
119 void WebIDBServerConnection::close()
123 void WebIDBServerConnection::openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode, BoolCallbackFunction successCallback)
125 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
127 serverRequest->setAbortHandler([successCallback]() {
128 successCallback(false);
131 uint64_t requestID = serverRequest->requestID();
132 ASSERT(!m_serverRequests.contains(requestID));
133 m_serverRequests.add(requestID, serverRequest.release());
135 LOG(IDB, "WebProcess openTransaction ID %lli (request ID %llu)", transactionID, requestID);
137 Vector<int64_t> objectStoreIDVector;
138 copyToVector(objectStoreIDs, objectStoreIDVector);
139 send(Messages::DatabaseProcessIDBConnection::OpenTransaction(requestID, transactionID, objectStoreIDVector, static_cast<uint64_t>(mode)));
142 void WebIDBServerConnection::didOpenTransaction(uint64_t requestID, bool success)
144 LOG(IDB, "WebProcess didOpenTransaction request ID %llu", requestID);
146 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
151 serverRequest->completeRequest(success);
154 void WebIDBServerConnection::beginTransaction(int64_t transactionID, std::function<void()> completionCallback)
156 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
158 uint64_t requestID = serverRequest->requestID();
159 ASSERT(!m_serverRequests.contains(requestID));
160 m_serverRequests.add(requestID, serverRequest.release());
162 LOG(IDB, "WebProcess beginTransaction ID %lli (request ID %llu)", transactionID, requestID);
164 send(Messages::DatabaseProcessIDBConnection::BeginTransaction(requestID, transactionID));
167 void WebIDBServerConnection::didBeginTransaction(uint64_t requestID, bool)
169 LOG(IDB, "WebProcess didBeginTransaction request ID %llu", requestID);
171 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
176 serverRequest->completeRequest();
179 void WebIDBServerConnection::commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback)
181 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
183 serverRequest->setAbortHandler([successCallback]() {
184 successCallback(false);
187 uint64_t requestID = serverRequest->requestID();
188 ASSERT(!m_serverRequests.contains(requestID));
189 m_serverRequests.add(requestID, serverRequest.release());
191 LOG(IDB, "WebProcess commitTransaction ID %lli (request ID %llu)", transactionID, requestID);
193 send(Messages::DatabaseProcessIDBConnection::CommitTransaction(requestID, transactionID));
196 void WebIDBServerConnection::didCommitTransaction(uint64_t requestID, bool success)
198 LOG(IDB, "WebProcess didCommitTransaction request ID %llu", requestID);
200 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
205 serverRequest->completeRequest(success);
208 void WebIDBServerConnection::resetTransaction(int64_t transactionID, std::function<void()> completionCallback)
210 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
212 uint64_t requestID = serverRequest->requestID();
213 ASSERT(!m_serverRequests.contains(requestID));
214 m_serverRequests.add(requestID, serverRequest.release());
216 LOG(IDB, "WebProcess resetTransaction ID %lli (request ID %llu)", transactionID, requestID);
218 send(Messages::DatabaseProcessIDBConnection::ResetTransaction(requestID, transactionID));
221 void WebIDBServerConnection::didResetTransaction(uint64_t requestID, bool)
223 LOG(IDB, "WebProcess didResetTransaction request ID %llu", requestID);
225 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
230 serverRequest->completeRequest();
233 void WebIDBServerConnection::rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback)
235 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
237 uint64_t requestID = serverRequest->requestID();
238 ASSERT(!m_serverRequests.contains(requestID));
239 m_serverRequests.add(requestID, serverRequest.release());
241 LOG(IDB, "WebProcess rollbackTransaction ID %lli (request ID %llu)", transactionID, requestID);
243 send(Messages::DatabaseProcessIDBConnection::RollbackTransaction(requestID, transactionID));
246 void WebIDBServerConnection::didRollbackTransaction(uint64_t requestID, bool)
248 LOG(IDB, "WebProcess didRollbackTransaction request ID %llu", requestID);
250 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
255 serverRequest->completeRequest();
258 void WebIDBServerConnection::setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
262 void WebIDBServerConnection::createObjectStore(IDBTransactionBackend& transaction, const CreateObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
264 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
266 String objectStoreName = operation.objectStoreMetadata().name;
267 serverRequest->setAbortHandler([objectStoreName, completionCallback]() {
268 completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Unknown error occured creating object store '%s'", objectStoreName.utf8().data())));
271 uint64_t requestID = serverRequest->requestID();
272 ASSERT(!m_serverRequests.contains(requestID));
273 m_serverRequests.add(requestID, serverRequest.release());
275 LOG(IDB, "WebProcess createObjectStore '%s' in transaction ID %llu (request ID %llu)", operation.objectStoreMetadata().name.utf8().data(), transaction.id(), requestID);
277 send(Messages::DatabaseProcessIDBConnection::CreateObjectStore(requestID, transaction.id(), operation.objectStoreMetadata()));
280 void WebIDBServerConnection::didCreateObjectStore(uint64_t requestID, bool success)
282 LOG(IDB, "WebProcess didCreateObjectStore request ID %llu", requestID);
284 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
289 serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured creating object store"));
292 void WebIDBServerConnection::createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
296 void WebIDBServerConnection::deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
300 void WebIDBServerConnection::get(IDBTransactionBackend&, const GetOperation&, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback)
304 void WebIDBServerConnection::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
306 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
308 serverRequest->setAbortHandler([completionCallback]() {
309 completionCallback(nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured putting record"));
312 uint64_t requestID = serverRequest->requestID();
313 ASSERT(!m_serverRequests.contains(requestID));
314 m_serverRequests.add(requestID, serverRequest.release());
316 LOG(IDB, "WebProcess put request ID %llu", requestID);
318 ASSERT(operation.key());
319 ASSERT(operation.value());
321 IPC::DataReference value(reinterpret_cast<const uint8_t*>(operation.value()->data()), operation.value()->size());
323 Vector<Vector<IDBKeyData>> indexKeys;
324 for (auto keys : operation.indexKeys()) {
325 indexKeys.append(Vector<IDBKeyData>());
326 for (auto key : keys)
327 indexKeys.last().append(IDBKeyData(key.get()));
330 send(Messages::DatabaseProcessIDBConnection::PutRecord(requestID, transaction.id(), operation.objectStore().id, IDBKeyData(operation.key()), value, operation.putMode(), operation.indexIDs(), indexKeys));
333 void WebIDBServerConnection::didPutRecord(uint64_t requestID, const WebCore::IDBKeyData& resultKey, uint32_t errorCode, const String& errorMessage)
335 LOG(IDB, "WebProcess didPutRecord request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
337 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
342 serverRequest->completeRequest(resultKey.isNull ? nullptr : resultKey.maybeCreateIDBKey(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
345 void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
349 void WebIDBServerConnection::count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
353 void WebIDBServerConnection::deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
357 void WebIDBServerConnection::clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
361 void WebIDBServerConnection::deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
363 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
365 serverRequest->setAbortHandler([completionCallback]() {
366 completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
369 uint64_t requestID = serverRequest->requestID();
370 ASSERT(!m_serverRequests.contains(requestID));
371 m_serverRequests.add(requestID, serverRequest.release());
373 LOG(IDB, "WebProcess deleteObjectStore request ID %llu", requestID);
375 send(Messages::DatabaseProcessIDBConnection::DeleteObjectStore(requestID, operation.transaction()->id(), operation.objectStoreMetadata().id));
378 void WebIDBServerConnection::didDeleteObjectStore(uint64_t requestID, bool success)
380 LOG(IDB, "WebProcess didDeleteObjectStore request ID %llu", requestID);
382 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
387 serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
390 void WebIDBServerConnection::changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
392 RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
394 serverRequest->setAbortHandler([completionCallback]() {
395 completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
398 uint64_t requestID = serverRequest->requestID();
399 ASSERT(!m_serverRequests.contains(requestID));
400 m_serverRequests.add(requestID, serverRequest.release());
402 LOG(IDB, "WebProcess changeDatabaseVersion request ID %llu", requestID);
404 send(Messages::DatabaseProcessIDBConnection::ChangeDatabaseVersion(requestID, operation.transaction()->id(), static_cast<uint64_t>(operation.version())));
407 void WebIDBServerConnection::didChangeDatabaseVersion(uint64_t requestID, bool success)
409 LOG(IDB, "WebProcess didChangeDatabaseVersion request ID %llu", requestID);
411 RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
416 serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
419 void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void()> completionCallback)
423 void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void()> completionCallback)
427 void WebIDBServerConnection::cursorPrefetchIteration(IDBCursorBackend&, const CursorPrefetchIterationOperation&, std::function<void()> completionCallback)
431 void WebIDBServerConnection::cursorPrefetchReset(IDBCursorBackend&, int usedPrefetches)
435 IPC::Connection* WebIDBServerConnection::messageSenderConnection()
437 return WebProcess::shared().webToDatabaseProcessConnection()->connection();
440 } // namespace WebKit
442 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)