| Index: content/browser/indexed_db/indexed_db_database.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
|
| index 0835c8aa2cdc35f42841e6829e23109faadd8789..da5be5ed6a00646204faf010b8dac9e0f69abe5e 100644
|
| --- a/content/browser/indexed_db/indexed_db_database.cc
|
| +++ b/content/browser/indexed_db/indexed_db_database.cc
|
| @@ -29,6 +29,7 @@
|
| #include "content/browser/indexed_db/indexed_db_cursor.h"
|
| #include "content/browser/indexed_db/indexed_db_factory.h"
|
| #include "content/browser/indexed_db/indexed_db_index_writer.h"
|
| +#include "content/browser/indexed_db/indexed_db_open_request_observer.h"
|
| #include "content/browser/indexed_db/indexed_db_pending_connection.h"
|
| #include "content/browser/indexed_db/indexed_db_return_value.h"
|
| #include "content/browser/indexed_db/indexed_db_tracing.h"
|
| @@ -78,31 +79,28 @@ HistogramIDBKeyPathType HistogramKeyPathType(const IndexedDBKeyPath& key_path) {
|
| } // namespace
|
|
|
| // PendingUpgradeCall has a std::unique_ptr<IndexedDBConnection> because it owns
|
| -// the
|
| -// in-progress connection.
|
| +// the in-progress connection.
|
| class IndexedDBDatabase::PendingUpgradeCall {
|
| public:
|
| - PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks,
|
| - std::unique_ptr<IndexedDBConnection> connection,
|
| - int64_t transaction_id,
|
| - int64_t version)
|
| - : callbacks_(callbacks),
|
| - connection_(std::move(connection)),
|
| - version_(version),
|
| - transaction_id_(transaction_id) {}
|
| - scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
|
| + PendingUpgradeCall(const IndexedDBPendingConnection& pending_connection,
|
| + std::unique_ptr<IndexedDBConnection> connection)
|
| + : pending_connection_(pending_connection),
|
| + connection_(std::move(connection)) {}
|
| + const IndexedDBPendingConnection& pending_connection() const {
|
| + return pending_connection_;
|
| + }
|
| + void OnBlocked(int64_t old_version) {
|
| + pending_connection_.OnBlocked(old_version);
|
| + }
|
| // Takes ownership of the connection object.
|
| std::unique_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT {
|
| return std::move(connection_);
|
| }
|
| - int64_t version() const { return version_; }
|
| - int64_t transaction_id() const { return transaction_id_; }
|
| + int64_t version() const { return pending_connection_.version(); }
|
|
|
| private:
|
| - scoped_refptr<IndexedDBCallbacks> callbacks_;
|
| + IndexedDBPendingConnection pending_connection_;
|
| std::unique_ptr<IndexedDBConnection> connection_;
|
| - int64_t version_;
|
| - const int64_t transaction_id_;
|
| };
|
|
|
| // PendingSuccessCall has a IndexedDBConnection* because the connection is now
|
| @@ -110,18 +108,22 @@ class IndexedDBDatabase::PendingUpgradeCall {
|
| // closes before it is sent.
|
| class IndexedDBDatabase::PendingSuccessCall {
|
| public:
|
| - PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks,
|
| - IndexedDBConnection* connection,
|
| - int64_t version)
|
| - : callbacks_(callbacks), connection_(connection), version_(version) {}
|
| - scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
|
| + PendingSuccessCall(const IndexedDBPendingConnection& pending_connection,
|
| + IndexedDBConnection* connection)
|
| + : pending_connection_(pending_connection), connection_(connection) {}
|
| + void OnSuccess(std::unique_ptr<IndexedDBConnection> connection,
|
| + const IndexedDBDatabaseMetadata& metadata) const {
|
| + // TODO(cmumford): Need to pass in the OpenResultCallback.
|
| + }
|
| + void OnError(const IndexedDBDatabaseError& error) const {
|
| + // TODO(cmumford): Need to pass in the OpenResultCallback.
|
| + }
|
| IndexedDBConnection* connection() const { return connection_; }
|
| - int64_t version() const { return version_; }
|
| + int64_t version() const { return pending_connection_.version(); }
|
|
|
| private:
|
| - scoped_refptr<IndexedDBCallbacks> callbacks_;
|
| + IndexedDBPendingConnection pending_connection_;
|
| IndexedDBConnection* connection_;
|
| - int64_t version_;
|
| };
|
|
|
| class IndexedDBDatabase::PendingDeleteCall {
|
| @@ -1529,23 +1531,23 @@ void IndexedDBDatabase::DeleteObjectStoreOperation(
|
| }
|
|
|
| void IndexedDBDatabase::VersionChangeOperation(
|
| - int64_t version,
|
| - scoped_refptr<IndexedDBCallbacks> callbacks,
|
| + const IndexedDBPendingConnection& pending_connection,
|
| std::unique_ptr<IndexedDBConnection> connection,
|
| IndexedDBTransaction* transaction) {
|
| IDB_TRACE1(
|
| "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id());
|
| int64_t old_version = metadata_.version;
|
| - DCHECK_GT(version, old_version);
|
| + DCHECK_GT(pending_connection.version(), old_version);
|
|
|
| if (!backing_store_->UpdateIDBDatabaseIntVersion(
|
| - transaction->BackingStoreTransaction(), id(), version)) {
|
| + transaction->BackingStoreTransaction(), id(),
|
| + pending_connection.version())) {
|
| IndexedDBDatabaseError error(
|
| blink::WebIDBDatabaseExceptionUnknownError,
|
| ASCIIToUTF16(
|
| "Internal error writing data to stable storage when "
|
| "updating version."));
|
| - callbacks->OnError(error);
|
| + pending_connection.OnError(error);
|
| transaction->Abort(error);
|
| return;
|
| }
|
| @@ -1553,12 +1555,13 @@ void IndexedDBDatabase::VersionChangeOperation(
|
| transaction->ScheduleAbortTask(
|
| base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this,
|
| metadata_.version));
|
| - metadata_.version = version;
|
| + metadata_.version = pending_connection.version();
|
|
|
| DCHECK(!pending_second_half_open_);
|
| pending_second_half_open_.reset(
|
| - new PendingSuccessCall(callbacks, connection.get(), version));
|
| - callbacks->OnUpgradeNeeded(old_version, std::move(connection), metadata());
|
| + new PendingSuccessCall(pending_connection, connection.get()));
|
| + pending_connection.open_observer()->OnUpgradeNeeded(
|
| + old_version, connection.get(), metadata());
|
| }
|
|
|
| void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
|
| @@ -1576,10 +1579,10 @@ void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
|
|
|
| // Connection was already minted for OnUpgradeNeeded callback.
|
| std::unique_ptr<IndexedDBConnection> connection;
|
| - pending_second_half_open_->callbacks()->OnSuccess(std::move(connection),
|
| - this->metadata());
|
| + pending_second_half_open_->OnSuccess(std::move(connection),
|
| + this->metadata());
|
| } else {
|
| - pending_second_half_open_->callbacks()->OnError(
|
| + pending_second_half_open_->OnError(
|
| IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError,
|
| "Version change transaction was aborted in "
|
| "upgradeneeded event handler."));
|
| @@ -1630,10 +1633,8 @@ void IndexedDBDatabase::ProcessPendingCalls() {
|
| metadata_.version);
|
| std::unique_ptr<PendingUpgradeCall> pending_call =
|
| std::move(pending_run_version_change_transaction_call_);
|
| - RunVersionChangeTransactionFinal(pending_call->callbacks(),
|
| - pending_call->ReleaseConnection(),
|
| - pending_call->transaction_id(),
|
| - pending_call->version());
|
| + RunVersionChangeTransactionFinal(pending_call->pending_connection(),
|
| + pending_call->ReleaseConnection());
|
| DCHECK_EQ(1u, ConnectionCount());
|
| // Fall through would be a no-op, since transaction must complete
|
| // asynchronously.
|
| @@ -1735,15 +1736,17 @@ bool IndexedDBDatabase::IsOpenConnectionBlocked() const {
|
| }
|
|
|
| void IndexedDBDatabase::OpenConnection(
|
| - const IndexedDBPendingConnection& connection) {
|
| + const IndexedDBPendingConnection& requested_connection) {
|
| DCHECK(backing_store_.get());
|
|
|
| + IndexedDBPendingConnection pending_connection(requested_connection);
|
| +
|
| if (IsOpenConnectionBlocked()) {
|
| // The backing store only detects data loss when it is first opened. The
|
| // presence of existing connections means we didn't even check for data loss
|
| // so there'd better not be any.
|
| - DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss());
|
| - pending_open_calls_.push(connection);
|
| + DCHECK_NE(blink::WebIDBDataLossTotal, requested_connection.data_loss());
|
| + pending_open_calls_.push(requested_connection);
|
| return;
|
| }
|
|
|
| @@ -1754,15 +1757,16 @@ void IndexedDBDatabase::OpenConnection(
|
| DCHECK_EQ(IndexedDBDatabaseMetadata::NO_VERSION, metadata_.version);
|
| } else {
|
| base::string16 message;
|
| - if (connection.version == IndexedDBDatabaseMetadata::NO_VERSION) {
|
| + if (pending_connection.version() ==
|
| + IndexedDBDatabaseMetadata::NO_VERSION) {
|
| message = ASCIIToUTF16(
|
| "Internal error opening database with no version specified.");
|
| } else {
|
| message =
|
| ASCIIToUTF16("Internal error opening database with version ") +
|
| - Int64ToString16(connection.version);
|
| + Int64ToString16(pending_connection.version());
|
| }
|
| - connection.callbacks->OnError(IndexedDBDatabaseError(
|
| + pending_connection.OnError(IndexedDBDatabaseError(
|
| blink::WebIDBDatabaseExceptionUnknownError, message));
|
| return;
|
| }
|
| @@ -1773,104 +1777,94 @@ void IndexedDBDatabase::OpenConnection(
|
| bool is_new_database =
|
| metadata_.version == IndexedDBDatabaseMetadata::NO_VERSION;
|
|
|
| - if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_VERSION) {
|
| + if (pending_connection.version() ==
|
| + IndexedDBDatabaseMetadata::DEFAULT_VERSION) {
|
| // For unit tests only - skip upgrade steps. Calling from script with
|
| // DEFAULT_VERSION throws exception.
|
| // TODO(jsbell): DCHECK that not in unit tests.
|
| DCHECK(is_new_database);
|
| - connection.callbacks->OnSuccess(
|
| - CreateConnection(connection.database_callbacks,
|
| - connection.child_process_id),
|
| + pending_connection.OnSuccess(
|
| + CreateConnection(pending_connection.database_callbacks(),
|
| + pending_connection.child_process_id()),
|
| this->metadata());
|
| return;
|
| }
|
|
|
| // We may need to change the version.
|
| - int64_t local_version = connection.version;
|
| - if (local_version == IndexedDBDatabaseMetadata::NO_VERSION) {
|
| + if (pending_connection.version() == IndexedDBDatabaseMetadata::NO_VERSION) {
|
| if (!is_new_database) {
|
| - connection.callbacks->OnSuccess(
|
| - CreateConnection(connection.database_callbacks,
|
| - connection.child_process_id),
|
| + pending_connection.OnSuccess(
|
| + CreateConnection(pending_connection.database_callbacks(),
|
| + pending_connection.child_process_id()),
|
| this->metadata());
|
| return;
|
| }
|
| // Spec says: If no version is specified and no database exists, set
|
| // database version to 1.
|
| - local_version = 1;
|
| + pending_connection.SetVersion(1);
|
| }
|
|
|
| - if (local_version > metadata_.version) {
|
| - RunVersionChangeTransaction(connection.callbacks,
|
| - CreateConnection(connection.database_callbacks,
|
| - connection.child_process_id),
|
| - connection.transaction_id,
|
| - local_version);
|
| + if (pending_connection.version() > metadata_.version) {
|
| + RunVersionChangeTransaction(
|
| + pending_connection,
|
| + CreateConnection(pending_connection.database_callbacks(),
|
| + pending_connection.child_process_id()));
|
| return;
|
| }
|
| - if (local_version < metadata_.version) {
|
| - connection.callbacks->OnError(IndexedDBDatabaseError(
|
| + if (pending_connection.version() < metadata_.version) {
|
| + pending_connection.OnError(IndexedDBDatabaseError(
|
| blink::WebIDBDatabaseExceptionVersionError,
|
| ASCIIToUTF16("The requested version (") +
|
| - Int64ToString16(local_version) +
|
| + Int64ToString16(pending_connection.version()) +
|
| ASCIIToUTF16(") is less than the existing version (") +
|
| Int64ToString16(metadata_.version) + ASCIIToUTF16(").")));
|
| return;
|
| }
|
| - DCHECK_EQ(local_version, metadata_.version);
|
| - connection.callbacks->OnSuccess(
|
| - CreateConnection(connection.database_callbacks,
|
| - connection.child_process_id),
|
| + DCHECK_EQ(pending_connection.version(), metadata_.version);
|
| + pending_connection.OnSuccess(
|
| + CreateConnection(pending_connection.database_callbacks(),
|
| + pending_connection.child_process_id()),
|
| this->metadata());
|
| }
|
|
|
| void IndexedDBDatabase::RunVersionChangeTransaction(
|
| - scoped_refptr<IndexedDBCallbacks> callbacks,
|
| - std::unique_ptr<IndexedDBConnection> connection,
|
| - int64_t transaction_id,
|
| - int64_t requested_version) {
|
| - DCHECK(callbacks.get());
|
| + const IndexedDBPendingConnection& pending_connection,
|
| + std::unique_ptr<IndexedDBConnection> connection) {
|
| DCHECK(connections_.count(connection.get()));
|
| if (ConnectionCount() > 1) {
|
| - DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss());
|
| + // TODO(cmumford): Replace this check?
|
| + // DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss());
|
| // Front end ensures the event is not fired at connections that have
|
| // close_pending set.
|
| for (const auto* iter : connections_) {
|
| if (iter != connection.get()) {
|
| iter->callbacks()->OnVersionChange(metadata_.version,
|
| - requested_version);
|
| + pending_connection.version());
|
| }
|
| }
|
| // OnBlocked will be fired at the request when one of the other
|
| // connections acks that the OnVersionChange was ignored.
|
|
|
| DCHECK(!pending_run_version_change_transaction_call_);
|
| - pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall(
|
| - callbacks, std::move(connection), transaction_id, requested_version));
|
| + pending_run_version_change_transaction_call_.reset(
|
| + new PendingUpgradeCall(pending_connection, std::move(connection)));
|
| return;
|
| }
|
| - RunVersionChangeTransactionFinal(callbacks, std::move(connection),
|
| - transaction_id, requested_version);
|
| + RunVersionChangeTransactionFinal(pending_connection, std::move(connection));
|
| }
|
|
|
| void IndexedDBDatabase::RunVersionChangeTransactionFinal(
|
| - scoped_refptr<IndexedDBCallbacks> callbacks,
|
| - std::unique_ptr<IndexedDBConnection> connection,
|
| - int64_t transaction_id,
|
| - int64_t requested_version) {
|
| + const IndexedDBPendingConnection& pending_connection,
|
| + std::unique_ptr<IndexedDBConnection> connection) {
|
| std::vector<int64_t> object_store_ids;
|
| - CreateTransaction(transaction_id,
|
| - connection.get(),
|
| + CreateTransaction(pending_connection.transaction_id(), connection.get(),
|
| object_store_ids,
|
| blink::WebIDBTransactionModeVersionChange);
|
|
|
| DCHECK(transaction_coordinator_.IsRunningVersionChangeTransaction());
|
| - transactions_[transaction_id]->ScheduleTask(
|
| - base::Bind(&IndexedDBDatabase::VersionChangeOperation,
|
| - this,
|
| - requested_version,
|
| - callbacks,
|
| - base::Passed(&connection)));
|
| + transactions_[pending_connection.transaction_id()]->ScheduleTask(
|
| + base::Bind(&IndexedDBDatabase::VersionChangeOperation, this,
|
| + pending_connection, base::Passed(&connection)));
|
| DCHECK(!pending_second_half_open_);
|
| }
|
|
|
| @@ -1937,12 +1931,13 @@ void IndexedDBDatabase::ForceClose() {
|
| IndexedDBConnection* connection = *it++;
|
| connection->ForceClose();
|
| }
|
| +
|
| DCHECK(connections_.empty());
|
| }
|
|
|
| void IndexedDBDatabase::VersionChangeIgnored() {
|
| if (pending_run_version_change_transaction_call_) {
|
| - pending_run_version_change_transaction_call_->callbacks()->OnBlocked(
|
| + pending_run_version_change_transaction_call_->OnBlocked(
|
| metadata_.version);
|
| }
|
|
|
| @@ -1975,7 +1970,7 @@ void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) {
|
|
|
| if (pending_second_half_open_ &&
|
| pending_second_half_open_->connection() == connection) {
|
| - pending_second_half_open_->callbacks()->OnError(
|
| + pending_second_half_open_->OnError(
|
| IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError,
|
| "The connection was closed."));
|
| pending_second_half_open_.reset();
|
|
|