indexed_db_database.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/indexed_db/indexed_db_connection.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/browser/indexed_db/indexed_db_context_impl.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_cursor.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_factory.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_index_writer.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_pending_connection.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_transaction.h" 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_value.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_path.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_range.h" 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16; 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::Int64ToString16; 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeNumber; 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in-progress connection. 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingUpgradeCall { 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 transaction_id, 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : callbacks_(callbacks), 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection_(connection.Pass()), 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version_(version), 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch transaction_id_(transaction_id) {} 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Takes ownership of the connection object. 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT { 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return connection_.Pass(); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 transaction_id() const { return transaction_id_; } 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection_; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version_; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 transaction_id_; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PendingSuccessCall has a IndexedDBConnection* because the connection is now 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// owned elsewhere, but we need to cancel the success call if that connection 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// closes before it is sent. 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabase::PendingSuccessCall { 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 version) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : callbacks_(callbacks), connection_(connection), version_(version) {} 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection() const { return connection_; } 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 version() const { return version_; } 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection_; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version_; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::PendingDeleteCall { 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : callbacks_(callbacks) {} 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks_; 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IndexedDBBackingStore* backing_store, 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBFactory* factory, 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const Identifier& unique_identifier) { 96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database = 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) new IndexedDBDatabase(name, backing_store, factory, unique_identifier); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!database->OpenInternal().ok()) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return database; 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const base::string16::value_type kNoStringVersion[] = {0}; 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)IndexedDBDatabase::IndexedDBDatabase(const base::string16& name, 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBBackingStore* backing_store, 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBFactory* factory, 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Identifier& unique_identifier) 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_(name, 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kNoStringVersion, 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION, 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId), 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) identifier_(unique_identifier), 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_(factory) { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddObjectStore( 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store, 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_object_store_id) { 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store.id) == 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) { 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(metadata_.max_object_store_id, new_max_object_store_id); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.max_object_store_id = new_max_object_store_id; 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store.id] = object_store; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveObjectStore(int64 object_store_id) { 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.erase(object_store_id); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddIndex(int64 object_store_id, 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index, 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_index_id) { 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index.id) == object_store.indexes.end()); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes[index.id] = index; 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_index_id != IndexedDBIndexMetadata::kInvalidId) { 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(object_store.max_index_id, new_max_index_id); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.max_index_id = new_max_index_id; 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveIndex(int64 object_store_id, int64 index_id) { 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end()); 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes.erase(index_id); 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status IndexedDBDatabase::OpenInternal() { 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool success = false; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, &metadata_, &success); 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(success == (metadata_.id != kInvalidId)) << "success = " << success 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " id = " << metadata_.id; 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (success) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->GetObjectStores(metadata_.id, 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &metadata_.object_stores); 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->CreateIDBDatabaseMetaData( 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id); 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBDatabase::~IndexedDBDatabase() { 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_open_calls_.empty()); 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int child_process_id) { 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection( 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new IndexedDBConnection(this, database_callbacks)); 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connections_.insert(connection.get()); 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /* TODO(ericu): Grant child process permissions here so that the connection 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * can create Blobs. 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connection.Pass(); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIndexedDBTransaction* IndexedDBDatabase::GetTransaction( 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 transaction_id) const { 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TransactionMap::const_iterator trans_iterator = 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transactions_.find(transaction_id); 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (trans_iterator == transactions_.end()) 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return trans_iterator->second; 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(metadata_.object_stores, object_store_id)) { 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(int64 object_store_id, 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ContainsKey(object_store_metadata.indexes, index_id)) { 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndOptionalIndexId( 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (index_id != IndexedDBIndexMetadata::kInvalidId && 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !ContainsKey(object_store_metadata.indexes, index_id)) { 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId( 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 object_store_id, 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 index_id) const { 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBObjectStoreMetadata& object_store_metadata = 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores.find(object_store_id)->second; 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(object_store_metadata.indexes, index_id)) { 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid index_id"; 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool auto_increment) { 265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::CreateObjectStore"); 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(metadata_.object_stores, object_store_id)) { 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DLOG(ERROR) << "Invalid object_store_id"; 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store_metadata( 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_path, 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) auto_increment, 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::kMinimumIndexId); 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateObjectStoreOperation, 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata), 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id)); 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddObjectStore(object_store_metadata, object_store_id); 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStoreOperation( 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateObjectStoreOperation"); 298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch leveldb::Status s = 299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch backing_store_->CreateObjectStore(transaction->BackingStoreTransaction(), 300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->database()->id(), 301e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.id, 302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name, 303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.key_path, 304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.auto_increment); 305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!s.ok()) { 306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error creating object store '") + 309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_store_metadata.name + ASCIIToUTF16("'.")); 310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 311e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 312e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteObjectStore"); 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata), 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata)); 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveObjectStore(object_store_id); 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateIndex(int64 transaction_id, 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool unique, 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool multi_entry) { 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::CreateIndex"); 3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) 3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata( 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, index_id, key_path, unique, multi_entry); 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateIndexOperation, 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata), 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::CreateIndexAbortOperation, 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id)); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddIndex(object_store_id, index_metadata, index_id); 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateIndexOperation( 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateIndexOperation"); 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.id, 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.name, 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.key_path, 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata.unique, 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) index_metadata.multi_entry).ok()) { 386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error creating index '") + 388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, error_string)); 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateIndexAbortOperation( 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteIndex(int64 transaction_id, 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id) { 407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteIndex"); 4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IndexedDBIndexMetadata& index_metadata = 4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metadata_.object_stores[object_store_id].indexes[index_id]; 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata), 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_metadata)); 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexOperation( 4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteIndexOperation"); 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction->database()->id(), 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) index_metadata.id); 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASCIIToUTF16("Internal error deleting index '") + 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) index_metadata.name + ASCIIToUTF16("'."); 445e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 446e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 447e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 448e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 449e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 450e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteIndexAbortOperation( 4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata, 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Commit(int64 transaction_id) { 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend suggests that we commit, but we may have previously initiated 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // an abort, and so have disposed of the transaction. on_abort has already 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // been dispatched to the frontend, so it will find out about that 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 4687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Commit(); 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id) { 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(); 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id, 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabaseError& error) { 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (transaction) 4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction->Abort(error); 488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Get(int64 transaction_id, 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool key_only, 495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Get"); 4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::GetOperation, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Passed(&key_range), 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::GetOperation( 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type, 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::GetOperation"); 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[object_store_id]; 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKey* key; 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (key_range->IsOnlyKey()) { 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = &key_range->lower(); 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); 536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ObjectStore Retrieval Operation 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 5643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = &backing_store_cursor->key(); 569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key; 572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s; 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Object Store Retrieval Operation 57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 582e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 583e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 584e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 585e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 586e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 587e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 588e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *key, object_store_metadata.key_path); 600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // From here we are dealing only with indexes. 608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetPrimaryKeyViaIndex( 609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 6103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 6113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &primary_key); 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 616e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 617e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetPrimaryKeyViaIndex."); 618e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 619e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 620e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 621e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!primary_key) { 6253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(*primary_key); 631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 63523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *primary_key, 640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &value); 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 642e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 643e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error in GetRecord."); 644e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callbacks->OnError(error); 645e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 646e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 647e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store_metadata.auto_increment && 6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !object_store_metadata.key_path.IsNull()) { 6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value, *primary_key, object_store_metadata.key_path); 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(&value); 661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static scoped_ptr<IndexedDBKey> GenerateKey( 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBBackingStore* backing_store, 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBTransaction* transaction, 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 max_generator_value = 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9007199254740992LL; // Maximum integer storable as ECMAScript number. 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 current_number; 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ¤t_number); 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "Failed to GetKeyGeneratorCurrentNumber"; 678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (current_number < 0 || current_number > max_generator_value) 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey(current_number, WebIDBKeyTypeNumber)); 684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store, 687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IndexedDBTransaction* transaction, 688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 database_id, 689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 object_store_id, 690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBKey& key, 691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool check_current) { 6923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(WebIDBKeyTypeNumber, key.type()); 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store->MaybeUpdateKeyGeneratorCurrentNumber( 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<int64>(floor(key.number())) + 1, 698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) check_current); 699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::PutOperationParams { 7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PutOperationParams() {} 7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 70423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PutMode put_mode; 7073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 7083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<IndexKeys> index_keys; 7093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PutOperationParams); 7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Put(int64 transaction_id, 715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 71623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue* value, 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PutMode put_mode, 719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Put"); 7227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 7237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 7287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key); 7313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<PutOperationParams> params(new PutOperationParams()); 7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 7333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value.swap(*value); 7343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key = key.Pass(); 7353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode = put_mode; 7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 7373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys = index_keys; 7383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); 7403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params, 7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 7443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::PutOperation"); 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_was_generated = false; 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(metadata_.object_stores.find(params->object_store_id) != 7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores.end()); 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store = 7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.object_stores[params->object_store_id]; 7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(object_store.auto_increment || params->key->IsValid()); 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 7563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store.auto_increment && !params->key->IsValid()) { 7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( 7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) backing_store_.get(), transaction, id(), params->object_store_id); 759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_was_generated = true; 760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!auto_inc_key->IsValid()) { 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Maximum key generator value reached.")); 764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = auto_inc_key.Pass(); 767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 7683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key = params->key.Pass(); 769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key->IsValid()); 772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 7743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->put_mode == IndexedDBDatabase::ADD_ONLY) { 775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 7783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 7793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier, 782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &found); 783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 784e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 785e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error checking key existence."); 786e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 787e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 788e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 789e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (found) { 7933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError( 794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Key already exists in the object store.")); 796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 801a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 8043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store, 807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *key, 808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch key_was_generated, 8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_keys, 810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 8143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 8203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnError(IndexedDBDatabaseError( 821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Before this point, don't do any mutation. After this point, rollback the 826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // transaction in case of error. 827a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->PutRecord(transaction->BackingStoreTransaction(), 8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key, 8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->value, 833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier); 834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 835e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error( 836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 837e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error: backing store error performing put/add."); 838e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 839e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 840e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 841e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 8483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) backing_store_.get(), 849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 8503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 8513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id); 852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (object_store.auto_increment && 8553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && 856ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch key->type() == WebIDBKeyTypeNumber) { 857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), 858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction, 859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->object_store_id, 861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *key, 862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !key_was_generated); 863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 864e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 865e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error updating key generator."); 866e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params->callbacks->OnError(error); 867e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 868e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 869e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess(*key); 875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, 878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::SetIndexKeys"); 8827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 8837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(alecflett): This method could be asynchronous, but we need to 888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // evaluate if it's worth the extra complexity. 889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = backing_store_->KeyExistsInObjectStore( 8921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) transaction->BackingStoreTransaction(), 8931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) metadata_.id, 8941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) object_store_id, 8951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *primary_key, 8961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &record_identifier, 8971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &found); 898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 899e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 900e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "Internal error setting index keys."); 901e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 902e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 903e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 904e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!found) { 908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error setting index keys for object store.")); 911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedVector<IndexWriter> index_writers; 915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_message; 916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool backing_store_success = MakeIndexWriters(transaction, 9221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id(), 924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch object_store_metadata, 925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *primary_key, 926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch index_keys, 928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &index_writers, 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error_message, 930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &obeys_constraints); 931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionConstraintError, error_message)); 940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexWriter* index_writer = index_writers[i]; 945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 9461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_, 947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id); 950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, 954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64, 955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids) { 956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::SetIndexesReady"); 9577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 9587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 9607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask( 9633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::PREEMPTIVE_TASK, 9643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 9653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 9663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_ids.size())); 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReadyOperation( 9703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t index_count, 9713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 9723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::SetIndexesReadyOperation"); 9733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < index_count; ++i) 974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->DidCompletePreemptiveEvent(); 975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct IndexedDBDatabase::OpenCursorOperationParams { 9783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OpenCursorOperationParams() {} 9793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id; 9803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id; 9813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range; 9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorDirection direction; 9833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) indexed_db::CursorType cursor_type; 9843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBDatabase::TaskType task_type; 9853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks; 9863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); 9893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenCursor( 992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorDirection direction, 997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_only, 998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskType task_type, 999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::OpenCursor"); 10017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 10027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 10037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 10047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams()); 10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id = object_store_id; 10103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id = index_id; 10113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->key_range = key_range.Pass(); 10123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction = direction; 10133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type = 10143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE; 10153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type = task_type; 10163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks = callbacks; 10173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 10183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(¶ms))); 10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::OpenCursorOperation( 10223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<OpenCursorOperationParams> params, 10233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::OpenCursorOperation"); 1025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend has begun indexing, so this pauses the transaction 1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the indexing is complete. This can't happen any earlier 1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // because we don't want to switch to early mode in case multiple 1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // indexes are being created in a row, with Put()'s in between. 10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK) 1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->AddPreemptiveEvent(); 1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { 1035424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1036424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 1037424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1038424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transaction->BackingStoreTransaction(), 1039424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id(), 1040424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->object_store_id, 1041424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *params->key_range, 1042424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->direction); 1043424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 1044424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 1045424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transaction->BackingStoreTransaction(), 1046424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id(), 1047424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) params->object_store_id, 1048424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *params->key_range, 10493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction); 1050424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 10523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 10533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction); 1061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 1063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 10643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->object_store_id, 10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->index_id, 10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *params->key_range, 10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->direction); 1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 107323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) params->callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCursor> cursor = 10783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new IndexedDBCursor(backing_store_cursor.Pass(), 10793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->cursor_type, 10803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->task_type, 10813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction); 10823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params->callbacks->OnSuccess( 1083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Count(int64 transaction_id, 1087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 index_id, 1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBKeyRange> key_range, 1090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Count"); 10927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 10937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 10947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 10957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1098868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 11003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 11013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 11043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CountOperation( 11083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 11093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 index_id, 11103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 11113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 11123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 11133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CountOperation"); 1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint32 count = 0; 1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index_id, 11303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 11343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++count; 11407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } while (backing_store_cursor->Continue()); 1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(count); 1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteRange( 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::DeleteRange"); 11517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 11527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 11537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 11547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 11557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 11567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 11603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 11613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key_range), 11633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 1164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteRangeOperation( 11673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 11683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 11693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 11703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 11713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteRangeOperation"); 1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor = 1173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->OpenObjectStoreCursor( 1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 11753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 11763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_id, 11773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *key_range, 1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (backing_store_cursor) { 1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->DeleteRecord( 1182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transaction->BackingStoreTransaction(), 1183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 1184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id, 1185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) backing_store_cursor->record_identifier()) 1186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .ok()) { 11873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError( 1188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting data in range")); 1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 11927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } while (backing_store_cursor->Continue()); 1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBDatabase::Clear(int64 transaction_id, 1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 object_store_id, 1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBDatabase::Clear"); 12027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IndexedDBTransaction* transaction = GetTransaction(transaction_id); 12037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!transaction) 1204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 1206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ValidateObjectStoreId(object_store_id)) 12087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transaction->ScheduleTask(base::Bind( 12113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::ClearOperation( 12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 12183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::ObjectStoreClearOperation"); 1219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!backing_store_->ClearObjectStore(transaction->BackingStoreTransaction(), 1220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), 1221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_store_id).ok()) { 12223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError( 1223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error clearing object store")); 1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(); 1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreOperation( 12313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 12323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBTransaction* transaction) { 12333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreOperation"); 1234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = 1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 12373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata.id); 1238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 1239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error_string = 1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error deleting object store '") + 12413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) object_store_metadata.name + ASCIIToUTF16("'."); 1242e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1243e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_string); 1244e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch transaction->Abort(error); 1245e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (s.IsCorruption()) 1246e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), 1247e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error); 1248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeOperation( 12523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 version, 12533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection, 1255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::VersionChangeOperation"); 12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 old_version = metadata_.int_version; 12583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_GT(version, old_version); 12593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version = version; 12603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!backing_store_->UpdateIDBDatabaseIntVersion( 1261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id(), 12633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version)) { 1264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError error( 1265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASCIIToUTF16( 12677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "Internal error writing data to stable storage when " 12687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "updating version.")); 12693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnError(error); 1270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(error); 1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 12733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_second_half_open_.reset( 1275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new PendingSuccessCall(callbacks, connection.get(), version)); 12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata()); 1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 12805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool committed) { 1281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transactions_[transaction->id()], transaction); 1283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.erase(transaction->id()); 1284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 12875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (committed) { 12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(pending_second_half_open_->version(), metadata_.int_version); 12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(metadata_.id != kInvalidId); 12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection was already minted for OnUpgradeNeeded callback. 12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<IndexedDBConnection> connection; 12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(), 12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this->metadata()); 12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Version change transaction was aborted in " 12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "upgradeneeded event handler.")); 13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection queue is now unblocked. 1305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBDatabase::TransactionCommitFailed() { 13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Factory may be null in unit tests. 13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!factory_) 13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 13131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) factory_->HandleBackingStoreFailure(backing_store_->origin_url()); 13141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 13151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t IndexedDBDatabase::ConnectionCount() const { 1317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This does not include pending open calls, as those should not block version 1318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // changes and deletes. 1319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return connections_.size(); 1320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingOpenCount() const { 1323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_open_calls_.size(); 1324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingUpgradeCount() const { 1327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_run_version_change_transaction_call_ ? 1 : 0; 1328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::RunningUpgradeCount() const { 1331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_second_half_open_ ? 1 : 0; 1332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBDatabase::PendingDeleteCount() const { 1335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pending_delete_calls_.size(); 1336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::ProcessPendingCalls() { 1339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { 13405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(pending_run_version_change_transaction_call_->version() > 1341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version); 1342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<PendingUpgradeCall> pending_call = 1343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_.Pass(); 13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal(pending_call->callbacks(), 13455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->ReleaseConnection(), 13465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->transaction_id(), 13475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_call->version()); 13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(1u, ConnectionCount()); 1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through would be a no-op, since transaction must complete 1350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsDeleteDatabaseBlocked()); 1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsOpenConnectionBlocked()); 1353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsDeleteDatabaseBlocked()) { 1357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingDeleteCallList pending_delete_calls; 1358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.swap(pending_delete_calls); 1359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_delete_calls.empty()) { 1360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Only the first delete call will delete the database, but each must fire 1361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // callbacks. 1362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingDeleteCall> pending_delete_call( 1363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.front()); 1364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.pop_front(); 13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteDatabaseFinal(pending_delete_call->callbacks()); 1366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // delete_database_final should never re-queue calls. 1368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 1369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through when complete, as pending opens may be unblocked. 1370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsOpenConnectionBlocked()) { 1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingOpenCallList pending_open_calls; 1374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls_.swap(pending_open_calls); 1375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_open_calls.empty()) { 1376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OpenConnection(pending_open_calls.front()); 1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls.pop_front(); 1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateTransaction( 1383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection, 1385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& object_store_ids, 1386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint16 mode) { 1387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 13894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(transactions_.find(transaction_id) == transactions_.end()); 13904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 13914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The transaction will add itself to this database's coordinator, which 13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // manages the lifetime of the object. 13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TransactionCreated(new IndexedDBTransaction( 13967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch transaction_id, 13977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch connection->callbacks(), 13987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::set<int64>(object_store_ids.begin(), object_store_ids.end()), 13997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static_cast<indexed_db::TransactionMode>(mode), 1400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, 14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new IndexedDBBackingStore::Transaction(backing_store_))); 1402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { 1405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transactions_[transaction->id()] = transaction; 1406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsOpenConnectionBlocked() const { 1409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !pending_delete_calls_.empty() || 14105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_coordinator_.IsRunningVersionChangeTransaction() || 1411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_; 1412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenConnection( 1415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IndexedDBPendingConnection& connection) { 1416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Should have a priority queue so that higher version 1419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // requests are processed first. http://crbug.com/225850 1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsOpenConnectionBlocked()) { 1421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The backing store only detects data loss when it is first opened. The 1422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // presence of existing connections means we didn't even check for data loss 1423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // so there'd better not be any. 1424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss()); 1425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pending_open_calls_.push_back(connection); 1426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (metadata_.id == kInvalidId) { 1430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The database was deleted then immediately re-opened; OpenInternal() 1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recreates it in the backing store. 1432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (OpenInternal().ok()) { 1433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, 1434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version); 1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 message; 1437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = ASCIIToUTF16( 1439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening database with no version specified."); 14405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = 1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error opening database with version ") + 1443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(connection.version); 14445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, message)); 1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We infer that the database didn't exist from its lack of either type of 1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // version. 1453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool is_new_database = 1454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version == kNoStringVersion && 1455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; 1456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { 1458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // For unit tests only - skip upgrade steps. Calling from script with 1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // DEFAULT_INT_VERSION throws exception. 1460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK that not in unit tests. 1461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(is_new_database); 1462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We may need to change the version. 1470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 local_version = connection.version; 1471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_new_database) { 1473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Spec says: If no version is specified and no database exists, set 1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database version to 1. 1481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version = 1; 1482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version > metadata_.int_version) { 1485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RunVersionChangeTransaction(connection.callbacks, 1486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.transaction_id, 1489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_version); 1490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (local_version < metadata_.int_version) { 1493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnError(IndexedDBDatabaseError( 1494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionVersionError, 1495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASCIIToUTF16("The requested version (") + 1496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Int64ToString16(local_version) + 1497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16(") is less than the existing version (") + 1498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); 1499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(local_version, metadata_.int_version); 1502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.callbacks->OnSuccess( 1503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateConnection(connection.database_callbacks, 1504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection.child_process_id), 1505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this->metadata()); 1506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransaction( 1509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 15125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 requested_version) { 1513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(callbacks); 15158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection.get())); 1516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ConnectionCount() > 1) { 15175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); 1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (*it != connection.get()) { 15243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (*it)->callbacks()->OnVersionChange(metadata_.int_version, 15253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) requested_version); 1526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Remove the call to OnBlocked and instead wait 1529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the frontend tells us that all the "versionchange" events 1530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // have been delivered. http://crbug.com/100123 1531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_run_version_change_transaction_call_); 1534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall( 1535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callbacks, connection.Pass(), transaction_id, requested_version)); 1536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 15385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunVersionChangeTransactionFinal( 15395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks, connection.Pass(), transaction_id, requested_version); 1540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransactionFinal( 1543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<IndexedDBConnection> connection, 1545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 requested_version) { 1547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<int64> object_store_ids; 1549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateTransaction(transaction_id, 1550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection.get(), 1551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_ids, 1552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::TRANSACTION_VERSION_CHANGE); 1553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 15545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transactions_[transaction_id] 15555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->ScheduleTask(base::Bind(&IndexedDBDatabase::VersionChangeOperation, 15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requested_version, 15585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks, 15595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&connection)), 15605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, 15615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metadata_.version, 15635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metadata_.int_version)); 1564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabase( 1569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsDeleteDatabaseBlocked()) { 1572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (ConnectionSet::const_iterator it = connections_.begin(); 1573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != connections_.end(); 1574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*it)->callbacks()->OnVersionChange( 1578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch metadata_.int_version, IndexedDBDatabaseMetadata::NO_INT_VERSION); 1579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): Only fire OnBlocked if there are open 1581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // connections after the VersionChangeEvents are received, not 1582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // just set up to fire. http://crbug.com/100123 1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); 1585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteDatabaseFinal(callbacks); 1588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { 1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !!ConnectionCount(); 1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabaseFinal( 1595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 1596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!IsDeleteDatabaseBlocked()); 1597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(backing_store_); 1598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!backing_store_->DeleteDatabase(metadata_.name).ok()) { 1599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError( 1600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting database.")); 1602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1604a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int64 old_version = metadata_.int_version; 1605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version = kNoStringVersion; 1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.id = kInvalidId; 1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.clear(); 1609a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callbacks->OnSuccess(old_version); 16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (factory_) 16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->DatabaseDeleted(identifier_); 16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 16135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 16145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBDatabase::ForceClose() { 16155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IndexedDBConnection::ForceClose() may delete this database, so hold ref. 16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> protect(this); 16175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConnectionSet::const_iterator it = connections_.begin(); 16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (it != connections_.end()) { 16195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBConnection* connection = *it++; 16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connection->ForceClose(); 16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(connections_.empty()); 1623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 162558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { 16268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connections_.count(connection)); 16278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->IsConnected()); 16288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(connection->database() == this); 1629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Abort outstanding transactions from the closing connection. This 1631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // can not happen if the close is requested by the connection itself 1632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as the front-end defers the close until all transactions are 16338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // complete, but can occur on process termination or forced close. 1634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 1635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap transactions(transactions_); 1636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TransactionMap::const_iterator it = transactions.begin(), 1637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) end = transactions.end(); 1638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != end; 1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (it->second->connection() == connection->callbacks()) 1641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second->Abort( 1642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Connection is closing.")); 1644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connections_.erase(connection); 1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_ && 16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->connection() == connection) { 16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_second_half_open_->callbacks()->OnError( 1651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, 1652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "The connection was closed.")); 1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Add a test for the pending_open_calls_ cases below. 1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ConnectionCount() && !pending_open_calls_.size() && 1660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !pending_delete_calls_.size()) { 1661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL origin_url = backing_store_->origin_url(); 16641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_ = NULL; 16651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // factory_ should only be null in unit tests. 1667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK(factory_ || !in_unit_tests) - somehow. 166858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (factory_) { 16695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory_->ReleaseDatabase(identifier_, forced); 167058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) factory_ = NULL; 167158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStoreAbortOperation( 16763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 object_store_id, 1677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 16783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); 1679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 16803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveObjectStore(object_store_id); 1681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStoreAbortOperation( 16843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata, 1685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 16863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreAbortOperation"); 1687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 16883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddObjectStore(object_store_metadata, 16893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IndexedDBObjectStoreMetadata::kInvalidId); 1690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBDatabase::VersionChangeAbortOperation( 1693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& previous_version, 16943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 previous_int_version, 1695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 16963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 16983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.version = previous_version; 16993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) metadata_.int_version = previous_int_version; 1700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 1703