1/*
2 * Copyright (C) 2016 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#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "IDBConnectionToServer.h"
31#include "IDBResourceIdentifier.h"
32#include "TransactionOperation.h"
33#include <wtf/CrossThreadQueue.h>
34#include <wtf/CrossThreadTask.h>
35#include <wtf/Forward.h>
36#include <wtf/Function.h>
37#include <wtf/HashMap.h>
38#include <wtf/MainThread.h>
39#include <wtf/RefPtr.h>
40#include <wtf/text/WTFString.h>
41
42namespace WebCore {
43
44class IDBDatabase;
45class IDBDatabaseIdentifier;
46class IDBError;
47class IDBOpenDBRequest;
48class IDBResultData;
49class IDBTransaction;
50class ScriptExecutionContext;
51class SecurityOrigin;
52
53struct IDBGetRecordData;
54struct IDBIterateCursorData;
55
56namespace IDBClient {
57
58class IDBConnectionToServer;
59
60class IDBConnectionProxy {
61 WTF_MAKE_NONCOPYABLE(IDBConnectionProxy);
62 WTF_MAKE_FAST_ALLOCATED;
63public:
64 IDBConnectionProxy(IDBConnectionToServer&);
65
66 Ref<IDBOpenDBRequest> openDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&, uint64_t version);
67 void didOpenDatabase(const IDBResultData&);
68
69 Ref<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&);
70 void didDeleteDatabase(const IDBResultData&);
71
72 void createObjectStore(TransactionOperation&, const IDBObjectStoreInfo&);
73 void deleteObjectStore(TransactionOperation&, const String& objectStoreName);
74 void clearObjectStore(TransactionOperation&, uint64_t objectStoreIdentifier);
75 void createIndex(TransactionOperation&, const IDBIndexInfo&);
76 void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
77 void putOrAdd(TransactionOperation&, IDBKeyData&&, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
78 void getRecord(TransactionOperation&, const IDBGetRecordData&);
79 void getAllRecords(TransactionOperation&, const IDBGetAllRecordsData&);
80 void getCount(TransactionOperation&, const IDBKeyRangeData&);
81 void deleteRecord(TransactionOperation&, const IDBKeyRangeData&);
82 void openCursor(TransactionOperation&, const IDBCursorInfo&);
83 void iterateCursor(TransactionOperation&, const IDBIterateCursorData&);
84 void renameObjectStore(TransactionOperation&, uint64_t objectStoreIdentifier, const String& newName);
85 void renameIndex(TransactionOperation&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName);
86
87 void fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
88 void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
89
90 void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
91 void openDBRequestCancelled(const IDBRequestData&);
92
93 void establishTransaction(IDBTransaction&);
94 void commitTransaction(IDBTransaction&);
95 void abortTransaction(IDBTransaction&);
96
97 void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
98 void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
99 void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
100
101 void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction&);
102 void databaseConnectionPendingClose(IDBDatabase&);
103 void databaseConnectionClosed(IDBDatabase&);
104
105 void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
106 void confirmDidCloseFromServer(IDBDatabase&);
107
108 void connectionToServerLost(const IDBError&);
109
110 void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
111
112 void completeOperation(const IDBResultData&);
113
114 uint64_t serverConnectionIdentifier() const { return m_serverConnectionIdentifier; }
115
116 void ref();
117 void deref();
118
119 void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, WTF::Function<void (const Vector<String>&)>&&);
120
121 void registerDatabaseConnection(IDBDatabase&);
122 void unregisterDatabaseConnection(IDBDatabase&);
123
124 void forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>&);
125 void forgetTransaction(IDBTransaction&);
126 void forgetActivityForCurrentThread();
127
128private:
129 void completeOpenDBRequest(const IDBResultData&);
130 bool hasRecordOfTransaction(const IDBTransaction&) const;
131
132 void saveOperation(TransactionOperation&);
133
134 template<typename... Parameters, typename... Arguments>
135 void callConnectionOnMainThread(void (IDBConnectionToServer::*method)(Parameters...), Arguments&&... arguments)
136 {
137 if (isMainThread())
138 (m_connectionToServer.*method)(std::forward<Arguments>(arguments)...);
139 else
140 postMainThreadTask(m_connectionToServer, method, arguments...);
141 }
142
143 template<typename... Arguments>
144 void postMainThreadTask(Arguments&&... arguments)
145 {
146 auto task = createCrossThreadTask(arguments...);
147 m_mainThreadQueue.append(WTFMove(task));
148
149 scheduleMainThreadTasks();
150 }
151
152 void scheduleMainThreadTasks();
153 void handleMainThreadTasks();
154
155 IDBConnectionToServer& m_connectionToServer;
156 uint64_t m_serverConnectionIdentifier;
157
158 HashMap<uint64_t, IDBDatabase*> m_databaseConnectionMap;
159 Lock m_databaseConnectionMapLock;
160
161 HashMap<IDBResourceIdentifier, RefPtr<IDBOpenDBRequest>> m_openDBRequestMap;
162 Lock m_openDBRequestMapLock;
163
164 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_pendingTransactions;
165 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_committingTransactions;
166 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_abortingTransactions;
167 Lock m_transactionMapLock;
168
169 HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_activeOperations;
170 Lock m_transactionOperationLock;
171
172 CrossThreadQueue<CrossThreadTask> m_mainThreadQueue;
173 Lock m_mainThreadTaskLock;
174 RefPtr<IDBConnectionToServer> m_mainThreadProtector;
175};
176
177} // namespace IDBClient
178} // namespace WebCore
179
180#endif // ENABLE(INDEXED_DATABASE)
181