indexed_db_database.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_database.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <math.h> 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <set> 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/auto_reset.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/scoped_vector.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/indexed_db/indexed_db_blob_info.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/indexed_db/indexed_db_connection.h" 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/browser/indexed_db/indexed_db_context_impl.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_cursor.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_factory.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_index_writer.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_pending_connection.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_transaction.h" 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_value.h" 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_path.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_range.h" 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "webkit/browser/blob/blob_data_handle.h" 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16; 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::Int64ToString16; 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeNumber; 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in-progress connection. 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingUpgradeCall { 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 transaction_id, 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : callbacks_(callbacks), 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection_(connection.Pass()), 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version_(version), 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch transaction_id_(transaction_id) {} 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Takes ownership of the connection object. 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT { 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return connection_.Pass(); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 transaction_id() const { return transaction_id_; } 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection_; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version_; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 transaction_id_; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingSuccessCall has a IndexedDBConnection* because the connection is now 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// owned elsewhere, but we need to cancel the success call if that connection 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// closes before it is sent. 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingSuccessCall { 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks, 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : callbacks_(callbacks), connection_(connection), version_(version) {} 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection() const { return connection_; } 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection_; 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version_; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::PendingDeleteCall { 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : callbacks_(callbacks) {} 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IndexedDBBackingStore* backing_store, 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBFactory* factory, 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Identifier& unique_identifier, 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status* s) { 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database = 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) new IndexedDBDatabase(name, backing_store, factory, unique_identifier); 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *s = database->OpenInternal(); 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s->ok()) 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return database; 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const base::string16::value_type kNoStringVersion[] = {0}; 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)IndexedDBDatabase::IndexedDBDatabase(const base::string16& name, 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBBackingStore* backing_store, 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBFactory* factory, 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Identifier& unique_identifier) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_(name, 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId, 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kNoStringVersion, 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION, 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId), 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) identifier_(unique_identifier), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_(factory) { 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddObjectStore( 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store, 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_object_store_id) { 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store.id) == 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(metadata_.max_object_store_id, new_max_object_store_id); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.max_object_store_id = new_max_object_store_id; 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store.id] = object_store; 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveObjectStore(int64 object_store_id) { 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.erase(object_store_id); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddIndex(int64 object_store_id, 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index, 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_index_id) { 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index.id) == object_store.indexes.end()); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes[index.id] = index; 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_index_id != IndexedDBIndexMetadata::kInvalidId) { 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(object_store.max_index_id, new_max_index_id); 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.max_index_id = new_max_index_id; 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveIndex(int64 object_store_id, int64 index_id) { 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end()); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes.erase(index_id); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status IndexedDBDatabase::OpenInternal() { 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool success = false; 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, &metadata_, &success); 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(success == (metadata_.id != kInvalidId)) << "success = " << success 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " id = " << metadata_.id; 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (success) 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->GetObjectStores(metadata_.id, 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &metadata_.object_stores); 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->CreateIDBDatabaseMetaData( 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id); 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBDatabase::~IndexedDBDatabase() { 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_open_calls_.empty()); 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int child_process_id) { 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection( 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new IndexedDBConnection(this, database_callbacks)); 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connections_.insert(connection.get()); 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch backing_store_->GrantChildProcessPermissions(child_process_id); 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connection.Pass(); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIndexedDBTransaction* IndexedDBDatabase::GetTransaction( 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 transaction_id) const { 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TransactionMap::const_iterator trans_iterator = 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transactions_.find(transaction_id); 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (trans_iterator == transactions_.end()) 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return trans_iterator->second; 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(metadata_.object_stores, object_store_id)) { 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(int64 object_store_id, 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(object_store_metadata.indexes, index_id)) { 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndOptionalIndexId( 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (index_id != IndexedDBIndexMetadata::kInvalidId && 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !ContainsKey(object_store_metadata.indexes, index_id)) { 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId( 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(object_store_metadata.indexes, index_id)) { 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool auto_increment) { 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::CreateObjectStore"); 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(metadata_.object_stores, object_store_id)) { 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store_metadata( 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_path, 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) auto_increment, 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::kMinimumIndexId); 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateObjectStoreOperation, 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata), 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id)); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddObjectStore(object_store_metadata, object_store_id); 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStoreOperation( 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateObjectStoreOperation"); 302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch leveldb::Status s = 303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch backing_store_->CreateObjectStore(transaction->BackingStoreTransaction(), 304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->database()->id(), 305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.id, 306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name, 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.key_path, 308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.auto_increment); 309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!s.ok()) { 310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error creating object store '") + 313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name + ASCIIToUTF16("'.")); 314e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 315e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 316e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteObjectStore"); 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata), 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata)); 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveObjectStore(object_store_id); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateIndex(int64 transaction_id, 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool unique, 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool multi_entry) { 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::CreateIndex"); 3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata( 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, index_id, key_path, unique, multi_entry); 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateIndexOperation, 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata), 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateIndexAbortOperation, 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id)); 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddIndex(object_store_id, index_metadata, index_id); 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateIndexOperation( 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateIndexOperation"); 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.id, 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.name, 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.key_path, 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.unique, 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) index_metadata.multi_entry).ok()) { 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error creating index '") + 392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, error_string)); 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateIndexAbortOperation( 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteIndex(int64 transaction_id, 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id) { 411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteIndex"); 4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBIndexMetadata& index_metadata = 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores[object_store_id].indexes[index_id]; 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata), 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata)); 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexOperation( 4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteIndexOperation"); 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction->database()->id(), 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) index_metadata.id); 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error deleting index '") + 448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 449e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 450e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 451e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 452e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 453e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 454e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexAbortOperation( 4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Commit(int64 transaction_id) { 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend suggests that we commit, but we may have previously initiated 469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // an abort, and so have disposed of the transaction. on_abort has already 470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // been dispatched to the frontend, so it will find out about that 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 4727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Commit(); 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id) { 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 4800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDB_TRACE("IndexedDBDatabase::Abort"); 4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(); 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id, 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabaseError& error) { 4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDB_TRACE("IndexedDBDatabase::Abort"); 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(error); 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Get(int64 transaction_id, 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool key_only, 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Get"); 5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::GetOperation, 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Passed(&key_range), 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::GetOperation( 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type, 5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::GetOperation"); 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[object_store_id]; 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKey* key; 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (key_range->IsOnlyKey()) { 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = &key_range->lower(); 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ObjectStore Retrieval Operation 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 5710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 5720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error deleting data in range"); 5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s.IsCorruption()) { 5780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 5790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 5800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = &backing_store_cursor->key(); 589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key; 5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Object Store Retrieval Operation 59423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 601e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 602e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 603e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 604e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 605e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 606e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 607e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *key, object_store_metadata.key_path); 619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // From here we are dealing only with indexes. 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetPrimaryKeyViaIndex( 628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &primary_key); 634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 635e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetPrimaryKeyViaIndex."); 637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 638e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 639e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 640e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!primary_key) { 6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(*primary_key); 650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 65423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *primary_key, 659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 661e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 662e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 663e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 664e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 665e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 666e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 6753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *primary_key, object_store_metadata.key_path); 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static scoped_ptr<IndexedDBKey> GenerateKey( 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBBackingStore* backing_store, 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBTransaction* transaction, 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 max_generator_value = 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9007199254740992LL; // Maximum integer storable as ECMAScript number. 689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 current_number; 690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( 691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ¤t_number); 695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "Failed to GetKeyGeneratorCurrentNumber"; 697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (current_number < 0 || current_number > max_generator_value) 700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey(current_number, WebIDBKeyTypeNumber)); 703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store, 706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IndexedDBTransaction* transaction, 707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 database_id, 708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 object_store_id, 709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBKey& key, 710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool check_current) { 7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(WebIDBKeyTypeNumber, key.type()); 712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store->MaybeUpdateKeyGeneratorCurrentNumber( 713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<int64>(floor(key.number())) + 1, 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) check_current); 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::PutOperationParams { 7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PutOperationParams() {} 7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 72323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 7240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScopedVector<webkit_blob::BlobDataHandle> handles; 7253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PutMode put_mode; 7273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<IndexKeys> index_keys; 7293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 7313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PutOperationParams); 7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 7333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Put(int64 transaction_id, 735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 73623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue* value, 7370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScopedVector<webkit_blob::BlobDataHandle>* handles, 738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PutMode put_mode, 740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Put"); 7437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 7447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 7497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key); 7520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(value); 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<PutOperationParams> params(new PutOperationParams()); 7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value.swap(*value); 7560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->handles.swap(*handles); 7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key = key.Pass(); 7583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode = put_mode; 7593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 7603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys = index_keys; 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 7623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); 7633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params, 7663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::PutOperation"); 768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_was_generated = false; 770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(params->object_store_id) != 7723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store = 7743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[params->object_store_id]; 7753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(object_store.auto_increment || params->key->IsValid()); 7763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 7793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store.auto_increment && !params->key->IsValid()) { 7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( 7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) backing_store_.get(), transaction, id(), params->object_store_id); 782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_was_generated = true; 783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!auto_inc_key->IsValid()) { 7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Maximum key generator value reached.")); 787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = auto_inc_key.Pass(); 790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 7913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = params->key.Pass(); 792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key->IsValid()); 795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 7973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode == IndexedDBDatabase::ADD_ONLY) { 798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 8013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 8033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier, 805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &found); 806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 807e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 808e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error checking key existence."); 809e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 810e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 811e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 812e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (found) { 8163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Key already exists in the object store.")); 819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 8273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 8283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store, 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *key, 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch key_was_generated, 8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys, 833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 8373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Before this point, don't do any mutation. After this point, rollback the 849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // transaction in case of error. 850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->PutRecord(transaction->BackingStoreTransaction(), 8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 8543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 8553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value, 8560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ¶ms->handles, 857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier); 858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 859e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 861e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error: backing store error performing put/add."); 862e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 863e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 864e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 865e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id); 876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store.auto_increment && 8793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 880ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch key->type() == WebIDBKeyTypeNumber) { 881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), 882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction, 883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->object_store_id, 885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !key_was_generated); 887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 888e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 889e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error updating key generator."); 890e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 891e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 892e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 893e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess(*key); 899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, 902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 905eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::SetIndexKeys"); 9067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 9077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(alecflett): This method could be asynchronous, but we need to 912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // evaluate if it's worth the extra complexity. 913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 9161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) transaction->BackingStoreTransaction(), 9171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) metadata_.id, 9181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) object_store_id, 9191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *primary_key, 9201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &record_identifier, 9211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &found); 922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 923e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 924e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error setting index keys."); 925e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 926e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 927e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 928e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!found) { 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error setting index keys for object store.")); 935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 939a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 9461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id(), 948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch object_store_metadata, 949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *primary_key, 950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch index_keys, 952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 9701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id); 974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, 978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64, 979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids) { 980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::SetIndexesReady"); 9817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 9827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 9847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask( 9873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PREEMPTIVE_TASK, 9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 9893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_ids.size())); 991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReadyOperation( 9943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t index_count, 9953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::SetIndexesReadyOperation"); 9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < index_count; ++i) 998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->DidCompletePreemptiveEvent(); 999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::OpenCursorOperationParams { 10023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OpenCursorOperationParams() {} 10033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 10043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id; 10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range; 10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorDirection direction; 10073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type; 10083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::TaskType task_type; 10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 10103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 10123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); 10133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 10143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenCursor( 1016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorDirection direction, 1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_only, 1022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskType task_type, 1023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::OpenCursor"); 10257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 10267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 10277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 10287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams()); 10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id = index_id; 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key_range = key_range.Pass(); 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction = direction; 10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type = 10383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE; 10393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type = task_type; 10403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 10413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 10423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(¶ms))); 10433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::OpenCursorOperation( 10463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params, 10473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 10483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::OpenCursorOperation"); 1049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend has begun indexing, so this pauses the transaction 1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the indexing is complete. This can't happen any earlier 1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // because we don't want to switch to early mode in case multiple 1053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // indexes are being created in a row, with Put()'s in between. 10543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK) 1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->AddPreemptiveEvent(); 1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 1058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 10593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { 1060424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1061424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 1062424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1063424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transaction->BackingStoreTransaction(), 1064424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id(), 1065424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->object_store_id, 1066424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *params->key_range, 10670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1069424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 1070424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 1071424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transaction->BackingStoreTransaction(), 1072424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id(), 1073424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->object_store_id, 1074424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *params->key_range, 10750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1077424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 10793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 10803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 10980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 10990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 11000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 11010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 11020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 11030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 11040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error opening cursor operation"); 11050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s.IsCorruption()) { 11060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 11070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 11120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Why is Success being called? 111323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) params->callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCursor> cursor = 11183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new IndexedDBCursor(backing_store_cursor.Pass(), 11193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type, 11203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type, 11213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction); 11223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess( 1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Count(int64 transaction_id, 1127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 1129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 1130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Count"); 11327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 11337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 11347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 11357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 11367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 11403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 11413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 11443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CountOperation( 11483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 11493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 11503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 11513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 11523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 11533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CountOperation"); 1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint32 count = 0; 1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 11583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 11640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 11650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 11730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 11740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 11750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 11760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 11770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); 11780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 11790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error performing count operation"); 11800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s.IsCorruption()) { 11810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 11820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 11830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 11863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++count; 11920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } while (backing_store_cursor->Continue(&s)); 11930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 11940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(cmumford): Check for database corruption. 1195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteRange( 1200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteRange"); 12057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 12067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 12077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 12097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 1211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 12173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteRangeOperation( 12213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 12223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 12233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 12253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteRangeOperation"); 12260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor = 1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->OpenObjectStoreCursor( 1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 12303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 12313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 12323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 12330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 12340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 12350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (backing_store_cursor && s.ok()) { 1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->DeleteRecord( 1238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction->BackingStoreTransaction(), 1239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 1240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 1241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) backing_store_cursor->record_identifier()) 1242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .ok()) { 12433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError( 1244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting data in range")); 1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } while (backing_store_cursor->Continue(&s)); 12490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 12500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 12510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 12520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 12530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ASCIIToUTF16("Internal error deleting range")); 12540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch transaction->Abort(error); 12550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s.IsCorruption()) { 12560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 12570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 12580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 12590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Clear(int64 transaction_id, 1266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Clear"); 12697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 12707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 12757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 12783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::ClearOperation( 12823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 12833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 12853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::ObjectStoreClearOperation"); 12860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s = backing_store_->ClearObjectStore( 12870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch transaction->BackingStoreTransaction(), id(), object_store_id); 12880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 12890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 12900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error clearing object store"); 12910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callbacks->OnError(error); 12920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s.IsCorruption()) { 12930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 12940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 12950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreOperation( 13023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 13033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 13043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreOperation"); 1305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 1306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 13083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata.id); 1309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 1310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error deleting object store '") + 13123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata.name + ASCIIToUTF16("'."); 1313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1314e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 1315e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 1316e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 1317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 1318e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeOperation( 13233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 version, 13243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 13253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection, 1326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 13273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::VersionChangeOperation"); 13283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 old_version = metadata_.int_version; 13293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_GT(version, old_version); 13303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version = version; 13313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!backing_store_->UpdateIDBDatabaseIntVersion( 1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 13333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 13343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version)) { 1335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError error( 1336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 13377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASCIIToUTF16( 13387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "Internal error writing data to stable storage when " 13397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "updating version.")); 13403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError(error); 1341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(error); 1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 13443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_second_half_open_.reset( 1346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new PendingSuccessCall(callbacks, connection.get(), version)); 13475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata()); 1348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 13515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool committed) { 1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transactions_[transaction->id()], transaction); 1354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.erase(transaction->id()); 1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 13585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (committed) { 13595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(pending_second_half_open_->version(), metadata_.int_version); 13605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(metadata_.id != kInvalidId); 13615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection was already minted for OnUpgradeNeeded callback. 13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection; 13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(), 13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this->metadata()); 13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 13675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Version change transaction was aborted in " 13705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "upgradeneeded event handler.")); 13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection queue is now unblocked. 1376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBDatabase::TransactionCommitFailed() { 13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Factory may be null in unit tests. 13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!factory_) 13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 13841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) factory_->HandleBackingStoreFailure(backing_store_->origin_url()); 13851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 13861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t IndexedDBDatabase::ConnectionCount() const { 1388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This does not include pending open calls, as those should not block version 1389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // changes and deletes. 1390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return connections_.size(); 1391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingOpenCount() const { 1394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_open_calls_.size(); 1395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingUpgradeCount() const { 1398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_run_version_change_transaction_call_ ? 1 : 0; 1399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::RunningUpgradeCount() const { 1402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_second_half_open_ ? 1 : 0; 1403ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingDeleteCount() const { 1406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_delete_calls_.size(); 1407ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1408ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::ProcessPendingCalls() { 1410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { 14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(pending_run_version_change_transaction_call_->version() > 1412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version); 1413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<PendingUpgradeCall> pending_call = 1414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_.Pass(); 14155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal(pending_call->callbacks(), 14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->ReleaseConnection(), 14175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->transaction_id(), 14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->version()); 14195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(1u, ConnectionCount()); 1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through would be a no-op, since transaction must complete 1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 1422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsDeleteDatabaseBlocked()); 1423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsOpenConnectionBlocked()); 1424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsDeleteDatabaseBlocked()) { 1428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingDeleteCallList pending_delete_calls; 1429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.swap(pending_delete_calls); 1430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_delete_calls.empty()) { 1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Only the first delete call will delete the database, but each must fire 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // callbacks. 1433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingDeleteCall> pending_delete_call( 1434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.front()); 1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.pop_front(); 14365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteDatabaseFinal(pending_delete_call->callbacks()); 1437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // delete_database_final should never re-queue calls. 1439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 1440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through when complete, as pending opens may be unblocked. 1441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsOpenConnectionBlocked()) { 1444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingOpenCallList pending_open_calls; 1445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls_.swap(pending_open_calls); 1446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_open_calls.empty()) { 1447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OpenConnection(pending_open_calls.front()); 1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls.pop_front(); 1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateTransaction( 1454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 1456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& object_store_ids, 1457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint16 mode) { 1458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDB_TRACE("IndexedDBDatabase::CreateTransaction"); 14608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 14614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(transactions_.find(transaction_id) == transactions_.end()); 14624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 14634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The transaction will add itself to this database's coordinator, which 14665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // manages the lifetime of the object. 14675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TransactionCreated(new IndexedDBTransaction( 14687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction_id, 14697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch connection->callbacks(), 14707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::set<int64>(object_store_ids.begin(), object_store_ids.end()), 14717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static_cast<indexed_db::TransactionMode>(mode), 1472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, 14735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new IndexedDBBackingStore::Transaction(backing_store_))); 1474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { 1477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transactions_[transaction->id()] = transaction; 1478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsOpenConnectionBlocked() const { 1481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !pending_delete_calls_.empty() || 14825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_coordinator_.IsRunningVersionChangeTransaction() || 1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_; 1484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenConnection( 1487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBPendingConnection& connection) { 1488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Should have a priority queue so that higher version 1491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // requests are processed first. http://crbug.com/225850 1492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsOpenConnectionBlocked()) { 1493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The backing store only detects data loss when it is first opened. The 1494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // presence of existing connections means we didn't even check for data loss 1495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // so there'd better not be any. 1496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss()); 1497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pending_open_calls_.push_back(connection); 1498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (metadata_.id == kInvalidId) { 1502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The database was deleted then immediately re-opened; OpenInternal() 1503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recreates it in the backing store. 1504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (OpenInternal().ok()) { 1505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, 1506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version); 1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 message; 1509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = ASCIIToUTF16( 1511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening database with no version specified."); 15125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = 1514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error opening database with version ") + 1515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(connection.version); 15165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, message)); 1519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We infer that the database didn't exist from its lack of either type of 1524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // version. 1525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool is_new_database = 1526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version == kNoStringVersion && 1527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; 1528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { 1530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // For unit tests only - skip upgrade steps. Calling from script with 1531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // DEFAULT_INT_VERSION throws exception. 1532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK that not in unit tests. 1533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(is_new_database); 1534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We may need to change the version. 1542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 local_version = connection.version; 1543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_new_database) { 1545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Spec says: If no version is specified and no database exists, set 1552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database version to 1. 1553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version = 1; 1554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version > metadata_.int_version) { 1557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RunVersionChangeTransaction(connection.callbacks, 1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.transaction_id, 1561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version); 1562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version < metadata_.int_version) { 1565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionVersionError, 1567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASCIIToUTF16("The requested version (") + 1568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(local_version) + 1569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16(") is less than the existing version (") + 1570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); 1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(local_version, metadata_.int_version); 1574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransaction( 1581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 15845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 requested_version) { 1585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(callbacks); 15878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection.get())); 1588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ConnectionCount() > 1) { 15895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); 1590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (*it != connection.get()) { 15963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (*it)->callbacks()->OnVersionChange(metadata_.int_version, 15973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) requested_version); 1598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Remove the call to OnBlocked and instead wait 1601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the frontend tells us that all the "versionchange" events 1602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // have been delivered. http://crbug.com/100123 1603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_run_version_change_transaction_call_); 1606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall( 1607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callbacks, connection.Pass(), transaction_id, requested_version)); 1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal( 16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks, connection.Pass(), transaction_id, requested_version); 1612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransactionFinal( 1615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 requested_version) { 1619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<int64> object_store_ids; 1621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateTransaction(transaction_id, 1622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection.get(), 1623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_ids, 1624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::TRANSACTION_VERSION_CHANGE); 1625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transactions_[transaction_id] 16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->ScheduleTask(base::Bind(&IndexedDBDatabase::VersionChangeOperation, 16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requested_version, 16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks, 16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&connection)), 16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, 16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metadata_.version, 16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metadata_.int_version)); 1636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabase( 1641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsDeleteDatabaseBlocked()) { 1644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*it)->callbacks()->OnVersionChange( 1650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version, IndexedDBDatabaseMetadata::NO_INT_VERSION); 1651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Only fire OnBlocked if there are open 1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // connections after the VersionChangeEvents are received, not 1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // just set up to fire. http://crbug.com/100123 1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); 1657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteDatabaseFinal(callbacks); 1660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { 1663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !!ConnectionCount(); 1664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabaseFinal( 1667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!IsDeleteDatabaseBlocked()); 1669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!backing_store_->DeleteDatabase(metadata_.name).ok()) { 1671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError( 1672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting database.")); 1674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1676a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64 old_version = metadata_.int_version; 1677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version = kNoStringVersion; 1678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.id = kInvalidId; 1679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.clear(); 1681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callbacks->OnSuccess(old_version); 16825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (factory_) 16835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->DatabaseDeleted(identifier_); 16845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 16855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 16865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::ForceClose() { 16875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IndexedDBConnection::ForceClose() may delete this database, so hold ref. 16885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> protect(this); 16895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConnectionSet::const_iterator it = connections_.begin(); 16905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (it != connections_.end()) { 16915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection = *it++; 16925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connection->ForceClose(); 16935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 16945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(connections_.empty()); 1695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 169758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { 16988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 16998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->IsConnected()); 17008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->database() == this); 1701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDB_TRACE("IndexedDBDatabase::Close"); 17038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Abort outstanding transactions from the closing connection. This 1704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // can not happen if the close is requested by the connection itself 1705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as the front-end defers the close until all transactions are 17068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // complete, but can occur on process termination or forced close. 1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 1708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap transactions(transactions_); 1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TransactionMap::const_iterator it = transactions.begin(), 1710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) end = transactions.end(); 1711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != end; 1712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (it->second->connection() == connection->callbacks()) 1714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second->Abort( 1715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Connection is closing.")); 1717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connections_.erase(connection); 1721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_ && 17225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->connection() == connection) { 17235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 1724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 1725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "The connection was closed.")); 1726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Add a test for the pending_open_calls_ cases below. 1732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ConnectionCount() && !pending_open_calls_.size() && 1733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !pending_delete_calls_.size()) { 1734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 1735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL origin_url = backing_store_->origin_url(); 17371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_ = NULL; 17381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // factory_ should only be null in unit tests. 1740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK(factory_ || !in_unit_tests) - somehow. 174158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (factory_) { 17425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->ReleaseDatabase(identifier_, forced); 174358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) factory_ = NULL; 174458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStoreAbortOperation( 17493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 1750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 17513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); 1752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 17533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveObjectStore(object_store_id); 1754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreAbortOperation( 17573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 1758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 17593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreAbortOperation"); 1760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 17613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddObjectStore(object_store_metadata, 17623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBObjectStoreMetadata::kInvalidId); 1763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeAbortOperation( 1766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& previous_version, 17673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 previous_int_version, 1768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 17693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 17713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.version = previous_version; 17723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version = previous_int_version; 1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 1776