indexed_db_database.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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" 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "third_party/leveldatabase/env_chromium.h" 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "webkit/browser/blob/blob_data_handle.h" 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16; 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::Int64ToString16; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeNumber; 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in-progress connection. 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingUpgradeCall { 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 transaction_id, 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : callbacks_(callbacks), 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection_(connection.Pass()), 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version_(version), 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch transaction_id_(transaction_id) {} 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Takes ownership of the connection object. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT { 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return connection_.Pass(); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 transaction_id() const { return transaction_id_; } 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection_; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version_; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 transaction_id_; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingSuccessCall has a IndexedDBConnection* because the connection is now 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// owned elsewhere, but we need to cancel the success call if that connection 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// closes before it is sent. 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingSuccessCall { 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks, 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : callbacks_(callbacks), connection_(connection), version_(version) {} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection() const { return connection_; } 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection_; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version_; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::PendingDeleteCall { 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : callbacks_(callbacks) {} 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IndexedDBBackingStore* backing_store, 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBFactory* factory, 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Identifier& unique_identifier, 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status* s) { 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database = 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) new IndexedDBDatabase(name, backing_store, factory, unique_identifier); 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *s = database->OpenInternal(); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (s->ok()) 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return database; 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const base::string16::value_type kNoStringVersion[] = {0}; 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)IndexedDBDatabase::IndexedDBDatabase(const base::string16& name, 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBBackingStore* backing_store, 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBFactory* factory, 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Identifier& unique_identifier) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_(name, 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId, 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kNoStringVersion, 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION, 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId), 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) identifier_(unique_identifier), 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_(factory) { 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddObjectStore( 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store, 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_object_store_id) { 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store.id) == 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) { 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(metadata_.max_object_store_id, new_max_object_store_id); 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.max_object_store_id = new_max_object_store_id; 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store.id] = object_store; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveObjectStore(int64 object_store_id) { 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.erase(object_store_id); 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddIndex(int64 object_store_id, 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index, 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_index_id) { 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index.id) == object_store.indexes.end()); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes[index.id] = index; 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_index_id != IndexedDBIndexMetadata::kInvalidId) { 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(object_store.max_index_id, new_max_index_id); 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.max_index_id = new_max_index_id; 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveIndex(int64 object_store_id, int64 index_id) { 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end()); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes.erase(index_id); 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status IndexedDBDatabase::OpenInternal() { 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool success = false; 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, &metadata_, &success); 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(success == (metadata_.id != kInvalidId)) << "success = " << success 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " id = " << metadata_.id; 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (success) 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->GetObjectStores(metadata_.id, 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &metadata_.object_stores); 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->CreateIDBDatabaseMetaData( 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id); 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBDatabase::~IndexedDBDatabase() { 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_open_calls_.empty()); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int child_process_id) { 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection( 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new IndexedDBConnection(this, database_callbacks)); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connections_.insert(connection.get()); 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch backing_store_->GrantChildProcessPermissions(child_process_id); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connection.Pass(); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIndexedDBTransaction* IndexedDBDatabase::GetTransaction( 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 transaction_id) const { 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TransactionMap::const_iterator trans_iterator = 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transactions_.find(transaction_id); 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (trans_iterator == transactions_.end()) 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return trans_iterator->second; 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const { 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(metadata_.object_stores, object_store_id)) { 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(int64 object_store_id, 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(object_store_metadata.indexes, index_id)) { 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndOptionalIndexId( 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (index_id != IndexedDBIndexMetadata::kInvalidId && 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !ContainsKey(object_store_metadata.indexes, index_id)) { 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId( 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(object_store_metadata.indexes, index_id)) { 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool auto_increment) { 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(metadata_.object_stores, object_store_id)) { 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Store creation is done synchronously, as it may be followed by 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // index creation (also sync) since preemptive OpenCursor/SetIndexKeys 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // may follow. 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store_metadata( 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_path, 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) auto_increment, 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::kMinimumIndexId); 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 291e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch leveldb::Status s = 292e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch backing_store_->CreateObjectStore(transaction->BackingStoreTransaction(), 293e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->database()->id(), 294e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.id, 295e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name, 296e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.key_path, 297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.auto_increment); 298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!s.ok()) { 299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error creating object store '") + 302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name + ASCIIToUTF16("'.")); 303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AddObjectStore(object_store_metadata, object_store_id); 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->ScheduleAbortTask( 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_id)); 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); 3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_id)); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateIndex(int64 transaction_id, 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool unique, 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool multi_entry) { 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) 3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Index creation is done synchronously since preemptive 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // OpenCursor/SetIndexKeys may follow. 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata( 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, index_id, key_path, unique, multi_entry); 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.id, 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.name, 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.key_path, 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.unique, 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) index_metadata.multi_entry).ok()) { 363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error creating index '") + 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, error_string)); 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AddIndex(object_store_id, index_metadata, index_id); 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->ScheduleAbortTask( 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateIndexAbortOperation, 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_id, 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) index_id)); 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateIndexAbortOperation( 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CreateIndexAbortOperation", 384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteIndex(int64 transaction_id, 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id) { 393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) index_id)); 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexOperation( 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int64 index_id, 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1( 414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id()); 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata = 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.object_stores[object_store_id].indexes[index_id]; 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction->database()->id(), 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) index_id); 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error deleting index '") + 427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 428e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 429e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 430e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 432e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 433e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->ScheduleAbortTask( 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_id, 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) index_metadata)); 443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexAbortOperation( 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 450f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteIndexAbortOperation", 451f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Commit(int64 transaction_id) { 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend suggests that we commit, but we may have previously initiated 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // an abort, and so have disposed of the transaction. on_abort has already 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // been dispatched to the frontend, so it will find out about that 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Commit(); 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id) { 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id); 4707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(); 473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id, 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabaseError& error) { 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", 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. 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(error); 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Get(int64 transaction_id, 486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool key_only, 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); 4927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 4957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::GetOperation, 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Passed(&key_range), 505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::GetOperation( 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type, 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::GetOperation", "txn.id", transaction->id()); 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[object_store_id]; 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKey* key; 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (key_range->IsOnlyKey()) { 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = &key_range->lower(); 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ObjectStore Retrieval Operation 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 5580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 5590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 5600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 5610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 5640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 5650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error deleting data in range"); 56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) { 5670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 5680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = &backing_store_cursor->key(); 578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key; 5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Object Store Retrieval Operation 58323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 590e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 591e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 592e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 593e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 59446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 595e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 596e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 6013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 6073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *key, object_store_metadata.key_path); 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // From here we are dealing only with indexes. 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetPrimaryKeyViaIndex( 617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &primary_key); 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 624e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 625e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetPrimaryKeyViaIndex."); 626e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 62746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 628e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!primary_key) { 6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(*primary_key); 639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 64323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *primary_key, 648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 650e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 651e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 652e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 654e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 655e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *primary_key, object_store_metadata.key_path); 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static scoped_ptr<IndexedDBKey> GenerateKey( 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBBackingStore* backing_store, 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBTransaction* transaction, 674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 max_generator_value = 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9007199254740992LL; // Maximum integer storable as ECMAScript number. 678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 current_number; 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( 680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ¤t_number); 684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "Failed to GetKeyGeneratorCurrentNumber"; 686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (current_number < 0 || current_number > max_generator_value) 689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey(current_number, WebIDBKeyTypeNumber)); 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store, 695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IndexedDBTransaction* transaction, 696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 database_id, 697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 object_store_id, 698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBKey& key, 699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool check_current) { 7003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(WebIDBKeyTypeNumber, key.type()); 701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store->MaybeUpdateKeyGeneratorCurrentNumber( 702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<int64>(floor(key.number())) + 1, 706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) check_current); 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::PutOperationParams { 7103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PutOperationParams() {} 7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 71223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 7130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScopedVector<webkit_blob::BlobDataHandle> handles; 7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PutMode put_mode; 7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 7173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<IndexKeys> index_keys; 7183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PutOperationParams); 7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Put(int64 transaction_id, 724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 72523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue* value, 7260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScopedVector<webkit_blob::BlobDataHandle>* handles, 727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PutMode put_mode, 729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 731f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); 7327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 7337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 7387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key); 7410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(value); 7423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<PutOperationParams> params(new PutOperationParams()); 7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 7443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value.swap(*value); 7450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->handles.swap(*handles); 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key = key.Pass(); 7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode = put_mode; 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys = index_keys; 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); 7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params, 7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id()); 757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_was_generated = false; 759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(params->object_store_id) != 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 7623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store = 7633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[params->object_store_id]; 7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(object_store.auto_increment || params->key->IsValid()); 7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 7683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store.auto_increment && !params->key->IsValid()) { 7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( 7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) backing_store_.get(), transaction, id(), params->object_store_id); 771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_was_generated = true; 772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!auto_inc_key->IsValid()) { 7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Maximum key generator value reached.")); 776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = auto_inc_key.Pass(); 779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = params->key.Pass(); 781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key->IsValid()); 784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 7863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode == IndexedDBDatabase::ADD_ONLY) { 787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 7903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 7913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 7923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier, 794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &found); 795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 796e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 797e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error checking key existence."); 798e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 79946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 800e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 801e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (found) { 8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Key already exists in the object store.")); 808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 8163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 8173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store, 819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *key, 820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch key_was_generated, 8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys, 822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Before this point, don't do any mutation. After this point, rollback the 838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // transaction in case of error. 839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->PutRecord(transaction->BackingStoreTransaction(), 8413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 8443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value, 8450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ¶ms->handles, 846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier); 847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 848e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 850e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error: backing store error performing put/add."); 851e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 85246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 853e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 854e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 8633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id); 865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store.auto_increment && 8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 869ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch key->type() == WebIDBKeyTypeNumber) { 870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), 871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction, 872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->object_store_id, 874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !key_was_generated); 876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 877e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 878e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error updating key generator."); 879e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 88046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 881e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 882e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess(*key); 888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, 891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 894f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); 8957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 8967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(alecflett): This method could be asynchronous, but we need to 901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // evaluate if it's worth the extra complexity. 902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 9051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) transaction->BackingStoreTransaction(), 9061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) metadata_.id, 9071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) object_store_id, 9081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *primary_key, 9091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &record_identifier, 9101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &found); 911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 912e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 913e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error setting index keys."); 914e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 91546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 916e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 917e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!found) { 921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error setting index keys for object store.")); 924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 928a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 9351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id(), 937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch object_store_metadata, 938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *primary_key, 939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch index_keys, 941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 952f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 9591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id); 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64, 968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids) { 969f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::SetIndexesReady", "txn.id", transaction_id); 9707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 9717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 9737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask( 9763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PREEMPTIVE_TASK, 9773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 9783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 9793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_ids.size())); 980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReadyOperation( 9833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t index_count, 9843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 985f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::SetIndexesReadyOperation", 986f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 987f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < index_count; ++i) 989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->DidCompletePreemptiveEvent(); 990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::OpenCursorOperationParams { 9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OpenCursorOperationParams() {} 9943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 9953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id; 9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range; 9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorDirection direction; 9983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type; 9993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::TaskType task_type; 10003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 10013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 10033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); 10043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenCursor( 1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 1010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorDirection direction, 1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_only, 1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskType task_type, 1014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1015f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); 10167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 10177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 10187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 10197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams()); 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id = index_id; 10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key_range = key_range.Pass(); 10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction = direction; 10283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type = 10293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE; 10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type = task_type; 10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(¶ms))); 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::OpenCursorOperation( 10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params, 10383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 1039f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1( 1040f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "IndexedDBDatabase::OpenCursorOperation", "txn.id", transaction->id()); 1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend has begun indexing, so this pauses the transaction 1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the indexing is complete. This can't happen any earlier 1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // because we don't want to switch to early mode in case multiple 1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // indexes are being created in a row, with Put()'s in between. 10463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK) 1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->AddPreemptiveEvent(); 1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 10513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { 1052424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1053424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 1054424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1055424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transaction->BackingStoreTransaction(), 1056424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id(), 1057424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->object_store_id, 1058424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *params->key_range, 10590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1061424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 1062424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 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) } 1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 10713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 10723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 1083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch params->direction, 10890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 10900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 10910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 10920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 10930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 10940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 10950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 10960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error opening cursor operation"); 109746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) { 10980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 10990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 11040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Why is Success being called? 110523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) params->callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 1106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCursor> cursor = 11103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new IndexedDBCursor(backing_store_cursor.Pass(), 11113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type, 11123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type, 11133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction); 11143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess( 1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Count(int64 transaction_id, 1119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 1121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 1122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id); 11247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 11257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 11267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 11277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 11287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 11323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 11333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 11363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CountOperation( 11403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 11413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 11423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 11433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 11443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 1145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CountOperation", "txn.id", transaction->id()); 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint32 count = 0; 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 11503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 11560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 11570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 11650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch indexed_db::CURSOR_NEXT, 11660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s); 11670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 11680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 11690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); 11700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 11710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error performing count operation"); 117246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) { 11730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 11740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 11750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 11783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++count; 11840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } while (backing_store_cursor->Continue(&s)); 11850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 11860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(cmumford): Check for database corruption. 1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteRange( 1192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); 11977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 11987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 11997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 12017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 12063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 12073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 12083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 12093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteRangeOperation( 12133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 1217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1( 1218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "IndexedDBDatabase::DeleteRangeOperation", "txn.id", transaction->id()); 121946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) leveldb::Status s = 122046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) backing_store_->DeleteRange(transaction->BackingStoreTransaction(), 122146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) id(), 122246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) object_store_id, 122346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *key_range); 12240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 122546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::string16 error_string = 122646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ASCIIToUTF16("Internal error deleting data in range"); 12270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 122846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) error_string); 12290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch transaction->Abort(error); 123046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) { 12310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 12320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 12330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 12340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Clear(int64 transaction_id, 1240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); 12437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 12447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 1247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 12497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 12523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::ClearOperation( 12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 1259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id()); 12600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s = backing_store_->ClearObjectStore( 12610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch transaction->BackingStoreTransaction(), id(), object_store_id); 12620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) { 12630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 12640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "Internal error clearing object store"); 12650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callbacks->OnError(error); 126646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) { 12670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 12680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error); 12690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreOperation( 1276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int64 object_store_id, 12773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 1278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", 1279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 1280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 1281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store_metadata = 1283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.object_stores[object_store_id]; 1284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 1285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 1287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_id); 1288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 1289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error deleting object store '") + 12913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata.name + ASCIIToUTF16("'."); 1292e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1293e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 1294e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 129546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (leveldb_env::IsCorruption(s)) 1296e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 1297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 1298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 1299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RemoveObjectStore(object_store_id); 1302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->ScheduleAbortTask( 1303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 1304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 1305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_store_metadata)); 1306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeOperation( 13093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 version, 13103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 13113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection, 1312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1( 1314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id()); 13153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 old_version = metadata_.int_version; 13163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_GT(version, old_version); 1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!backing_store_->UpdateIDBDatabaseIntVersion( 1319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->BackingStoreTransaction(), id(), version)) { 1320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError error( 1321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 13227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASCIIToUTF16( 13237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "Internal error writing data to stable storage when " 13247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "updating version.")); 13253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError(error); 1326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(error); 1327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transaction->ScheduleAbortTask( 1331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, 1332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 1333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.version, 1334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.int_version)); 1335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.int_version = version; 1336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metadata_.version = kNoStringVersion; 1337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_second_half_open_.reset( 1340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new PendingSuccessCall(callbacks, connection.get(), version)); 13415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata()); 1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 13455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool committed) { 1346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transactions_[transaction->id()], transaction); 1348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.erase(transaction->id()); 1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 13525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (committed) { 13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(pending_second_half_open_->version(), metadata_.int_version); 13545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(metadata_.id != kInvalidId); 13555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection was already minted for OnUpgradeNeeded callback. 13575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection; 13585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(), 13595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this->metadata()); 13605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 13615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Version change transaction was aborted in " 13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "upgradeneeded event handler.")); 13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection queue is now unblocked. 1370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBDatabase::TransactionCommitFailed() { 13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Factory may be null in unit tests. 13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!factory_) 13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 13781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) factory_->HandleBackingStoreFailure(backing_store_->origin_url()); 13791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 13801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t IndexedDBDatabase::ConnectionCount() const { 1382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This does not include pending open calls, as those should not block version 1383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // changes and deletes. 1384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return connections_.size(); 1385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingOpenCount() const { 1388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_open_calls_.size(); 1389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingUpgradeCount() const { 1392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_run_version_change_transaction_call_ ? 1 : 0; 1393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::RunningUpgradeCount() const { 1396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_second_half_open_ ? 1 : 0; 1397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingDeleteCount() const { 1400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_delete_calls_.size(); 1401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::ProcessPendingCalls() { 1404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { 14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(pending_run_version_change_transaction_call_->version() > 1406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version); 1407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<PendingUpgradeCall> pending_call = 1408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_.Pass(); 14095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal(pending_call->callbacks(), 14105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->ReleaseConnection(), 14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->transaction_id(), 14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->version()); 14135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(1u, ConnectionCount()); 1414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through would be a no-op, since transaction must complete 1415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 1416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsDeleteDatabaseBlocked()); 1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsOpenConnectionBlocked()); 1418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsDeleteDatabaseBlocked()) { 1422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingDeleteCallList pending_delete_calls; 1423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.swap(pending_delete_calls); 1424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_delete_calls.empty()) { 1425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Only the first delete call will delete the database, but each must fire 1426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // callbacks. 1427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingDeleteCall> pending_delete_call( 1428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.front()); 1429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.pop_front(); 14305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteDatabaseFinal(pending_delete_call->callbacks()); 1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // delete_database_final should never re-queue calls. 1433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 1434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through when complete, as pending opens may be unblocked. 1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsOpenConnectionBlocked()) { 1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingOpenCallList pending_open_calls; 1439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls_.swap(pending_open_calls); 1440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_open_calls.empty()) { 1441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OpenConnection(pending_open_calls.front()); 1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls.pop_front(); 1443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateTransaction( 1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 1450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& object_store_ids, 1451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint16 mode) { 1452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); 14538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 14544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(transactions_.find(transaction_id) == transactions_.end()); 14554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 14564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The transaction will add itself to this database's coordinator, which 14595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // manages the lifetime of the object. 14605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TransactionCreated(new IndexedDBTransaction( 14617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction_id, 14627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch connection->callbacks(), 14637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::set<int64>(object_store_ids.begin(), object_store_ids.end()), 14647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static_cast<indexed_db::TransactionMode>(mode), 1465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, 14665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new IndexedDBBackingStore::Transaction(backing_store_))); 1467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { 1470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transactions_[transaction->id()] = transaction; 1471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsOpenConnectionBlocked() const { 1474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !pending_delete_calls_.empty() || 14755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_coordinator_.IsRunningVersionChangeTransaction() || 1476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_; 1477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenConnection( 1480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBPendingConnection& connection) { 1481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Should have a priority queue so that higher version 1484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // requests are processed first. http://crbug.com/225850 1485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsOpenConnectionBlocked()) { 1486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The backing store only detects data loss when it is first opened. The 1487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // presence of existing connections means we didn't even check for data loss 1488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // so there'd better not be any. 1489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss()); 1490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pending_open_calls_.push_back(connection); 1491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (metadata_.id == kInvalidId) { 1495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The database was deleted then immediately re-opened; OpenInternal() 1496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recreates it in the backing store. 1497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (OpenInternal().ok()) { 1498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, 1499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version); 1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 message; 1502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = ASCIIToUTF16( 1504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening database with no version specified."); 15055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = 1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error opening database with version ") + 1508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(connection.version); 15095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, message)); 1512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We infer that the database didn't exist from its lack of either type of 1517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // version. 1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool is_new_database = 1519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version == kNoStringVersion && 1520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; 1521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { 1523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // For unit tests only - skip upgrade steps. Calling from script with 1524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // DEFAULT_INT_VERSION throws exception. 1525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK that not in unit tests. 1526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(is_new_database); 1527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We may need to change the version. 1535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 local_version = connection.version; 1536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_new_database) { 1538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Spec says: If no version is specified and no database exists, set 1545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database version to 1. 1546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version = 1; 1547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version > metadata_.int_version) { 1550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RunVersionChangeTransaction(connection.callbacks, 1551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.transaction_id, 1554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version); 1555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version < metadata_.int_version) { 1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionVersionError, 1560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASCIIToUTF16("The requested version (") + 1561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(local_version) + 1562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16(") is less than the existing version (") + 1563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); 1564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(local_version, metadata_.int_version); 1567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransaction( 1574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 15775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 requested_version) { 1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(callbacks); 15808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection.get())); 1581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ConnectionCount() > 1) { 15825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); 1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (*it != connection.get()) { 15893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (*it)->callbacks()->OnVersionChange(metadata_.int_version, 15903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) requested_version); 1591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Remove the call to OnBlocked and instead wait 1594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the frontend tells us that all the "versionchange" events 1595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // have been delivered. http://crbug.com/100123 1596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_run_version_change_transaction_call_); 1599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall( 1600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callbacks, connection.Pass(), transaction_id, requested_version)); 1601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 16035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal( 16045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks, connection.Pass(), transaction_id, requested_version); 1605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransactionFinal( 1608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 requested_version) { 1612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<int64> object_store_ids; 1614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateTransaction(transaction_id, 1615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection.get(), 1616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_ids, 1617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::TRANSACTION_VERSION_CHANGE); 1618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transactions_[transaction_id]->ScheduleTask( 1620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&IndexedDBDatabase::VersionChangeOperation, 1621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 1622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requested_version, 1623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callbacks, 1624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Passed(&connection))); 1625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabase( 1629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsDeleteDatabaseBlocked()) { 1632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*it)->callbacks()->OnVersionChange( 1638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version, IndexedDBDatabaseMetadata::NO_INT_VERSION); 1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Only fire OnBlocked if there are open 1641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // connections after the VersionChangeEvents are received, not 1642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // just set up to fire. http://crbug.com/100123 1643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); 1645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteDatabaseFinal(callbacks); 1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { 1651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !!ConnectionCount(); 1652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabaseFinal( 1655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!IsDeleteDatabaseBlocked()); 1657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!backing_store_->DeleteDatabase(metadata_.name).ok()) { 1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError( 1660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting database.")); 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1664a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64 old_version = metadata_.int_version; 1665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version = kNoStringVersion; 1666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.id = kInvalidId; 1667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.clear(); 1669a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callbacks->OnSuccess(old_version); 16705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (factory_) 16715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->DatabaseDeleted(identifier_); 16725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 16735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 16745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::ForceClose() { 16755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IndexedDBConnection::ForceClose() may delete this database, so hold ref. 16765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> protect(this); 16775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConnectionSet::const_iterator it = connections_.begin(); 16785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (it != connections_.end()) { 16795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection = *it++; 16805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connection->ForceClose(); 16815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 16825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(connections_.empty()); 1683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 168558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { 16868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 16878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->IsConnected()); 16888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->database() == this); 1689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDB_TRACE("IndexedDBDatabase::Close"); 16918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Abort outstanding transactions from the closing connection. This 1692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // can not happen if the close is requested by the connection itself 1693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as the front-end defers the close until all transactions are 16948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // complete, but can occur on process termination or forced close. 1695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 1696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap transactions(transactions_); 1697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TransactionMap::const_iterator it = transactions.begin(), 1698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) end = transactions.end(); 1699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != end; 1700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (it->second->connection() == connection->callbacks()) 1702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second->Abort( 1703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Connection is closing.")); 1705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connections_.erase(connection); 1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_ && 17105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->connection() == connection) { 17115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 1712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 1713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "The connection was closed.")); 1714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Add a test for the pending_open_calls_ cases below. 1720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ConnectionCount() && !pending_open_calls_.size() && 1721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !pending_delete_calls_.size()) { 1722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 1723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL origin_url = backing_store_->origin_url(); 17251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_ = NULL; 17261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // factory_ should only be null in unit tests. 1728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK(factory_ || !in_unit_tests) - somehow. 172958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (factory_) { 17305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->ReleaseDatabase(identifier_, forced); 173158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) factory_ = NULL; 173258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStoreAbortOperation( 17373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 1738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::CreateObjectStoreAbortOperation", 1741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 1742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 17433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveObjectStore(object_store_id); 1744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreAbortOperation( 17473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 1748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreAbortOperation", 1751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 1752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 17533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddObjectStore(object_store_metadata, 17543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBObjectStoreMetadata::kInvalidId); 1755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeAbortOperation( 1758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& previous_version, 17593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 previous_int_version, 1760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", 1763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "txn.id", 1764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) transaction->id()); 17653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.version = previous_version; 17663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version = previous_int_version; 1767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 1770