2b6352d22064ab6173615c9ea1a7e7987cc0f172
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / UniqueIDBDatabaseConnection.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 "UniqueIDBDatabaseConnection.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBConnectionToClient.h"
32 #include "IDBServer.h"
33 #include "IDBTransactionInfo.h"
34 #include "Logging.h"
35 #include "ServerOpenDBRequest.h"
36 #include "UniqueIDBDatabase.h"
37
38 namespace WebCore {
39 namespace IDBServer {
40
41 static uint64_t nextDatabaseConnectionIdentifier()
42 {
43     static uint64_t nextIdentifier = 0;
44     return ++nextIdentifier;
45 }
46
47 Ref<UniqueIDBDatabaseConnection> UniqueIDBDatabaseConnection::create(UniqueIDBDatabase& database, ServerOpenDBRequest& request)
48 {
49     return adoptRef(*new UniqueIDBDatabaseConnection(database, request));
50 }
51
52 UniqueIDBDatabaseConnection::UniqueIDBDatabaseConnection(UniqueIDBDatabase& database, ServerOpenDBRequest& request)
53     : m_identifier(nextDatabaseConnectionIdentifier())
54     , m_database(database)
55     , m_connectionToClient(request.connection())
56     , m_openRequestIdentifier(request.requestData().requestIdentifier())
57 {
58     m_database.server().registerDatabaseConnection(*this);
59     m_connectionToClient.registerDatabaseConnection(*this);
60 }
61
62 UniqueIDBDatabaseConnection::~UniqueIDBDatabaseConnection()
63 {
64     m_database.server().unregisterDatabaseConnection(*this);
65     m_connectionToClient.unregisterDatabaseConnection(*this);
66 }
67
68 bool UniqueIDBDatabaseConnection::hasNonFinishedTransactions() const
69 {
70     return !m_transactionMap.isEmpty();
71 }
72
73 void UniqueIDBDatabaseConnection::abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction& transaction)
74 {
75     ASSERT(m_transactionMap.contains(transaction.info().identifier()));
76
77     const auto& transactionIdentifier = transaction.info().identifier();
78     RefPtr<UniqueIDBDatabaseConnection> protectedThis(this);
79
80     m_database.abortTransaction(transaction, [this, protectedThis, transactionIdentifier](const IDBError&) {
81         ASSERT(m_transactionMap.contains(transactionIdentifier));
82         m_transactionMap.remove(transactionIdentifier);
83     });
84 }
85
86 void UniqueIDBDatabaseConnection::connectionClosedFromClient()
87 {
88     LOG(IndexedDB, "UniqueIDBDatabaseConnection::connectionClosedFromClient - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
89
90     m_closePending = true;
91     m_database.connectionClosedFromClient(*this);
92 }
93
94 void UniqueIDBDatabaseConnection::confirmDidCloseFromServer()
95 {
96     LOG(IndexedDB, "UniqueIDBDatabaseConnection::confirmDidCloseFromServer - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
97
98     m_database.confirmDidCloseFromServer(*this);
99 }
100
101 void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier)
102 {
103     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFireVersionChangeEvent - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
104
105     m_database.didFireVersionChangeEvent(*this, requestIdentifier);
106 }
107
108 void UniqueIDBDatabaseConnection::didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier)
109 {
110     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFinishHandlingVersionChange - %s - %" PRIu64, transactionIdentifier.loggingString().utf8().data(), m_identifier);
111
112     m_database.didFinishHandlingVersionChange(*this, transactionIdentifier);
113 }
114
115 void UniqueIDBDatabaseConnection::fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
116 {
117     ASSERT(!m_closePending);
118     m_connectionToClient.fireVersionChangeEvent(*this, requestIdentifier, requestedVersion);
119 }
120
121 UniqueIDBDatabaseTransaction& UniqueIDBDatabaseConnection::createVersionChangeTransaction(uint64_t newVersion)
122 {
123     LOG(IndexedDB, "UniqueIDBDatabaseConnection::createVersionChangeTransaction - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
124     ASSERT(!m_closePending);
125
126     IDBTransactionInfo info = IDBTransactionInfo::versionChange(m_connectionToClient, m_database.info(), newVersion);
127
128     Ref<UniqueIDBDatabaseTransaction> transaction = UniqueIDBDatabaseTransaction::create(*this, info);
129     m_transactionMap.set(transaction->info().identifier(), &transaction.get());
130
131     return transaction.get();
132 }
133
134 void UniqueIDBDatabaseConnection::establishTransaction(const IDBTransactionInfo& info)
135 {
136     LOG(IndexedDB, "UniqueIDBDatabaseConnection::establishTransaction - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
137
138     ASSERT(info.mode() != IDBTransactionMode::Versionchange);
139
140     // No transactions should ever come from the client after the client has already told us
141     // the connection is closing.
142     ASSERT(!m_closePending);
143
144     Ref<UniqueIDBDatabaseTransaction> transaction = UniqueIDBDatabaseTransaction::create(*this, info);
145     m_transactionMap.set(transaction->info().identifier(), &transaction.get());
146     m_database.enqueueTransaction(WTFMove(transaction));
147 }
148
149 void UniqueIDBDatabaseConnection::didAbortTransaction(UniqueIDBDatabaseTransaction& transaction, const IDBError& error)
150 {
151     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didAbortTransaction - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
152
153     auto transactionIdentifier = transaction.info().identifier();
154     auto takenTransaction = m_transactionMap.take(transactionIdentifier);
155
156     ASSERT(takenTransaction || m_database.hardClosedForUserDelete());
157     if (takenTransaction)
158         m_connectionToClient.didAbortTransaction(transactionIdentifier, error);
159 }
160
161 void UniqueIDBDatabaseConnection::didCommitTransaction(UniqueIDBDatabaseTransaction& transaction, const IDBError& error)
162 {
163     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didCommitTransaction - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), m_identifier);
164
165     auto transactionIdentifier = transaction.info().identifier();
166
167     ASSERT(m_transactionMap.contains(transactionIdentifier));
168     m_transactionMap.remove(transactionIdentifier);
169
170     m_connectionToClient.didCommitTransaction(transactionIdentifier, error);
171 }
172
173 void UniqueIDBDatabaseConnection::didCreateObjectStore(const IDBResultData& resultData)
174 {
175     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didCreateObjectStore");
176
177     m_connectionToClient.didCreateObjectStore(resultData);
178 }
179
180 void UniqueIDBDatabaseConnection::didDeleteObjectStore(const IDBResultData& resultData)
181 {
182     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didDeleteObjectStore");
183
184     m_connectionToClient.didDeleteObjectStore(resultData);
185 }
186
187 void UniqueIDBDatabaseConnection::didRenameObjectStore(const IDBResultData& resultData)
188 {
189     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didRenameObjectStore");
190
191     m_connectionToClient.didRenameObjectStore(resultData);
192 }
193
194 void UniqueIDBDatabaseConnection::didClearObjectStore(const IDBResultData& resultData)
195 {
196     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didClearObjectStore");
197
198     m_connectionToClient.didClearObjectStore(resultData);
199 }
200
201 void UniqueIDBDatabaseConnection::didCreateIndex(const IDBResultData& resultData)
202 {
203     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didCreateIndex");
204
205     m_connectionToClient.didCreateIndex(resultData);
206 }
207
208 void UniqueIDBDatabaseConnection::didDeleteIndex(const IDBResultData& resultData)
209 {
210     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didDeleteIndex");
211
212     m_connectionToClient.didDeleteIndex(resultData);
213 }
214
215 void UniqueIDBDatabaseConnection::didRenameIndex(const IDBResultData& resultData)
216 {
217     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didRenameIndex");
218
219     m_connectionToClient.didRenameIndex(resultData);
220 }
221
222 } // namespace IDBServer
223 } // namespace WebCore
224
225 #endif // ENABLE(INDEXED_DATABASE)