OLD | NEW |
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 Loading... |
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(¤tTransactionId); | 109 return atomicIncrement(¤tTransactionId); |
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::setOwnMetadata(const IDBDatabaseOwnMetadata& metadata) |
120 { | 118 { |
121 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f
ind(objectStoreId); | 119 m_metadata.own = metadata; |
122 ASSERT_WITH_SECURITY_IMPLICATION(it != m_metadata.objectStores.end()); | |
123 it->value.indexes.remove(indexId); | |
124 } | |
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(indexIterator != storeMetadata.indexes.end()); | |
134 indexIterator->value.name = newName; | |
135 } | 120 } |
136 | 121 |
137 void IDBDatabase::transactionCreated(IDBTransaction* transaction) | 122 void IDBDatabase::transactionCreated(IDBTransaction* transaction) |
138 { | 123 { |
139 ASSERT(transaction); | 124 ASSERT(transaction); |
140 ASSERT(!m_transactions.contains(transaction->id())); | 125 ASSERT(!m_transactions.contains(transaction->id())); |
141 m_transactions.add(transaction->id(), transaction); | 126 m_transactions.add(transaction->id(), transaction); |
142 | 127 |
143 if (transaction->isVersionChange()) { | 128 if (transaction->isVersionChange()) { |
144 ASSERT(!m_versionChangeTransaction); | 129 ASSERT(!m_versionChangeTransaction); |
(...skipping 26 matching lines...) Expand all Loading... |
171 void IDBDatabase::onComplete(int64_t transactionId) | 156 void IDBDatabase::onComplete(int64_t transactionId) |
172 { | 157 { |
173 ASSERT(m_transactions.contains(transactionId)); | 158 ASSERT(m_transactions.contains(transactionId)); |
174 m_transactions.get(transactionId)->onComplete(); | 159 m_transactions.get(transactionId)->onComplete(); |
175 } | 160 } |
176 | 161 |
177 DOMStringList* IDBDatabase::objectStoreNames() const | 162 DOMStringList* IDBDatabase::objectStoreNames() const |
178 { | 163 { |
179 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index
edDB); | 164 DOMStringList* objectStoreNames = DOMStringList::create(DOMStringList::Index
edDB); |
180 for (const auto& it : m_metadata.objectStores) | 165 for (const auto& it : m_metadata.objectStores) |
181 objectStoreNames->append(it.value.name); | 166 objectStoreNames->append(it.value->own.name); |
182 objectStoreNames->sort(); | 167 objectStoreNames->sort(); |
183 return objectStoreNames; | 168 return objectStoreNames; |
184 } | 169 } |
185 | 170 |
186 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const | 171 const String& IDBDatabase::getObjectStoreName(int64_t objectStoreId) const |
187 { | 172 { |
188 const auto& it = m_metadata.objectStores.find(objectStoreId); | 173 const auto& it = m_metadata.objectStores.find(objectStoreId); |
189 DCHECK(it != m_metadata.objectStores.end()); | 174 DCHECK(it != m_metadata.objectStores.end()); |
190 return it->value.name; | 175 return it->value->own.name; |
191 } | 176 } |
192 | 177 |
193 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, const IDBKeyP
ath& keyPath, bool autoIncrement, ExceptionState& exceptionState) | 178 IDBObjectStore* IDBDatabase::createObjectStore(const String& name, const IDBKeyP
ath& keyPath, bool autoIncrement, ExceptionState& exceptionState) |
194 { | 179 { |
195 IDB_TRACE("IDBDatabase::createObjectStore"); | 180 IDB_TRACE("IDBDatabase::createObjectStore"); |
196 recordApiCallsHistogram(IDBCreateObjectStoreCall); | 181 recordApiCallsHistogram(IDBCreateObjectStoreCall); |
197 | 182 |
198 if (!m_versionChangeTransaction) { | 183 if (!m_versionChangeTransaction) { |
199 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers
ionChangeTransactionErrorMessage); | 184 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers
ionChangeTransactionErrorMessage); |
200 return nullptr; | 185 return nullptr; |
(...skipping 20 matching lines...) Expand all Loading... |
221 if (autoIncrement && ((keyPath.getType() == IDBKeyPath::StringType && keyPat
h.string().isEmpty()) || keyPath.getType() == IDBKeyPath::ArrayType)) { | 206 if (autoIncrement && ((keyPath.getType() == IDBKeyPath::StringType && keyPat
h.string().isEmpty()) || keyPath.getType() == IDBKeyPath::ArrayType)) { |
222 exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement
option was set but the keyPath option was empty or an array."); | 207 exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement
option was set but the keyPath option was empty or an array."); |
223 return nullptr; | 208 return nullptr; |
224 } | 209 } |
225 | 210 |
226 if (!m_backend) { | 211 if (!m_backend) { |
227 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); | 212 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); |
228 return nullptr; | 213 return nullptr; |
229 } | 214 } |
230 | 215 |
231 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; | 216 int64_t objectStoreId = m_metadata.own.maxObjectStoreId + 1; |
| 217 DCHECK(objectStoreId != IDBObjectStoreMetadata::InvalidId); |
232 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId
, name, keyPath, autoIncrement); | 218 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId
, name, keyPath, autoIncrement); |
233 | 219 |
234 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement,
WebIDBDatabase::minimumIndexId); | 220 RefPtr<IDBObjectStoreMetadata> storeMetadata = adoptRef(new IDBObjectStoreMe
tadata( |
235 IDBObjectStore* objectStore = IDBObjectStore::create(metadata, m_versionChan
geTransaction.get()); | 221 name, objectStoreId, keyPath, autoIncrement, WebIDBDatabase::minimumInde
xId)); |
236 m_metadata.objectStores.set(metadata.id, metadata); | 222 IDBObjectStore* objectStore = IDBObjectStore::create(storeMetadata, m_versio
nChangeTransaction.get()); |
237 ++m_metadata.maxObjectStoreId; | 223 m_versionChangeTransaction->objectStoreCreated(name, objectStore); |
| 224 m_metadata.objectStores.set(objectStoreId, std::move(storeMetadata)); |
| 225 ++m_metadata.own.maxObjectStoreId; |
238 | 226 |
239 m_versionChangeTransaction->objectStoreCreated(name, objectStore); | |
240 return objectStore; | 227 return objectStore; |
241 } | 228 } |
242 | 229 |
243 void IDBDatabase::deleteObjectStore(const String& name, ExceptionState& exceptio
nState) | 230 void IDBDatabase::deleteObjectStore(const String& name, ExceptionState& exceptio
nState) |
244 { | 231 { |
245 IDB_TRACE("IDBDatabase::deleteObjectStore"); | 232 IDB_TRACE("IDBDatabase::deleteObjectStore"); |
246 recordApiCallsHistogram(IDBDeleteObjectStoreCall); | 233 recordApiCallsHistogram(IDBDeleteObjectStoreCall); |
247 if (!m_versionChangeTransaction) { | 234 if (!m_versionChangeTransaction) { |
248 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers
ionChangeTransactionErrorMessage); | 235 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers
ionChangeTransactionErrorMessage); |
249 return; | 236 return; |
(...skipping 12 matching lines...) Expand all Loading... |
262 exceptionState.throwDOMException(NotFoundError, "The specified object st
ore was not found."); | 249 exceptionState.throwDOMException(NotFoundError, "The specified object st
ore was not found."); |
263 return; | 250 return; |
264 } | 251 } |
265 | 252 |
266 if (!m_backend) { | 253 if (!m_backend) { |
267 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); | 254 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); |
268 return; | 255 return; |
269 } | 256 } |
270 | 257 |
271 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId
); | 258 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId
); |
272 m_versionChangeTransaction->objectStoreDeleted(name); | 259 m_versionChangeTransaction->objectStoreDeleted(objectStoreId, name); |
273 m_metadata.objectStores.remove(objectStoreId); | 260 m_metadata.objectStores.remove(objectStoreId); |
274 } | 261 } |
275 | 262 |
276 IDBTransaction* IDBDatabase::transaction(ScriptState* scriptState, const StringO
rStringSequenceOrDOMStringList& storeNames, const String& modeString, ExceptionS
tate& exceptionState) | 263 IDBTransaction* IDBDatabase::transaction(ScriptState* scriptState, const StringO
rStringSequenceOrDOMStringList& storeNames, const String& modeString, ExceptionS
tate& exceptionState) |
277 { | 264 { |
278 IDB_TRACE("IDBDatabase::transaction"); | 265 IDB_TRACE("IDBDatabase::transaction"); |
279 recordApiCallsHistogram(IDBTransactionCall); | 266 recordApiCallsHistogram(IDBTransactionCall); |
280 | 267 |
281 HashSet<String> scope; | 268 HashSet<String> scope; |
282 if (storeNames.isString()) { | 269 if (storeNames.isString()) { |
(...skipping 17 matching lines...) Expand all Loading... |
300 if (m_closePending) { | 287 if (m_closePending) { |
301 exceptionState.throwDOMException(InvalidStateError, "The database connec
tion is closing."); | 288 exceptionState.throwDOMException(InvalidStateError, "The database connec
tion is closing."); |
302 return nullptr; | 289 return nullptr; |
303 } | 290 } |
304 | 291 |
305 if (!m_backend) { | 292 if (!m_backend) { |
306 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); | 293 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas
eClosedErrorMessage); |
307 return nullptr; | 294 return nullptr; |
308 } | 295 } |
309 | 296 |
310 | |
311 if (scope.isEmpty()) { | 297 if (scope.isEmpty()) { |
312 exceptionState.throwDOMException(InvalidAccessError, "The storeNames par
ameter was empty."); | 298 exceptionState.throwDOMException(InvalidAccessError, "The storeNames par
ameter was empty."); |
313 return nullptr; | 299 return nullptr; |
314 } | 300 } |
315 | 301 |
316 Vector<int64_t> objectStoreIds; | 302 Vector<int64_t> objectStoreIds; |
317 for (const String& name : scope) { | 303 for (const String& name : scope) { |
318 int64_t objectStoreId = findObjectStoreId(name); | 304 int64_t objectStoreId = findObjectStoreId(name); |
319 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { | 305 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { |
320 exceptionState.throwDOMException(NotFoundError, "One of the specifie
d object stores was not found."); | 306 exceptionState.throwDOMException(NotFoundError, "One of the specifie
d object stores was not found."); |
321 return nullptr; | 307 return nullptr; |
322 } | 308 } |
323 objectStoreIds.append(objectStoreId); | 309 objectStoreIds.append(objectStoreId); |
324 } | 310 } |
325 | 311 |
326 WebIDBTransactionMode mode = IDBTransaction::stringToMode(modeString); | 312 WebIDBTransactionMode mode = IDBTransaction::stringToMode(modeString); |
327 if (mode != WebIDBTransactionModeReadOnly && mode != WebIDBTransactionModeRe
adWrite) { | 313 if (mode != WebIDBTransactionModeReadOnly && mode != WebIDBTransactionModeRe
adWrite) { |
328 exceptionState.throwTypeError("The mode provided ('" + modeString + "')
is not one of 'readonly' or 'readwrite'."); | 314 exceptionState.throwTypeError("The mode provided ('" + modeString + "')
is not one of 'readonly' or 'readwrite'."); |
329 return nullptr; | 315 return nullptr; |
330 } | 316 } |
331 | 317 |
332 int64_t transactionId = nextTransactionId(); | 318 int64_t transactionId = nextTransactionId(); |
333 m_backend->createTransaction(transactionId, WebIDBDatabaseCallbacksImpl::cre
ate(m_databaseCallbacks).release(), objectStoreIds, mode); | 319 m_backend->createTransaction(transactionId, WebIDBDatabaseCallbacksImpl::cre
ate(m_databaseCallbacks).release(), objectStoreIds, mode); |
334 | 320 |
335 return IDBTransaction::create(scriptState, transactionId, scope, mode, this)
; | 321 return IDBTransaction::createNonVersionChange(scriptState, transactionId, sc
ope, mode, this); |
336 } | 322 } |
337 | 323 |
338 void IDBDatabase::forceClose() | 324 void IDBDatabase::forceClose() |
339 { | 325 { |
340 for (const auto& it : m_transactions) | 326 for (const auto& it : m_transactions) |
341 it.value->abort(IGNORE_EXCEPTION); | 327 it.value->abort(IGNORE_EXCEPTION); |
342 this->close(); | 328 this->close(); |
343 enqueueEvent(Event::create(EventTypeNames::close)); | 329 enqueueEvent(Event::create(EventTypeNames::close)); |
344 } | 330 } |
345 | 331 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 406 |
421 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even
t); | 407 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even
t); |
422 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b
ackend) | 408 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b
ackend) |
423 m_backend->versionChangeIgnored(); | 409 m_backend->versionChangeIgnored(); |
424 return dispatchResult; | 410 return dispatchResult; |
425 } | 411 } |
426 | 412 |
427 int64_t IDBDatabase::findObjectStoreId(const String& name) const | 413 int64_t IDBDatabase::findObjectStoreId(const String& name) const |
428 { | 414 { |
429 for (const auto& it : m_metadata.objectStores) { | 415 for (const auto& it : m_metadata.objectStores) { |
430 if (it.value.name == name) { | 416 if (it.value->own.name == name) { |
431 ASSERT(it.key != IDBObjectStoreMetadata::InvalidId); | 417 ASSERT(it.key != IDBObjectStoreMetadata::InvalidId); |
432 return it.key; | 418 return it.key; |
433 } | 419 } |
434 } | 420 } |
435 return IDBObjectStoreMetadata::InvalidId; | 421 return IDBObjectStoreMetadata::InvalidId; |
436 } | 422 } |
437 | 423 |
438 void IDBDatabase::objectStoreRenamed(int64_t storeId, const String& newName) | 424 void IDBDatabase::renameObjectStore(int64_t objectStoreId, const String& newName
) |
439 { | 425 { |
440 DCHECK(m_metadata.objectStores.contains(storeId)); | 426 DCHECK(m_versionChangeTransaction) << "Object store renamed on database with
out a versionchange transaction"; |
441 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f
ind(storeId); | 427 DCHECK(m_versionChangeTransaction->isActive()) << "Object store renamed when
versionchange transaction is not active"; |
442 it->value.name = newName; | 428 DCHECK(m_backend) << "Object store renamed after database connection closed"
; |
| 429 DCHECK(m_metadata.objectStores.contains(objectStoreId)); |
| 430 |
| 431 m_backend->renameObjectStore(m_versionChangeTransaction->id(), objectStoreId
, newName); |
| 432 |
| 433 IDBDatabaseMetadata::ObjectStoreMap::iterator it = m_metadata.objectStores.f
ind(objectStoreId); |
| 434 IDBObjectStoreMetadata* objectStoreMetadata = it->value.get(); |
| 435 m_versionChangeTransaction->objectStoreRenamed(objectStoreMetadata->own.name
, newName); |
| 436 objectStoreMetadata->own.name = newName; |
| 437 } |
| 438 |
| 439 void IDBDatabase::revertObjectStoreCreation(int64_t objectStoreId) |
| 440 { |
| 441 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on dat
abase without a versionchange transaction"; |
| 442 DCHECK(!m_versionChangeTransaction->isActive()) << "Object store metadata re
verted when versionchange transaction is still active"; |
| 443 DCHECK(m_metadata.objectStores.contains(objectStoreId)); |
| 444 m_metadata.objectStores.remove(objectStoreId); |
| 445 } |
| 446 |
| 447 void IDBDatabase::revertObjectStoreMetadata(RefPtr<IDBObjectStoreMetadata> oldMe
tadata) |
| 448 { |
| 449 DCHECK(m_versionChangeTransaction) << "Object store metadata reverted on dat
abase without a versionchange transaction"; |
| 450 DCHECK(!m_versionChangeTransaction->isActive()) << "Object store metadata re
verted when versionchange transaction is still active"; |
| 451 DCHECK(oldMetadata.get()); |
| 452 m_metadata.objectStores.set(oldMetadata->own.id, std::move(oldMetadata)); |
443 } | 453 } |
444 | 454 |
445 bool IDBDatabase::hasPendingActivity() const | 455 bool IDBDatabase::hasPendingActivity() const |
446 { | 456 { |
447 // The script wrapper must not be collected before the object is closed or | 457 // The script wrapper must not be collected before the object is closed or |
448 // we can't fire a "versionchange" event to let script manually close the co
nnection. | 458 // we can't fire a "versionchange" event to let script manually close the co
nnection. |
449 return !m_closePending && hasEventListeners() && !m_contextStopped; | 459 return !m_closePending && hasEventListeners() && !m_contextStopped; |
450 } | 460 } |
451 | 461 |
452 void IDBDatabase::stop() | 462 void IDBDatabase::stop() |
(...skipping 19 matching lines...) Expand all Loading... |
472 return ActiveDOMObject::getExecutionContext(); | 482 return ActiveDOMObject::getExecutionContext(); |
473 } | 483 } |
474 | 484 |
475 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) | 485 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) |
476 { | 486 { |
477 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new
EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax)); | 487 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new
EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax)); |
478 apiCallsHistogram.count(method); | 488 apiCallsHistogram.count(method); |
479 } | 489 } |
480 | 490 |
481 } // namespace blink | 491 } // namespace blink |
OLD | NEW |