IDB: Implement cross-thread and IPC plumbing for 'get' support
[WebKit-https.git] / Source / WebKit2 / DatabaseProcess / IndexedDB / DatabaseProcessIDBConnection.cpp
1 /*
2  * Copyright (C) 2013 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 "DatabaseProcessIDBConnection.h"
28
29 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
30
31 #include "DatabaseProcess.h"
32 #include "DatabaseToWebProcessConnection.h"
33 #include "IDBTransactionIdentifier.h"
34 #include "Logging.h"
35 #include "UniqueIDBDatabase.h"
36 #include "WebCoreArgumentCoders.h"
37 #include "WebIDBServerConnectionMessages.h"
38 #include <WebCore/IDBDatabaseMetadata.h>
39 #include <WebCore/IDBServerConnection.h>
40 #include <WebCore/IndexedDB.h>
41
42 using namespace WebCore;
43
44 namespace WebKit {
45
46 DatabaseProcessIDBConnection::DatabaseProcessIDBConnection(DatabaseToWebProcessConnection& connection, uint64_t serverConnectionIdentifier)
47     : m_connection(connection)
48     , m_serverConnectionIdentifier(serverConnectionIdentifier)
49 {
50 }
51
52 DatabaseProcessIDBConnection::~DatabaseProcessIDBConnection()
53 {
54     ASSERT(!m_uniqueIDBDatabase);
55 }
56
57 void DatabaseProcessIDBConnection::disconnectedFromWebProcess()
58 {
59     m_uniqueIDBDatabase->unregisterConnection(*this);
60     m_uniqueIDBDatabase.clear();
61 }
62
63 void DatabaseProcessIDBConnection::establishConnection(const String& databaseName, const SecurityOriginData& openingOrigin, const SecurityOriginData& mainFrameOrigin)
64 {
65     m_uniqueIDBDatabase = DatabaseProcess::shared().getOrCreateUniqueIDBDatabase(UniqueIDBDatabaseIdentifier(databaseName, openingOrigin, mainFrameOrigin));
66     m_uniqueIDBDatabase->registerConnection(*this);
67 }
68
69 void DatabaseProcessIDBConnection::getOrEstablishIDBDatabaseMetadata(uint64_t requestID)
70 {
71     ASSERT(m_uniqueIDBDatabase);
72
73     LOG(IDB, "DatabaseProcess getOrEstablishIDBDatabaseMetadata request ID %llu", requestID);
74
75     RefPtr<DatabaseProcessIDBConnection> connection(this);
76     m_uniqueIDBDatabase->getOrEstablishIDBDatabaseMetadata([connection, requestID](bool success, const IDBDatabaseMetadata& metadata) {
77         connection->send(Messages::WebIDBServerConnection::DidGetOrEstablishIDBDatabaseMetadata(requestID, success, metadata));
78     });
79 }
80
81 void DatabaseProcessIDBConnection::openTransaction(uint64_t requestID, int64_t transactionID, const Vector<int64_t>& objectStoreIDs, uint64_t intMode)
82 {
83     ASSERT(m_uniqueIDBDatabase);
84
85     LOG(IDB, "DatabaseProcess openTransaction request ID %llu", requestID);
86
87     if (intMode > IndexedDB::TransactionModeMaximum) {
88         send(Messages::WebIDBServerConnection::DidOpenTransaction(requestID, false));
89         return;
90     }
91
92     IndexedDB::TransactionMode mode = static_cast<IndexedDB::TransactionMode>(intMode);
93     RefPtr<DatabaseProcessIDBConnection> connection(this);
94     m_uniqueIDBDatabase->openTransaction(IDBTransactionIdentifier(*this, transactionID), objectStoreIDs, mode, [connection, requestID](bool success) {
95         connection->send(Messages::WebIDBServerConnection::DidOpenTransaction(requestID, success));
96     });
97 }
98
99 void DatabaseProcessIDBConnection::beginTransaction(uint64_t requestID, int64_t transactionID)
100 {
101     ASSERT(m_uniqueIDBDatabase);
102
103     LOG(IDB, "DatabaseProcess beginTransaction request ID %llu", requestID);
104
105     RefPtr<DatabaseProcessIDBConnection> connection(this);
106     m_uniqueIDBDatabase->beginTransaction(IDBTransactionIdentifier(*this, transactionID), [connection, requestID](bool success) {
107         connection->send(Messages::WebIDBServerConnection::DidBeginTransaction(requestID, success));
108     });
109 }
110
111 void DatabaseProcessIDBConnection::commitTransaction(uint64_t requestID, int64_t transactionID)
112 {
113     ASSERT(m_uniqueIDBDatabase);
114
115     LOG(IDB, "DatabaseProcess commitTransaction request ID %llu", requestID);
116
117     RefPtr<DatabaseProcessIDBConnection> connection(this);
118     m_uniqueIDBDatabase->commitTransaction(IDBTransactionIdentifier(*this, transactionID), [connection, requestID](bool success) {
119         connection->send(Messages::WebIDBServerConnection::DidCommitTransaction(requestID, success));
120     });
121 }
122
123 void DatabaseProcessIDBConnection::resetTransaction(uint64_t requestID, int64_t transactionID)
124 {
125     ASSERT(m_uniqueIDBDatabase);
126
127     LOG(IDB, "DatabaseProcess resetTransaction request ID %llu", requestID);
128
129     RefPtr<DatabaseProcessIDBConnection> connection(this);
130     m_uniqueIDBDatabase->resetTransaction(IDBTransactionIdentifier(*this, transactionID), [connection, requestID](bool success) {
131         connection->send(Messages::WebIDBServerConnection::DidResetTransaction(requestID, success));
132     });
133 }
134
135 void DatabaseProcessIDBConnection::rollbackTransaction(uint64_t requestID, int64_t transactionID)
136 {
137     ASSERT(m_uniqueIDBDatabase);
138
139     LOG(IDB, "DatabaseProcess rollbackTransaction request ID %llu", requestID);
140
141     RefPtr<DatabaseProcessIDBConnection> connection(this);
142     m_uniqueIDBDatabase->rollbackTransaction(IDBTransactionIdentifier(*this, transactionID), [connection, requestID](bool success) {
143         connection->send(Messages::WebIDBServerConnection::DidRollbackTransaction(requestID, success));
144     });
145 }
146
147 void DatabaseProcessIDBConnection::changeDatabaseVersion(uint64_t requestID, int64_t transactionID, uint64_t newVersion)
148 {
149     ASSERT(m_uniqueIDBDatabase);
150
151     LOG(IDB, "DatabaseProcess changeDatabaseVersion request ID %llu, new version %llu", requestID, newVersion);
152
153     RefPtr<DatabaseProcessIDBConnection> connection(this);
154     m_uniqueIDBDatabase->changeDatabaseVersion(IDBTransactionIdentifier(*this, transactionID), newVersion, [connection, requestID](bool success) {
155         connection->send(Messages::WebIDBServerConnection::DidChangeDatabaseVersion(requestID, success));
156     });
157 }
158
159 void DatabaseProcessIDBConnection::createObjectStore(uint64_t requestID, int64_t transactionID, WebCore::IDBObjectStoreMetadata metadata)
160 {
161     ASSERT(m_uniqueIDBDatabase);
162
163     LOG(IDB, "DatabaseProcess createObjectStore request ID %llu, object store name '%s'", requestID, metadata.name.utf8().data());
164     RefPtr<DatabaseProcessIDBConnection> connection(this);
165     m_uniqueIDBDatabase->createObjectStore(IDBTransactionIdentifier(*this, transactionID), metadata, [connection, requestID](bool success) {
166         connection->send(Messages::WebIDBServerConnection::DidCreateObjectStore(requestID, success));
167     });
168 }
169
170 void DatabaseProcessIDBConnection::deleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID)
171 {
172     ASSERT(m_uniqueIDBDatabase);
173
174     LOG(IDB, "DatabaseProcess deleteObjectStore request ID %llu, object store id %lli", requestID, objectStoreID);
175     RefPtr<DatabaseProcessIDBConnection> connection(this);
176     m_uniqueIDBDatabase->deleteObjectStore(IDBTransactionIdentifier(*this, transactionID), objectStoreID, [connection, requestID](bool success) {
177         connection->send(Messages::WebIDBServerConnection::DidDeleteObjectStore(requestID, success));
178     });
179 }
180
181 void DatabaseProcessIDBConnection::putRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, const WebCore::IDBKeyData& key, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys)
182 {
183     ASSERT(m_uniqueIDBDatabase);
184
185     LOG(IDB, "DatabaseProcess putRecord request ID %llu, object store id %lli", requestID, objectStoreID);
186     RefPtr<DatabaseProcessIDBConnection> connection(this);
187     m_uniqueIDBDatabase->putRecord(IDBTransactionIdentifier(*this, transactionID), objectStoreID, key, value, putMode, indexIDs, indexKeys, [connection, requestID](const IDBKeyData& keyData, uint32_t errorCode, const String& errorMessage) {
188         connection->send(Messages::WebIDBServerConnection::DidPutRecord(requestID, keyData, errorCode, errorMessage));
189     });
190 }
191
192 void DatabaseProcessIDBConnection::getRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRange, int64_t cursorType)
193 {
194     ASSERT(m_uniqueIDBDatabase);
195
196     LOG(IDB, "DatabaseProcess getRecord request ID %llu, object store id %lli", requestID, objectStoreID);
197     RefPtr<DatabaseProcessIDBConnection> connection(this);
198     m_uniqueIDBDatabase->getRecord(IDBTransactionIdentifier(*this, transactionID), objectStoreID, indexID, keyRange, static_cast<IndexedDB::CursorType>(cursorType), [connection, requestID](const IDBGetResult& getResult, uint32_t errorCode, const String& errorMessage) {
199         connection->send(Messages::WebIDBServerConnection::DidGetRecord(requestID, getResult, errorCode, errorMessage));
200     });
201 }
202
203 IPC::Connection* DatabaseProcessIDBConnection::messageSenderConnection()
204 {
205     return m_connection->connection();
206 }
207
208 } // namespace WebKit
209
210 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)