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

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

Issue 2314933005: Align IndexedDB metadata rollback on transaction abort to spec. (Closed)
Patch Set: Addressed feedback. 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 ActiveDOMObject::trace(visitor); 119 ActiveDOMObject::trace(visitor);
120 } 120 }
121 121
122 int64_t IDBDatabase::nextTransactionId() { 122 int64_t IDBDatabase::nextTransactionId() {
123 // Only keep a 32-bit counter to allow ports to use the other 32 123 // Only keep a 32-bit counter to allow ports to use the other 32
124 // bits of the id. 124 // bits of the id.
125 static int currentTransactionId = 0; 125 static int currentTransactionId = 0;
126 return atomicIncrement(&currentTransactionId); 126 return atomicIncrement(&currentTransactionId);
127 } 127 }
128 128
129 void IDBDatabase::indexCreated(int64_t objectStoreId, 129 void IDBDatabase::setMetadata(const IDBDatabaseMetadata& metadata) {
130 const IDBIndexMetadata& metadata) { 130 m_metadata = metadata;
131 IDBDatabaseMetadata::ObjectStoreMap::iterator it =
132 m_metadata.objectStores.find(objectStoreId);
133 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end());
134 it->value.indexes.set(metadata.id, metadata);
135 } 131 }
136 132
137 void IDBDatabase::indexDeleted(int64_t objectStoreId, int64_t indexId) { 133 void IDBDatabase::setDatabaseMetadata(const IDBDatabaseMetadata& metadata) {
138 IDBDatabaseMetadata::ObjectStoreMap::iterator it = 134 m_metadata.copyDatabaseMetadataFrom(metadata);
139 m_metadata.objectStores.find(objectStoreId);
140 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end());
141 it->value.indexes.remove(indexId);
142 }
143
144 void IDBDatabase::indexRenamed(int64_t objectStoreId,
145 int64_t indexId,
146 const String& newName) {
147 IDBDatabaseMetadata::ObjectStoreMap::iterator storeIterator =
148 m_metadata.objectStores.find(objectStoreId);
149 SECURITY_DCHECK(storeIterator != m_metadata.objectStores.end());
150
151 IDBObjectStoreMetadata& storeMetadata = storeIterator->value;
152 IDBObjectStoreMetadata::IndexMap::iterator indexIterator =
153 storeMetadata.indexes.find(indexId);
154 DCHECK_NE(indexIterator, storeMetadata.indexes.end());
155 indexIterator->value.name = newName;
156 } 135 }
157 136
158 void IDBDatabase::transactionCreated(IDBTransaction* transaction) { 137 void IDBDatabase::transactionCreated(IDBTransaction* transaction) {
159 DCHECK(transaction); 138 DCHECK(transaction);
160 DCHECK(!m_transactions.contains(transaction->id())); 139 DCHECK(!m_transactions.contains(transaction->id()));
161 m_transactions.add(transaction->id(), transaction); 140 m_transactions.add(transaction->id(), transaction);
162 141
163 if (transaction->isVersionChange()) { 142 if (transaction->isVersionChange()) {
164 DCHECK(!m_versionChangeTransaction); 143 DCHECK(!m_versionChangeTransaction);
165 m_versionChangeTransaction = transaction; 144 m_versionChangeTransaction = transaction;
(...skipping 22 matching lines...) Expand all
188 167
189 void IDBDatabase::onComplete(int64_t transactionId) { 168 void IDBDatabase::onComplete(int64_t transactionId) {
190 DCHECK(m_transactions.contains(transactionId)); 169 DCHECK(m_transactions.contains(transactionId));
191 m_transactions.get(transactionId)->onComplete(); 170 m_transactions.get(transactionId)->onComplete();
192 } 171 }
193 172
194 DOMStringList* IDBDatabase::objectStoreNames() const { 173 DOMStringList* IDBDatabase::objectStoreNames() const {
195 DOMStringList* objectStoreNames = 174 DOMStringList* objectStoreNames =
196 DOMStringList::create(DOMStringList::IndexedDB); 175 DOMStringList::create(DOMStringList::IndexedDB);
197 for (const auto& it : m_metadata.objectStores) 176 for (const auto& it : m_metadata.objectStores)
198 objectStoreNames->append(it.value.name); 177 objectStoreNames->append(it.value->name);
199 objectStoreNames->sort(); 178 objectStoreNames->sort();
200 return objectStoreNames; 179 return objectStoreNames;
201 } 180 }
202 181
203 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const { 182 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const {
204 const auto& it = m_metadata.objectStores.find(objectStoreId); 183 const auto& it = m_metadata.objectStores.find(objectStoreId);
205 DCHECK(it != m_metadata.objectStores.end()); 184 DCHECK(it != m_metadata.objectStores.end());
206 return it->value.name; 185 return it->value->name;
207 } 186 }
208 187
209 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, 188 IDBObjectStore* IDBDatabase::createObjectStore(const String& name,
210 const IDBKeyPath& keyPath, 189 const IDBKeyPath& keyPath,
211 bool autoIncrement, 190 bool autoIncrement,
212 ExceptionState& exceptionState) { 191 ExceptionState& exceptionState) {
213 IDB_TRACE("IDBDatabase::createObjectStore"); 192 IDB_TRACE("IDBDatabase::createObjectStore");
214 recordApiCallsHistogram(IDBCreateObjectStoreCall); 193 recordApiCallsHistogram(IDBCreateObjectStoreCall);
215 194
216 if (!m_versionChangeTransaction) { 195 if (!m_versionChangeTransaction) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 return nullptr; 231 return nullptr;
253 } 232 }
254 233
255 if (!m_backend) { 234 if (!m_backend) {
256 exceptionState.throwDOMException(InvalidStateError, 235 exceptionState.throwDOMException(InvalidStateError,
257 IDBDatabase::databaseClosedErrorMessage); 236 IDBDatabase::databaseClosedErrorMessage);
258 return nullptr; 237 return nullptr;
259 } 238 }
260 239
261 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; 240 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
241 DCHECK_NE(objectStoreId, IDBObjectStoreMetadata::InvalidId);
262 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, 242 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId,
263 name, keyPath, autoIncrement); 243 name, keyPath, autoIncrement);
264 244
265 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, 245 RefPtr<IDBObjectStoreMetadata> storeMetadata = adoptRef(
266 WebIDBDatabase::minimumIndexId); 246 new IDBObjectStoreMetadata(name, objectStoreId, keyPath, autoIncrement,
247 WebIDBDatabase::minimumIndexId));
267 IDBObjectStore* objectStore = 248 IDBObjectStore* objectStore =
268 IDBObjectStore::create(metadata, m_versionChangeTransaction.get()); 249 IDBObjectStore::create(storeMetadata, m_versionChangeTransaction.get());
269 m_metadata.objectStores.set(metadata.id, metadata); 250 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
251 m_metadata.objectStores.set(objectStoreId, std::move(storeMetadata));
270 ++m_metadata.maxObjectStoreId; 252 ++m_metadata.maxObjectStoreId;
271 253
272 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
273 return objectStore; 254 return objectStore;
274 } 255 }
275 256
276 void IDBDatabase::deleteObjectStore(const String& name, 257 void IDBDatabase::deleteObjectStore(const String& name,
277 ExceptionState& exceptionState) { 258 ExceptionState& exceptionState) {
278 IDB_TRACE("IDBDatabase::deleteObjectStore"); 259 IDB_TRACE("IDBDatabase::deleteObjectStore");
279 recordApiCallsHistogram(IDBDeleteObjectStoreCall); 260 recordApiCallsHistogram(IDBDeleteObjectStoreCall);
280 if (!m_versionChangeTransaction) { 261 if (!m_versionChangeTransaction) {
281 exceptionState.throwDOMException( 262 exceptionState.throwDOMException(
282 InvalidStateError, 263 InvalidStateError,
(...skipping 19 matching lines...) Expand all
302 return; 283 return;
303 } 284 }
304 285
305 if (!m_backend) { 286 if (!m_backend) {
306 exceptionState.throwDOMException(InvalidStateError, 287 exceptionState.throwDOMException(InvalidStateError,
307 IDBDatabase::databaseClosedErrorMessage); 288 IDBDatabase::databaseClosedErrorMessage);
308 return; 289 return;
309 } 290 }
310 291
311 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId); 292 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId);
312 m_versionChangeTransaction->objectStoreDeleted(name); 293 m_versionChangeTransaction->objectStoreDeleted(objectStoreId, name);
313 m_metadata.objectStores.remove(objectStoreId); 294 m_metadata.objectStores.remove(objectStoreId);
314 } 295 }
315 296
316 IDBTransaction* IDBDatabase::transaction( 297 IDBTransaction* IDBDatabase::transaction(
317 ScriptState* scriptState, 298 ScriptState* scriptState,
318 const StringOrStringSequenceOrDOMStringList& storeNames, 299 const StringOrStringSequenceOrDOMStringList& storeNames,
319 const String& modeString, 300 const String& modeString,
320 ExceptionState& exceptionState) { 301 ExceptionState& exceptionState) {
321 IDB_TRACE("IDBDatabase::transaction"); 302 IDB_TRACE("IDBDatabase::transaction");
322 recordApiCallsHistogram(IDBTransactionCall); 303 recordApiCallsHistogram(IDBTransactionCall);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 DispatchEventResult dispatchResult = 452 DispatchEventResult dispatchResult =
472 EventTarget::dispatchEventInternal(event); 453 EventTarget::dispatchEventInternal(event);
473 if (event->type() == EventTypeNames::versionchange && !m_closePending && 454 if (event->type() == EventTypeNames::versionchange && !m_closePending &&
474 m_backend) 455 m_backend)
475 m_backend->versionChangeIgnored(); 456 m_backend->versionChangeIgnored();
476 return dispatchResult; 457 return dispatchResult;
477 } 458 }
478 459
479 int64_t IDBDatabase::findObjectStoreId(const String& name) const { 460 int64_t IDBDatabase::findObjectStoreId(const String& name) const {
480 for (const auto& it : m_metadata.objectStores) { 461 for (const auto& it : m_metadata.objectStores) {
481 if (it.value.name == name) { 462 if (it.value->name == name) {
482 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId); 463 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId);
483 return it.key; 464 return it.key;
484 } 465 }
485 } 466 }
486 return IDBObjectStoreMetadata::InvalidId; 467 return IDBObjectStoreMetadata::InvalidId;
487 } 468 }
488 469
489 void IDBDatabase::objectStoreRenamed(int64_t objectStoreId, 470 void IDBDatabase::renameObjectStore(int64_t objectStoreId,
490 const String& newName) { 471 const String& newName) {
491 DCHECK(m_versionChangeTransaction) 472 DCHECK(m_versionChangeTransaction)
492 << "Object store renamed on database without a versionchange transaction"; 473 << "Object store renamed on database without a versionchange transaction";
493 DCHECK(m_versionChangeTransaction->isActive()) 474 DCHECK(m_versionChangeTransaction->isActive())
494 << "Object store renamed when versionchange transaction is not active"; 475 << "Object store renamed when versionchange transaction is not active";
495 DCHECK(m_backend) << "Object store renamed after database connection closed"; 476 DCHECK(m_backend) << "Object store renamed after database connection closed";
496 DCHECK(m_metadata.objectStores.contains(objectStoreId)); 477 DCHECK(m_metadata.objectStores.contains(objectStoreId));
497 IDBDatabaseMetadata::ObjectStoreMap::iterator it = 478
498 m_metadata.objectStores.find(objectStoreId); 479 m_backend->renameObjectStore(m_versionChangeTransaction->id(), objectStoreId,
499 it->value.name = newName; 480 newName);
481
482 IDBObjectStoreMetadata* objectStoreMetadata =
483 m_metadata.objectStores.get(objectStoreId);
484 m_versionChangeTransaction->objectStoreRenamed(objectStoreMetadata->name,
485 newName);
486 objectStoreMetadata->name = newName;
487 }
488
489 void IDBDatabase::revertObjectStoreCreation(int64_t objectStoreId) {
490 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on "
491 "database without a versionchange "
492 "transaction";
493 DCHECK(!m_versionChangeTransaction->isActive())
494 << "Object store metadata reverted when versionchange transaction is "
495 "still active";
496 DCHECK(m_metadata.objectStores.contains(objectStoreId));
497 m_metadata.objectStores.remove(objectStoreId);
498 }
499
500 void IDBDatabase::revertObjectStoreMetadata(
501 RefPtr<IDBObjectStoreMetadata> oldMetadata) {
502 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on "
503 "database without a versionchange "
504 "transaction";
505 DCHECK(!m_versionChangeTransaction->isActive())
506 << "Object store metadata reverted when versionchange transaction is "
507 "still active";
508 DCHECK(oldMetadata.get());
509 m_metadata.objectStores.set(oldMetadata->id, std::move(oldMetadata));
500 } 510 }
501 511
502 bool IDBDatabase::hasPendingActivity() const { 512 bool IDBDatabase::hasPendingActivity() const {
503 // The script wrapper must not be collected before the object is closed or 513 // The script wrapper must not be collected before the object is closed or
504 // we can't fire a "versionchange" event to let script manually close the 514 // we can't fire a "versionchange" event to let script manually close the
505 // connection. 515 // connection.
506 return !m_closePending && hasEventListeners() && !m_contextStopped; 516 return !m_closePending && hasEventListeners() && !m_contextStopped;
507 } 517 }
508 518
509 void IDBDatabase::contextDestroyed() { 519 void IDBDatabase::contextDestroyed() {
(...skipping 18 matching lines...) Expand all
528 538
529 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) { 539 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) {
530 DEFINE_THREAD_SAFE_STATIC_LOCAL( 540 DEFINE_THREAD_SAFE_STATIC_LOCAL(
531 EnumerationHistogram, apiCallsHistogram, 541 EnumerationHistogram, apiCallsHistogram,
532 new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", 542 new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls",
533 IDBMethodsMax)); 543 IDBMethodsMax));
534 apiCallsHistogram.count(method); 544 apiCallsHistogram.count(method);
535 } 545 }
536 546
537 } // namespace blink 547 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698