Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp

Issue 2349413002: Minor IndexedDB refactorings. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 28 matching lines...) Expand all
39 #include "modules/indexeddb/IDBObjectStore.h" 39 #include "modules/indexeddb/IDBObjectStore.h"
40 #include "modules/indexeddb/IDBOpenDBRequest.h" 40 #include "modules/indexeddb/IDBOpenDBRequest.h"
41 #include "modules/indexeddb/IDBTracing.h" 41 #include "modules/indexeddb/IDBTracing.h"
42 #include "wtf/PtrUtil.h" 42 #include "wtf/PtrUtil.h"
43 #include <memory> 43 #include <memory>
44 44
45 using blink::WebIDBDatabase; 45 using blink::WebIDBDatabase;
46 46
47 namespace blink { 47 namespace blink {
48 48
49 IDBTransaction* IDBTransaction::create(ScriptState* scriptState, int64_t id, con st HashSet<String>& objectStoreNames, WebIDBTransactionMode mode, IDBDatabase* d b) 49 IDBTransaction* IDBTransaction::createNonVersionChange(ScriptState* scriptState, int64_t id, const HashSet<String>& objectStoreNames, WebIDBTransactionMode mode , IDBDatabase* db)
50 { 50 {
51 DCHECK_NE(mode, WebIDBTransactionModeVersionChange);
52 DCHECK(!objectStoreNames.isEmpty()) << "Non-version transactions should oper ate on a well-defined set of stores";
cmumford 2016/09/19 23:26:48 Add a space before 'Non'
pwnall 2016/09/20 09:11:14 I apologize in advance for being clueless, but can
51 IDBOpenDBRequest* openDBRequest = nullptr; 53 IDBOpenDBRequest* openDBRequest = nullptr;
52 IDBTransaction* transaction = new IDBTransaction(scriptState, id, objectStor eNames, mode, db, openDBRequest, IDBDatabaseMetadata()); 54 IDBTransaction* transaction = new IDBTransaction(scriptState, id, objectStor eNames, mode, db, openDBRequest, IDBDatabaseMetadata());
53 transaction->suspendIfNeeded(); 55 transaction->suspendIfNeeded();
54 return transaction; 56 return transaction;
55 } 57 }
56 58
57 IDBTransaction* IDBTransaction::create(ScriptState* scriptState, int64_t id, IDB Database* db, IDBOpenDBRequest* openDBRequest, const IDBDatabaseMetadata& previo usMetadata) 59 IDBTransaction* IDBTransaction::createVersionChange(ScriptState* scriptState, in t64_t id, IDBDatabase* db, IDBOpenDBRequest* openDBRequest, const IDBDatabaseMet adata& oldMetadata)
58 { 60 {
59 IDBTransaction* transaction = new IDBTransaction(scriptState, id, HashSet<St ring>(), WebIDBTransactionModeVersionChange, db, openDBRequest, previousMetadata ); 61 IDBTransaction* transaction = new IDBTransaction(scriptState, id, HashSet<St ring>(), WebIDBTransactionModeVersionChange, db, openDBRequest, oldMetadata);
60 transaction->suspendIfNeeded(); 62 transaction->suspendIfNeeded();
61 return transaction; 63 return transaction;
62 } 64 }
63 65
64 namespace { 66 namespace {
65 67
66 class DeactivateTransactionTask : public V8PerIsolateData::EndOfScopeTask { 68 class DeactivateTransactionTask : public V8PerIsolateData::EndOfScopeTask {
67 public: 69 public:
68 static std::unique_ptr<DeactivateTransactionTask> create(IDBTransaction* tra nsaction) 70 static std::unique_ptr<DeactivateTransactionTask> create(IDBTransaction* tra nsaction)
69 { 71 {
70 return wrapUnique(new DeactivateTransactionTask(transaction)); 72 return wrapUnique(new DeactivateTransactionTask(transaction));
71 } 73 }
72 74
73 void run() override 75 void run() override
74 { 76 {
75 m_transaction->setActive(false); 77 m_transaction->setActive(false);
76 m_transaction.clear(); 78 m_transaction.clear();
77 } 79 }
78 80
79 private: 81 private:
80 explicit DeactivateTransactionTask(IDBTransaction* transaction) 82 explicit DeactivateTransactionTask(IDBTransaction* transaction)
81 : m_transaction(transaction) { } 83 : m_transaction(transaction) { }
82 84
83 Persistent<IDBTransaction> m_transaction; 85 Persistent<IDBTransaction> m_transaction;
84 }; 86 };
85 87
86 } // namespace 88 } // namespace
87 89
88 IDBTransaction::IDBTransaction(ScriptState* scriptState, int64_t id, const HashS et<String>& objectStoreNames, WebIDBTransactionMode mode, IDBDatabase* db, IDBOp enDBRequest* openDBRequest, const IDBDatabaseMetadata& previousMetadata) 90 IDBTransaction::IDBTransaction(ScriptState* scriptState, int64_t id, const HashS et<String>& objectStoreNames, WebIDBTransactionMode mode, IDBDatabase* db, IDBOp enDBRequest* openDBRequest, const IDBDatabaseMetadata& oldMetadata)
89 : ActiveScriptWrappable(this) 91 : ActiveScriptWrappable(this)
90 , ActiveDOMObject(scriptState->getExecutionContext()) 92 , ActiveDOMObject(scriptState->getExecutionContext())
91 , m_id(id) 93 , m_id(id)
92 , m_database(db) 94 , m_database(db)
93 , m_objectStoreNames(objectStoreNames) 95 , m_scope(objectStoreNames)
cmumford 2016/09/19 23:26:48 Nit: It does seem a bit odd to have a public name
pwnall 2016/09/20 09:11:14 I agree that it does seem weird. Here is my ration
94 , m_openDBRequest(openDBRequest) 96 , m_openDBRequest(openDBRequest)
95 , m_mode(mode) 97 , m_mode(mode)
96 , m_previousMetadata(previousMetadata) 98 , m_oldDatabaseMetadata(oldMetadata)
97 { 99 {
98 if (mode == WebIDBTransactionModeVersionChange) { 100 if (isVersionChange()) {
cmumford 2016/09/19 23:26:48 Is there a need to DCHECK mode?
pwnall 2016/09/20 09:11:14 We got by without it, but it seems like a good ide
101 DCHECK(objectStoreNames.isEmpty());
102
99 // Not active until the callback. 103 // Not active until the callback.
100 m_state = Inactive; 104 m_state = Inactive;
105 } else {
106 DCHECK(!objectStoreNames.isEmpty()) << "Non-versionchange transactions m ust operate on a well-defined set of stores";
cmumford 2016/09/19 23:26:48 Space before 'Non'
pwnall 2016/09/20 09:11:14 The same question as above applies. After I unders
101 } 107 }
102 108
103 if (m_state == Active) 109 if (m_state == Active)
104 V8PerIsolateData::from(scriptState->isolate())->addEndOfScopeTask(Deacti vateTransactionTask::create(this)); 110 V8PerIsolateData::from(scriptState->isolate())->addEndOfScopeTask(Deacti vateTransactionTask::create(this));
105 m_database->transactionCreated(this); 111 m_database->transactionCreated(this);
106 } 112 }
107 113
108 IDBTransaction::~IDBTransaction() 114 IDBTransaction::~IDBTransaction()
109 { 115 {
110 ASSERT(m_state == Finished || m_contextStopped); 116 ASSERT(m_state == Finished || m_contextStopped);
111 ASSERT(m_requestList.isEmpty() || m_contextStopped); 117 ASSERT(m_requestList.isEmpty() || m_contextStopped);
112 } 118 }
113 119
114 DEFINE_TRACE(IDBTransaction) 120 DEFINE_TRACE(IDBTransaction)
115 { 121 {
116 visitor->trace(m_database); 122 visitor->trace(m_database);
117 visitor->trace(m_openDBRequest); 123 visitor->trace(m_openDBRequest);
118 visitor->trace(m_error); 124 visitor->trace(m_error);
119 visitor->trace(m_requestList); 125 visitor->trace(m_requestList);
120 visitor->trace(m_objectStoreMap); 126 visitor->trace(m_objectStoreMap);
121 visitor->trace(m_createdObjectStores); 127 visitor->trace(m_createdObjectStores);
122 visitor->trace(m_deletedObjectStores); 128 visitor->trace(m_deletedObjectStores);
123 visitor->trace(m_objectStoreCleanupMap); 129 visitor->trace(m_objectStoreCleanupMap);
124 EventTargetWithInlineData::trace(visitor); 130 EventTargetWithInlineData::trace(visitor);
125 ActiveDOMObject::trace(visitor); 131 ActiveDOMObject::trace(visitor);
126 } 132 }
127 133
128 void IDBTransaction::setError(DOMException* error) 134 void IDBTransaction::setError(DOMException* error)
129 { 135 {
130 ASSERT(m_state != Finished); 136 DCHECK_NE(m_state, Finished);
131 ASSERT(error); 137 DCHECK(error);
132 138
133 // The first error to be set is the true cause of the 139 // The first error to be set is the true cause of the
134 // transaction abort. 140 // transaction abort.
135 if (!m_error) { 141 if (!m_error) {
136 m_error = error; 142 m_error = error;
137 } 143 }
138 } 144 }
139 145
140 IDBObjectStore* IDBTransaction::objectStore(const String& name, ExceptionState& exceptionState) 146 IDBObjectStore* IDBTransaction::objectStore(const String& name, ExceptionState& exceptionState)
141 { 147 {
142 if (m_state == Finished) { 148 if (isFinished()) {
143 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); 149 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage);
144 return nullptr; 150 return nullptr;
145 } 151 }
146 152
147 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name); 153 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
148 if (it != m_objectStoreMap.end()) 154 if (it != m_objectStoreMap.end())
149 return it->value; 155 return it->value;
150 156
151 if (!isVersionChange() && !m_objectStoreNames.contains(name)) { 157 if (!isVersionChange() && !m_scope.contains(name)) {
152 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage); 158 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage);
153 return nullptr; 159 return nullptr;
154 } 160 }
155 161
156 int64_t objectStoreId = m_database->findObjectStoreId(name); 162 int64_t objectStoreId = m_database->findObjectStoreId(name);
157 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { 163 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) {
158 ASSERT(isVersionChange()); 164 ASSERT(isVersionChange());
159 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage); 165 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage);
160 return nullptr; 166 return nullptr;
161 } 167 }
162 168
163 const IDBDatabaseMetadata& metadata = m_database->metadata(); 169 DCHECK(m_database->metadata().objectStores.contains(objectStoreId));
170 const IDBObjectStoreMetadata& objectStoreMetadata = m_database->metadata().o bjectStores.get(objectStoreId);
164 171
165 IDBObjectStore* objectStore = IDBObjectStore::create(metadata.objectStores.g et(objectStoreId), this); 172 IDBObjectStore* objectStore = IDBObjectStore::create(objectStoreMetadata, th is);
173 DCHECK(!m_objectStoreMap.contains(name));
166 m_objectStoreMap.set(name, objectStore); 174 m_objectStoreMap.set(name, objectStore);
167 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 175 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
168 return objectStore; 176 return objectStore;
169 } 177 }
170 178
171 void IDBTransaction::objectStoreCreated(const String& name, IDBObjectStore* obje ctStore) 179 void IDBTransaction::objectStoreCreated(const String& name, IDBObjectStore* obje ctStore)
172 { 180 {
173 ASSERT(m_state != Finished); 181 DCHECK_NE(m_state, Finished) << "A finished transaction created an object st ore";
cmumford 2016/09/19 23:26:48 spaces before these (and all) strings, so: DCHE
pwnall 2016/09/20 09:11:14 The same question as above applies. After I unders
174 ASSERT(isVersionChange()); 182 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction created an object store";
183 DCHECK(!m_objectStoreMap.contains(name)) << "An object store was created wit h the name of an existing store";
175 m_objectStoreMap.set(name, objectStore); 184 m_objectStoreMap.set(name, objectStore);
176 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 185 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
177 m_createdObjectStores.add(objectStore); 186 m_createdObjectStores.add(objectStore);
178 } 187 }
179 188
180 void IDBTransaction::objectStoreDeleted(const String& name) 189 void IDBTransaction::objectStoreDeleted(const String& name)
181 { 190 {
182 ASSERT(m_state != Finished); 191 DCHECK_NE(m_state, Finished) << "A finished transaction deleted an object st ore";
183 ASSERT(isVersionChange()); 192 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction deleted an object store";
184 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name); 193 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
185 if (it != m_objectStoreMap.end()) { 194 if (it != m_objectStoreMap.end()) {
186 IDBObjectStore* objectStore = it->value; 195 IDBObjectStore* objectStore = it->value;
187 m_objectStoreMap.remove(name); 196 m_objectStoreMap.remove(name);
188 objectStore->markDeleted(); 197 objectStore->markDeleted();
189 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 198 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
190 m_deletedObjectStores.add(objectStore); 199 m_deletedObjectStores.add(objectStore);
191 } 200 }
192 } 201 }
193 202
194 void IDBTransaction::objectStoreRenamed(const String& oldName, const String& new Name) 203 void IDBTransaction::objectStoreRenamed(const String& oldName, const String& new Name)
195 { 204 {
196 DCHECK(m_state != Finished); 205 DCHECK_NE(m_state, Finished) << "A finished transaction renamed an object st ore";
197 DCHECK(isVersionChange()); 206 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction renamed an object store";
198 207
199 DCHECK(!m_objectStoreMap.contains(newName)); 208 DCHECK(!m_objectStoreMap.contains(newName));
200 DCHECK(m_objectStoreMap.contains(oldName)) << "The object store had to be ac cessed in order to be renamed."; 209 DCHECK(m_objectStoreMap.contains(oldName)) << "The object store had to be ac cessed in order to be renamed.";
201 210 IDBObjectStore* objectStore = m_objectStoreMap.take(oldName);
202 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(oldName); 211 m_objectStoreMap.set(newName, objectStore);
203 m_objectStoreMap.set(newName, it->value);
204 m_objectStoreMap.remove(oldName);
205 } 212 }
206 213
207 void IDBTransaction::setActive(bool active) 214 void IDBTransaction::setActive(bool active)
208 { 215 {
209 DCHECK_NE(m_state, Finished) << "A finished transaction tried to setActive(" << (active ? "true" : "false") << ")"; 216 DCHECK_NE(m_state, Finished) << "A finished transaction tried to setActive(" << (active ? "true" : "false") << ")";
210 if (m_state == Finishing) 217 if (m_state == Finishing)
211 return; 218 return;
212 ASSERT(active != (m_state == Active)); 219 ASSERT(active != (m_state == Active));
213 m_state = active ? Active : Inactive; 220 m_state = active ? Active : Inactive;
214 221
215 if (!active && m_requestList.isEmpty() && backendDB()) 222 if (!active && m_requestList.isEmpty() && backendDB())
216 backendDB()->commit(m_id); 223 backendDB()->commit(m_id);
217 } 224 }
218 225
219 void IDBTransaction::abort(ExceptionState& exceptionState) 226 void IDBTransaction::abort(ExceptionState& exceptionState)
220 { 227 {
221 if (m_state == Finishing || m_state == Finished) { 228 if (m_state == Finishing || m_state == Finished) {
222 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); 229 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage);
223 return; 230 return;
224 } 231 }
225 232
226 m_state = Finishing; 233 m_state = Finishing;
227 234
228 if (m_contextStopped) 235 if (m_contextStopped)
229 return; 236 return;
230 237
231 for (IDBRequest* request : m_requestList) 238 abortOutstandingRequests();
232 request->abort(); 239 revertDatabaseMetadata();
233 m_requestList.clear();
234
235 for (IDBObjectStore* store : m_createdObjectStores) {
236 store->abort();
237 store->markDeleted();
238 }
239 240
240 if (backendDB()) 241 if (backendDB())
241 backendDB()->abort(m_id); 242 backendDB()->abort(m_id);
242 } 243 }
243 244
244 void IDBTransaction::registerRequest(IDBRequest* request) 245 void IDBTransaction::registerRequest(IDBRequest* request)
245 { 246 {
246 ASSERT(request); 247 ASSERT(request);
247 ASSERT(m_state == Active); 248 ASSERT(m_state == Active);
248 m_requestList.add(request); 249 m_requestList.add(request);
249 } 250 }
250 251
251 void IDBTransaction::unregisterRequest(IDBRequest* request) 252 void IDBTransaction::unregisterRequest(IDBRequest* request)
252 { 253 {
253 ASSERT(request); 254 ASSERT(request);
254 // If we aborted the request, it will already have been removed. 255 // If we aborted the request, it will already have been removed.
255 m_requestList.remove(request); 256 m_requestList.remove(request);
256 } 257 }
257 258
258 void IDBTransaction::onAbort(DOMException* error) 259 void IDBTransaction::onAbort(DOMException* error)
259 { 260 {
260 IDB_TRACE("IDBTransaction::onAbort"); 261 IDB_TRACE("IDBTransaction::onAbort");
261 if (m_contextStopped) { 262 if (m_contextStopped) {
262 m_database->transactionFinished(this); 263 finish();
263 return; 264 return;
264 } 265 }
265 266
266 ASSERT(m_state != Finished); 267 ASSERT(m_state != Finished);
267 if (m_state != Finishing) { 268 if (m_state != Finishing) {
268 // Abort was not triggered by front-end. 269 // Abort was not triggered by front-end.
269 ASSERT(error); 270 DCHECK(error);
270 setError(error); 271 setError(error);
271 272
272 // Outstanding requests must be aborted. 273 abortOutstandingRequests();
273 for (IDBRequest* request : m_requestList) 274 revertDatabaseMetadata();
274 request->abort();
275 m_requestList.clear();
276
277 // Newly created stores must be marked as deleted.
278 for (IDBObjectStore* store : m_createdObjectStores)
279 store->markDeleted();
280
281 // Used stores may need to mark indexes as deleted.
282 for (auto& it : m_objectStoreCleanupMap)
283 it.key->abort();
284 275
285 m_state = Finishing; 276 m_state = Finishing;
286 } 277 }
287 278
288 if (isVersionChange()) { 279 if (isVersionChange())
289 for (auto& it : m_objectStoreCleanupMap)
290 it.key->setMetadata(it.value);
291 m_database->setMetadata(m_previousMetadata);
292 m_database->close(); 280 m_database->close();
293 }
294 m_objectStoreCleanupMap.clear();
295 281
296 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters. 282 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters.
297 enqueueEvent(Event::createBubble(EventTypeNames::abort)); 283 enqueueEvent(Event::createBubble(EventTypeNames::abort));
298 284 finish();
299 m_database->transactionFinished(this);
300 } 285 }
301 286
302 void IDBTransaction::onComplete() 287 void IDBTransaction::onComplete()
303 { 288 {
304 IDB_TRACE("IDBTransaction::onComplete"); 289 IDB_TRACE("IDBTransaction::onComplete");
305 if (m_contextStopped) { 290 if (m_contextStopped) {
306 m_database->transactionFinished(this); 291 finish();
307 return; 292 return;
308 } 293 }
309 294
310 ASSERT(m_state != Finished); 295 ASSERT(m_state != Finished);
311 m_state = Finishing; 296 m_state = Finishing;
312 m_objectStoreCleanupMap.clear();
313 297
314 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters. 298 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters.
315 enqueueEvent(Event::create(EventTypeNames::complete)); 299 enqueueEvent(Event::create(EventTypeNames::complete));
316 300 finish();
317 m_database->transactionFinished(this);
318 } 301 }
319 302
320 bool IDBTransaction::hasPendingActivity() const 303 bool IDBTransaction::hasPendingActivity() const
321 { 304 {
322 // FIXME: In an ideal world, we should return true as long as anyone has a o r can 305 // FIXME: In an ideal world, we should return true as long as anyone has a o r can
323 // get a handle to us or any child request object and any of those ha ve 306 // get a handle to us or any child request object and any of those ha ve
324 // event listeners. This is in order to handle user generated events properly. 307 // event listeners. This is in order to handle user generated events properly.
325 return m_hasPendingActivity && !m_contextStopped; 308 return m_hasPendingActivity && !m_contextStopped;
326 } 309 }
327 310
(...skipping 19 matching lines...) Expand all
347 return IndexedDBNames::readwrite; 330 return IndexedDBNames::readwrite;
348 331
349 case WebIDBTransactionModeVersionChange: 332 case WebIDBTransactionModeVersionChange:
350 return IndexedDBNames::versionchange; 333 return IndexedDBNames::versionchange;
351 } 334 }
352 335
353 ASSERT_NOT_REACHED(); 336 ASSERT_NOT_REACHED();
354 return IndexedDBNames::readonly; 337 return IndexedDBNames::readonly;
355 } 338 }
356 339
340 WebIDBDatabase* IDBTransaction::backendDB() const
341 {
342 return m_database->backend();
343 }
344
357 DOMStringList* IDBTransaction::objectStoreNames() const 345 DOMStringList* IDBTransaction::objectStoreNames() const
358 { 346 {
359 if (m_mode == WebIDBTransactionModeVersionChange) 347 if (isVersionChange())
360 return m_database->objectStoreNames(); 348 return m_database->objectStoreNames();
361 349
362 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB); 350 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB);
363 for (const String& name : m_objectStoreNames) 351 for (const String& objectStoreName : m_scope)
364 objectStoreNames->append(name); 352 objectStoreNames->append(objectStoreName);
365 objectStoreNames->sort(); 353 objectStoreNames->sort();
366 return objectStoreNames; 354 return objectStoreNames;
367 } 355 }
368 356
369 const AtomicString& IDBTransaction::interfaceName() const 357 const AtomicString& IDBTransaction::interfaceName() const
370 { 358 {
371 return EventTargetNames::IDBTransaction; 359 return EventTargetNames::IDBTransaction;
372 } 360 }
373 361
374 ExecutionContext* IDBTransaction::getExecutionContext() const 362 ExecutionContext* IDBTransaction::getExecutionContext() const
375 { 363 {
376 return ActiveDOMObject::getExecutionContext(); 364 return ActiveDOMObject::getExecutionContext();
377 } 365 }
378 366
379 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event) 367 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event)
380 { 368 {
381 IDB_TRACE("IDBTransaction::dispatchEvent"); 369 IDB_TRACE("IDBTransaction::dispatchEvent");
382 if (m_contextStopped || !getExecutionContext()) { 370 if (m_contextStopped || !getExecutionContext()) {
383 m_state = Finished; 371 m_state = Finished;
384 return DispatchEventResult::CanceledBeforeDispatch; 372 return DispatchEventResult::CanceledBeforeDispatch;
385 } 373 }
386 ASSERT(m_state != Finished); 374 DCHECK_NE(m_state, Finished);
387 ASSERT(m_hasPendingActivity); 375 DCHECK(m_hasPendingActivity);
388 ASSERT(getExecutionContext()); 376 DCHECK(getExecutionContext());
389 ASSERT(event->target() == this); 377 DCHECK_EQ(event->target(), this);
390 m_state = Finished; 378 m_state = Finished;
391 379
392 // Break reference cycles.
393 // TODO(jsbell): This can be removed c/o Oilpan.
394 for (auto& it : m_objectStoreMap)
395 it.value->transactionFinished();
396 m_objectStoreMap.clear();
397 for (auto& it : m_deletedObjectStores)
398 it->transactionFinished();
399 m_createdObjectStores.clear();
400 m_deletedObjectStores.clear();
401
402 HeapVector<Member<EventTarget>> targets; 380 HeapVector<Member<EventTarget>> targets;
403 targets.append(this); 381 targets.append(this);
404 targets.append(db()); 382 targets.append(db());
405 383
406 // FIXME: When we allow custom event dispatching, this will probably need to change. 384 // FIXME: When we allow custom event dispatching, this will probably need to change.
407 ASSERT(event->type() == EventTypeNames::complete || event->type() == EventTy peNames::abort); 385 DCHECK(event->type() == EventTypeNames::complete || event->type() == EventTy peNames::abort);
408 DispatchEventResult dispatchResult = IDBEventDispatcher::dispatch(event, tar gets); 386 DispatchEventResult dispatchResult = IDBEventDispatcher::dispatch(event, tar gets);
409 // FIXME: Try to construct a test where |this| outlives openDBRequest and we 387 // FIXME: Try to construct a test where |this| outlives openDBRequest and we
410 // get a crash. 388 // get a crash.
411 if (m_openDBRequest) { 389 if (m_openDBRequest) {
412 ASSERT(isVersionChange()); 390 DCHECK(isVersionChange());
413 m_openDBRequest->transactionDidFinishAndDispatch(); 391 m_openDBRequest->transactionDidFinishAndDispatch();
414 } 392 }
415 m_hasPendingActivity = false; 393 m_hasPendingActivity = false;
416 return dispatchResult; 394 return dispatchResult;
417 } 395 }
418 396
419 void IDBTransaction::stop() 397 void IDBTransaction::stop()
420 { 398 {
421 if (m_contextStopped) 399 if (m_contextStopped)
422 return; 400 return;
423 401
424 m_contextStopped = true; 402 m_contextStopped = true;
425 403
426 abort(IGNORE_EXCEPTION); 404 abort(IGNORE_EXCEPTION);
427 } 405 }
428 406
429 void IDBTransaction::enqueueEvent(Event* event) 407 void IDBTransaction::enqueueEvent(Event* event)
430 { 408 {
431 DCHECK_NE(m_state, Finished) << "A finished transaction tried to enqueue an event of type " << event->type() << "."; 409 DCHECK_NE(m_state, Finished) << "A finished transaction tried to enqueue an event of type " << event->type() << ".";
432 if (m_contextStopped || !getExecutionContext()) 410 if (m_contextStopped || !getExecutionContext())
433 return; 411 return;
434 412
435 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); 413 EventQueue* eventQueue = getExecutionContext()->getEventQueue();
436 event->setTarget(this); 414 event->setTarget(this);
437 eventQueue->enqueueEvent(event); 415 eventQueue->enqueueEvent(event);
438 } 416 }
439 417
440 WebIDBDatabase* IDBTransaction::backendDB() const 418 void IDBTransaction::abortOutstandingRequests()
441 { 419 {
442 return m_database->backend(); 420 for (IDBRequest* request : m_requestList)
421 request->abort();
422 m_requestList.clear();
423 }
424
425 void IDBTransaction::revertDatabaseMetadata()
426 {
427 DCHECK_NE(m_state, Active);
428 if (!isVersionChange())
429 return;
430
431 // Newly created stores must be marked as deleted.
432 for (IDBObjectStore* store : m_createdObjectStores) {
433 store->abort();
434 store->markDeleted();
435 }
436
437 // Used stores may need to mark indexes as deleted.
438 for (auto& it : m_objectStoreCleanupMap) {
439 it.key->abort();
440 it.key->setMetadata(it.value);
441 }
442
443 m_database->setMetadata(m_oldDatabaseMetadata);
444 }
445
446 void IDBTransaction::finish()
447 {
448 #if DCHECK_IS_ON()
449 DCHECK(!m_finishCalled);
450 m_finishCalled = true;
451 #endif // DCHECK_IS_ON()
452
453 m_database->transactionFinished(this);
454
455 // Break reference cycles.
456 // TODO(jsbell): This can be removed c/o Oilpan.
457 for (auto& it : m_objectStoreMap)
458 it.value->transactionFinished();
459 m_objectStoreMap.clear();
460 for (auto& it : m_deletedObjectStores)
461 it->transactionFinished();
462 m_createdObjectStores.clear();
463 m_deletedObjectStores.clear();
464
465 m_objectStoreCleanupMap.clear();
443 } 466 }
444 467
445 } // namespace blink 468 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698