summaryrefslogtreecommitdiffstats
path: root/content/browser/indexed_db/indexed_db_database_impl.cc
diff options
context:
space:
mode:
authoralecflett@chromium.org <alecflett@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-30 23:09:08 +0000
committeralecflett@chromium.org <alecflett@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-30 23:09:08 +0000
commite1bcc0207442374ab4d539e6a5623fe4cf1fe8cb (patch)
tree01141ee8180a33ca0fba59379bf5d9e0f19c51db /content/browser/indexed_db/indexed_db_database_impl.cc
parent71c1cbb0f63b371bc4167c9735e400457b376df2 (diff)
downloadchromium_src-e1bcc0207442374ab4d539e6a5623fe4cf1fe8cb.zip
chromium_src-e1bcc0207442374ab4d539e6a5623fe4cf1fe8cb.tar.gz
chromium_src-e1bcc0207442374ab4d539e6a5623fe4cf1fe8cb.tar.bz2
Revert "Migrate the IndexedDB backend from Blink to Chromium"
This reverts commit 71c1cbb0f63b371bc4167c9735e400457b376df2. Landed the wrong patch. BUG= TBR=jsbell Review URL: https://codereview.chromium.org/15853013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203258 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/indexed_db/indexed_db_database_impl.cc')
-rw-r--r--content/browser/indexed_db/indexed_db_database_impl.cc1823
1 files changed, 0 insertions, 1823 deletions
diff --git a/content/browser/indexed_db/indexed_db_database_impl.cc b/content/browser/indexed_db/indexed_db_database_impl.cc
deleted file mode 100644
index 9ecc611..0000000
--- a/content/browser/indexed_db/indexed_db_database_impl.cc
+++ /dev/null
@@ -1,1823 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/indexed_db/indexed_db_database_impl.h"
-
-#include <math.h>
-#include <vector>
-
-#include "base/auto_reset.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "content/browser/indexed_db/indexed_db_backing_store.h"
-#include "content/browser/indexed_db/indexed_db_cursor_impl.h"
-#include "content/browser/indexed_db/indexed_db_factory_impl.h"
-#include "content/browser/indexed_db/indexed_db_index_writer.h"
-#include "content/browser/indexed_db/indexed_db_tracing.h"
-#include "content/browser/indexed_db/indexed_db_transaction.h"
-#include "content/common/indexed_db/indexed_db_key_path.h"
-#include "content/common/indexed_db/indexed_db_key_range.h"
-#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
-
-using base::Int64ToString16;
-using WebKit::WebIDBKey;
-
-namespace content {
-
-class CreateObjectStoreOperation : public IndexedDBTransaction::Operation {
- public:
- CreateObjectStoreOperation(
- scoped_refptr<IndexedDBBackingStore> backing_store,
- const IndexedDBObjectStoreMetadata& object_store_metadata)
- : backing_store_(backing_store),
- object_store_metadata_(object_store_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const IndexedDBObjectStoreMetadata object_store_metadata_;
-};
-
-class DeleteObjectStoreOperation : public IndexedDBTransaction::Operation {
- public:
- DeleteObjectStoreOperation(
- scoped_refptr<IndexedDBBackingStore> backing_store,
- const IndexedDBObjectStoreMetadata& object_store_metadata)
- : backing_store_(backing_store),
- object_store_metadata_(object_store_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const IndexedDBObjectStoreMetadata object_store_metadata_;
-};
-
-class IndexedDBDatabaseImpl::VersionChangeOperation
- : public IndexedDBTransaction::Operation {
- public:
- VersionChangeOperation(
- scoped_refptr<IndexedDBDatabaseImpl> database,
- int64 transaction_id,
- int64 version,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks)
- : database_(database),
- transaction_id_(transaction_id),
- version_(version),
- callbacks_(callbacks),
- database_callbacks_(database_callbacks) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- scoped_refptr<IndexedDBDatabaseImpl> database_;
- int64 transaction_id_;
- int64 version_;
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks_;
-};
-
-class CreateObjectStoreAbortOperation : public IndexedDBTransaction::Operation {
- public:
- CreateObjectStoreAbortOperation(scoped_refptr<IndexedDBDatabaseImpl> database,
- int64 object_store_id)
- : database_(database), object_store_id_(object_store_id) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBDatabaseImpl> database_;
- const int64 object_store_id_;
-};
-
-class DeleteObjectStoreAbortOperation : public IndexedDBTransaction::Operation {
- public:
- DeleteObjectStoreAbortOperation(
- scoped_refptr<IndexedDBDatabaseImpl> database,
- const IndexedDBObjectStoreMetadata& object_store_metadata)
- : database_(database), object_store_metadata_(object_store_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- scoped_refptr<IndexedDBDatabaseImpl> database_;
- IndexedDBObjectStoreMetadata object_store_metadata_;
-};
-
-class IndexedDBDatabaseImpl::VersionChangeAbortOperation
- : public IndexedDBTransaction::Operation {
- public:
- VersionChangeAbortOperation(scoped_refptr<IndexedDBDatabaseImpl> database,
- const string16& previous_version,
- int64 previous_int_version)
- : database_(database),
- previous_version_(previous_version),
- previous_int_version_(previous_int_version) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- scoped_refptr<IndexedDBDatabaseImpl> database_;
- string16 previous_version_;
- int64 previous_int_version_;
-};
-
-class CreateIndexOperation : public IndexedDBTransaction::Operation {
- public:
- CreateIndexOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 object_store_id,
- const IndexedDBIndexMetadata& index_metadata)
- : backing_store_(backing_store),
- object_store_id_(object_store_id),
- index_metadata_(index_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 object_store_id_;
- const IndexedDBIndexMetadata index_metadata_;
-};
-
-class DeleteIndexOperation : public IndexedDBTransaction::Operation {
- public:
- DeleteIndexOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 object_store_id,
- const IndexedDBIndexMetadata& index_metadata)
- : backing_store_(backing_store),
- object_store_id_(object_store_id),
- index_metadata_(index_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 object_store_id_;
- const IndexedDBIndexMetadata index_metadata_;
-};
-
-class CreateIndexAbortOperation : public IndexedDBTransaction::Operation {
- public:
- CreateIndexAbortOperation(scoped_refptr<IndexedDBDatabaseImpl> database,
- int64 object_store_id,
- int64 index_id)
- : database_(database),
- object_store_id_(object_store_id),
- index_id_(index_id) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBDatabaseImpl> database_;
- const int64 object_store_id_;
- const int64 index_id_;
-};
-
-class DeleteIndexAbortOperation : public IndexedDBTransaction::Operation {
- public:
- DeleteIndexAbortOperation(scoped_refptr<IndexedDBDatabaseImpl> database,
- int64 object_store_id,
- const IndexedDBIndexMetadata& index_metadata)
- : database_(database),
- object_store_id_(object_store_id),
- index_metadata_(index_metadata) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBDatabaseImpl> database_;
- const int64 object_store_id_;
- const IndexedDBIndexMetadata index_metadata_;
-};
-
-class GetOperation : public IndexedDBTransaction::Operation {
- public:
- GetOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- const IndexedDBDatabaseMetadata& metadata,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- indexed_db::CursorType cursor_type,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : backing_store_(backing_store),
- database_id_(metadata.id),
- object_store_id_(object_store_id),
- index_id_(index_id),
- key_path_(metadata.object_stores.find(object_store_id)
- ->second.key_path),
- auto_increment_(metadata.object_stores.find(object_store_id)
- ->second.auto_increment),
- key_range_(key_range.Pass()),
- cursor_type_(cursor_type),
- callbacks_(callbacks) {
- DCHECK(metadata.object_stores.find(object_store_id) !=
- metadata.object_stores.end());
- DCHECK(metadata.object_stores.find(object_store_id)->second.id ==
- object_store_id);
- }
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const int64 object_store_id_;
- const int64 index_id_;
- const IndexedDBKeyPath key_path_;
- const bool auto_increment_;
- const scoped_ptr<IndexedDBKeyRange> key_range_;
- const indexed_db::CursorType cursor_type_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-class PutOperation : public IndexedDBTransaction::Operation {
- public:
- PutOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 database_id,
- const IndexedDBObjectStoreMetadata& object_store,
- std::vector<char>* value,
- scoped_ptr<IndexedDBKey> key,
- IndexedDBDatabase::PutMode put_mode,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- const std::vector<int64>& index_ids,
- const std::vector<IndexedDBDatabase::IndexKeys>& index_keys)
- : backing_store_(backing_store),
- database_id_(database_id),
- object_store_(object_store),
- key_(key.Pass()),
- put_mode_(put_mode),
- callbacks_(callbacks),
- index_ids_(index_ids),
- index_keys_(index_keys) {
- value_.swap(*value);
- }
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const IndexedDBObjectStoreMetadata object_store_;
- std::vector<char> value_;
- scoped_ptr<IndexedDBKey> key_;
- const IndexedDBDatabase::PutMode put_mode_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
- const std::vector<int64> index_ids_;
- const std::vector<IndexedDBDatabase::IndexKeys> index_keys_;
-};
-
-class SetIndexesReadyOperation : public IndexedDBTransaction::Operation {
- public:
- explicit SetIndexesReadyOperation(size_t index_count)
- : index_count_(index_count) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const size_t index_count_;
-};
-
-class OpenCursorOperation : public IndexedDBTransaction::Operation {
- public:
- OpenCursorOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- indexed_db::CursorDirection direction,
- indexed_db::CursorType cursor_type,
- IndexedDBDatabase::TaskType task_type,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : backing_store_(backing_store),
- database_id_(database_id),
- object_store_id_(object_store_id),
- index_id_(index_id),
- key_range_(key_range.Pass()),
- direction_(direction),
- cursor_type_(cursor_type),
- task_type_(task_type),
- callbacks_(callbacks) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const int64 object_store_id_;
- const int64 index_id_;
- const scoped_ptr<IndexedDBKeyRange> key_range_;
- const indexed_db::CursorDirection direction_;
- const indexed_db::CursorType cursor_type_;
- const IndexedDBDatabase::TaskType task_type_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-class CountOperation : public IndexedDBTransaction::Operation {
- public:
- CountOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : backing_store_(backing_store),
- database_id_(database_id),
- object_store_id_(object_store_id),
- index_id_(index_id),
- key_range_(key_range.Pass()),
- callbacks_(callbacks) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const int64 object_store_id_;
- const int64 index_id_;
- const scoped_ptr<IndexedDBKeyRange> key_range_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-class DeleteRangeOperation : public IndexedDBTransaction::Operation {
- public:
- DeleteRangeOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 database_id,
- int64 object_store_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : backing_store_(backing_store),
- database_id_(database_id),
- object_store_id_(object_store_id),
- key_range_(key_range.Pass()),
- callbacks_(callbacks) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const int64 object_store_id_;
- const scoped_ptr<IndexedDBKeyRange> key_range_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-class ClearOperation : public IndexedDBTransaction::Operation {
- public:
- ClearOperation(scoped_refptr<IndexedDBBackingStore> backing_store,
- int64 database_id,
- int64 object_store_id,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : backing_store_(backing_store),
- database_id_(database_id),
- object_store_id_(object_store_id),
- callbacks_(callbacks) {}
- virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE;
-
- private:
- const scoped_refptr<IndexedDBBackingStore> backing_store_;
- const int64 database_id_;
- const int64 object_store_id_;
- const scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-class IndexedDBDatabaseImpl::PendingOpenCall {
- public:
- PendingOpenCall(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks,
- int64 transaction_id,
- int64 version)
- : callbacks_(callbacks),
- database_callbacks_(database_callbacks),
- version_(version),
- transaction_id_(transaction_id) {}
- scoped_refptr<IndexedDBCallbacksWrapper> Callbacks() { return callbacks_; }
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> DatabaseCallbacks() {
- return database_callbacks_;
- }
- int64 Version() { return version_; }
- int64 TransactionId() const { return transaction_id_; }
-
- private:
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks_;
- int64 version_;
- const int64 transaction_id_;
-};
-
-class IndexedDBDatabaseImpl::PendingDeleteCall {
- public:
- explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacksWrapper> callbacks)
- : callbacks_(callbacks) {}
- scoped_refptr<IndexedDBCallbacksWrapper> Callbacks() { return callbacks_; }
-
- private:
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks_;
-};
-
-scoped_refptr<IndexedDBDatabaseImpl> IndexedDBDatabaseImpl::Create(
- const string16& name,
- IndexedDBBackingStore* database,
- IndexedDBFactoryImpl* factory,
- const string16& unique_identifier) {
- scoped_refptr<IndexedDBDatabaseImpl> backend =
- new IndexedDBDatabaseImpl(name, database, factory, unique_identifier);
- if (!backend->OpenInternal())
- return 0;
- return backend;
-}
-
-namespace {
-const base::string16::value_type kNoStringVersion[] = {0};
-}
-
-IndexedDBDatabaseImpl::IndexedDBDatabaseImpl(
- const string16& name,
- IndexedDBBackingStore* backing_store,
- IndexedDBFactoryImpl* factory,
- const string16& unique_identifier)
- : backing_store_(backing_store),
- metadata_(name,
- kInvalidId,
- kNoStringVersion,
- IndexedDBDatabaseMetadata::NO_INT_VERSION,
- kInvalidId),
- identifier_(unique_identifier),
- factory_(factory),
- running_version_change_transaction_(NULL),
- closing_connection_(false) {
- DCHECK(!metadata_.name.empty());
-}
-
-void IndexedDBDatabaseImpl::AddObjectStore(
- const IndexedDBObjectStoreMetadata& object_store,
- int64 new_max_object_store_id) {
- DCHECK(metadata_.object_stores.find(object_store.id) ==
- metadata_.object_stores.end());
- if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) {
- DCHECK_LT(metadata_.max_object_store_id, new_max_object_store_id);
- metadata_.max_object_store_id = new_max_object_store_id;
- }
- metadata_.object_stores[object_store.id] = object_store;
-}
-
-void IndexedDBDatabaseImpl::RemoveObjectStore(int64 object_store_id) {
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- metadata_.object_stores.erase(object_store_id);
-}
-
-void IndexedDBDatabaseImpl::AddIndex(int64 object_store_id,
- const IndexedDBIndexMetadata& index,
- int64 new_max_index_id) {
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- IndexedDBObjectStoreMetadata object_store =
- metadata_.object_stores[object_store_id];
-
- DCHECK(object_store.indexes.find(index.id) == object_store.indexes.end());
- object_store.indexes[index.id] = index;
- if (new_max_index_id != IndexedDBIndexMetadata::kInvalidId) {
- DCHECK_LT(object_store.max_index_id, new_max_index_id);
- object_store.max_index_id = new_max_index_id;
- }
- metadata_.object_stores[object_store_id] = object_store;
-}
-
-void IndexedDBDatabaseImpl::RemoveIndex(int64 object_store_id, int64 index_id) {
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- IndexedDBObjectStoreMetadata object_store =
- metadata_.object_stores[object_store_id];
-
- DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end());
- object_store.indexes.erase(index_id);
- metadata_.object_stores[object_store_id] = object_store;
-}
-
-bool IndexedDBDatabaseImpl::OpenInternal() {
- bool success = false;
- bool ok = backing_store_->GetIDBDatabaseMetaData(
- metadata_.name, &metadata_, success);
- DCHECK(success == (metadata_.id != kInvalidId)) << "success = " << success
- << " id_ = " << metadata_.id;
- if (!ok)
- return false;
- if (success)
- return backing_store_->GetObjectStores(metadata_.id,
- &metadata_.object_stores);
-
- return backing_store_->CreateIDBDatabaseMetaData(
- metadata_.name, metadata_.version, metadata_.int_version, metadata_.id);
-}
-
-IndexedDBDatabaseImpl::~IndexedDBDatabaseImpl() {
- DCHECK(transactions_.empty());
- DCHECK(pending_open_calls_.empty());
- DCHECK(pending_delete_calls_.empty());
-}
-
-scoped_refptr<IndexedDBBackingStore> IndexedDBDatabaseImpl::BackingStore()
- const {
- return backing_store_;
-}
-
-void IndexedDBDatabaseImpl::CreateObjectStore(int64 transaction_id,
- int64 object_store_id,
- const string16& name,
- const IndexedDBKeyPath& key_path,
- bool auto_increment) {
- IDB_TRACE("IndexedDBDatabaseImpl::create_object_store");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE);
-
- DCHECK(metadata_.object_stores.find(object_store_id) ==
- metadata_.object_stores.end());
- IndexedDBObjectStoreMetadata object_store_metadata(
- name,
- object_store_id,
- key_path,
- auto_increment,
- IndexedDBDatabase::kMinimumIndexId);
-
- transaction->ScheduleTask(
- new CreateObjectStoreOperation(backing_store_, object_store_metadata),
- new CreateObjectStoreAbortOperation(this, object_store_id));
-
- AddObjectStore(object_store_metadata, object_store_id);
-}
-
-void CreateObjectStoreOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("CreateObjectStoreOperation");
- if (!backing_store_->CreateObjectStore(
- transaction->BackingStoreTransaction(),
- transaction->database()->id(),
- object_store_metadata_.id,
- object_store_metadata_.name,
- object_store_metadata_.key_path,
- object_store_metadata_.auto_increment)) {
- string16 error_string =
- ASCIIToUTF16("Internal error creating object store '") +
- object_store_metadata_.name + ASCIIToUTF16("'.");
-
- scoped_refptr<IndexedDBDatabaseError> error =
- IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError, error_string);
- transaction->Abort(error);
- return;
- }
-}
-
-void IndexedDBDatabaseImpl::DeleteObjectStore(int64 transaction_id,
- int64 object_store_id) {
- IDB_TRACE("IndexedDBDatabaseImpl::delete_object_store");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE);
-
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- const IndexedDBObjectStoreMetadata& object_store_metadata =
- metadata_.object_stores[object_store_id];
-
- transaction->ScheduleTask(
- new DeleteObjectStoreOperation(backing_store_, object_store_metadata),
- new DeleteObjectStoreAbortOperation(this, object_store_metadata));
- RemoveObjectStore(object_store_id);
-}
-
-void IndexedDBDatabaseImpl::CreateIndex(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
- const string16& name,
- const IndexedDBKeyPath& key_path,
- bool unique,
- bool multi_entry) {
- IDB_TRACE("IndexedDBDatabaseImpl::create_index");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE);
-
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- const IndexedDBObjectStoreMetadata object_store =
- metadata_.object_stores[object_store_id];
-
- DCHECK(object_store.indexes.find(index_id) == object_store.indexes.end());
- const IndexedDBIndexMetadata index_metadata(
- name, index_id, key_path, unique, multi_entry);
-
- transaction->ScheduleTask(
- new CreateIndexOperation(backing_store_, object_store_id, index_metadata),
- new CreateIndexAbortOperation(this, object_store_id, index_id));
-
- AddIndex(object_store_id, index_metadata, index_id);
-}
-
-void CreateIndexOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("CreateIndexOperation");
- if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(),
- transaction->database()->id(),
- object_store_id_,
- index_metadata_.id,
- index_metadata_.name,
- index_metadata_.key_path,
- index_metadata_.unique,
- index_metadata_.multi_entry)) {
- string16 error_string = ASCIIToUTF16("Internal error creating index '") +
- index_metadata_.name + ASCIIToUTF16("'.");
- transaction->Abort(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError, error_string));
- return;
- }
-}
-
-void CreateIndexAbortOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("CreateIndexAbortOperation");
- DCHECK(!transaction);
- database_->RemoveIndex(object_store_id_, index_id_);
-}
-
-void IndexedDBDatabaseImpl::DeleteIndex(int64 transaction_id,
- int64 object_store_id,
- int64 index_id) {
- IDB_TRACE("IndexedDBDatabaseImpl::delete_index");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE);
-
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- IndexedDBObjectStoreMetadata object_store =
- metadata_.object_stores[object_store_id];
-
- DCHECK(object_store.indexes.find(index_id) != object_store.indexes.end());
- const IndexedDBIndexMetadata& index_metadata = object_store.indexes[index_id];
-
- transaction->ScheduleTask(
- new DeleteIndexOperation(backing_store_, object_store_id, index_metadata),
- new DeleteIndexAbortOperation(this, object_store_id, index_metadata));
-
- RemoveIndex(object_store_id, index_id);
-}
-
-void DeleteIndexOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("DeleteIndexOperation");
- bool ok = backing_store_->DeleteIndex(transaction->BackingStoreTransaction(),
- transaction->database()->id(),
- object_store_id_,
- index_metadata_.id);
- if (!ok) {
- string16 error_string = ASCIIToUTF16("Internal error deleting index '") +
- index_metadata_.name + ASCIIToUTF16("'.");
- scoped_refptr<IndexedDBDatabaseError> error =
- IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError, error_string);
- transaction->Abort(error);
- }
-}
-
-void DeleteIndexAbortOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("DeleteIndexAbortOperation");
- DCHECK(!transaction);
- database_->AddIndex(
- object_store_id_, index_metadata_, IndexedDBIndexMetadata::kInvalidId);
-}
-
-void IndexedDBDatabaseImpl::Commit(int64 transaction_id) {
- // The frontend suggests that we commit, but we may have previously initiated
- // an abort, and so have disposed of the transaction. on_abort has already
- // been dispatched to the frontend, so it will find out about that
- // asynchronously.
- if (transactions_.find(transaction_id) != transactions_.end())
- transactions_[transaction_id]->Commit();
-}
-
-void IndexedDBDatabaseImpl::Abort(int64 transaction_id) {
- // If the transaction is unknown, then it has already been aborted by the
- // backend before this call so it is safe to ignore it.
- if (transactions_.find(transaction_id) != transactions_.end())
- transactions_[transaction_id]->Abort();
-}
-
-void IndexedDBDatabaseImpl::Abort(int64 transaction_id,
- scoped_refptr<IndexedDBDatabaseError> error) {
- // If the transaction is unknown, then it has already been aborted by the
- // backend before this call so it is safe to ignore it.
- if (transactions_.find(transaction_id) != transactions_.end())
- transactions_[transaction_id]->Abort(error);
-}
-
-void IndexedDBDatabaseImpl::Get(
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- bool key_only,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- IDB_TRACE("IndexedDBDatabaseImpl::get");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
-
- transaction->ScheduleTask(new GetOperation(
- backing_store_,
- metadata_,
- object_store_id,
- index_id,
- key_range.Pass(),
- key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
- callbacks));
-}
-
-void GetOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("GetOperation");
-
- const IndexedDBKey* key;
-
- scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
- if (key_range_->IsOnlyKey()) {
- key = &key_range_->lower();
- } else {
- if (index_id_ == IndexedDBIndexMetadata::kInvalidId) {
- DCHECK_NE(cursor_type_, indexed_db::CURSOR_KEY_ONLY);
- // ObjectStore Retrieval Operation
- backing_store_cursor = backing_store_->OpenObjectStoreCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- } else if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) {
- // Index Value Retrieval Operation
- backing_store_cursor = backing_store_->OpenIndexKeyCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- } else {
- // Index Referenced Value Retrieval Operation
- backing_store_cursor = backing_store_->OpenIndexCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- }
-
- if (!backing_store_cursor) {
- callbacks_->OnSuccess();
- return;
- }
-
- key = &backing_store_cursor->key();
- }
-
- scoped_ptr<IndexedDBKey> primary_key;
- bool ok;
- if (index_id_ == IndexedDBIndexMetadata::kInvalidId) {
- // Object Store Retrieval Operation
- std::vector<char> value;
- ok = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *key,
- value);
- if (!ok) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error in get_record.")));
- return;
- }
-
- if (value.empty()) {
- callbacks_->OnSuccess();
- return;
- }
-
- if (auto_increment_ && !key_path_.IsNull()) {
- callbacks_->OnSuccess(&value, *key, key_path_);
- return;
- }
-
- callbacks_->OnSuccess(&value);
- return;
- }
-
- // From here we are dealing only with indexes.
- ok = backing_store_->GetPrimaryKeyViaIndex(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key,
- &primary_key);
- if (!ok) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error in get_primary_key_via_index.")));
- return;
- }
- if (!primary_key) {
- callbacks_->OnSuccess();
- return;
- }
- if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) {
- // Index Value Retrieval Operation
- callbacks_->OnSuccess(*primary_key);
- return;
- }
-
- // Index Referenced Value Retrieval Operation
- std::vector<char> value;
- ok = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *primary_key,
- value);
- if (!ok) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error in get_record.")));
- return;
- }
-
- if (value.empty()) {
- callbacks_->OnSuccess();
- return;
- }
- if (auto_increment_ && !key_path_.IsNull()) {
- callbacks_->OnSuccess(&value, *primary_key, key_path_);
- return;
- }
- callbacks_->OnSuccess(&value);
-}
-
-static scoped_ptr<IndexedDBKey> GenerateKey(
- scoped_refptr<IndexedDBBackingStore> backing_store,
- scoped_refptr<IndexedDBTransaction> transaction,
- int64 database_id,
- int64 object_store_id) {
- const int64 max_generator_value =
- 9007199254740992LL; // Maximum integer storable as ECMAScript number.
- int64 current_number;
- bool ok = backing_store->GetKeyGeneratorCurrentNumber(
- transaction->BackingStoreTransaction(),
- database_id,
- object_store_id,
- current_number);
- if (!ok) {
- LOG(ERROR) << "Failed to get_key_generator_current_number";
- return make_scoped_ptr(new IndexedDBKey());
- }
- if (current_number < 0 || current_number > max_generator_value)
- return make_scoped_ptr(new IndexedDBKey());
-
- return make_scoped_ptr(
- new IndexedDBKey(current_number, WebIDBKey::NumberType));
-}
-
-static bool UpdateKeyGenerator(
- scoped_refptr<IndexedDBBackingStore> backing_store,
- scoped_refptr<IndexedDBTransaction> transaction,
- int64 database_id,
- int64 object_store_id,
- const IndexedDBKey* key,
- bool check_current) {
- DCHECK(key && key->type() == WebIDBKey::NumberType);
- return backing_store->MaybeUpdateKeyGeneratorCurrentNumber(
- transaction->BackingStoreTransaction(),
- database_id,
- object_store_id,
- static_cast<int64>(floor(key->number())) + 1,
- check_current);
-}
-
-void IndexedDBDatabaseImpl::Put(
- int64 transaction_id,
- int64 object_store_id,
- std::vector<char>* value,
- scoped_ptr<IndexedDBKey> key,
- PutMode put_mode,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- const std::vector<int64>& index_ids,
- const std::vector<IndexKeys>& index_keys) {
- IDB_TRACE("IndexedDBDatabaseImpl::put");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY);
-
- const IndexedDBObjectStoreMetadata object_store_metadata =
- metadata_.object_stores[object_store_id];
-
- DCHECK(key);
- DCHECK(object_store_metadata.auto_increment || key->IsValid());
- transaction->ScheduleTask(new PutOperation(backing_store_,
- id(),
- object_store_metadata,
- value,
- key.Pass(),
- put_mode,
- callbacks,
- index_ids,
- index_keys));
-}
-
-void PutOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("PutOperation");
- DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY);
- DCHECK_EQ(index_ids_.size(), index_keys_.size());
- bool key_was_generated = false;
-
- scoped_ptr<IndexedDBKey> key;
- if (put_mode_ != IndexedDBDatabase::CURSOR_UPDATE &&
- object_store_.auto_increment && !key_->IsValid()) {
- scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey(
- backing_store_, transaction, database_id_, object_store_.id);
- key_was_generated = true;
- if (!auto_inc_key->IsValid()) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionConstraintError,
- ASCIIToUTF16("Maximum key generator value reached.")));
- return;
- }
- key = auto_inc_key.Pass();
- } else {
- key = key_.Pass();
- }
-
- DCHECK(key->IsValid());
-
- IndexedDBBackingStore::RecordIdentifier record_identifier;
- if (put_mode_ == IndexedDBDatabase::ADD_ONLY) {
- bool found = false;
- bool ok = backing_store_->KeyExistsInObjectStore(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_.id,
- *key.get(),
- &record_identifier,
- found);
- if (!ok) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error checking key existence.")));
- return;
- }
- if (found) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionConstraintError,
- ASCIIToUTF16("Key already exists in the object store.")));
- return;
- }
- }
-
- ScopedVector<IndexedDBObjectStoreImpl::IndexWriter> index_writers;
- string16 error_message;
- bool obeys_constraints = false;
- bool backing_store_success =
- IndexedDBObjectStoreImpl::MakeIndexWriters(transaction,
- backing_store_.get(),
- database_id_,
- object_store_,
- *key,
- key_was_generated,
- index_ids_,
- index_keys_,
- &index_writers,
- &error_message,
- &obeys_constraints);
- if (!backing_store_success) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16(
- "Internal error: backing store error updating index keys.")));
- return;
- }
- if (!obeys_constraints) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionConstraintError, error_message));
- return;
- }
-
- // Before this point, don't do any mutation. After this point, rollback the
- // transaction in case of error.
- backing_store_success =
- backing_store_->PutRecord(transaction->BackingStoreTransaction(),
- database_id_,
- object_store_.id,
- *key.get(),
- value_,
- &record_identifier);
- if (!backing_store_success) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16(
- "Internal error: backing store error performing put/add.")));
- return;
- }
-
- for (size_t i = 0; i < index_writers.size(); ++i) {
- IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i];
- index_writer->WriteIndexKeys(record_identifier,
- backing_store_,
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_.id);
- }
-
- if (object_store_.auto_increment &&
- put_mode_ != IndexedDBDatabase::CURSOR_UPDATE &&
- key->type() == WebIDBKey::NumberType) {
- bool ok = UpdateKeyGenerator(backing_store_,
- transaction,
- database_id_,
- object_store_.id,
- key.get(),
- !key_was_generated);
- if (!ok) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error updating key generator.")));
- return;
- }
- }
-
- callbacks_->OnSuccess(*key);
-}
-
-void IndexedDBDatabaseImpl::SetIndexKeys(
- int64 transaction_id,
- int64 object_store_id,
- scoped_ptr<IndexedDBKey> primary_key,
- const std::vector<int64>& index_ids,
- const std::vector<IndexKeys>& index_keys) {
- IDB_TRACE("IndexedDBDatabaseImpl::set_index_keys");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE);
-
- scoped_refptr<IndexedDBBackingStore> store = BackingStore();
- // TODO(jsbell): This method could be asynchronous, but we need to
- // evaluate if it's worth the extra complexity.
- IndexedDBBackingStore::RecordIdentifier record_identifier;
- bool found = false;
- bool ok =
- store->KeyExistsInObjectStore(transaction->BackingStoreTransaction(),
- metadata_.id,
- object_store_id,
- *primary_key,
- &record_identifier,
- found);
- if (!ok) {
- transaction->Abort(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error setting index keys.")));
- return;
- }
- if (!found) {
- scoped_refptr<IndexedDBDatabaseError> error =
- IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16(
- "Internal error setting index keys for object store."));
- transaction->Abort(error);
- return;
- }
-
- ScopedVector<IndexedDBObjectStoreImpl::IndexWriter> index_writers;
- string16 error_message;
- bool obeys_constraints = false;
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- const IndexedDBObjectStoreMetadata& object_store_metadata =
- metadata_.object_stores[object_store_id];
- bool backing_store_success =
- IndexedDBObjectStoreImpl::MakeIndexWriters(transaction,
- store.get(),
- id(),
- object_store_metadata,
- *primary_key,
- false,
- index_ids,
- index_keys,
- &index_writers,
- &error_message,
- &obeys_constraints);
- if (!backing_store_success) {
- transaction->Abort(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16(
- "Internal error: backing store error updating index keys.")));
- return;
- }
- if (!obeys_constraints) {
- transaction->Abort(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionConstraintError, error_message));
- return;
- }
-
- for (size_t i = 0; i < index_writers.size(); ++i) {
- IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i];
- index_writer->WriteIndexKeys(record_identifier,
- store.get(),
- transaction->BackingStoreTransaction(),
- id(),
- object_store_id);
- }
-}
-
-void IndexedDBDatabaseImpl::SetIndexesReady(
- int64 transaction_id,
- int64,
- const std::vector<int64>& index_ids) {
- IDB_TRACE("IndexedDBObjectStoreImpl::set_indexes_ready");
-
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
-
- transaction->ScheduleTask(IndexedDBDatabase::PREEMPTIVE_TASK,
- new SetIndexesReadyOperation(index_ids.size()));
-}
-
-void SetIndexesReadyOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("SetIndexesReadyOperation");
- for (size_t i = 0; i < index_count_; ++i)
- transaction->DidCompletePreemptiveEvent();
-}
-
-void IndexedDBDatabaseImpl::OpenCursor(
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- indexed_db::CursorDirection direction,
- bool key_only,
- TaskType task_type,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- IDB_TRACE("IndexedDBDatabaseImpl::open_cursor");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
-
- transaction->ScheduleTask(new OpenCursorOperation(
- backing_store_,
- id(),
- object_store_id,
- index_id,
- key_range.Pass(),
- direction,
- key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
- task_type,
- callbacks));
-}
-
-void OpenCursorOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("OpenCursorOperation");
-
- // The frontend has begun indexing, so this pauses the transaction
- // until the indexing is complete. This can't happen any earlier
- // because we don't want to switch to early mode in case multiple
- // indexes are being created in a row, with Put()'s in between.
- if (task_type_ == IndexedDBDatabase::PREEMPTIVE_TASK)
- transaction->AddPreemptiveEvent();
-
- scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
- if (index_id_ == IndexedDBIndexMetadata::kInvalidId) {
- DCHECK_NE(cursor_type_, indexed_db::CURSOR_KEY_ONLY);
- backing_store_cursor = backing_store_->OpenObjectStoreCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *key_range_,
- direction_);
- } else {
- DCHECK_EQ(task_type_, IndexedDBDatabase::NORMAL_TASK);
- if (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) {
- backing_store_cursor = backing_store_->OpenIndexKeyCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key_range_,
- direction_);
- } else {
- backing_store_cursor = backing_store_->OpenIndexCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key_range_,
- direction_);
- }
- }
-
- if (!backing_store_cursor) {
- callbacks_->OnSuccess(static_cast<std::vector<char>*>(NULL));
- return;
- }
-
- IndexedDBDatabase::TaskType task_type(
- static_cast<IndexedDBDatabase::TaskType>(task_type_));
- scoped_refptr<IndexedDBCursorImpl> cursor =
- IndexedDBCursorImpl::Create(backing_store_cursor.Pass(),
- cursor_type_,
- task_type,
- transaction,
- object_store_id_);
- callbacks_->OnSuccess(
- cursor, cursor->key(), cursor->primary_key(), cursor->Value());
-}
-
-void IndexedDBDatabaseImpl::Count(
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- IDB_TRACE("IndexedDBDatabaseImpl::count");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
-
- DCHECK(metadata_.object_stores.find(object_store_id) !=
- metadata_.object_stores.end());
- transaction->ScheduleTask(new CountOperation(backing_store_,
- id(),
- object_store_id,
- index_id,
- key_range.Pass(),
- callbacks));
-}
-
-void CountOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("CountOperation");
- uint32 count = 0;
- scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
-
- if (index_id_ == IndexedDBIndexMetadata::kInvalidId) {
- backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- } else {
- backing_store_cursor = backing_store_->OpenIndexKeyCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- index_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- }
- if (!backing_store_cursor) {
- callbacks_->OnSuccess(count);
- return;
- }
-
- do {
- ++count;
- } while (backing_store_cursor->ContinueFunction(0));
-
- callbacks_->OnSuccess(count);
-}
-
-void IndexedDBDatabaseImpl::DeleteRange(
- int64 transaction_id,
- int64 object_store_id,
- scoped_ptr<IndexedDBKeyRange> key_range,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- IDB_TRACE("IndexedDBDatabaseImpl::delete_range");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
-
- transaction->ScheduleTask(new DeleteRangeOperation(
- backing_store_, id(), object_store_id, key_range.Pass(), callbacks));
-}
-
-void DeleteRangeOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("DeleteRangeOperation");
- scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor =
- backing_store_->OpenObjectStoreCursor(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- *key_range_,
- indexed_db::CURSOR_NEXT);
- if (backing_store_cursor) {
- do {
- if (!backing_store_->DeleteRecord(
- transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_,
- backing_store_cursor->record_identifier())) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error deleting data in range")));
- return;
- }
- } while (backing_store_cursor->ContinueFunction(0));
- }
-
- callbacks_->OnSuccess();
-}
-
-void IndexedDBDatabaseImpl::Clear(
- int64 transaction_id,
- int64 object_store_id,
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- IDB_TRACE("IndexedDBDatabaseImpl::clear");
- TransactionMap::const_iterator trans_iterator =
- transactions_.find(transaction_id);
- if (trans_iterator == transactions_.end())
- return;
- IndexedDBTransaction* transaction = trans_iterator->second;
- DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY);
-
- transaction->ScheduleTask(
- new ClearOperation(backing_store_, id(), object_store_id, callbacks));
-}
-
-void ClearOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("ObjectStoreClearOperation");
- if (!backing_store_->ClearObjectStore(transaction->BackingStoreTransaction(),
- database_id_,
- object_store_id_)) {
- callbacks_->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error clearing object store")));
- return;
- }
- callbacks_->OnSuccess();
-}
-
-void DeleteObjectStoreOperation::Perform(IndexedDBTransaction* transaction) {
- IDB_TRACE("DeleteObjectStoreOperation");
- bool ok =
- backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(),
- transaction->database()->id(),
- object_store_metadata_.id);
- if (!ok) {
- string16 error_string =
- ASCIIToUTF16("Internal error deleting object store '") +
- object_store_metadata_.name + ASCIIToUTF16("'.");
- scoped_refptr<IndexedDBDatabaseError> error =
- IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError, error_string);
- transaction->Abort(error);
- }
-}
-
-void IndexedDBDatabaseImpl::VersionChangeOperation::Perform(
- IndexedDBTransaction* transaction) {
- IDB_TRACE("VersionChangeOperation");
- int64 database_id = database_->id();
- int64 old_version = database_->metadata_.int_version;
- DCHECK_GT(version_, old_version);
- database_->metadata_.int_version = version_;
- if (!database_->backing_store_->UpdateIDBDatabaseIntVersion(
- transaction->BackingStoreTransaction(),
- database_id,
- database_->metadata_.int_version)) {
- scoped_refptr<IndexedDBDatabaseError> error =
- IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error writing data to stable storage when "
- "updating version."));
- callbacks_->OnError(error);
- transaction->Abort(error);
- return;
- }
- DCHECK(!database_->pending_second_half_open_);
- database_->pending_second_half_open_.reset(new PendingOpenCall(
- callbacks_, database_callbacks_, transaction_id_, version_));
- callbacks_->OnUpgradeNeeded(old_version, database_, database_->metadata());
-}
-
-void IndexedDBDatabaseImpl::TransactionStarted(
- IndexedDBTransaction* transaction) {
-
- if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) {
- DCHECK(!running_version_change_transaction_);
- running_version_change_transaction_ = transaction;
- }
-}
-
-void IndexedDBDatabaseImpl::TransactionFinished(
- IndexedDBTransaction* transaction) {
-
- DCHECK(transactions_.find(transaction->id()) != transactions_.end());
- DCHECK_EQ(transactions_[transaction->id()], transaction);
- transactions_.erase(transaction->id());
- if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) {
- DCHECK_EQ(transaction, running_version_change_transaction_);
- running_version_change_transaction_ = NULL;
- }
-}
-
-void IndexedDBDatabaseImpl::TransactionFinishedAndAbortFired(
- IndexedDBTransaction* transaction) {
- if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) {
- if (pending_second_half_open_) {
- pending_second_half_open_->Callbacks()
- ->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionAbortError,
- ASCIIToUTF16("Version change transaction was aborted in "
- "upgradeneeded event handler.")));
- pending_second_half_open_.reset();
- }
- ProcessPendingCalls();
- }
-}
-
-void IndexedDBDatabaseImpl::TransactionFinishedAndCompleteFired(
- IndexedDBTransaction* transaction) {
- if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) {
- DCHECK(pending_second_half_open_);
- if (pending_second_half_open_) {
- DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version);
- DCHECK(metadata_.id != kInvalidId);
- pending_second_half_open_->Callbacks()->OnSuccess(this, this->metadata());
- pending_second_half_open_.reset();
- }
- ProcessPendingCalls();
- }
-}
-
-size_t IndexedDBDatabaseImpl::ConnectionCount() const {
- // This does not include pending open calls, as those should not block version
- // changes and deletes.
- return database_callbacks_set_.size();
-}
-
-void IndexedDBDatabaseImpl::ProcessPendingCalls() {
- if (pending_second_half_open_) {
- DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version);
- DCHECK(metadata_.id != kInvalidId);
- scoped_ptr<PendingOpenCall> pending_call = pending_second_half_open_.Pass();
- pending_call->Callbacks()->OnSuccess(this, this->metadata());
- // Fall through when complete, as pending opens may be unblocked.
- }
-
- if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) {
- DCHECK(pending_run_version_change_transaction_call_->Version() >
- metadata_.int_version);
- scoped_ptr<PendingOpenCall> pending_call =
- pending_run_version_change_transaction_call_.Pass();
- RunVersionChangeTransactionFinal(pending_call->Callbacks(),
- pending_call->DatabaseCallbacks(),
- pending_call->TransactionId(),
- pending_call->Version());
- DCHECK_EQ(static_cast<size_t>(1), ConnectionCount());
- // Fall through would be a no-op, since transaction must complete
- // asynchronously.
- DCHECK(IsDeleteDatabaseBlocked());
- DCHECK(IsOpenConnectionBlocked());
- return;
- }
-
- if (!IsDeleteDatabaseBlocked()) {
- PendingDeleteCallList pending_delete_calls;
- pending_delete_calls_.swap(pending_delete_calls);
- while (!pending_delete_calls.empty()) {
- // Only the first delete call will delete the database, but each must fire
- // callbacks.
- scoped_ptr<PendingDeleteCall> pending_delete_call(
- pending_delete_calls.front());
- pending_delete_calls.pop_front();
- DeleteDatabaseFinal(pending_delete_call->Callbacks());
- }
- // delete_database_final should never re-queue calls.
- DCHECK(pending_delete_calls_.empty());
- // Fall through when complete, as pending opens may be unblocked.
- }
-
- if (!IsOpenConnectionBlocked()) {
- PendingOpenCallList pending_open_calls;
- pending_open_calls_.swap(pending_open_calls);
- while (!pending_open_calls.empty()) {
- scoped_ptr<PendingOpenCall> pending_open_call(pending_open_calls.front());
- pending_open_calls.pop_front();
- OpenConnection(pending_open_call->Callbacks(),
- pending_open_call->DatabaseCallbacks(),
- pending_open_call->TransactionId(),
- pending_open_call->Version());
- }
- }
-}
-
-void IndexedDBDatabaseImpl::CreateTransaction(
- int64 transaction_id,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks,
- const std::vector<int64>& object_store_ids,
- uint16 mode) {
-
- DCHECK(database_callbacks_set_.has(callbacks));
-
- scoped_refptr<IndexedDBTransaction> transaction =
- IndexedDBTransaction::Create(
- transaction_id,
- callbacks,
- object_store_ids,
- static_cast<indexed_db::TransactionMode>(mode),
- this);
- DCHECK(transactions_.find(transaction_id) == transactions_.end());
- transactions_[transaction_id] = transaction;
-}
-
-bool IndexedDBDatabaseImpl::IsOpenConnectionBlocked() const {
- return !pending_delete_calls_.empty() ||
- running_version_change_transaction_ ||
- pending_run_version_change_transaction_call_;
-}
-
-void IndexedDBDatabaseImpl::OpenConnection(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks,
- int64 transaction_id,
- int64 version) {
- DCHECK(backing_store_.get());
-
- // TODO(jsbell): Should have a priority queue so that higher version
- // requests are processed first. http://crbug.com/225850
- if (IsOpenConnectionBlocked()) {
- pending_open_calls_.push_back(new PendingOpenCall(
- callbacks, database_callbacks, transaction_id, version));
- return;
- }
-
- if (metadata_.id == kInvalidId) {
- // The database was deleted then immediately re-opened; OpenInternal()
- // recreates it in the backing store.
- if (OpenInternal()) {
- DCHECK_EQ(metadata_.int_version,
- IndexedDBDatabaseMetadata::NO_INT_VERSION);
- } else {
- string16 message;
- scoped_refptr<IndexedDBDatabaseError> error;
- if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
- message = ASCIIToUTF16(
- "Internal error opening database with no version specified.");
- else
- message =
- ASCIIToUTF16("Internal error opening database with version ") +
- Int64ToString16(version);
- callbacks->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError, message));
- return;
- }
- }
-
- // We infer that the database didn't exist from its lack of either type of
- // version.
- bool is_new_database =
- metadata_.version == kNoStringVersion &&
- metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION;
-
- if (version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) {
- // For unit tests only - skip upgrade steps. Calling from script with
- // DEFAULT_INT_VERSION throws exception.
- // TODO(jsbell): Assert that we're executing a unit test.
- DCHECK(is_new_database);
- database_callbacks_set_.insert(database_callbacks);
- callbacks->OnSuccess(this, this->metadata());
- return;
- }
-
- if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) {
- if (!is_new_database) {
- database_callbacks_set_.insert(database_callbacks);
- callbacks->OnSuccess(this, this->metadata());
- return;
- }
- // Spec says: If no version is specified and no database exists, set
- // database version to 1.
- version = 1;
- }
-
- if (version > metadata_.int_version) {
- database_callbacks_set_.insert(database_callbacks);
- RunVersionChangeTransaction(
- callbacks, database_callbacks, transaction_id, version);
- return;
- }
- if (version < metadata_.int_version) {
- callbacks->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionVersionError,
- ASCIIToUTF16("The requested version (") + Int64ToString16(version) +
- ASCIIToUTF16(") is less than the existing version (") +
- Int64ToString16(metadata_.int_version) + ASCIIToUTF16(").")));
- return;
- }
- DCHECK_EQ(version, metadata_.int_version);
- database_callbacks_set_.insert(database_callbacks);
- callbacks->OnSuccess(this, this->metadata());
-}
-
-void IndexedDBDatabaseImpl::RunVersionChangeTransaction(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks,
- int64 transaction_id,
- int64 requested_version) {
-
- DCHECK(callbacks);
- DCHECK(database_callbacks_set_.has(database_callbacks));
- if (ConnectionCount() > 1) {
- // Front end ensures the event is not fired at connections that have
- // close_pending set.
- for (DatabaseCallbacksSet::const_iterator it =
- database_callbacks_set_.begin();
- it != database_callbacks_set_.end();
- ++it) {
- if (*it != database_callbacks.get())
- (*it)->OnVersionChange(metadata_.int_version, requested_version);
- }
- // TODO(jsbell): Remove the call to on_blocked and instead wait
- // until the frontend tells us that all the "versionchange" events
- // have been delivered. http://crbug.com/100123
- callbacks->OnBlocked(metadata_.int_version);
-
- DCHECK(!pending_run_version_change_transaction_call_);
- pending_run_version_change_transaction_call_.reset(new PendingOpenCall(
- callbacks, database_callbacks, transaction_id, requested_version));
- return;
- }
- RunVersionChangeTransactionFinal(
- callbacks, database_callbacks, transaction_id, requested_version);
-}
-
-void IndexedDBDatabaseImpl::RunVersionChangeTransactionFinal(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks,
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks,
- int64 transaction_id,
- int64 requested_version) {
-
- std::vector<int64> object_store_ids;
- CreateTransaction(transaction_id,
- database_callbacks,
- object_store_ids,
- indexed_db::TRANSACTION_VERSION_CHANGE);
- scoped_refptr<IndexedDBTransaction> transaction =
- transactions_[transaction_id];
-
- transaction->ScheduleTask(
- new VersionChangeOperation(this,
- transaction_id,
- requested_version,
- callbacks,
- database_callbacks),
- new VersionChangeAbortOperation(
- this, metadata_.version, metadata_.int_version));
-
- DCHECK(!pending_second_half_open_);
-}
-
-void IndexedDBDatabaseImpl::DeleteDatabase(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
-
- if (IsDeleteDatabaseBlocked()) {
- for (DatabaseCallbacksSet::const_iterator it =
- database_callbacks_set_.begin();
- it != database_callbacks_set_.end();
- ++it) {
- // Front end ensures the event is not fired at connections that have
- // close_pending set.
- (*it)->OnVersionChange(metadata_.int_version,
- IndexedDBDatabaseMetadata::NO_INT_VERSION);
- }
- // TODO(jsbell): Only fire on_blocked if there are open
- // connections after the VersionChangeEvents are received, not
- // just set up to fire. http://crbug.com/100123
- callbacks->OnBlocked(metadata_.int_version);
- pending_delete_calls_.push_back(new PendingDeleteCall(callbacks));
- return;
- }
- DeleteDatabaseFinal(callbacks);
-}
-
-bool IndexedDBDatabaseImpl::IsDeleteDatabaseBlocked() const {
- return !!ConnectionCount();
-}
-
-void IndexedDBDatabaseImpl::DeleteDatabaseFinal(
- scoped_refptr<IndexedDBCallbacksWrapper> callbacks) {
- DCHECK(!IsDeleteDatabaseBlocked());
- DCHECK(backing_store_);
- if (!backing_store_->DeleteDatabase(metadata_.name)) {
- callbacks->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Internal error deleting database.")));
- return;
- }
- metadata_.version = kNoStringVersion;
- metadata_.id = kInvalidId;
- metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION;
- metadata_.object_stores.clear();
- callbacks->OnSuccess();
-}
-
-void IndexedDBDatabaseImpl::Close(
- scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks) {
- DCHECK(callbacks);
- DCHECK(database_callbacks_set_.has(callbacks));
-
- // Close outstanding transactions from the closing connection. This
- // can not happen if the close is requested by the connection itself
- // as the front-end defers the close until all transactions are
- // complete, so something unusual has happened e.g. unexpected
- // process termination.
- {
- TransactionMap transactions(transactions_);
- for (TransactionMap::const_iterator it = transactions.begin(),
- end = transactions.end();
- it != end;
- ++it) {
- if (it->second->connection() == callbacks)
- it->second->Abort(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionUnknownError,
- ASCIIToUTF16("Connection is closing.")));
- }
- }
-
- database_callbacks_set_.erase(callbacks);
- if (pending_second_half_open_ &&
- pending_second_half_open_->DatabaseCallbacks() == callbacks) {
- pending_second_half_open_->Callbacks()
- ->OnError(IndexedDBDatabaseError::Create(
- WebKit::WebIDBDatabaseExceptionAbortError,
- ASCIIToUTF16("The connection was closed.")));
- pending_second_half_open_.reset();
- }
-
- // process_pending_calls allows the inspector to process a pending open call
- // and call close, reentering IndexedDBDatabaseImpl::close. Then the
- // backend would be removed both by the inspector closing its connection, and
- // by the connection that first called close.
- // To avoid that situation, don't proceed in case of reentrancy.
- if (closing_connection_)
- return;
- base::AutoReset<bool> ClosingConnection(&closing_connection_, true);
- ProcessPendingCalls();
-
- // TODO(jsbell): Add a test for the pending_open_calls_ cases below.
- if (!ConnectionCount() && !pending_open_calls_.size() &&
- !pending_delete_calls_.size()) {
- DCHECK(transactions_.empty());
-
- backing_store_ = NULL;
-
- // This check should only be false in unit tests.
- // TODO(jsbell): Assert factory_ || we're executing a unit test.
- if (factory_)
- factory_->RemoveIDBDatabaseBackend(identifier_);
- }
-}
-
-void CreateObjectStoreAbortOperation::Perform(
- IndexedDBTransaction* transaction) {
- IDB_TRACE("CreateObjectStoreAbortOperation");
- DCHECK(!transaction);
- database_->RemoveObjectStore(object_store_id_);
-}
-
-void DeleteObjectStoreAbortOperation::Perform(
- IndexedDBTransaction* transaction) {
- IDB_TRACE("DeleteObjectStoreAbortOperation");
- DCHECK(!transaction);
- database_->AddObjectStore(object_store_metadata_,
- IndexedDBObjectStoreMetadata::kInvalidId);
-}
-
-void IndexedDBDatabaseImpl::VersionChangeAbortOperation::Perform(
- IndexedDBTransaction* transaction) {
- IDB_TRACE("VersionChangeAbortOperation");
- DCHECK(!transaction);
- database_->metadata_.version = previous_version_;
- database_->metadata_.int_version = previous_int_version_;
-}
-
-} // namespace content