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

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. 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 } 102 }
103 103
104 int64_t IDBDatabase::nextTransactionId() 104 int64_t IDBDatabase::nextTransactionId()
105 { 105 {
106 // Only keep a 32-bit counter to allow ports to use the other 32 106 // Only keep a 32-bit counter to allow ports to use the other 32
107 // bits of the id. 107 // bits of the id.
108 static int currentTransactionId = 0; 108 static int currentTransactionId = 0;
109 return atomicIncrement(&currentTransactionId); 109 return atomicIncrement(&currentTransactionId);
110 } 110 }
111 111
112 void IDBDatabase::indexCreated(int64_t objectStoreId, const IDBIndexMetadata& me tadata) 112 void IDBDatabase::setMetadata(const IDBDatabaseMetadata& metadata)
113 { 113 {
114 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f ind(objectStoreId); 114 m_metadata = metadata;
115 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end());
116 it->value.indexes.set(metadata.id, metadata);
117 } 115 }
118 116
119 void IDBDatabase::indexDeleted(int64_t objectStoreId, int64_t indexId) 117 void IDBDatabase::setDatabaseMetadata(const IDBDatabaseMetadata& metadata)
120 { 118 {
121 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f ind(objectStoreId); 119 m_metadata.name = metadata.name;
122 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end()); 120 m_metadata.id = metadata.id;
123 it->value.indexes.remove(indexId); 121 m_metadata.version = metadata.version;
124 } 122 m_metadata.maxObjectStoreId = metadata.maxObjectStoreId;
125
126 void IDBDatabase::indexRenamed(int64_t objectStoreId, int64_t indexId, const Str ing& newName)
127 {
128 IDBDatabaseMetadata::ObjectStoreMap::iterator storeIterator = m_metadata.obj ectStores.find(objectStoreId);
129 SECURITY_DCHECK(storeIterator != m_metadata.objectStores.end());
130
131 IDBObjectStoreMetadata& storeMetadata = storeIterator->value;
132 IDBObjectStoreMetadata::IndexMap::iterator indexIterator = storeMetadata.ind exes.find(indexId);
133 DCHECK_NE(indexIterator, storeMetadata.indexes.end());
134 indexIterator->value.name = newName;
135 } 123 }
136 124
137 void IDBDatabase::transactionCreated(IDBTransaction* transaction) 125 void IDBDatabase::transactionCreated(IDBTransaction* transaction)
138 { 126 {
139 DCHECK(transaction); 127 DCHECK(transaction);
140 DCHECK(!m_transactions.contains(transaction->id())); 128 DCHECK(!m_transactions.contains(transaction->id()));
141 m_transactions.add(transaction->id(), transaction); 129 m_transactions.add(transaction->id(), transaction);
142 130
143 if (transaction->isVersionChange()) { 131 if (transaction->isVersionChange()) {
144 DCHECK(!m_versionChangeTransaction); 132 DCHECK(!m_versionChangeTransaction);
(...skipping 26 matching lines...) Expand all
171 void IDBDatabase::onComplete(int64_t transactionId) 159 void IDBDatabase::onComplete(int64_t transactionId)
172 { 160 {
173 DCHECK(m_transactions.contains(transactionId)); 161 DCHECK(m_transactions.contains(transactionId));
174 m_transactions.get(transactionId)->onComplete(); 162 m_transactions.get(transactionId)->onComplete();
175 } 163 }
176 164
177 DOMStringList* IDBDatabase::objectStoreNames() const 165 DOMStringList* IDBDatabase::objectStoreNames() const
178 { 166 {
179 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB); 167 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index edDB);
180 for (const auto& it : m_metadata.objectStores) 168 for (const auto& it : m_metadata.objectStores)
181 objectStoreNames->append(it.value.name); 169 objectStoreNames->append(it.value->name);
182 objectStoreNames->sort(); 170 objectStoreNames->sort();
183 return objectStoreNames; 171 return objectStoreNames;
184 } 172 }
185 173
186 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const 174 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const
187 { 175 {
188 const auto& it = m_metadata.objectStores.find(objectStoreId); 176 const auto& it = m_metadata.objectStores.find(objectStoreId);
189 DCHECK(it != m_metadata.objectStores.end()); 177 DCHECK(it != m_metadata.objectStores.end());
190 return it->value.name; 178 return it->value->name;
191 } 179 }
192 180
193 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, const IDBKeyP ath& keyPath, bool autoIncrement, ExceptionState& exceptionState) 181 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, const IDBKeyP ath& keyPath, bool autoIncrement, ExceptionState& exceptionState)
194 { 182 {
195 IDB_TRACE("IDBDatabase::createObjectStore"); 183 IDB_TRACE("IDBDatabase::createObjectStore");
196 recordApiCallsHistogram(IDBCreateObjectStoreCall); 184 recordApiCallsHistogram(IDBCreateObjectStoreCall);
197 185
198 if (!m_versionChangeTransaction) { 186 if (!m_versionChangeTransaction) {
199 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); 187 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage);
200 return nullptr; 188 return nullptr;
(...skipping 21 matching lines...) Expand all
222 exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement option was set but the keyPath option was empty or an array."); 210 exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement option was set but the keyPath option was empty or an array.");
223 return nullptr; 211 return nullptr;
224 } 212 }
225 213
226 if (!m_backend) { 214 if (!m_backend) {
227 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 215 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
228 return nullptr; 216 return nullptr;
229 } 217 }
230 218
231 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; 219 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
220 DCHECK_NE(objectStoreId, IDBObjectStoreMetadata::InvalidId);
232 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId , name, keyPath, autoIncrement); 221 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId , name, keyPath, autoIncrement);
233 222
234 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, WebIDBDatabase::minimumIndexId); 223 RefPtr<IDBObjectStoreMetadata> storeMetadata = adoptRef(new IDBObjectStoreMe tadata(
235 IDBObjectStore* objectStore = IDBObjectStore::create(metadata, m_versionChan geTransaction.get()); 224 name, objectStoreId, keyPath, autoIncrement, WebIDBDatabase::minimumInde xId));
236 m_metadata.objectStores.set(metadata.id, metadata); 225 IDBObjectStore* objectStore = IDBObjectStore::create(storeMetadata, m_versio nChangeTransaction.get());
226 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
227 m_metadata.objectStores.set(objectStoreId, std::move(storeMetadata));
237 ++m_metadata.maxObjectStoreId; 228 ++m_metadata.maxObjectStoreId;
238 229
239 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
240 return objectStore; 230 return objectStore;
241 } 231 }
242 232
243 void IDBDatabase::deleteObjectStore(const String& name, ExceptionState& exceptio nState) 233 void IDBDatabase::deleteObjectStore(const String& name, ExceptionState& exceptio nState)
244 { 234 {
245 IDB_TRACE("IDBDatabase::deleteObjectStore"); 235 IDB_TRACE("IDBDatabase::deleteObjectStore");
246 recordApiCallsHistogram(IDBDeleteObjectStoreCall); 236 recordApiCallsHistogram(IDBDeleteObjectStoreCall);
247 if (!m_versionChangeTransaction) { 237 if (!m_versionChangeTransaction) {
248 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); 238 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage);
249 return; 239 return;
(...skipping 12 matching lines...) Expand all
262 exceptionState.throwDOMException(NotFoundError, "The specified object st ore was not found."); 252 exceptionState.throwDOMException(NotFoundError, "The specified object st ore was not found.");
263 return; 253 return;
264 } 254 }
265 255
266 if (!m_backend) { 256 if (!m_backend) {
267 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 257 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
268 return; 258 return;
269 } 259 }
270 260
271 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId ); 261 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId );
272 m_versionChangeTransaction->objectStoreDeleted(name); 262 m_versionChangeTransaction->objectStoreDeleted(objectStoreId, name);
273 m_metadata.objectStores.remove(objectStoreId); 263 m_metadata.objectStores.remove(objectStoreId);
274 } 264 }
275 265
276 IDBTransaction* IDBDatabase::transaction(ScriptState* scriptState, const StringO rStringSequenceOrDOMStringList& storeNames, const String& modeString, ExceptionS tate& exceptionState) 266 IDBTransaction* IDBDatabase::transaction(ScriptState* scriptState, const StringO rStringSequenceOrDOMStringList& storeNames, const String& modeString, ExceptionS tate& exceptionState)
277 { 267 {
278 IDB_TRACE("IDBDatabase::transaction"); 268 IDB_TRACE("IDBDatabase::transaction");
279 recordApiCallsHistogram(IDBTransactionCall); 269 recordApiCallsHistogram(IDBTransactionCall);
280 270
281 HashSet<String> scope; 271 HashSet<String> scope;
282 if (storeNames.isString()) { 272 if (storeNames.isString()) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 409
420 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even t); 410 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even t);
421 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b ackend) 411 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b ackend)
422 m_backend->versionChangeIgnored(); 412 m_backend->versionChangeIgnored();
423 return dispatchResult; 413 return dispatchResult;
424 } 414 }
425 415
426 int64_t IDBDatabase::findObjectStoreId(const String& name) const 416 int64_t IDBDatabase::findObjectStoreId(const String& name) const
427 { 417 {
428 for (const auto& it : m_metadata.objectStores) { 418 for (const auto& it : m_metadata.objectStores) {
429 if (it.value.name == name) { 419 if (it.value->name == name) {
430 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId); 420 DCHECK_NE(it.key, IDBObjectStoreMetadata::InvalidId);
431 return it.key; 421 return it.key;
432 } 422 }
433 } 423 }
434 return IDBObjectStoreMetadata::InvalidId; 424 return IDBObjectStoreMetadata::InvalidId;
435 } 425 }
436 426
437 void IDBDatabase::objectStoreRenamed(int64_t objectStoreId, const String& newNam e) 427 void IDBDatabase::renameObjectStore(int64_t objectStoreId, const String& newName )
438 { 428 {
439 DCHECK(m_versionChangeTransaction) << "Object store renamed on database with out a versionchange transaction"; 429 DCHECK(m_versionChangeTransaction) << "Object store renamed on database with out a versionchange transaction";
440 DCHECK(m_versionChangeTransaction->isActive()) << "Object store renamed when versionchange transaction is not active"; 430 DCHECK(m_versionChangeTransaction->isActive()) << "Object store renamed when versionchange transaction is not active";
441 DCHECK(m_backend) << "Object store renamed after database connection closed" ; 431 DCHECK(m_backend) << "Object store renamed after database connection closed" ;
442 DCHECK(m_metadata.objectStores.contains(objectStoreId)); 432 DCHECK(m_metadata.objectStores.contains(objectStoreId));
433
434 m_backend->renameObjectStore(m_versionChangeTransaction->id(), objectStoreId , newName);
435
443 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f ind(objectStoreId); 436 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f ind(objectStoreId);
444 it->value.name = newName; 437 IDBObjectStoreMetadata* objectStoreMetadata = it->value.get();
438 m_versionChangeTransaction->objectStoreRenamed(objectStoreMetadata->name, ne wName);
439 objectStoreMetadata->name = newName;
440 }
441
442 void IDBDatabase::revertObjectStoreCreation(int64_t objectStoreId)
443 {
444 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on dat abase without a versionchange transaction";
445 DCHECK(!m_versionChangeTransaction->isActive()) << "Object store metadata re verted when versionchange transaction is still active";
446 DCHECK(m_metadata.objectStores.contains(objectStoreId));
447 m_metadata.objectStores.remove(objectStoreId);
448 }
449
450 void IDBDatabase::revertObjectStoreMetadata(RefPtr<IDBObjectStoreMetadata> oldMe tadata)
451 {
452 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on dat abase without a versionchange transaction";
453 DCHECK(!m_versionChangeTransaction->isActive()) << "Object store metadata re verted when versionchange transaction is still active";
454 DCHECK(oldMetadata.get());
455 m_metadata.objectStores.set(oldMetadata->id, std::move(oldMetadata));
445 } 456 }
446 457
447 bool IDBDatabase::hasPendingActivity() const 458 bool IDBDatabase::hasPendingActivity() const
448 { 459 {
449 // The script wrapper must not be collected before the object is closed or 460 // The script wrapper must not be collected before the object is closed or
450 // we can't fire a "versionchange" event to let script manually close the co nnection. 461 // we can't fire a "versionchange" event to let script manually close the co nnection.
451 return !m_closePending && hasEventListeners() && !m_contextStopped; 462 return !m_closePending && hasEventListeners() && !m_contextStopped;
452 } 463 }
453 464
454 void IDBDatabase::stop() 465 void IDBDatabase::stop()
(...skipping 19 matching lines...) Expand all
474 return ActiveDOMObject::getExecutionContext(); 485 return ActiveDOMObject::getExecutionContext();
475 } 486 }
476 487
477 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) 488 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method)
478 { 489 {
479 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax)); 490 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax));
480 apiCallsHistogram.count(method); 491 apiCallsHistogram.count(method);
481 } 492 }
482 493
483 } // namespace blink 494 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698