Chromium Code Reviews| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 #include <v8.h> | 50 #include <v8.h> |
| 51 | 51 |
| 52 using blink::WebBlobInfo; | 52 using blink::WebBlobInfo; |
| 53 using blink::WebIDBCallbacks; | 53 using blink::WebIDBCallbacks; |
| 54 using blink::WebIDBCursor; | 54 using blink::WebIDBCursor; |
| 55 using blink::WebIDBDatabase; | 55 using blink::WebIDBDatabase; |
| 56 using blink::WebVector; | 56 using blink::WebVector; |
| 57 | 57 |
| 58 namespace blink { | 58 namespace blink { |
| 59 | 59 |
| 60 namespace { | |
| 61 | |
| 62 using IndexKeys = HeapVector<Member<IDBKey>>; | |
| 63 | |
| 64 } | |
| 65 | |
| 60 IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, IDBTransa ction* transaction) | 66 IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, IDBTransa ction* transaction) |
| 61 : m_metadata(metadata) | 67 : m_metadata(metadata) |
| 62 , m_transaction(transaction) | 68 , m_transaction(transaction) |
| 63 { | 69 { |
| 64 ASSERT(m_transaction); | 70 DCHECK(m_transaction); |
| 65 } | 71 } |
| 66 | 72 |
| 67 DEFINE_TRACE(IDBObjectStore) | 73 DEFINE_TRACE(IDBObjectStore) |
| 68 { | 74 { |
| 69 visitor->trace(m_transaction); | 75 visitor->trace(m_transaction); |
| 70 visitor->trace(m_indexMap); | 76 visitor->trace(m_indexMap); |
| 71 visitor->trace(m_createdIndexes); | 77 visitor->trace(m_createdIndexes); |
| 72 } | 78 } |
| 73 | 79 |
| 74 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState) | 80 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 87 } | 93 } |
| 88 if (m_transaction->isFinished() || m_transaction->isFinishing()) { | 94 if (m_transaction->isFinished() || m_transaction->isFinishing()) { |
| 89 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase:: transactionFinishedErrorMessage); | 95 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase:: transactionFinishedErrorMessage); |
| 90 return; | 96 return; |
| 91 } | 97 } |
| 92 if (!m_transaction->isActive()) { | 98 if (!m_transaction->isActive()) { |
| 93 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase:: transactionInactiveErrorMessage); | 99 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase:: transactionInactiveErrorMessage); |
| 94 return; | 100 return; |
| 95 } | 101 } |
| 96 | 102 |
| 97 if (m_metadata.name == name) | 103 if (this->name() == name) |
| 98 return; | 104 return; |
| 99 if (m_transaction->db()->containsObjectStore(name)) { | 105 if (m_transaction->db()->containsObjectStore(name)) { |
| 100 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage); | 106 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage); |
| 101 return; | 107 return; |
| 102 } | 108 } |
| 103 if (!backendDB()) { | 109 if (!backendDB()) { |
| 104 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
| 105 return; | 111 return; |
| 106 } | 112 } |
| 107 | 113 |
| 108 backendDB()->renameObjectStore(m_transaction->id(), id(), name); | 114 backendDB()->renameObjectStore(m_transaction->id(), id(), name); |
| 109 m_transaction->objectStoreRenamed(m_metadata.name, name); | 115 m_transaction->objectStoreRenamed(m_metadata.name, name); |
| 110 m_metadata.name = name; | 116 m_metadata.name = name; |
| 111 | 117 |
| 112 // The name inside the database's version of the object store metadata is us ed by IDBDatabase.objectStoreNames(). | 118 // The name inside the database's version of the object store metadata is us ed by IDBDatabase.objectStoreNames(). |
| 113 // If the transaction is aborted, this name will be reverted when the metada ta is overwritten with the previousMetadata in IDBTransaction. | 119 // If the transaction is aborted, this name will be reverted when the metada ta is overwritten with the previousMetadata in IDBTransaction. |
| 114 m_transaction->db()->objectStoreRenamed(id(), name); | 120 m_transaction->db()->objectStoreRenamed(id(), name); |
| 115 } | 121 } |
| 116 | 122 |
| 117 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const | 123 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const |
| 118 { | 124 { |
| 119 return ScriptValue::from(scriptState, m_metadata.keyPath); | 125 return ScriptValue::from(scriptState, metadata().keyPath); |
| 120 } | 126 } |
| 121 | 127 |
| 122 DOMStringList* IDBObjectStore::indexNames() const | 128 DOMStringList* IDBObjectStore::indexNames() const |
| 123 { | 129 { |
| 124 IDB_TRACE("IDBObjectStore::indexNames"); | 130 IDB_TRACE("IDBObjectStore::indexNames"); |
| 125 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); | 131 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); |
| 126 for (const auto& it : m_metadata.indexes) | 132 for (const auto& it : metadata().indexes) |
| 127 indexNames->append(it.value.name); | 133 indexNames->append(it.value.name); |
| 128 indexNames->sort(); | 134 indexNames->sort(); |
| 129 return indexNames; | 135 return indexNames; |
| 130 } | 136 } |
| 131 | 137 |
| 132 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState) | 138 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState) |
| 133 { | 139 { |
| 134 IDB_TRACE("IDBObjectStore::get"); | 140 IDB_TRACE("IDBObjectStore::get"); |
| 135 if (isDeleted()) { | 141 if (isDeleted()) { |
| 136 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); | 142 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 if (!backendDB()) { | 264 if (!backendDB()) { |
| 259 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 265 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
| 260 return nullptr; | 266 return nullptr; |
| 261 } | 267 } |
| 262 | 268 |
| 263 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); | 269 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); |
| 264 backendDB()->getAll(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, maxCount, true, WebIDBCallbacksImpl::create(request).release()); | 270 backendDB()->getAll(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, maxCount, true, WebIDBCallbacksImpl::create(request).release()); |
| 265 return request; | 271 return request; |
| 266 } | 272 } |
| 267 | 273 |
| 268 static void generateIndexKeysForValue(v8::Isolate* isolate, const IDBIndexMetada ta& indexMetadata, const ScriptValue& objectValue, IDBObjectStore::IndexKeys* in dexKeys) | 274 static void generateIndexKeysForValue(v8::Isolate* isolate, const IDBIndexMetada ta& indexMetadata, const ScriptValue& objectValue, IndexKeys* indexKeys) |
| 269 { | 275 { |
| 270 ASSERT(indexKeys); | 276 DCHECK(indexKeys); |
| 271 NonThrowableExceptionState exceptionState; | 277 NonThrowableExceptionState exceptionState; |
| 272 IDBKey* indexKey = ScriptValue::to<IDBKey*>(isolate, objectValue, exceptionS tate, indexMetadata.keyPath); | 278 IDBKey* indexKey = ScriptValue::to<IDBKey*>(isolate, objectValue, exceptionS tate, indexMetadata.keyPath); |
| 273 | 279 |
| 274 if (!indexKey) | 280 if (!indexKey) |
| 275 return; | 281 return; |
| 276 | 282 |
| 277 if (!indexMetadata.multiEntry || indexKey->getType() != IDBKey::ArrayType) { | 283 if (!indexMetadata.multiEntry || indexKey->getType() != IDBKey::ArrayType) { |
| 278 if (!indexKey->isValid()) | 284 if (!indexKey->isValid()) |
| 279 return; | 285 return; |
| 280 | 286 |
| 281 indexKeys->append(indexKey); | 287 indexKeys->append(indexKey); |
| 282 } else { | 288 } else { |
| 283 ASSERT(indexMetadata.multiEntry); | 289 DCHECK(indexMetadata.multiEntry); |
| 284 ASSERT(indexKey->getType() == IDBKey::ArrayType); | 290 DCHECK_EQ(indexKey->getType(), IDBKey::ArrayType); |
| 285 indexKey = IDBKey::createMultiEntryArray(indexKey->array()); | 291 indexKey = IDBKey::createMultiEntryArray(indexKey->array()); |
| 286 | 292 |
| 287 for (size_t i = 0; i < indexKey->array().size(); ++i) | 293 for (size_t i = 0; i < indexKey->array().size(); ++i) |
| 288 indexKeys->append(indexKey->array()[i]); | 294 indexKeys->append(indexKey->array()[i]); |
| 289 } | 295 } |
| 290 } | 296 } |
| 291 | 297 |
| 292 IDBRequest* IDBObjectStore::add(ScriptState* scriptState, const ScriptValue& val ue, const ScriptValue& key, ExceptionState& exceptionState) | 298 IDBRequest* IDBObjectStore::add(ScriptState* scriptState, const ScriptValue& val ue, const ScriptValue& key, ExceptionState& exceptionState) |
| 293 { | 299 { |
| 294 IDB_TRACE("IDBObjectStore::add"); | 300 IDB_TRACE("IDBObjectStore::add"); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 Vector<WebBlobInfo> blobInfo; | 339 Vector<WebBlobInfo> blobInfo; |
| 334 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::seria lize(isolate, value.v8Value(), nullptr, &blobInfo, exceptionState); | 340 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::seria lize(isolate, value.v8Value(), nullptr, &blobInfo, exceptionState); |
| 335 if (exceptionState.hadException()) | 341 if (exceptionState.hadException()) |
| 336 return nullptr; | 342 return nullptr; |
| 337 | 343 |
| 338 // Keys that need to be extracted must be taken from a clone so that | 344 // Keys that need to be extracted must be taken from a clone so that |
| 339 // side effects (i.e. getters) are not triggered. Construct the | 345 // side effects (i.e. getters) are not triggered. Construct the |
| 340 // clone lazily since the operation may be expensive. | 346 // clone lazily since the operation may be expensive. |
| 341 ScriptValue clone; | 347 ScriptValue clone; |
| 342 | 348 |
| 343 const IDBKeyPath& keyPath = m_metadata.keyPath; | 349 const IDBKeyPath& keyPath = idbKeyPath(); |
| 344 const bool usesInLineKeys = !keyPath.isNull(); | 350 const bool usesInLineKeys = !keyPath.isNull(); |
| 345 const bool hasKeyGenerator = autoIncrement(); | 351 const bool hasKeyGenerator = autoIncrement(); |
| 346 | 352 |
| 347 if (putMode != WebIDBPutModeCursorUpdate && usesInLineKeys && key) { | 353 if (putMode != WebIDBPutModeCursorUpdate && usesInLineKeys && key) { |
| 348 exceptionState.throwDOMException(DataError, "The object store uses in-li ne keys and the key parameter was provided."); | 354 exceptionState.throwDOMException(DataError, "The object store uses in-li ne keys and the key parameter was provided."); |
| 349 return nullptr; | 355 return nullptr; |
| 350 } | 356 } |
| 351 | 357 |
| 352 // This test logically belongs in IDBCursor, but must operate on the cloned value. | 358 // This test logically belongs in IDBCursor, but must operate on the cloned value. |
| 353 if (putMode == WebIDBPutModeCursorUpdate && usesInLineKeys) { | 359 if (putMode == WebIDBPutModeCursorUpdate && usesInLineKeys) { |
| 354 ASSERT(key); | 360 DCHECK(key); |
| 355 if (clone.isEmpty()) | 361 if (clone.isEmpty()) |
| 356 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); | 362 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); |
| 357 IDBKey* keyPathKey = ScriptValue::to<IDBKey*>(scriptState->isolate(), cl one, exceptionState, keyPath); | 363 IDBKey* keyPathKey = ScriptValue::to<IDBKey*>(scriptState->isolate(), cl one, exceptionState, keyPath); |
| 358 if (exceptionState.hadException()) | 364 if (exceptionState.hadException()) |
| 359 return nullptr; | 365 return nullptr; |
| 360 if (!keyPathKey || !keyPathKey->isEqual(key)) { | 366 if (!keyPathKey || !keyPathKey->isEqual(key)) { |
| 361 exceptionState.throwDOMException(DataError, "The effective object st ore of this cursor uses in-line keys and evaluating the key path of the value pa rameter results in a different value than the cursor's effective key."); | 367 exceptionState.throwDOMException(DataError, "The effective object st ore of this cursor uses in-line keys and evaluating the key path of the value pa rameter results in a different value than the cursor's effective key."); |
| 362 return nullptr; | 368 return nullptr; |
| 363 } | 369 } |
| 364 } | 370 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 395 return nullptr; | 401 return nullptr; |
| 396 } | 402 } |
| 397 | 403 |
| 398 if (!backendDB()) { | 404 if (!backendDB()) { |
| 399 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 405 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
| 400 return nullptr; | 406 return nullptr; |
| 401 } | 407 } |
| 402 | 408 |
| 403 Vector<int64_t> indexIds; | 409 Vector<int64_t> indexIds; |
| 404 HeapVector<IndexKeys> indexKeys; | 410 HeapVector<IndexKeys> indexKeys; |
| 405 for (const auto& it : m_metadata.indexes) { | 411 for (const auto& it : metadata().indexes) { |
| 406 if (clone.isEmpty()) | 412 if (clone.isEmpty()) |
| 407 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); | 413 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); |
| 408 IndexKeys keys; | 414 IndexKeys keys; |
| 409 generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys ); | 415 generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys ); |
| 410 indexIds.append(it.key); | 416 indexIds.append(it.key); |
| 411 indexKeys.append(keys); | 417 indexKeys.append(keys); |
| 412 } | 418 } |
| 413 | 419 |
| 414 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get()); | 420 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get()); |
| 415 Vector<char> wireBytes; | 421 Vector<char> wireBytes; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) | 520 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) |
| 515 : EventListener(CPPEventListenerType) | 521 : EventListener(CPPEventListenerType) |
| 516 , m_scriptState(scriptState) | 522 , m_scriptState(scriptState) |
| 517 , m_database(database) | 523 , m_database(database) |
| 518 , m_transactionId(transactionId) | 524 , m_transactionId(transactionId) |
| 519 , m_objectStoreId(objectStoreId) | 525 , m_objectStoreId(objectStoreId) |
| 520 , m_indexMetadata(indexMetadata) | 526 , m_indexMetadata(indexMetadata) |
| 521 { | 527 { |
| 522 } | 528 } |
| 523 | 529 |
| 530 const IDBIndexMetadata& indexMetadata() const { return m_indexMetadata; } | |
| 531 | |
| 524 void handleEvent(ExecutionContext* executionContext, Event* event) override | 532 void handleEvent(ExecutionContext* executionContext, Event* event) override |
| 525 { | 533 { |
| 526 ASSERT(m_scriptState->getExecutionContext() == executionContext); | 534 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); |
| 527 ASSERT(event->type() == EventTypeNames::success); | 535 DCHECK_EQ(event->type(), EventTypeNames::success); |
| 528 EventTarget* target = event->target(); | 536 EventTarget* target = event->target(); |
| 529 IDBRequest* request = static_cast<IDBRequest*>(target); | 537 IDBRequest* request = static_cast<IDBRequest*>(target); |
| 530 | 538 |
| 531 if (!m_database->backend()) // If database is stopped? | 539 if (!m_database->backend()) // If database is stopped? |
| 532 return; | 540 return; |
| 533 | 541 |
| 534 IDBAny* cursorAny = request->resultAsAny(); | 542 IDBAny* cursorAny = request->resultAsAny(); |
| 535 IDBCursorWithValue* cursor = nullptr; | 543 IDBCursorWithValue* cursor = nullptr; |
| 536 if (cursorAny->getType() == IDBAny::IDBCursorWithValueType) | 544 if (cursorAny->getType() == IDBAny::IDBCursorWithValueType) |
| 537 cursor = cursorAny->idbCursorWithValue(); | 545 cursor = cursorAny->idbCursorWithValue(); |
| 538 | 546 |
| 539 Vector<int64_t> indexIds; | 547 Vector<int64_t> indexIds; |
| 540 indexIds.append(m_indexMetadata.id); | 548 indexIds.append(indexMetadata().id); |
| 541 if (cursor && !cursor->isDeleted()) { | 549 if (cursor && !cursor->isDeleted()) { |
| 542 cursor->continueFunction(nullptr, nullptr, ASSERT_NO_EXCEPTION); | 550 cursor->continueFunction(nullptr, nullptr, ASSERT_NO_EXCEPTION); |
| 543 | 551 |
| 544 IDBKey* primaryKey = cursor->idbPrimaryKey(); | 552 IDBKey* primaryKey = cursor->idbPrimaryKey(); |
| 545 ScriptValue value = cursor->value(m_scriptState.get()); | 553 ScriptValue value = cursor->value(m_scriptState.get()); |
| 546 | 554 |
| 547 IDBObjectStore::IndexKeys indexKeys; | 555 IndexKeys indexKeys; |
| 548 generateIndexKeysForValue(m_scriptState->isolate(), m_indexMetadata, value, &indexKeys); | 556 generateIndexKeysForValue(m_scriptState->isolate(), indexMetadata(), value, &indexKeys); |
| 549 | 557 |
| 550 HeapVector<IDBObjectStore::IndexKeys> indexKeysList; | 558 HeapVector<IndexKeys> indexKeysList; |
| 551 indexKeysList.append(indexKeys); | 559 indexKeysList.append(indexKeys); |
| 552 | 560 |
| 553 m_database->backend()->setIndexKeys(m_transactionId, m_objectStoreId , primaryKey, indexIds, indexKeysList); | 561 m_database->backend()->setIndexKeys(m_transactionId, m_objectStoreId , primaryKey, indexIds, indexKeysList); |
| 554 } else { | 562 } else { |
| 555 // Now that we are done indexing, tell the backend to go | 563 // Now that we are done indexing, tell the backend to go |
| 556 // back to processing tasks of type NormalTask. | 564 // back to processing tasks of type NormalTask. |
| 557 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds); | 565 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds); |
| 558 m_database.clear(); | 566 m_database.clear(); |
| 559 } | 567 } |
| 560 | 568 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) { | 606 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) { |
| 599 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true."); | 607 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true."); |
| 600 return nullptr; | 608 return nullptr; |
| 601 } | 609 } |
| 602 if (!backendDB()) { | 610 if (!backendDB()) { |
| 603 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 611 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
| 604 return nullptr; | 612 return nullptr; |
| 605 } | 613 } |
| 606 | 614 |
| 607 int64_t indexId = m_metadata.maxIndexId + 1; | 615 int64_t indexId = m_metadata.maxIndexId + 1; |
| 616 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); | |
| 608 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); | 617 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); |
| 609 | 618 |
| 610 ++m_metadata.maxIndexId; | 619 ++m_metadata.maxIndexId; |
| 611 | 620 |
| 612 IDBIndexMetadata metadata(name, indexId, keyPath, options.unique(), options. multiEntry()); | 621 IDBIndexMetadata indexMetadata(name, indexId, keyPath, options.unique(), opt ions.multiEntry()); |
| 613 IDBIndex* index = IDBIndex::create(metadata, this, m_transaction.get()); | 622 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; |
| 614 m_indexMap.set(name, index); | 623 m_indexMap.set(name, index); |
| 615 m_createdIndexes.add(index); | 624 m_createdIndexes.add(index); |
| 616 m_metadata.indexes.set(indexId, metadata); | 625 m_metadata.indexes.set(indexId, indexMetadata); |
| 617 m_transaction->db()->indexCreated(id(), metadata); | 626 m_transaction->db()->indexCreated(id(), indexMetadata); |
| 618 | 627 |
| 619 ASSERT(!exceptionState.hadException()); | 628 DCHECK(!exceptionState.hadException()); |
| 620 if (exceptionState.hadException()) | 629 if (exceptionState.hadException()) |
| 621 return nullptr; | 630 return nullptr; |
| 622 | 631 |
| 623 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive); | 632 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive); |
| 624 indexRequest->preventPropagation(); | 633 indexRequest->preventPropagation(); |
| 625 | 634 |
| 626 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. | 635 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. |
| 627 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), metadata); | 636 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), indexMetadata); |
| 628 indexRequest->setOnsuccess(indexPopulator); | 637 indexRequest->setOnsuccess(indexPopulator); |
| 629 return index; | 638 return index; |
| 630 } | 639 } |
| 631 | 640 |
| 632 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te) | 641 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te) |
| 633 { | 642 { |
| 634 IDB_TRACE("IDBObjectStore::index"); | 643 IDB_TRACE("IDBObjectStore::index"); |
| 635 if (isDeleted()) { | 644 if (isDeleted()) { |
| 636 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); | 645 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); |
| 637 return nullptr; | 646 return nullptr; |
| 638 } | 647 } |
| 639 if (m_transaction->isFinished() || m_transaction->isFinishing()) { | 648 if (m_transaction->isFinished() || m_transaction->isFinishing()) { |
| 640 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); | 649 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); |
| 641 return nullptr; | 650 return nullptr; |
| 642 } | 651 } |
| 643 | 652 |
| 644 IDBIndexMap::iterator it = m_indexMap.find(name); | 653 IDBIndexMap::iterator it = m_indexMap.find(name); |
| 645 if (it != m_indexMap.end()) | 654 if (it != m_indexMap.end()) |
| 646 return it->value; | 655 return it->value; |
| 647 | 656 |
| 648 int64_t indexId = findIndexId(name); | 657 int64_t indexId = findIndexId(name); |
| 649 if (indexId == IDBIndexMetadata::InvalidId) { | 658 if (indexId == IDBIndexMetadata::InvalidId) { |
| 650 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); | 659 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); |
| 651 return nullptr; | 660 return nullptr; |
| 652 } | 661 } |
| 653 | 662 |
| 654 const IDBIndexMetadata* indexMetadata(nullptr); | 663 DCHECK(metadata().indexes.contains(indexId)); |
| 655 for (const auto& it : m_metadata.indexes) { | 664 const IDBIndexMetadata& indexMetadata = metadata().indexes.get(indexId); |
| 656 if (it.value.name == name) { | 665 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; |
| 657 indexMetadata = &it.value; | |
| 658 break; | |
| 659 } | |
| 660 } | |
| 661 ASSERT(indexMetadata); | |
| 662 ASSERT(indexMetadata->id != IDBIndexMetadata::InvalidId); | |
| 663 | |
| 664 IDBIndex* index = IDBIndex::create(*indexMetadata, this, m_transaction.get() ); | |
| 665 m_indexMap.set(name, index); | 666 m_indexMap.set(name, index); |
| 666 return index; | 667 return index; |
| 667 } | 668 } |
| 668 | 669 |
| 669 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate) | 670 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate) |
| 670 { | 671 { |
| 671 IDB_TRACE("IDBObjectStore::deleteIndex"); | 672 IDB_TRACE("IDBObjectStore::deleteIndex"); |
| 672 if (!m_transaction->isVersionChange()) { | 673 if (!m_transaction->isVersionChange()) { |
| 673 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); | 674 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); |
| 674 return; | 675 return; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 if (!backendDB()) { | 801 if (!backendDB()) { |
| 801 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 802 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
| 802 return nullptr; | 803 return nullptr; |
| 803 } | 804 } |
| 804 | 805 |
| 805 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); | 806 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); |
| 806 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release()); | 807 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release()); |
| 807 return request; | 808 return request; |
| 808 } | 809 } |
| 809 | 810 |
| 811 void IDBObjectStore::markDeleted() | |
| 812 { | |
| 813 DCHECK(m_transaction->isVersionChange()) << " an object store got deleted ou tside a versionchange transaction"; | |
|
cmumford
2016/09/23 22:21:11
I guess you don't need this leading space now - :-
pwnall
2016/09/23 22:33:04
Sweet, thank you for catching that!
| |
| 814 m_deleted = true; | |
| 815 } | |
| 816 | |
| 810 void IDBObjectStore::abort() | 817 void IDBObjectStore::abort() |
| 811 { | 818 { |
| 812 for (auto& index : m_createdIndexes) | 819 for (auto& index : m_createdIndexes) |
| 813 index->markDeleted(); | 820 index->markDeleted(); |
| 814 } | 821 } |
| 815 | 822 |
| 816 void IDBObjectStore::transactionFinished() | 823 void IDBObjectStore::transactionFinished() |
| 817 { | 824 { |
| 818 ASSERT(m_transaction->isFinished()); | 825 DCHECK(!m_transaction->isActive()); |
| 819 | 826 |
| 820 // Break reference cycles. | 827 // Break reference cycles. |
| 821 // TODO(jsbell): This can be removed c/o Oilpan. | 828 // TODO(jsbell): This can be removed c/o Oilpan. |
| 822 m_indexMap.clear(); | 829 m_indexMap.clear(); |
| 823 m_createdIndexes.clear(); | 830 m_createdIndexes.clear(); |
| 824 } | 831 } |
| 825 | 832 |
| 826 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) | 833 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) |
| 827 { | 834 { |
| 828 DCHECK(m_transaction->isVersionChange()); | 835 DCHECK(m_transaction->isVersionChange()); |
| 829 DCHECK(m_transaction->isActive()); | 836 DCHECK(m_transaction->isActive()); |
| 830 | 837 |
| 831 IDBObjectStoreMetadata::IndexMap::iterator metadataIterator = m_metadata.ind exes.find(indexId); | 838 auto metadataIterator = m_metadata.indexes.find(indexId); |
| 832 DCHECK(metadataIterator != m_metadata.indexes.end()) << "Invalid indexId"; | 839 DCHECK_NE(metadataIterator, m_metadata.indexes.end()) << "Invalid indexId"; |
| 833 const String& oldName = metadataIterator->value.name; | 840 const String& oldName = metadataIterator->value.name; |
| 834 | 841 |
| 835 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed."; | 842 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed."; |
| 836 DCHECK(!m_indexMap.contains(newName)); | 843 DCHECK(!m_indexMap.contains(newName)); |
| 837 IDBIndexMap::iterator it = m_indexMap.find(oldName); | 844 m_indexMap.set(newName, m_indexMap.take(oldName)); |
| 838 m_indexMap.set(newName, it->value); | |
| 839 m_indexMap.remove(oldName); | |
| 840 | 845 |
| 841 metadataIterator->value.name = newName; | 846 metadataIterator->value.name = newName; |
| 842 } | 847 } |
| 843 | 848 |
| 844 int64_t IDBObjectStore::findIndexId(const String& name) const | 849 int64_t IDBObjectStore::findIndexId(const String& name) const |
| 845 { | 850 { |
| 846 for (const auto& it : m_metadata.indexes) { | 851 for (const auto& it : metadata().indexes) { |
| 847 if (it.value.name == name) { | 852 if (it.value.name == name) { |
| 848 ASSERT(it.key != IDBIndexMetadata::InvalidId); | 853 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); |
| 849 return it.key; | 854 return it.key; |
| 850 } | 855 } |
| 851 } | 856 } |
| 852 return IDBIndexMetadata::InvalidId; | 857 return IDBIndexMetadata::InvalidId; |
| 853 } | 858 } |
| 854 | 859 |
| 855 WebIDBDatabase* IDBObjectStore::backendDB() const | 860 WebIDBDatabase* IDBObjectStore::backendDB() const |
| 856 { | 861 { |
| 857 return m_transaction->backendDB(); | 862 return m_transaction->backendDB(); |
| 858 } | 863 } |
| 859 | 864 |
| 860 } // namespace blink | 865 } // namespace blink |
| OLD | NEW |