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

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

Issue 2349413002: Minor IndexedDB refactorings. (Closed)
Patch Set: Rebased Created 4 years, 2 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>& scope, WebIDBTransactionMode mode, IDBDataba se* db)
50 { 50 {
51 DCHECK_NE(mode, WebIDBTransactionModeVersionChange);
52 DCHECK(!scope.isEmpty()) << "Non-version transactions should operate on a we ll-defined set of stores";
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, scope, mod e, 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>& scope, WebIDBTransactionMode mode, IDBDatabase* db, IDBOpenDBRequest * 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)
94 , m_openDBRequest(openDBRequest) 95 , m_openDBRequest(openDBRequest)
95 , m_mode(mode) 96 , m_mode(mode)
96 , m_previousMetadata(previousMetadata) 97 , m_scope(scope)
98 , m_oldDatabaseMetadata(oldMetadata)
97 { 99 {
98 if (mode == WebIDBTransactionModeVersionChange) { 100 DCHECK(m_database);
101
102 if (isVersionChange()) {
103 DCHECK(scope.isEmpty());
104
99 // Not active until the callback. 105 // Not active until the callback.
100 m_state = Inactive; 106 m_state = Inactive;
107 } else {
108 DCHECK(!scope.isEmpty()) << "Non-versionchange transactions must operate on a well-defined set of stores";
109 DCHECK(m_mode == WebIDBTransactionModeReadOnly || m_mode == WebIDBTransa ctionModeReadWrite) << "Invalid transaction mode";
101 } 110 }
102 111
103 if (m_state == Active) 112 if (m_state == Active)
104 V8PerIsolateData::from(scriptState->isolate())->addEndOfScopeTask(Deacti vateTransactionTask::create(this)); 113 V8PerIsolateData::from(scriptState->isolate())->addEndOfScopeTask(Deacti vateTransactionTask::create(this));
105 m_database->transactionCreated(this); 114 m_database->transactionCreated(this);
106 } 115 }
107 116
108 IDBTransaction::~IDBTransaction() 117 IDBTransaction::~IDBTransaction()
109 { 118 {
110 ASSERT(m_state == Finished || m_contextStopped); 119 DCHECK(m_state == Finished || m_contextStopped);
111 ASSERT(m_requestList.isEmpty() || m_contextStopped); 120 DCHECK(m_requestList.isEmpty() || m_contextStopped);
112 } 121 }
113 122
114 DEFINE_TRACE(IDBTransaction) 123 DEFINE_TRACE(IDBTransaction)
115 { 124 {
116 visitor->trace(m_database); 125 visitor->trace(m_database);
117 visitor->trace(m_openDBRequest); 126 visitor->trace(m_openDBRequest);
118 visitor->trace(m_error); 127 visitor->trace(m_error);
119 visitor->trace(m_requestList); 128 visitor->trace(m_requestList);
120 visitor->trace(m_objectStoreMap); 129 visitor->trace(m_objectStoreMap);
121 visitor->trace(m_createdObjectStores); 130 visitor->trace(m_createdObjectStores);
122 visitor->trace(m_deletedObjectStores); 131 visitor->trace(m_deletedObjectStores);
123 visitor->trace(m_objectStoreCleanupMap); 132 visitor->trace(m_objectStoreCleanupMap);
124 EventTargetWithInlineData::trace(visitor); 133 EventTargetWithInlineData::trace(visitor);
125 ActiveDOMObject::trace(visitor); 134 ActiveDOMObject::trace(visitor);
126 } 135 }
127 136
128 void IDBTransaction::setError(DOMException* error) 137 void IDBTransaction::setError(DOMException* error)
129 { 138 {
130 ASSERT(m_state != Finished); 139 DCHECK_NE(m_state, Finished);
131 ASSERT(error); 140 DCHECK(error);
132 141
133 // The first error to be set is the true cause of the 142 // The first error to be set is the true cause of the
134 // transaction abort. 143 // transaction abort.
135 if (!m_error) { 144 if (!m_error) {
136 m_error = error; 145 m_error = error;
137 } 146 }
138 } 147 }
139 148
140 IDBObjectStore* IDBTransaction::objectStore(const String& name, ExceptionState& exceptionState) 149 IDBObjectStore* IDBTransaction::objectStore(const String& name, ExceptionState& exceptionState)
141 { 150 {
142 if (m_state == Finished) { 151 if (isFinished()) {
143 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); 152 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage);
144 return nullptr; 153 return nullptr;
145 } 154 }
146 155
147 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name); 156 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
148 if (it != m_objectStoreMap.end()) 157 if (it != m_objectStoreMap.end())
149 return it->value; 158 return it->value;
150 159
151 if (!isVersionChange() && !m_objectStoreNames.contains(name)) { 160 if (!isVersionChange() && !m_scope.contains(name)) {
152 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage); 161 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage);
153 return nullptr; 162 return nullptr;
154 } 163 }
155 164
156 int64_t objectStoreId = m_database->findObjectStoreId(name); 165 int64_t objectStoreId = m_database->findObjectStoreId(name);
157 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { 166 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) {
158 ASSERT(isVersionChange()); 167 DCHECK(isVersionChange());
159 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage); 168 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchObjec tStoreErrorMessage);
160 return nullptr; 169 return nullptr;
161 } 170 }
162 171
163 const IDBDatabaseMetadata& metadata = m_database->metadata(); 172 DCHECK(m_database->metadata().objectStores.contains(objectStoreId));
173 const IDBObjectStoreMetadata& objectStoreMetadata = m_database->metadata().o bjectStores.get(objectStoreId);
164 174
165 IDBObjectStore* objectStore = IDBObjectStore::create(metadata.objectStores.g et(objectStoreId), this); 175 IDBObjectStore* objectStore = IDBObjectStore::create(objectStoreMetadata, th is);
176 DCHECK(!m_objectStoreMap.contains(name));
166 m_objectStoreMap.set(name, objectStore); 177 m_objectStoreMap.set(name, objectStore);
167 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 178 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
168 return objectStore; 179 return objectStore;
169 } 180 }
170 181
171 void IDBTransaction::objectStoreCreated(const String& name, IDBObjectStore* obje ctStore) 182 void IDBTransaction::objectStoreCreated(const String& name, IDBObjectStore* obje ctStore)
172 { 183 {
173 ASSERT(m_state != Finished); 184 DCHECK_NE(m_state, Finished) << "A finished transaction created an object st ore";
174 ASSERT(isVersionChange()); 185 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction created an object store";
186 DCHECK(!m_objectStoreMap.contains(name)) << "An object store was created wit h the name of an existing store";
175 m_objectStoreMap.set(name, objectStore); 187 m_objectStoreMap.set(name, objectStore);
176 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 188 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
177 m_createdObjectStores.add(objectStore); 189 m_createdObjectStores.add(objectStore);
178 } 190 }
179 191
180 void IDBTransaction::objectStoreDeleted(const String& name) 192 void IDBTransaction::objectStoreDeleted(const String& name)
181 { 193 {
182 ASSERT(m_state != Finished); 194 DCHECK_NE(m_state, Finished) << "A finished transaction deleted an object st ore";
183 ASSERT(isVersionChange()); 195 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction deleted an object store";
184 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name); 196 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
185 if (it != m_objectStoreMap.end()) { 197 if (it != m_objectStoreMap.end()) {
186 IDBObjectStore* objectStore = it->value; 198 IDBObjectStore* objectStore = it->value;
187 m_objectStoreMap.remove(name); 199 m_objectStoreMap.remove(name);
188 objectStore->markDeleted(); 200 objectStore->markDeleted();
189 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata()); 201 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
190 m_deletedObjectStores.add(objectStore); 202 m_deletedObjectStores.add(objectStore);
191 } 203 }
192 } 204 }
193 205
194 void IDBTransaction::objectStoreRenamed(const String& oldName, const String& new Name) 206 void IDBTransaction::objectStoreRenamed(const String& oldName, const String& new Name)
195 { 207 {
196 DCHECK(m_state != Finished); 208 DCHECK_NE(m_state, Finished) << "A finished transaction renamed an object st ore";
197 DCHECK(isVersionChange()); 209 DCHECK_EQ(m_mode, WebIDBTransactionModeVersionChange) << "A non-versionchang e transaction renamed an object store";
198 210
199 DCHECK(!m_objectStoreMap.contains(newName)); 211 DCHECK(!m_objectStoreMap.contains(newName));
200 DCHECK(m_objectStoreMap.contains(oldName)) << "The object store had to be ac cessed in order to be renamed."; 212 DCHECK(m_objectStoreMap.contains(oldName)) << "The object store had to be ac cessed in order to be renamed.";
201 213 m_objectStoreMap.set(newName, m_objectStoreMap.take(oldName));
202 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(oldName);
203 m_objectStoreMap.set(newName, it->value);
204 m_objectStoreMap.remove(oldName);
205 } 214 }
206 215
207 void IDBTransaction::setActive(bool active) 216 void IDBTransaction::setActive(bool active)
208 { 217 {
209 DCHECK_NE(m_state, Finished) << "A finished transaction tried to setActive(" << (active ? "true" : "false") << ")"; 218 DCHECK_NE(m_state, Finished) << "A finished transaction tried to setActive(" << (active ? "true" : "false") << ")";
210 if (m_state == Finishing) 219 if (m_state == Finishing)
211 return; 220 return;
212 ASSERT(active != (m_state == Active)); 221 DCHECK_NE(active, (m_state == Active));
213 m_state = active ? Active : Inactive; 222 m_state = active ? Active : Inactive;
214 223
215 if (!active && m_requestList.isEmpty() && backendDB()) 224 if (!active && m_requestList.isEmpty() && backendDB())
216 backendDB()->commit(m_id); 225 backendDB()->commit(m_id);
217 } 226 }
218 227
219 void IDBTransaction::abort(ExceptionState& exceptionState) 228 void IDBTransaction::abort(ExceptionState& exceptionState)
220 { 229 {
221 if (m_state == Finishing || m_state == Finished) { 230 if (m_state == Finishing || m_state == Finished) {
222 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); 231 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage);
223 return; 232 return;
224 } 233 }
225 234
226 m_state = Finishing; 235 m_state = Finishing;
227 236
228 if (m_contextStopped) 237 if (m_contextStopped)
229 return; 238 return;
230 239
231 for (IDBRequest* request : m_requestList) 240 abortOutstandingRequests();
232 request->abort(); 241 revertDatabaseMetadata();
233 m_requestList.clear();
234
235 for (IDBObjectStore* store : m_createdObjectStores) {
236 store->abort();
237 store->markDeleted();
238 }
239 242
240 if (backendDB()) 243 if (backendDB())
241 backendDB()->abort(m_id); 244 backendDB()->abort(m_id);
242 } 245 }
243 246
244 void IDBTransaction::registerRequest(IDBRequest* request) 247 void IDBTransaction::registerRequest(IDBRequest* request)
245 { 248 {
246 ASSERT(request); 249 DCHECK(request);
247 ASSERT(m_state == Active); 250 DCHECK_EQ(m_state, Active);
248 m_requestList.add(request); 251 m_requestList.add(request);
249 } 252 }
250 253
251 void IDBTransaction::unregisterRequest(IDBRequest* request) 254 void IDBTransaction::unregisterRequest(IDBRequest* request)
252 { 255 {
253 ASSERT(request); 256 DCHECK(request);
254 // If we aborted the request, it will already have been removed. 257 // If we aborted the request, it will already have been removed.
255 m_requestList.remove(request); 258 m_requestList.remove(request);
256 } 259 }
257 260
258 void IDBTransaction::onAbort(DOMException* error) 261 void IDBTransaction::onAbort(DOMException* error)
259 { 262 {
260 IDB_TRACE("IDBTransaction::onAbort"); 263 IDB_TRACE("IDBTransaction::onAbort");
261 if (m_contextStopped) { 264 if (m_contextStopped) {
262 m_database->transactionFinished(this); 265 finished();
263 return; 266 return;
264 } 267 }
265 268
266 ASSERT(m_state != Finished); 269 DCHECK_NE(m_state, Finished);
267 if (m_state != Finishing) { 270 if (m_state != Finishing) {
268 // Abort was not triggered by front-end. 271 // Abort was not triggered by front-end.
269 ASSERT(error); 272 DCHECK(error);
270 setError(error); 273 setError(error);
271 274
272 // Outstanding requests must be aborted. 275 abortOutstandingRequests();
273 for (IDBRequest* request : m_requestList) 276 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 277
285 m_state = Finishing; 278 m_state = Finishing;
286 } 279 }
287 280
288 if (isVersionChange()) { 281 if (isVersionChange())
289 for (auto& it : m_objectStoreCleanupMap)
290 it.key->setMetadata(it.value);
291 m_database->setMetadata(m_previousMetadata);
292 m_database->close(); 282 m_database->close();
293 }
294 m_objectStoreCleanupMap.clear();
295 283
296 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters. 284 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters.
297 enqueueEvent(Event::createBubble(EventTypeNames::abort)); 285 enqueueEvent(Event::createBubble(EventTypeNames::abort));
298 286 finished();
299 m_database->transactionFinished(this);
300 } 287 }
301 288
302 void IDBTransaction::onComplete() 289 void IDBTransaction::onComplete()
303 { 290 {
304 IDB_TRACE("IDBTransaction::onComplete"); 291 IDB_TRACE("IDBTransaction::onComplete");
305 if (m_contextStopped) { 292 if (m_contextStopped) {
306 m_database->transactionFinished(this); 293 finished();
307 return; 294 return;
308 } 295 }
309 296
310 ASSERT(m_state != Finished); 297 DCHECK_NE(m_state, Finished);
311 m_state = Finishing; 298 m_state = Finishing;
312 m_objectStoreCleanupMap.clear();
313 299
314 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters. 300 // Enqueue events before notifying database, as database may close which enq ueues more events and order matters.
315 enqueueEvent(Event::create(EventTypeNames::complete)); 301 enqueueEvent(Event::create(EventTypeNames::complete));
316 302 finished();
317 m_database->transactionFinished(this);
318 } 303 }
319 304
320 bool IDBTransaction::hasPendingActivity() const 305 bool IDBTransaction::hasPendingActivity() const
321 { 306 {
322 // FIXME: In an ideal world, we should return true as long as anyone has a o r can 307 // 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 308 // 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. 309 // event listeners. This is in order to handle user generated events properly.
325 return m_hasPendingActivity && !m_contextStopped; 310 return m_hasPendingActivity && !m_contextStopped;
326 } 311 }
327 312
328 WebIDBTransactionMode IDBTransaction::stringToMode(const String& modeString) 313 WebIDBTransactionMode IDBTransaction::stringToMode(const String& modeString)
329 { 314 {
330 if (modeString == IndexedDBNames::readonly) 315 if (modeString == IndexedDBNames::readonly)
331 return WebIDBTransactionModeReadOnly; 316 return WebIDBTransactionModeReadOnly;
332 if (modeString == IndexedDBNames::readwrite) 317 if (modeString == IndexedDBNames::readwrite)
333 return WebIDBTransactionModeReadWrite; 318 return WebIDBTransactionModeReadWrite;
334 if (modeString == IndexedDBNames::versionchange) 319 if (modeString == IndexedDBNames::versionchange)
335 return WebIDBTransactionModeVersionChange; 320 return WebIDBTransactionModeVersionChange;
336 ASSERT_NOT_REACHED(); 321 NOTREACHED();
337 return WebIDBTransactionModeReadOnly; 322 return WebIDBTransactionModeReadOnly;
338 } 323 }
339 324
340 const String& IDBTransaction::mode() const 325 const String& IDBTransaction::mode() const
341 { 326 {
342 switch (m_mode) { 327 switch (m_mode) {
343 case WebIDBTransactionModeReadOnly: 328 case WebIDBTransactionModeReadOnly:
344 return IndexedDBNames::readonly; 329 return IndexedDBNames::readonly;
345 330
346 case WebIDBTransactionModeReadWrite: 331 case WebIDBTransactionModeReadWrite:
347 return IndexedDBNames::readwrite; 332 return IndexedDBNames::readwrite;
348 333
349 case WebIDBTransactionModeVersionChange: 334 case WebIDBTransactionModeVersionChange:
350 return IndexedDBNames::versionchange; 335 return IndexedDBNames::versionchange;
351 } 336 }
352 337
353 ASSERT_NOT_REACHED(); 338 NOTREACHED();
354 return IndexedDBNames::readonly; 339 return IndexedDBNames::readonly;
355 } 340 }
356 341
342 WebIDBDatabase* IDBTransaction::backendDB() const
343 {
344 return m_database->backend();
345 }
346
357 DOMStringList* IDBTransaction::objectStoreNames() const 347 DOMStringList* IDBTransaction::objectStoreNames() const
358 { 348 {
359 if (m_mode == WebIDBTransactionModeVersionChange) 349 if (isVersionChange())
360 return m_database->objectStoreNames(); 350 return m_database->objectStoreNames();
361 351
362 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB); 352 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB);
363 for (const String& name : m_objectStoreNames) 353 for (const String& objectStoreName : m_scope)
364 objectStoreNames->append(name); 354 objectStoreNames->append(objectStoreName);
365 objectStoreNames->sort(); 355 objectStoreNames->sort();
366 return objectStoreNames; 356 return objectStoreNames;
367 } 357 }
368 358
369 const AtomicString& IDBTransaction::interfaceName() const 359 const AtomicString& IDBTransaction::interfaceName() const
370 { 360 {
371 return EventTargetNames::IDBTransaction; 361 return EventTargetNames::IDBTransaction;
372 } 362 }
373 363
374 ExecutionContext* IDBTransaction::getExecutionContext() const 364 ExecutionContext* IDBTransaction::getExecutionContext() const
375 { 365 {
376 return ActiveDOMObject::getExecutionContext(); 366 return ActiveDOMObject::getExecutionContext();
377 } 367 }
378 368
379 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event) 369 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event)
380 { 370 {
381 IDB_TRACE("IDBTransaction::dispatchEvent"); 371 IDB_TRACE("IDBTransaction::dispatchEvent");
382 if (m_contextStopped || !getExecutionContext()) { 372 if (m_contextStopped || !getExecutionContext()) {
383 m_state = Finished; 373 m_state = Finished;
384 return DispatchEventResult::CanceledBeforeDispatch; 374 return DispatchEventResult::CanceledBeforeDispatch;
385 } 375 }
386 ASSERT(m_state != Finished); 376 DCHECK_NE(m_state, Finished);
387 ASSERT(m_hasPendingActivity); 377 DCHECK(m_hasPendingActivity);
388 ASSERT(getExecutionContext()); 378 DCHECK(getExecutionContext());
389 ASSERT(event->target() == this); 379 DCHECK_EQ(event->target(), this);
390 m_state = Finished; 380 m_state = Finished;
391 381
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; 382 HeapVector<Member<EventTarget>> targets;
403 targets.append(this); 383 targets.append(this);
404 targets.append(db()); 384 targets.append(db());
405 385
406 // FIXME: When we allow custom event dispatching, this will probably need to change. 386 // FIXME: When we allow custom event dispatching, this will probably need to change.
407 ASSERT(event->type() == EventTypeNames::complete || event->type() == EventTy peNames::abort); 387 DCHECK(event->type() == EventTypeNames::complete || event->type() == EventTy peNames::abort);
408 DispatchEventResult dispatchResult = IDBEventDispatcher::dispatch(event, tar gets); 388 DispatchEventResult dispatchResult = IDBEventDispatcher::dispatch(event, tar gets);
409 // FIXME: Try to construct a test where |this| outlives openDBRequest and we 389 // FIXME: Try to construct a test where |this| outlives openDBRequest and we
410 // get a crash. 390 // get a crash.
411 if (m_openDBRequest) { 391 if (m_openDBRequest) {
412 ASSERT(isVersionChange()); 392 DCHECK(isVersionChange());
413 m_openDBRequest->transactionDidFinishAndDispatch(); 393 m_openDBRequest->transactionDidFinishAndDispatch();
414 } 394 }
415 m_hasPendingActivity = false; 395 m_hasPendingActivity = false;
416 return dispatchResult; 396 return dispatchResult;
417 } 397 }
418 398
419 void IDBTransaction::stop() 399 void IDBTransaction::stop()
420 { 400 {
421 if (m_contextStopped) 401 if (m_contextStopped)
422 return; 402 return;
423 403
424 m_contextStopped = true; 404 m_contextStopped = true;
425 405
426 abort(IGNORE_EXCEPTION); 406 abort(IGNORE_EXCEPTION);
427 } 407 }
428 408
429 void IDBTransaction::enqueueEvent(Event* event) 409 void IDBTransaction::enqueueEvent(Event* event)
430 { 410 {
431 DCHECK_NE(m_state, Finished) << "A finished transaction tried to enqueue an event of type " << event->type() << "."; 411 DCHECK_NE(m_state, Finished) << "A finished transaction tried to enqueue an event of type " << event->type() << ".";
432 if (m_contextStopped || !getExecutionContext()) 412 if (m_contextStopped || !getExecutionContext())
433 return; 413 return;
434 414
435 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); 415 EventQueue* eventQueue = getExecutionContext()->getEventQueue();
436 event->setTarget(this); 416 event->setTarget(this);
437 eventQueue->enqueueEvent(event); 417 eventQueue->enqueueEvent(event);
438 } 418 }
439 419
440 WebIDBDatabase* IDBTransaction::backendDB() const 420 void IDBTransaction::abortOutstandingRequests()
441 { 421 {
442 return m_database->backend(); 422 for (IDBRequest* request : m_requestList)
423 request->abort();
424 m_requestList.clear();
425 }
426
427 void IDBTransaction::revertDatabaseMetadata()
428 {
429 DCHECK_NE(m_state, Active);
430 if (!isVersionChange())
431 return;
432
433 // Newly created stores must be marked as deleted.
434 for (IDBObjectStore* store : m_createdObjectStores) {
435 store->abort();
436 store->markDeleted();
437 }
438
439 // Used stores may need to mark indexes as deleted.
440 for (auto& it : m_objectStoreCleanupMap) {
441 it.key->abort();
442 it.key->setMetadata(it.value);
443 }
444
445 m_database->setMetadata(m_oldDatabaseMetadata);
446 }
447
448 void IDBTransaction::finished()
449 {
450 #if DCHECK_IS_ON()
451 DCHECK(!m_finishCalled);
452 m_finishCalled = true;
453 #endif // DCHECK_IS_ON()
454
455 m_database->transactionFinished(this);
456
457 // Break reference cycles.
458 // TODO(jsbell): This can be removed c/o Oilpan.
459 for (auto& it : m_objectStoreMap)
460 it.value->transactionFinished();
461 m_objectStoreMap.clear();
462 for (auto& it : m_deletedObjectStores)
463 it->transactionFinished();
464 m_createdObjectStores.clear();
465 m_deletedObjectStores.clear();
466
467 m_objectStoreCleanupMap.clear();
443 } 468 }
444 469
445 } // namespace blink 470 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698