indexed_db_database.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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> 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector> 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" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_backing_store.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_cursor.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_factory.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_index_writer.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_transaction.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_path.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_range.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::Int64ToString16; 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using WebKit::WebIDBKey; 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CreateObjectStoreOperation : public IndexedDBTransaction::Operation { 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateObjectStoreOperation( 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store, 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_(object_store_metadata) {} 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store_metadata_; 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DeleteObjectStoreOperation : public IndexedDBTransaction::Operation { 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteObjectStoreOperation( 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store, 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata) 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_(object_store_metadata) {} 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store_metadata_; 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::VersionChangeOperation 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : public IndexedDBTransaction::Operation { 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) VersionChangeOperation( 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database, 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version, 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks) 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_id_(transaction_id), 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) version_(version), 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks), 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_(database_callbacks) {} 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database_; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id_; 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version_; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks_; 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CreateObjectStoreAbortOperation : public IndexedDBTransaction::Operation { 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateObjectStoreAbortOperation(scoped_refptr<IndexedDBDatabase> database, 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), object_store_id_(object_store_id) {} 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBDatabase> database_; 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DeleteObjectStoreAbortOperation : public IndexedDBTransaction::Operation { 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteObjectStoreAbortOperation( 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database, 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), object_store_metadata_(object_store_metadata) {} 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database_; 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store_metadata_; 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::VersionChangeAbortOperation 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : public IndexedDBTransaction::Operation { 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) VersionChangeAbortOperation(scoped_refptr<IndexedDBDatabase> database, 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& previous_version, 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 previous_int_version) 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) previous_version_(previous_version), 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) previous_int_version_(previous_int_version) {} 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database_; 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 previous_version_; 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 previous_int_version_; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CreateIndexOperation : public IndexedDBTransaction::Operation { 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateIndexOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata) 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_(index_metadata) {} 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata_; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DeleteIndexOperation : public IndexedDBTransaction::Operation { 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteIndexOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_(index_metadata) {} 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata_; 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CreateIndexAbortOperation : public IndexedDBTransaction::Operation { 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateIndexAbortOperation(scoped_refptr<IndexedDBDatabase> database, 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id) 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_(index_id) {} 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBDatabase> database_; 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 index_id_; 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DeleteIndexAbortOperation : public IndexedDBTransaction::Operation { 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteIndexAbortOperation(scoped_refptr<IndexedDBDatabase> database, 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata) 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : database_(database), 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_(index_metadata) {} 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBDatabase> database_; 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata_; 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class GetOperation : public IndexedDBTransaction::Operation { 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int64 database_id, 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const IndexedDBKeyPath& key_path, 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const bool auto_increment, 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorType cursor_type, 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) database_id_(database_id), 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_(index_id), 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) key_path_(key_path), 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) auto_increment_(auto_increment), 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range_(key_range.Pass()), 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_type_(cursor_type), 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks) { 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 index_id_; 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath key_path_; 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const bool auto_increment_; 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_ptr<IndexedDBKeyRange> key_range_; 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const indexed_db::CursorType cursor_type_; 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class PutOperation : public IndexedDBTransaction::Operation { 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PutOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store, 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<char>* value, 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::PutMode put_mode, 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids, 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexedDBDatabase::IndexKeys>& index_keys) 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_(database_id), 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_(object_store), 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_(key.Pass()), 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) put_mode_(put_mode), 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks), 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_ids_(index_ids), 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_keys_(index_keys) { 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) value_.swap(*value); 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store_; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<char> value_; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key_; 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabase::PutMode put_mode_; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64> index_ids_; 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexedDBDatabase::IndexKeys> index_keys_; 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class SetIndexesReadyOperation : public IndexedDBTransaction::Operation { 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit SetIndexesReadyOperation(size_t index_count) 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : index_count_(index_count) {} 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const size_t index_count_; 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class OpenCursorOperation : public IndexedDBTransaction::Operation { 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OpenCursorOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorDirection direction, 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorType cursor_type, 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::TaskType task_type, 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_(database_id), 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_(index_id), 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range_(key_range.Pass()), 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_(direction), 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_type_(cursor_type), 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) task_type_(task_type), 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks) {} 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 index_id_; 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_ptr<IndexedDBKeyRange> key_range_; 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const indexed_db::CursorDirection direction_; 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const indexed_db::CursorType cursor_type_; 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabase::TaskType task_type_; 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CountOperation : public IndexedDBTransaction::Operation { 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CountOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_(database_id), 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_(index_id), 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range_(key_range.Pass()), 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks) {} 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 index_id_; 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_ptr<IndexedDBKeyRange> key_range_; 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DeleteRangeOperation : public IndexedDBTransaction::Operation { 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteRangeOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_(database_id), 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range_(key_range.Pass()), 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks) {} 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_ptr<IndexedDBKeyRange> key_range_; 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ClearOperation : public IndexedDBTransaction::Operation { 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ClearOperation(scoped_refptr<IndexedDBBackingStore> backing_store, 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_(database_id), 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_(object_store_id), 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_(callbacks) {} 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBBackingStore> backing_store_; 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 database_id_; 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 object_store_id_; 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::PendingOpenCall { 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingOpenCall( 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version) 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : callbacks_(callbacks), 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_(database_callbacks), 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) version_(version), 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_id_(transaction_id) {} 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> Callbacks() { return callbacks_; } 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> DatabaseCallbacks() { 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return database_callbacks_; 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 Version() { return version_; } 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 TransactionId() const { return transaction_id_; } 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks_; 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version_; 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 transaction_id_; 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBDatabase::PendingDeleteCall { 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacksWrapper> callbacks) 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : callbacks_(callbacks) {} 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> Callbacks() { return callbacks_; } 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks_; 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& name, 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore* database, 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBFactory* factory, 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& unique_identifier) { 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> backend = 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new IndexedDBDatabase(name, database, factory, unique_identifier); 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backend->OpenInternal()) 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backend; 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const base::string16::value_type kNoStringVersion[] = {0}; 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBDatabase::IndexedDBDatabase(const string16& name, 420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore* backing_store, 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBFactory* factory, 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& unique_identifier) 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : backing_store_(backing_store), 424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_(name, 425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId, 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kNoStringVersion, 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION, 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidId), 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) identifier_(unique_identifier), 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) factory_(factory), 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) running_version_change_transaction_(NULL), 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) closing_connection_(false) { 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!metadata_.name.empty()); 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddObjectStore( 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store, 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_object_store_id) { 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store.id) == 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) { 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(metadata_.max_object_store_id, new_max_object_store_id); 443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.max_object_store_id = new_max_object_store_id; 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store.id] = object_store; 446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveObjectStore(int64 object_store_id) { 449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.erase(object_store_id); 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::AddIndex(int64 object_store_id, 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index, 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 new_max_index_id) { 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index.id) == object_store.indexes.end()); 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes[index.id] = index; 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_max_index_id != IndexedDBIndexMetadata::kInvalidId) { 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_LT(object_store.max_index_id, new_max_index_id); 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.max_index_id = new_max_index_id; 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RemoveIndex(int64 object_store_id, int64 index_id) { 472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end()); 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store.indexes.erase(index_id); 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id] = object_store; 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::OpenInternal() { 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool success = false; 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = backing_store_->GetIDBDatabaseMetaData( 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, &metadata_, &success); 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(success == (metadata_.id != kInvalidId)) << "success = " << success 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " id_ = " << metadata_.id; 488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (success) 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->GetObjectStores(metadata_.id, 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &metadata_.object_stores); 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_->CreateIDBDatabaseMetaData( 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id); 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBDatabase::~IndexedDBDatabase() { 499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_open_calls_.empty()); 501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBBackingStore> IndexedDBDatabase::BackingStore() const { 505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store_; 506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& name, 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool auto_increment) { 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::create_object_store"); 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) == 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store_metadata( 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, 525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_path, 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) auto_increment, 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::kMinimumIndexId); 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new CreateObjectStoreOperation(backing_store_, object_store_metadata), 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new CreateObjectStoreAbortOperation(this, object_store_id)); 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddObjectStore(object_store_metadata, object_store_id); 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CreateObjectStoreOperation::Perform(IndexedDBTransaction* transaction) { 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("CreateObjectStoreOperation"); 539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->CreateObjectStore( 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.id, 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.name, 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.key_path, 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.auto_increment)) { 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error creating object store '") + 549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.name + ASCIIToUTF16("'."))); 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::delete_object_store"); 557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new DeleteObjectStoreOperation(backing_store_, object_store_metadata), 571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new DeleteObjectStoreAbortOperation(this, object_store_metadata)); 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveObjectStore(object_store_id); 573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateIndex(int64 transaction_id, 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const string16& name, 579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKeyPath& key_path, 580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool unique, 581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool multi_entry) { 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::create_index"); 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store = 593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) == object_store.indexes.end()); 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata index_metadata( 597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) name, index_id, key_path, unique, multi_entry); 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new CreateIndexOperation(backing_store_, object_store_id, index_metadata), 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new CreateIndexAbortOperation(this, object_store_id, index_id)); 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddIndex(object_store_id, index_metadata, index_id); 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CreateIndexOperation::Perform(IndexedDBTransaction* transaction) { 607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("CreateIndexOperation"); 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), 609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.id, 612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.name, 613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.key_path, 614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.unique, 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.multi_entry)) { 616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 error_string = ASCIIToUTF16("Internal error creating index '") + 617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.name + ASCIIToUTF16("'."); 618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, error_string)); 620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CreateIndexAbortOperation::Perform(IndexedDBTransaction* transaction) { 625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("CreateIndexAbortOperation"); 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->RemoveIndex(object_store_id_, index_id_); 628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteIndex(int64 transaction_id, 631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id) { 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::delete_index"); 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata object_store = 644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end()); 647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBIndexMetadata& index_metadata = object_store.indexes[index_id]; 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new DeleteIndexOperation(backing_store_, object_store_id, index_metadata), 651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new DeleteIndexAbortOperation(this, object_store_id, index_metadata)); 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveIndex(object_store_id, index_id); 654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeleteIndexOperation::Perform(IndexedDBTransaction* transaction) { 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("DeleteIndexOperation"); 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.id); 662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 error_string = ASCIIToUTF16("Internal error deleting index '") + 664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_metadata_.name + ASCIIToUTF16("'."); 665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, error_string)); 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeleteIndexAbortOperation::Perform(IndexedDBTransaction* transaction) { 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("DeleteIndexAbortOperation"); 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->AddIndex( 674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, index_metadata_, IndexedDBIndexMetadata::kInvalidId); 675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Commit(int64 transaction_id) { 678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend suggests that we commit, but we may have previously initiated 679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // an abort, and so have disposed of the transaction. on_abort has already 680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // been dispatched to the frontend, so it will find out about that 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_[transaction_id]->Commit(); 684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id) { 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_[transaction_id]->Abort(); 691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Abort(int64 transaction_id, 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBDatabaseError& error) { 695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If the transaction is unknown, then it has already been aborted by the 696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend before this call so it is safe to ignore it. 697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transactions_.find(transaction_id) != transactions_.end()) 698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_[transaction_id]->Abort(error); 699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Get( 702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_only, 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::get"); 709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 7137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) IndexedDBDatabaseMetadata::ObjectStoreMap::const_iterator store_iterator = 7147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) metadata_.object_stores.find(object_store_id); 7157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (store_iterator == metadata_.object_stores.end()) 7167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(new GetOperation( 720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_, 7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) metadata_.id, 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) store_iterator->second.key_path, 7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) store_iterator->second.auto_increment, 726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range.Pass(), 727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GetOperation::Perform(IndexedDBTransaction* transaction) { 732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("GetOperation"); 733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKey* key; 735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (key_range_->IsOnlyKey()) { 738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = &key_range_->lower(); 739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (index_id_ == IndexedDBIndexMetadata::kInvalidId) { 741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(cursor_type_, indexed_db::CURSOR_KEY_ONLY); 742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ObjectStore Retrieval Operation 743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) { 750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = &backing_store_cursor->key(); 775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key; 778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok; 779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (index_id_ == IndexedDBIndexMetadata::kInvalidId) { 780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Object Store Retrieval Operation 781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<char> value; 782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ok = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &value); 787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error in get_record.")); 791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (auto_increment_ && !key_path_.IsNull()) { 800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(&value, *key, key_path_); 801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(&value); 805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 806868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // From here we are dealing only with indexes. 809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ok = backing_store_->GetPrimaryKeyViaIndex( 810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &primary_key); 816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error in get_primary_key_via_index.")); 820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!primary_key) { 823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) { 827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Value Retrieval Operation 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(*primary_key); 829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Index Referenced Value Retrieval Operation 833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<char> value; 834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ok = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *primary_key, 838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &value); 839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error in get_record.")); 843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (value.empty()) { 847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (auto_increment_ && !key_path_.IsNull()) { 851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(&value, *primary_key, key_path_); 852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(&value); 855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static scoped_ptr<IndexedDBKey> GenerateKey( 858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store, 859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBTransaction> transaction, 860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id) { 862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 max_generator_value = 863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9007199254740992LL; // Maximum integer storable as ECMAScript number. 864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 current_number; 865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = backing_store->GetKeyGeneratorCurrentNumber( 866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ¤t_number); 870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Failed to get_key_generator_current_number"; 872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (current_number < 0 || current_number > max_generator_value) 875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new IndexedDBKey()); 876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr( 878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new IndexedDBKey(current_number, WebIDBKey::NumberType)); 879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static bool UpdateKeyGenerator( 882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store, 883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBTransaction> transaction, 884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id, 885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBKey* key, 887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool check_current) { 888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key); 889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(WebIDBKey::NumberType, key->type()); 890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store->MaybeUpdateKeyGeneratorCurrentNumber( 891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<int64>(floor(key->number())) + 1, 895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) check_current); 896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Put(int64 transaction_id, 899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<char>* value, 901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PutMode put_mode, 903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids, 905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::put"); 907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata object_store_metadata = 915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key); 918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(object_store_metadata.auto_increment || key->IsValid()); 919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(new PutOperation(backing_store_, 920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata, 922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) value, 923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key.Pass(), 924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) put_mode, 925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, 926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_ids, 927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_keys)); 928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PutOperation::Perform(IndexedDBTransaction* transaction) { 931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("PutOperation"); 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(index_ids_.size(), index_keys_.size()); 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_was_generated = false; 935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> key; 937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && 938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_.auto_increment && !key_->IsValid()) { 939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( 940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_, transaction, database_id_, object_store_.id); 941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_was_generated = true; 942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!auto_inc_key->IsValid()) { 943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionConstraintError, 945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Maximum key generator value reached.")); 946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = auto_inc_key.Pass(); 949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key = key_.Pass(); 951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(key->IsValid()); 954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (put_mode_ == IndexedDBDatabase::ADD_ONLY) { 957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = backing_store_->KeyExistsInObjectStore( 959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_.id, 962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key.get(), 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier, 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &found); 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error checking key existence.")); 969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 970868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (found) { 972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionConstraintError, 974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Key already exists in the object store.")); 975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedVector<IndexedDBObjectStoreImpl::IndexWriter> index_writers; 980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 error_message; 981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 982868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool backing_store_success = 983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreImpl::MakeIndexWriters(transaction, 984868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_.get(), 985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_, 987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key, 988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_was_generated, 989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_ids_, 990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_keys_, 991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &index_writers, 992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &error_message, 993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &obeys_constraints); 994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError(IndexedDBDatabaseError( 996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError(IndexedDBDatabaseError( 1002868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionConstraintError, error_message)); 1003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Before this point, don't do any mutation. After this point, rollback the 1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // transaction in case of error. 1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_success = 1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->PutRecord(transaction->BackingStoreTransaction(), 1010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_.id, 1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key.get(), 1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) value_, 1014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier); 1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 1016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError(IndexedDBDatabaseError( 1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 1018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error performing put/add.")); 1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i]; 1024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 10257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) backing_store_.get(), 1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_.id); 1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (object_store_.auto_increment && 1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && 1033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key->type() == WebIDBKey::NumberType) { 1034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = UpdateKeyGenerator(backing_store_, 1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction, 1036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_.id, 1038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key.get(), 1039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !key_was_generated); 1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error updating key generator.")); 1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(*key); 1049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, 1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids, 1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<IndexKeys>& index_keys) { 1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::set_index_keys"); 1057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1059868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); 1063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> store = BackingStore(); 1065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): This method could be asynchronous, but we need to 1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // evaluate if it's worth the extra complexity. 1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::RecordIdentifier record_identifier; 1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found = false; 1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = 1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) store->KeyExistsInObjectStore(transaction->BackingStoreTransaction(), 1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.id, 1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *primary_key, 1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &record_identifier, 1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &found); 1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort( 1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error setting index keys.")); 1080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!found) { 1083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 1084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 1085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error setting index keys for object store.")); 1086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedVector<IndexedDBObjectStoreImpl::IndexWriter> index_writers; 1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 error_message; 1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool obeys_constraints = false; 1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 1094868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const IndexedDBObjectStoreMetadata& object_store_metadata = 1095868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores[object_store_id]; 1096868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool backing_store_success = 1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreImpl::MakeIndexWriters(transaction, 1098868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) store.get(), 1099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata, 1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *primary_key, 1102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) false, 1103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_ids, 1104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_keys, 1105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &index_writers, 1106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &error_message, 1107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &obeys_constraints); 1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_success) { 1109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error: backing store error updating index keys.")); 1112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!obeys_constraints) { 1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionConstraintError, error_message)); 1117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_writers.size(); ++i) { 1121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i]; 1122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_writer->WriteIndexKeys(record_identifier, 1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) store.get(), 1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id); 1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, 1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64, 1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& index_ids) { 1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBObjectStoreImpl::set_indexes_ready"); 1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(IndexedDBDatabase::PREEMPTIVE_TASK, 1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new SetIndexesReadyOperation(index_ids.size())); 1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SetIndexesReadyOperation::Perform(IndexedDBTransaction* transaction) { 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("SetIndexesReadyOperation"); 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < index_count_; ++i) 1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->DidCompletePreemptiveEvent(); 1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenCursor( 1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorDirection direction, 1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool key_only, 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskType task_type, 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::open_cursor"); 1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(new OpenCursorOperation( 1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_, 1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 1170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 1171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range.Pass(), 1173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction, 1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 1175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) task_type, 1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OpenCursorOperation::Perform(IndexedDBTransaction* transaction) { 1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("OpenCursorOperation"); 1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The frontend has begun indexing, so this pauses the transaction 1183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the indexing is complete. This can't happen any earlier 1184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // because we don't want to switch to early mode in case multiple 1185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // indexes are being created in a row, with Put()'s in between. 1186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (task_type_ == IndexedDBDatabase::PREEMPTIVE_TASK) 1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->AddPreemptiveEvent(); 1188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (index_id_ == IndexedDBIndexMetadata::kInvalidId) { 1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(cursor_type_, indexed_db::CURSOR_KEY_ONLY); 1192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreCursor( 1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_); 1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(task_type_, IndexedDBDatabase::NORMAL_TASK); 1200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) { 1201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 1206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_); 1208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexCursor( 1210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 1214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_); 1216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(static_cast<std::vector<char>*>(NULL)); 1221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::TaskType task_type( 1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<IndexedDBDatabase::TaskType>(task_type_)); 1226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCursor> cursor = IndexedDBCursor::Create( 1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor.Pass(), cursor_type_, task_type, transaction); 1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess( 1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Count( 1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 index_id, 1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::count"); 1239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.object_stores.find(object_store_id) != 1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.end()); 1247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(new CountOperation(backing_store_, 1248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) id(), 1249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id, 1250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id, 1251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) key_range.Pass(), 1252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks)); 1253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CountOperation::Perform(IndexedDBTransaction* transaction) { 1256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("CountOperation"); 1257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint32 count = 0; 1258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (index_id_ == IndexedDBIndexMetadata::kInvalidId) { 1261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) index_id_, 1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_cursor) { 1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(count); 1278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++count; 1283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } while (backing_store_cursor->ContinueFunction(0)); 1284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(count); 1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteRange( 1289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBKeyRange> key_range, 1292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::delete_range"); 1294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask(new DeleteRangeOperation( 1301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_, id(), object_store_id, key_range.Pass(), callbacks)); 1302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeleteRangeOperation::Perform(IndexedDBTransaction* transaction) { 1305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("DeleteRangeOperation"); 1306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor = 1307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->OpenObjectStoreCursor( 1308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *key_range_, 1312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CURSOR_NEXT); 1313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (backing_store_cursor) { 1314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) do { 1315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->DeleteRecord( 1316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_, 1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_cursor->record_identifier())) { 1320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 1321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting data in range")); 1323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } while (backing_store_cursor->ContinueFunction(0)); 1326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 1329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Clear( 1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 object_store_id, 1334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("IndexedDBDatabase::clear"); 1336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap::const_iterator trans_iterator = 1337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.find(transaction_id); 1338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (trans_iterator == transactions_.end()) 1339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction = trans_iterator->second; 1341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); 1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 1344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ClearOperation(backing_store_, id(), object_store_id, callbacks)); 1345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ClearOperation::Perform(IndexedDBTransaction* transaction) { 1348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("ObjectStoreClearOperation"); 1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->ClearObjectStore(transaction->BackingStoreTransaction(), 1350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id_, 1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_id_)) { 1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError( 1353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error clearing object store")); 1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnSuccess(); 1358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeleteObjectStoreOperation::Perform(IndexedDBTransaction* transaction) { 1361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("DeleteObjectStoreOperation"); 1362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ok = 1363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->database()->id(), 1365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.id); 1366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ok) { 1367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 error_string = 1368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error deleting object store '") + 1369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_metadata_.name + ASCIIToUTF16("'."); 1370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(IndexedDBDatabaseError( 1371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, error_string)); 1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::VersionChangeOperation::Perform( 1376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("VersionChangeOperation"); 1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 database_id = database_->id(); 1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 old_version = database_->metadata_.int_version; 1380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_GT(version_, old_version); 1381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->metadata_.int_version = version_; 1382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!database_->backing_store_->UpdateIDBDatabaseIntVersion( 1383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->BackingStoreTransaction(), 1384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_id, 1385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->metadata_.int_version)) { 1386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError error( 1387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, 1388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error writing data to stable storage when " 1389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "updating version.")); 1390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnError(error); 1391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->Abort(error); 1392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!database_->pending_second_half_open_); 1395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->pending_second_half_open_.reset(new PendingOpenCall( 1396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_, database_callbacks_, transaction_id_, version_)); 1397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks_->OnUpgradeNeeded(old_version, database_, database_->metadata()); 1398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::TransactionStarted(IndexedDBTransaction* transaction) { 1401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!running_version_change_transaction_); 1404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) running_version_change_transaction_ = transaction; 1405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction) { 1409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transactions_[transaction->id()], transaction); 1412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_.erase(transaction->id()); 1413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(transaction, running_version_change_transaction_); 1415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) running_version_change_transaction_ = NULL; 1416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::TransactionFinishedAndAbortFired( 1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 1423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_->Callbacks()->OnError( 1424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, 1425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Version change transaction was aborted in " 1426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "upgradeneeded event handler.")); 1427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::TransactionFinishedAndCompleteFired( 1434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { 1436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_second_half_open_); 1437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version); 1439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.id != kInvalidId); 1440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_->Callbacks()->OnSuccess(this, this->metadata()); 1441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)size_t IndexedDBDatabase::ConnectionCount() const { 1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This does not include pending open calls, as those should not block version 1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // changes and deletes. 1450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return database_callbacks_set_.size(); 1451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::ProcessPendingCalls() { 1454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_) { 1455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version); 1456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(metadata_.id != kInvalidId); 1457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingOpenCall> pending_call = pending_second_half_open_.Pass(); 1458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_call->Callbacks()->OnSuccess(this, this->metadata()); 1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through when complete, as pending opens may be unblocked. 1460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { 1463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_run_version_change_transaction_call_->Version() > 1464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version); 1465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingOpenCall> pending_call = 1466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_.Pass(); 1467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RunVersionChangeTransactionFinal(pending_call->Callbacks(), 1468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_call->DatabaseCallbacks(), 1469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_call->TransactionId(), 1470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_call->Version()); 1471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(static_cast<size_t>(1), ConnectionCount()); 1472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through would be a no-op, since transaction must complete 1473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // asynchronously. 1474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsDeleteDatabaseBlocked()); 1475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsOpenConnectionBlocked()); 1476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsDeleteDatabaseBlocked()) { 1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingDeleteCallList pending_delete_calls; 1481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.swap(pending_delete_calls); 1482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_delete_calls.empty()) { 1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Only the first delete call will delete the database, but each must fire 1484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // callbacks. 1485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingDeleteCall> pending_delete_call( 1486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.front()); 1487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls.pop_front(); 1488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteDatabaseFinal(pending_delete_call->Callbacks()); 1489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // delete_database_final should never re-queue calls. 1491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(pending_delete_calls_.empty()); 1492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fall through when complete, as pending opens may be unblocked. 1493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsOpenConnectionBlocked()) { 1496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PendingOpenCallList pending_open_calls; 1497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls_.swap(pending_open_calls); 1498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (!pending_open_calls.empty()) { 1499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<PendingOpenCall> pending_open_call(pending_open_calls.front()); 1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls.pop_front(); 1501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OpenConnection(pending_open_call->Callbacks(), 1502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_call->DatabaseCallbacks(), 1503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_call->TransactionId(), 1504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_call->Version()); 1505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::CreateTransaction( 1510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks, 1512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<int64>& object_store_ids, 1513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint16 mode) { 1514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(database_callbacks_set_.has(callbacks)); 1516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBTransaction> transaction = 1518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction::Create( 1519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_id, 1520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, 1521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_ids, 1522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<indexed_db::TransactionMode>(mode), 1523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 1524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.find(transaction_id) == transactions_.end()); 15257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) transactions_[transaction_id] = transaction.get(); 1526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsOpenConnectionBlocked() const { 1529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !pending_delete_calls_.empty() || 1530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) running_version_change_transaction_ || 1531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_; 1532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::OpenConnection( 1535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 1536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, 1537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version) { 1539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(backing_store_.get()); 1540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Should have a priority queue so that higher version 1542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // requests are processed first. http://crbug.com/225850 1543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsOpenConnectionBlocked()) { 1544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_open_calls_.push_back(new PendingOpenCall( 1545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, database_callbacks, transaction_id, version)); 1546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (metadata_.id == kInvalidId) { 1550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The database was deleted then immediately re-opened; OpenInternal() 1551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recreates it in the backing store. 1552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (OpenInternal()) { 1553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(metadata_.int_version, 1554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION); 1555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) string16 message; 1557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) 1558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = ASCIIToUTF16( 1559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening database with no version specified."); 1560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 1561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message = 1562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("Internal error opening database with version ") + 1563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Int64ToString16(version); 1564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError(IndexedDBDatabaseError( 1565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionUnknownError, message)); 1566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We infer that the database didn't exist from its lack of either type of 1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // version. 1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool is_new_database = 1573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version == kNoStringVersion && 1574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; 1575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { 1577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // For unit tests only - skip upgrade steps. Calling from script with 1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // DEFAULT_INT_VERSION throws exception. 1579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Assert that we're executing a unit test. 1580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(is_new_database); 1581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.insert(database_callbacks); 1582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnSuccess(this, this->metadata()); 1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_new_database) { 1588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.insert(database_callbacks); 1589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnSuccess(this, this->metadata()); 1590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Spec says: If no version is specified and no database exists, set 1593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database version to 1. 1594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) version = 1; 1595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (version > metadata_.int_version) { 1598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.insert(database_callbacks); 1599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RunVersionChangeTransaction( 1600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, database_callbacks, transaction_id, version); 1601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (version < metadata_.int_version) { 1604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError(IndexedDBDatabaseError( 1605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebKit::WebIDBDatabaseExceptionVersionError, 1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16("The requested version (") + Int64ToString16(version) + 1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16(") is less than the existing version (") + 1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); 1609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(version, metadata_.int_version); 1612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.insert(database_callbacks); 1613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnSuccess(this, this->metadata()); 1614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransaction( 1617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 1618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, 1619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 requested_version) { 1621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(callbacks.get()); 1623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(database_callbacks_set_.has(database_callbacks)); 1624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ConnectionCount() > 1) { 1625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (DatabaseCallbacksSet::const_iterator it = 1628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.begin(); 1629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != database_callbacks_set_.end(); 1630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 16317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->get() != database_callbacks.get()) 1632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (*it)->OnVersionChange(metadata_.int_version, requested_version); 1633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Remove the call to on_blocked and instead wait 1635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // until the frontend tells us that all the "versionchange" events 1636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // have been delivered. http://crbug.com/100123 1637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_run_version_change_transaction_call_); 1640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_run_version_change_transaction_call_.reset(new PendingOpenCall( 1641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, database_callbacks, transaction_id, requested_version)); 1642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RunVersionChangeTransactionFinal( 1645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, database_callbacks, transaction_id, requested_version); 1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::RunVersionChangeTransactionFinal( 1649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks, 1650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, 1651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 1652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 requested_version) { 1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<int64> object_store_ids; 1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateTransaction(transaction_id, 1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks, 1657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) object_store_ids, 1658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::TRANSACTION_VERSION_CHANGE); 1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBTransaction> transaction = 1660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transactions_[transaction_id]; 1661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction->ScheduleTask( 1663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new VersionChangeOperation(this, 1664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_id, 1665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) requested_version, 1666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks, 1667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks), 1668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new VersionChangeAbortOperation( 1669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, metadata_.version, metadata_.int_version)); 1670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!pending_second_half_open_); 1672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabase( 1675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsDeleteDatabaseBlocked()) { 1678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (DatabaseCallbacksSet::const_iterator it = 1679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.begin(); 1680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != database_callbacks_set_.end(); 1681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 1682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Front end ensures the event is not fired at connections that have 1683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // close_pending set. 1684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (*it)->OnVersionChange(metadata_.int_version, 1685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseMetadata::NO_INT_VERSION); 1686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Only fire on_blocked if there are open 1688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // connections after the VersionChangeEvents are received, not 1689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // just set up to fire. http://crbug.com/100123 1690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnBlocked(metadata_.int_version); 1691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); 1692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeleteDatabaseFinal(callbacks); 1695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { 1698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !!ConnectionCount(); 1699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::DeleteDatabaseFinal( 1702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { 1703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!IsDeleteDatabaseBlocked()); 17047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(backing_store_.get()); 1705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!backing_store_->DeleteDatabase(metadata_.name)) { 1706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError( 1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error deleting database.")); 1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.version = kNoStringVersion; 1712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.id = kInvalidId; 1713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) metadata_.object_stores.clear(); 1715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnSuccess(); 1716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::Close( 1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks) { 17207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(callbacks.get()); 1721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(database_callbacks_set_.has(callbacks)); 1722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Close outstanding transactions from the closing connection. This 1724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // can not happen if the close is requested by the connection itself 1725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as the front-end defers the close until all transactions are 1726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // complete, so something unusual has happened e.g. unexpected 1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // process termination. 1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 1729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionMap transactions(transactions_); 1730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TransactionMap::const_iterator it = transactions.begin(), 1731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) end = transactions.end(); 1732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != end; 1733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++it) { 17347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->second->connection() == callbacks.get()) 1735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second->Abort( 1736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, 1737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Connection is closing.")); 1738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_callbacks_set_.erase(callbacks); 1742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_second_half_open_ && 17437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) pending_second_half_open_->DatabaseCallbacks().get() == callbacks.get()) { 1744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_->Callbacks()->OnError( 1745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, 1746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "The connection was closed.")); 1747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_second_half_open_.reset(); 1748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // process_pending_calls allows the inspector to process a pending open call 1751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // and call close, reentering IndexedDBDatabase::close. Then the 1752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // backend would be removed both by the inspector closing its connection, and 1753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // by the connection that first called close. 1754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // To avoid that situation, don't proceed in case of reentrancy. 1755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (closing_connection_) 1756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::AutoReset<bool> ClosingConnection(&closing_connection_, true); 1758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessPendingCalls(); 1759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Add a test for the pending_open_calls_ cases below. 1761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ConnectionCount() && !pending_open_calls_.size() && 1762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !pending_delete_calls_.size()) { 1763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(transactions_.empty()); 1764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) backing_store_ = NULL; 1766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This check should only be false in unit tests. 1768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jsbell): Assert factory_ || we're executing a unit test. 17697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (factory_.get()) 1770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) factory_->RemoveIDBDatabaseBackend(identifier_); 1771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CreateObjectStoreAbortOperation::Perform( 1775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("CreateObjectStoreAbortOperation"); 1777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->RemoveObjectStore(object_store_id_); 1779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeleteObjectStoreAbortOperation::Perform( 1782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("DeleteObjectStoreAbortOperation"); 1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->AddObjectStore(object_store_metadata_, 1786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBObjectStoreMetadata::kInvalidId); 1787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBDatabase::VersionChangeAbortOperation::Perform( 1790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) { 1791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDB_TRACE("VersionChangeAbortOperation"); 1792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!transaction); 1793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->metadata_.version = previous_version_; 1794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) database_->metadata_.int_version = previous_int_version_; 1795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 1798