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

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: Rebased past the big reformat. 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) {
cmumford 2016/10/05 21:15:26 I worry that the knowledge of which members to cop
pwnall 2016/10/05 23:15:45 Done. Thank you! I didn't like the assignments, bu
138 IDBDatabaseMetadata::ObjectStoreMap::iterator it = 134 m_metadata.name = metadata.name;
139 m_metadata.objectStores.find(objectStoreId); 135 m_metadata.id = metadata.id;
140 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end()); 136 m_metadata.version = metadata.version;
141 it->value.indexes.remove(indexId); 137 m_metadata.maxObjectStoreId = metadata.maxObjectStoreId;
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 } 138 }
157 139
158 void IDBDatabase::transactionCreated(IDBTransaction* transaction) { 140 void IDBDatabase::transactionCreated(IDBTransaction* transaction) {
159 DCHECK(transaction); 141 DCHECK(transaction);
160 DCHECK(!m_transactions.contains(transaction->id())); 142 DCHECK(!m_transactions.contains(transaction->id()));
161 m_transactions.add(transaction->id(), transaction); 143 m_transactions.add(transaction->id(), transaction);
162 144
163 if (transaction->isVersionChange()) { 145 if (transaction->isVersionChange()) {
164 DCHECK(!m_versionChangeTransaction); 146 DCHECK(!m_versionChangeTransaction);
165 m_versionChangeTransaction = transaction; 147 m_versionChangeTransaction = transaction;
(...skipping 22 matching lines...) Expand all
188 170
189 void IDBDatabase::onComplete(int64_t transactionId) { 171 void IDBDatabase::onComplete(int64_t transactionId) {
190 DCHECK(m_transactions.contains(transactionId)); 172 DCHECK(m_transactions.contains(transactionId));
191 m_transactions.get(transactionId)->onComplete(); 173 m_transactions.get(transactionId)->onComplete();
192 } 174 }
193 175
194 DOMStringList* IDBDatabase::objectStoreNames() const { 176 DOMStringList* IDBDatabase::objectStoreNames() const {
195 DOMStringList* objectStoreNames = 177 DOMStringList* objectStoreNames =
196 DOMStringList::create(DOMStringList::IndexedDB); 178 DOMStringList::create(DOMStringList::IndexedDB);
197 for (const auto& it : m_metadata.objectStores) 179 for (const auto& it : m_metadata.objectStores)
198 objectStoreNames->append(it.value.name); 180 objectStoreNames->append(it.value->name);
199 objectStoreNames->sort(); 181 objectStoreNames->sort();
200 return objectStoreNames; 182 return objectStoreNames;
201 } 183 }
202 184
203 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const { 185 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const {
204 const auto& it = m_metadata.objectStores.find(objectStoreId); 186 const auto& it = m_metadata.objectStores.find(objectStoreId);
205 DCHECK(it != m_metadata.objectStores.end()); 187 DCHECK(it != m_metadata.objectStores.end());
206 return it->value.name; 188 return it->value->name;
207 } 189 }
208 190
209 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, 191 IDBObjectStore* IDBDatabase::createObjectStore(const String& name,
210 const IDBKeyPath& keyPath, 192 const IDBKeyPath& keyPath,
211 bool autoIncrement, 193 bool autoIncrement,
212 ExceptionState& exceptionState) { 194 ExceptionState& exceptionState) {
213 IDB_TRACE("IDBDatabase::createObjectStore"); 195 IDB_TRACE("IDBDatabase::createObjectStore");
214 recordApiCallsHistogram(IDBCreateObjectStoreCall); 196 recordApiCallsHistogram(IDBCreateObjectStoreCall);
215 197
216 if (!m_versionChangeTransaction) { 198 if (!m_versionChangeTransaction) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 return nullptr; 234 return nullptr;
253 } 235 }
254 236
255 if (!m_backend) { 237 if (!m_backend) {
256 exceptionState.throwDOMException(InvalidStateError, 238 exceptionState.throwDOMException(InvalidStateError,
257 IDBDatabase::databaseClosedErrorMessage); 239 IDBDatabase::databaseClosedErrorMessage);
258 return nullptr; 240 return nullptr;
259 } 241 }
260 242
261 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; 243 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
244 DCHECK_NE(objectStoreId, IDBObjectStoreMetadata::InvalidId);
262 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, 245 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId,
263 name, keyPath, autoIncrement); 246 name, keyPath, autoIncrement);
264 247
265 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, 248 RefPtr<IDBObjectStoreMetadata> storeMetadata = adoptRef(
266 WebIDBDatabase::minimumIndexId); 249 new IDBObjectStoreMetadata(name, objectStoreId, keyPath, autoIncrement,
250 WebIDBDatabase::minimumIndexId));
267 IDBObjectStore* objectStore = 251 IDBObjectStore* objectStore =
268 IDBObjectStore::create(metadata, m_versionChangeTransaction.get()); 252 IDBObjectStore::create(storeMetadata, m_versionChangeTransaction.get());
269 m_metadata.objectStores.set(metadata.id, metadata); 253 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
254 m_metadata.objectStores.set(objectStoreId, std::move(storeMetadata));
270 ++m_metadata.maxObjectStoreId; 255 ++m_metadata.maxObjectStoreId;
271 256
272 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
273 return objectStore; 257 return objectStore;
274 } 258 }
275 259
276 void IDBDatabase::deleteObjectStore(const String& name, 260 void IDBDatabase::deleteObjectStore(const String& name,
277 ExceptionState& exceptionState) { 261 ExceptionState& exceptionState) {
278 IDB_TRACE("IDBDatabase::deleteObjectStore"); 262 IDB_TRACE("IDBDatabase::deleteObjectStore");
279 recordApiCallsHistogram(IDBDeleteObjectStoreCall); 263 recordApiCallsHistogram(IDBDeleteObjectStoreCall);
280 if (!m_versionChangeTransaction) { 264 if (!m_versionChangeTransaction) {
281 exceptionState.throwDOMException( 265 exceptionState.throwDOMException(
282 InvalidStateError, 266 InvalidStateError,
(...skipping 19 matching lines...) Expand all
302 return; 286 return;
303 } 287 }
304 288
305 if (!m_backend) { 289 if (!m_backend) {
306 exceptionState.throwDOMException(InvalidStateError, 290 exceptionState.throwDOMException(InvalidStateError,
307 IDBDatabase::databaseClosedErrorMessage); 291 IDBDatabase::databaseClosedErrorMessage);
308 return; 292 return;
309 } 293 }
310 294
311 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId); 295 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId);
312 m_versionChangeTransaction->objectStoreDeleted(name); 296 m_versionChangeTransaction->objectStoreDeleted(objectStoreId, name);
313 m_metadata.objectStores.remove(objectStoreId); 297 m_metadata.objectStores.remove(objectStoreId);
314 } 298 }
315 299
316 IDBTransaction* IDBDatabase::transaction( 300 IDBTransaction* IDBDatabase::transaction(
317 ScriptState* scriptState, 301 ScriptState* scriptState,
318 const StringOrStringSequenceOrDOMStringList& storeNames, 302 const StringOrStringSequenceOrDOMStringList& storeNames,
319 const String& modeString, 303 const String& modeString,
320 ExceptionState& exceptionState) { 304 ExceptionState& exceptionState) {
321 IDB_TRACE("IDBDatabase::transaction"); 305 IDB_TRACE("IDBDatabase::transaction");
322 recordApiCallsHistogram(IDBTransactionCall); 306 recordApiCallsHistogram(IDBTransactionCall);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 DispatchEventResult dispatchResult = 455 DispatchEventResult dispatchResult =
472 EventTarget::dispatchEventInternal(event); 456 EventTarget::dispatchEventInternal(event);
473 if (event->type() == EventTypeNames::versionchange && !m_closePending && 457 if (event->type() == EventTypeNames::versionchange && !m_closePending &&
474 m_backend) 458 m_backend)
475 m_backend->versionChangeIgnored(); 459 m_backend->versionChangeIgnored();
476 return dispatchResult; 460 return dispatchResult;
477 } 461 }
478 462
479 int64_t IDBDatabase::findObjectStoreId(const String& name) const { 463 int64_t IDBDatabase::findObjectStoreId(const String& name) const {
480 for (const auto& it : m_metadata.objectStores) { 464 for (const auto& it : m_metadata.objectStores) {
481 if (it.value.name == name) { 465 if (it.value->name == name) {
482 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId); 466 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId);
483 return it.key; 467 return it.key;
484 } 468 }
485 } 469 }
486 return IDBObjectStoreMetadata::InvalidId; 470 return IDBObjectStoreMetadata::InvalidId;
487 } 471 }
488 472
489 void IDBDatabase::objectStoreRenamed(int64_t objectStoreId, 473 void IDBDatabase::renameObjectStore(int64_t objectStoreId,
490 const String& newName) { 474 const String& newName) {
491 DCHECK(m_versionChangeTransaction) 475 DCHECK(m_versionChangeTransaction)
492 << "Object store renamed on database without a versionchange transaction"; 476 << "Object store renamed on database without a versionchange transaction";
493 DCHECK(m_versionChangeTransaction->isActive()) 477 DCHECK(m_versionChangeTransaction->isActive())
494 << "Object store renamed when versionchange transaction is not active"; 478 << "Object store renamed when versionchange transaction is not active";
495 DCHECK(m_backend) << "Object store renamed after database connection closed"; 479 DCHECK(m_backend) << "Object store renamed after database connection closed";
496 DCHECK(m_metadata.objectStores.contains(objectStoreId)); 480 DCHECK(m_metadata.objectStores.contains(objectStoreId));
481
482 m_backend->renameObjectStore(m_versionChangeTransaction->id(), objectStoreId,
483 newName);
484
497 IDBDatabaseMetadata::ObjectStoreMap::iterator it = 485 IDBDatabaseMetadata::ObjectStoreMap::iterator it =
498 m_metadata.objectStores.find(objectStoreId); 486 m_metadata.objectStores.find(objectStoreId);
499 it->value.name = newName; 487 IDBObjectStoreMetadata* objectStoreMetadata = it->value.get();
488 m_versionChangeTransaction->objectStoreRenamed(objectStoreMetadata->name,
489 newName);
490 objectStoreMetadata->name = newName;
491 }
492
493 void IDBDatabase::revertObjectStoreCreation(int64_t objectStoreId) {
494 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on "
495 "database without a versionchange "
496 "transaction";
497 DCHECK(!m_versionChangeTransaction->isActive())
498 << "Object store metadata reverted when versionchange transaction is "
499 "still active";
500 DCHECK(m_metadata.objectStores.contains(objectStoreId));
501 m_metadata.objectStores.remove(objectStoreId);
502 }
503
504 void IDBDatabase::revertObjectStoreMetadata(
505 RefPtr<IDBObjectStoreMetadata> oldMetadata) {
506 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on "
507 "database without a versionchange "
508 "transaction";
509 DCHECK(!m_versionChangeTransaction->isActive())
510 << "Object store metadata reverted when versionchange transaction is "
511 "still active";
512 DCHECK(oldMetadata.get());
513 m_metadata.objectStores.set(oldMetadata->id, std::move(oldMetadata));
500 } 514 }
501 515
502 bool IDBDatabase::hasPendingActivity() const { 516 bool IDBDatabase::hasPendingActivity() const {
503 // The script wrapper must not be collected before the object is closed or 517 // 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 conn ection. 518 // we can't fire a "versionchange" event to let script manually close the conn ection.
505 return !m_closePending && hasEventListeners() && !m_contextStopped; 519 return !m_closePending && hasEventListeners() && !m_contextStopped;
506 } 520 }
507 521
508 void IDBDatabase::stop() { 522 void IDBDatabase::stop() {
509 m_contextStopped = true; 523 m_contextStopped = true;
(...skipping 17 matching lines...) Expand all
527 541
528 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) { 542 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) {
529 DEFINE_THREAD_SAFE_STATIC_LOCAL( 543 DEFINE_THREAD_SAFE_STATIC_LOCAL(
530 EnumerationHistogram, apiCallsHistogram, 544 EnumerationHistogram, apiCallsHistogram,
531 new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", 545 new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls",
532 IDBMethodsMax)); 546 IDBMethodsMax));
533 apiCallsHistogram.count(method); 547 apiCallsHistogram.count(method);
534 } 548 }
535 549
536 } // namespace blink 550 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698