Commit fbd8d172 authored by cmumford's avatar cmumford Committed by Commit bot

IndexedDB: Saving data loss status in IndexedDBPendingConnection.

Database data loss is a non-standard extension to IDBVersionChangeEvent
(https://www.w3.org/Bugs/Public/show_bug.cgi?id=22370). This state only
needs to be persisted as part of the database open. So moving this value
from IndexedDBCallbacks (used for any IDB call) to
IndexedDBPendingConnection (only used during database open).

BUG=627484

Review-Url: https://codereview.chromium.org/2140193002
Cr-Commit-Position: refs/heads/master@{#407208}
parent 45d14bd8
......@@ -50,6 +50,7 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
host_transaction_id_(kNoTransaction),
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(kNoDatabaseCallbacks),
data_loss_(blink::WebIDBDataLossNone),
sent_blocked_(false) {}
IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
......@@ -63,6 +64,7 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
host_transaction_id_(kNoTransaction),
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(kNoDatabaseCallbacks),
data_loss_(blink::WebIDBDataLossNone),
sent_blocked_(false) {}
IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
......@@ -79,6 +81,7 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
origin_(origin),
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(ipc_database_callbacks_id),
data_loss_(blink::WebIDBDataLossNone),
sent_blocked_(false) {}
IndexedDBCallbacks::~IndexedDBCallbacks() {}
......@@ -105,7 +108,7 @@ void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
std::vector<base::string16> list;
for (unsigned i = 0; i < value.size(); ++i)
......@@ -140,14 +143,11 @@ void IndexedDBCallbacks::OnBlocked(int64_t existing_version) {
}
}
void IndexedDBCallbacks::OnDataLoss(const IndexedDBDataLossInfo& info) {
data_loss_info_ = info;
}
void IndexedDBCallbacks::OnUpgradeNeeded(
int64_t old_version,
std::unique_ptr<IndexedDBConnection> connection,
const IndexedDBDatabaseMetadata& metadata) {
const IndexedDBDatabaseMetadata& metadata,
const IndexedDBDataLossInfo& data_loss_info) {
DCHECK(dispatcher_host_.get());
DCHECK_EQ(kNoCursor, ipc_cursor_id_);
......@@ -155,6 +155,7 @@ void IndexedDBCallbacks::OnUpgradeNeeded(
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
data_loss_ = data_loss_info.status;
dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_);
int32_t ipc_database_id =
dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_);
......@@ -168,8 +169,8 @@ void IndexedDBCallbacks::OnUpgradeNeeded(
params.ipc_database_callbacks_id = ipc_database_callbacks_id_;
params.old_version = old_version;
params.idb_metadata = IndexedDBDispatcherHost::ConvertMetadata(metadata);
params.data_loss = data_loss_info_.status;
params.data_loss_message = data_loss_info_.message;
params.data_loss = data_loss_info.status;
params.data_loss_message = data_loss_info.message;
dispatcher_host_->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params));
if (!connection_open_start_time_.is_null()) {
......@@ -340,7 +341,7 @@ void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
int32_t ipc_object_id = dispatcher_host_->Add(cursor.get());
std::unique_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
......@@ -379,7 +380,7 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
IndexedDBCursor* idb_cursor =
dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
......@@ -430,7 +431,7 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch(
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
std::vector<IndexedDBKey> msg_keys;
std::vector<IndexedDBKey> msg_primary_keys;
......@@ -488,7 +489,7 @@ void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) {
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
std::unique_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(
new IndexedDBMsg_CallbacksSuccessValue_Params());
......@@ -524,7 +525,7 @@ void IndexedDBCallbacks::OnSuccessArray(
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
std::unique_ptr<IndexedDBMsg_CallbacksSuccessArray_Params> params(
new IndexedDBMsg_CallbacksSuccessArray_Params());
......@@ -568,7 +569,7 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
ipc_thread_id_, ipc_callbacks_id_, value));
......@@ -582,7 +583,7 @@ void IndexedDBCallbacks::OnSuccess(int64_t value) {
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
ipc_thread_id_, ipc_callbacks_id_, value));
......@@ -596,7 +597,7 @@ void IndexedDBCallbacks::OnSuccess() {
DCHECK_EQ(kNoTransaction, host_transaction_id_);
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_info_.status);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
ipc_thread_id_, ipc_callbacks_id_));
......
......@@ -27,15 +27,11 @@ class IndexedDBConnection;
class IndexedDBCursor;
class IndexedDBDatabase;
class IndexedDBDatabaseCallbacks;
struct IndexedDBDataLossInfo;
struct IndexedDBDatabaseMetadata;
struct IndexedDBReturnValue;
struct IndexedDBValue;
struct IndexedDBDataLossInfo {
blink::WebIDBDataLoss status = blink::WebIDBDataLossNone;
std::string message;
};
class CONTENT_EXPORT IndexedDBCallbacks
: public base::RefCounted<IndexedDBCallbacks> {
public:
......@@ -67,11 +63,11 @@ class CONTENT_EXPORT IndexedDBCallbacks
virtual void OnBlocked(int64_t existing_version);
// IndexedDBFactory::Open
virtual void OnDataLoss(const IndexedDBDataLossInfo& data_loss_info);
virtual void OnUpgradeNeeded(
int64_t old_version,
std::unique_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata);
const content::IndexedDBDatabaseMetadata& metadata,
const IndexedDBDataLossInfo& data_loss_info);
virtual void OnSuccess(std::unique_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata);
......@@ -111,10 +107,6 @@ class CONTENT_EXPORT IndexedDBCallbacks
// IndexedDBCursor::Continue / Advance (when complete)
virtual void OnSuccess();
const IndexedDBDataLossInfo& data_loss_info() const {
return data_loss_info_;
}
void SetConnectionOpenStartTime(const base::TimeTicks& start_time);
protected:
......@@ -141,7 +133,7 @@ class CONTENT_EXPORT IndexedDBCallbacks
int32_t ipc_database_callbacks_id_;
// Used to assert that OnSuccess is only called if there was no data loss.
IndexedDBDataLossInfo data_loss_info_;
blink::WebIDBDataLoss data_loss_;
// The "blocked" event should be sent at most once per request.
bool sent_blocked_;
......
......@@ -11,7 +11,7 @@
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_data_loss_info.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
#include "content/browser/indexed_db/leveldb/mock_leveldb_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
......
// Copyright 2016 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.
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_LOSS_INFO_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_LOSS_INFO_H_
#include <string>
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
namespace content {
struct IndexedDBDataLossInfo {
blink::WebIDBDataLoss status = blink::WebIDBDataLossNone;
std::string message;
};
} // namespace content
#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_LOSS_INFO_H_
......@@ -117,8 +117,8 @@ class IndexedDBDatabase::OpenRequest
: public IndexedDBDatabase::OpenOrDeleteRequest {
public:
OpenRequest(scoped_refptr<IndexedDBDatabase> db,
const IndexedDBPendingConnection& pending_connection)
: OpenOrDeleteRequest(db), pending_(pending_connection) {}
std::unique_ptr<IndexedDBPendingConnection> pending_connection)
: OpenOrDeleteRequest(db), pending_(std::move(pending_connection)) {}
void Perform() override {
if (db_->metadata_.id == kInvalidId) {
......@@ -127,15 +127,15 @@ class IndexedDBDatabase::OpenRequest
if (!db_->OpenInternal().ok()) {
// TODO(jsbell): Consider including sanitized leveldb status message.
base::string16 message;
if (pending_.version == IndexedDBDatabaseMetadata::NO_VERSION) {
if (pending_->version == IndexedDBDatabaseMetadata::NO_VERSION) {
message = ASCIIToUTF16(
"Internal error opening database with no version specified.");
} else {
message =
ASCIIToUTF16("Internal error opening database with version ") +
Int64ToString16(pending_.version);
Int64ToString16(pending_->version);
}
pending_.callbacks->OnError(IndexedDBDatabaseError(
pending_->callbacks->OnError(IndexedDBDatabaseError(
blink::WebIDBDatabaseExceptionUnknownError, message));
db_->RequestComplete(this);
return;
......@@ -145,7 +145,7 @@ class IndexedDBDatabase::OpenRequest
}
const int64_t old_version = db_->metadata_.version;
int64_t& new_version = pending_.version;
int64_t& new_version = pending_->version;
bool is_new_database = old_version == IndexedDBDatabaseMetadata::NO_VERSION;
......@@ -153,9 +153,9 @@ class IndexedDBDatabase::OpenRequest
// For unit tests only - skip upgrade steps. (Calling from script with
// DEFAULT_VERSION throws exception.)
DCHECK(is_new_database);
pending_.callbacks->OnSuccess(
db_->CreateConnection(pending_.database_callbacks,
pending_.child_process_id),
pending_->callbacks->OnSuccess(
db_->CreateConnection(pending_->database_callbacks,
pending_->child_process_id),
db_->metadata_);
db_->RequestComplete(this);
return;
......@@ -164,9 +164,9 @@ class IndexedDBDatabase::OpenRequest
if (!is_new_database &&
(new_version == old_version ||
new_version == IndexedDBDatabaseMetadata::NO_VERSION)) {
pending_.callbacks->OnSuccess(
db_->CreateConnection(pending_.database_callbacks,
pending_.child_process_id),
pending_->callbacks->OnSuccess(
db_->CreateConnection(pending_->database_callbacks,
pending_->child_process_id),
db_->metadata_);
db_->RequestComplete(this);
return;
......@@ -180,10 +180,10 @@ class IndexedDBDatabase::OpenRequest
} else if (new_version < old_version) {
// Requested version is lower than current version - fail the request.
DCHECK(!is_new_database);
pending_.callbacks->OnError(IndexedDBDatabaseError(
pending_->callbacks->OnError(IndexedDBDatabaseError(
blink::WebIDBDatabaseExceptionVersionError,
ASCIIToUTF16("The requested version (") +
Int64ToString16(pending_.version) +
Int64ToString16(pending_->version) +
ASCIIToUTF16(") is less than the existing version (") +
Int64ToString16(db_->metadata_.version) + ASCIIToUTF16(").")));
db_->RequestComplete(this);
......@@ -203,8 +203,7 @@ class IndexedDBDatabase::OpenRequest
// fired at connections that have close_pending set. A "blocked" event
// will be fired at the request when one of the connections acks that the
// "versionchange" event was ignored.
DCHECK_NE(pending_.callbacks->data_loss_info().status,
blink::WebIDBDataLossTotal);
DCHECK_NE(pending_->data_loss_info.status, blink::WebIDBDataLossTotal);
for (const auto* connection : db_->connections_)
connection->callbacks()->OnVersionChange(old_version, new_version);
......@@ -212,13 +211,13 @@ class IndexedDBDatabase::OpenRequest
}
void OnVersionChangeIgnored() const override {
pending_.callbacks->OnBlocked(db_->metadata_.version);
pending_->callbacks->OnBlocked(db_->metadata_.version);
}
void OnConnectionClosed(IndexedDBConnection* connection) override {
// This connection closed prematurely; signal an error and complete.
if (connection && connection->callbacks() == pending_.database_callbacks) {
pending_.callbacks->OnError(
if (connection && connection->callbacks() == pending_->database_callbacks) {
pending_->callbacks->OnError(
IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError,
"The connection was closed."));
db_->RequestComplete(this);
......@@ -235,26 +234,27 @@ class IndexedDBDatabase::OpenRequest
// IndexedDBDatabase::VersionChangeOperation in order to kick the
// transaction into the correct state.
void StartUpgrade() {
connection_ = db_->CreateConnection(pending_.database_callbacks,
pending_.child_process_id);
connection_ = db_->CreateConnection(pending_->database_callbacks,
pending_->child_process_id);
DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL);
std::vector<int64_t> object_store_ids;
IndexedDBTransaction* transaction = db_->CreateTransaction(
pending_.transaction_id, connection_.get(), object_store_ids,
pending_->transaction_id, connection_.get(), object_store_ids,
blink::WebIDBTransactionModeVersionChange);
DCHECK(db_->transaction_coordinator_.IsRunningVersionChangeTransaction());
transaction->ScheduleTask(
base::Bind(&IndexedDBDatabase::VersionChangeOperation, db_,
pending_.version, pending_.callbacks));
pending_->version, pending_->callbacks));
}
// Called when the upgrade transaction has started executing.
void UpgradeTransactionStarted(int64_t old_version) override {
DCHECK(connection_);
pending_.callbacks->OnUpgradeNeeded(old_version, std::move(connection_),
db_->metadata_);
pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_),
db_->metadata_,
pending_->data_loss_info);
}
void UpgradeTransactionFinished(bool committed) override {
......@@ -262,12 +262,12 @@ class IndexedDBDatabase::OpenRequest
DCHECK(!connection_);
if (committed) {
DCHECK_EQ(pending_.version, db_->metadata_.version);
pending_.callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(),
db_->metadata());
DCHECK_EQ(pending_->version, db_->metadata_.version);
pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(),
db_->metadata());
} else {
DCHECK_NE(pending_.version, db_->metadata_.version);
pending_.callbacks->OnError(
DCHECK_NE(pending_->version, db_->metadata_.version);
pending_->callbacks->OnError(
IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError,
"Version change transaction was aborted in "
"upgradeneeded event handler."));
......@@ -276,7 +276,7 @@ class IndexedDBDatabase::OpenRequest
}
private:
IndexedDBPendingConnection pending_;
std::unique_ptr<IndexedDBPendingConnection> pending_;
// If an upgrade is needed, holds the pending connection until ownership is
// transferred to the IndexedDBDispatcherHost via OnUpgradeNeeded.
......@@ -303,7 +303,6 @@ class IndexedDBDatabase::DeleteRequest
// close_pending set.
const int64_t old_version = db_->metadata_.version;
const int64_t new_version = IndexedDBDatabaseMetadata::NO_VERSION;
DCHECK_NE(callbacks_->data_loss_info().status, blink::WebIDBDataLossTotal);
for (const auto* connection : db_->connections_)
connection->callbacks()->OnVersionChange(old_version, new_version);
}
......@@ -1919,8 +1918,8 @@ void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) {
}
void IndexedDBDatabase::OpenConnection(
const IndexedDBPendingConnection& connection) {
AppendRequest(base::MakeUnique<OpenRequest>(this, connection));
std::unique_ptr<IndexedDBPendingConnection> connection) {
AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection)));
}
void IndexedDBDatabase::DeleteDatabase(
......
......@@ -79,7 +79,7 @@ class CONTENT_EXPORT IndexedDBDatabase
int64_t new_max_index_id);
void RemoveIndex(int64_t object_store_id, int64_t index_id);
void OpenConnection(const IndexedDBPendingConnection& connection);
void OpenConnection(std::unique_ptr<IndexedDBPendingConnection> connection);
void DeleteDatabase(scoped_refptr<IndexedDBCallbacks> callbacks);
const IndexedDBDatabaseMetadata& metadata() const { return metadata_; }
......
......@@ -76,10 +76,11 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
IndexedDBPendingConnection connection1(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION);
db->OpenConnection(connection1);
std::unique_ptr<IndexedDBPendingConnection> connection1(
new IndexedDBPendingConnection(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db->OpenConnection(std::move(connection1));
EXPECT_FALSE(backing_store->HasOneRef()); // db, connection count > 0
......@@ -87,10 +88,11 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
IndexedDBPendingConnection connection2(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
IndexedDBDatabaseMetadata::DEFAULT_VERSION);
db->OpenConnection(connection2);
std::unique_ptr<IndexedDBPendingConnection> connection2(
new IndexedDBPendingConnection(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db->OpenConnection(std::move(connection2));
EXPECT_FALSE(backing_store->HasOneRef()); // local and connection
......@@ -128,10 +130,11 @@ TEST(IndexedDBDatabaseTest, ForcedClose) {
new MockIndexedDBDatabaseCallbacks());
scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks());
const int64_t upgrade_transaction_id = 3;
IndexedDBPendingConnection connection(
request, callbacks, kFakeChildProcessId, upgrade_transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION);
database->OpenConnection(connection);
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
request, callbacks, kFakeChildProcessId, upgrade_transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
database->OpenConnection(std::move(connection));
EXPECT_EQ(database.get(), request->connection()->database());
const int64_t transaction_id = 123;
......@@ -189,10 +192,11 @@ TEST(IndexedDBDatabaseTest, PendingDelete) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
IndexedDBPendingConnection connection(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION);
db->OpenConnection(connection);
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db->OpenConnection(std::move(connection));
EXPECT_EQ(db->ConnectionCount(), 1UL);
EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL);
......@@ -246,9 +250,11 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
request_ = new MockIndexedDBCallbacks();
callbacks_ = new MockIndexedDBDatabaseCallbacks();
const int64_t transaction_id = 1;
db_->OpenConnection(IndexedDBPendingConnection(
request_, callbacks_, kFakeChildProcessId, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
request_, callbacks_, kFakeChildProcessId, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(IndexedDBDatabaseMetadata::NO_VERSION, db_->metadata().version);
connection_ = base::WrapUnique(new IndexedDBConnection(db_, callbacks_));
......
......@@ -379,14 +379,14 @@ void IndexedDBDispatcherHost::OnIDBFactoryOpen(
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks =
new IndexedDBDatabaseCallbacks(
this, params.ipc_thread_id, params.ipc_database_callbacks_id);
IndexedDBPendingConnection connection(callbacks,
database_callbacks,
ipc_process_id_,
host_transaction_id,
params.version);
std::unique_ptr<IndexedDBPendingConnection> connection =
base::WrapUnique(new IndexedDBPendingConnection(
callbacks, database_callbacks, ipc_process_id_, host_transaction_id,
params.version));
DCHECK(request_context_);
context()->GetIDBFactory()->Open(params.name, connection, request_context_,
params.origin, indexed_db_path);
context()->GetIDBFactory()->Open(params.name, std::move(connection),
request_context_, params.origin,
indexed_db_path);
}
void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
......
......@@ -8,6 +8,7 @@
#include <stddef.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
......@@ -48,7 +49,7 @@ class CONTENT_EXPORT IndexedDBFactory
const base::FilePath& data_directory,
net::URLRequestContext* request_context) = 0;
virtual void Open(const base::string16& name,
const IndexedDBPendingConnection& connection,
std::unique_ptr<IndexedDBPendingConnection> connection,
net::URLRequestContext* request_context,
const url::Origin& origin,
const base::FilePath& data_directory) = 0;
......
......@@ -397,11 +397,12 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
return 0;
}
void IndexedDBFactoryImpl::Open(const base::string16& name,
const IndexedDBPendingConnection& connection,
net::URLRequestContext* request_context,
const Origin& origin,
const base::FilePath& data_directory) {
void IndexedDBFactoryImpl::Open(
const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
net::URLRequestContext* request_context,
const Origin& origin,
const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactoryImpl::Open");
scoped_refptr<IndexedDBDatabase> database;
IndexedDBDatabase::Identifier unique_identifier(origin, name);
......@@ -416,18 +417,17 @@ void IndexedDBFactoryImpl::Open(const base::string16& name,
&data_loss_info, &disk_full, &s);
if (!backing_store.get()) {
if (disk_full) {
connection.callbacks->OnError(
IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError,
ASCIIToUTF16(
"Encountered full disk while opening "
"backing store for indexedDB.open.")));
connection->callbacks->OnError(IndexedDBDatabaseError(
blink::WebIDBDatabaseExceptionQuotaError,
ASCIIToUTF16("Encountered full disk while opening "
"backing store for indexedDB.open.")));
return;
}
IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
ASCIIToUTF16(
"Internal error opening backing store"
" for indexedDB.open."));
connection.callbacks->OnError(error);
connection->callbacks->OnError(error);
if (s.IsCorruption()) {
HandleBackingStoreCorruption(origin, error);
}
......@@ -443,7 +443,7 @@ void IndexedDBFactoryImpl::Open(const base::string16& name,
"Internal error creating "
"database backend for "
"indexedDB.open."));
connection.callbacks->OnError(error);
connection->callbacks->OnError(error);
if (s.IsCorruption()) {
backing_store = NULL; // Closes the LevelDB so that it can be deleted
HandleBackingStoreCorruption(origin, error);
......@@ -454,10 +454,9 @@ void IndexedDBFactoryImpl::Open(const base::string16& name,
database = it->second;
}
if (data_loss_info.status != blink::WebIDBDataLossNone)
connection.callbacks->OnDataLoss(data_loss_info);
connection->data_loss_info = data_loss_info;
database->OpenConnection(connection);
database->OpenConnection(std::move(connection));
if (!was_open && database->ConnectionCount() > 0) {
database_map_[unique_identifier] = database.get();
......
......@@ -36,7 +36,7 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
const base::FilePath& data_directory,
net::URLRequestContext* request_context) override;
void Open(const base::string16& name,
const IndexedDBPendingConnection& connection,
std::unique_ptr<IndexedDBPendingConnection> connection,
net::URLRequestContext* request_context,
const url::Origin& origin,
const base::FilePath& data_directory) override;
......
......@@ -253,12 +253,12 @@ TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
scoped_refptr<IndexedDBDatabaseCallbacks> dummy_database_callbacks =
new IndexedDBDatabaseCallbacks(NULL, 0, 0);
const base::string16 name(ASCIIToUTF16("name"));
IndexedDBPendingConnection connection(callbacks,
dummy_database_callbacks,
0, /* child_process_id */
2, /* transaction_id */
1 /* version */);
factory->Open(name, connection, NULL /* request_context */, origin,
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(callbacks, dummy_database_callbacks,
0, /* child_process_id */
2, /* transaction_id */
1 /* version */));
factory->Open(name, std::move(connection), NULL /* request_context */, origin,
temp_directory.path());
EXPECT_TRUE(callbacks->error_called());
}
......@@ -273,11 +273,12 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION);
factory()->Open(ASCIIToUTF16("db"), connection, NULL /* request_context */,
origin, temp_directory.path());
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory()->Open(ASCIIToUTF16("db"), std::move(connection),
NULL /* request_context */, origin, temp_directory.path());
EXPECT_TRUE(callbacks->connection());
......@@ -300,11 +301,12 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION);
factory()->Open(ASCIIToUTF16("db"), connection, NULL /* request_context */,
origin, temp_directory.path());
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory()->Open(ASCIIToUTF16("db"), std::move(connection),
NULL /* request_context */, origin, temp_directory.path());
EXPECT_TRUE(callbacks->connection());
IndexedDBBackingStore* store =
......@@ -386,11 +388,12 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION);
factory()->Open(ASCIIToUTF16("db"), connection, NULL /* request_context */,
origin, temp_directory.path());
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
callbacks, db_callbacks, 0, /* child_process_id */
transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory()->Open(ASCIIToUTF16("db"), std::move(connection),
NULL /* request_context */, origin, temp_directory.path());
EXPECT_TRUE(callbacks->connection());
EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
......@@ -420,10 +423,10 @@ class UpgradeNeededCallbacks : public MockIndexedDBCallbacks {
EXPECT_FALSE(connection.get());
}
void OnUpgradeNeeded(
int64_t old_version,
std::unique_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata) override {
void OnUpgradeNeeded(int64_t old_version,
std::unique_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata,
const IndexedDBDataLossInfo& data_loss_info) override {
connection_ = std::move(connection);
}
......@@ -466,13 +469,12 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
{
scoped_refptr<MockIndexedDBCallbacks> callbacks(
new UpgradeNeededCallbacks());
IndexedDBPendingConnection connection(callbacks,
db_callbacks,
0, /* child_process_id */
transaction_id,
db_version);
factory()->Open(db_name, connection, NULL /* request_context */, origin,
temp_directory.path());
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(callbacks, db_callbacks,
0, /* child_process_id */
transaction_id, db_version));
factory()->Open(db_name, std::move(connection), NULL /* request_context */,
origin, temp_directory.path());
EXPECT_TRUE(factory()->IsDatabaseOpen(origin, db_name));
// Pump the message loop so the upgrade transaction can run.
......@@ -488,13 +490,12 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
// the database object.
{
scoped_refptr<ErrorCallbacks> callbacks(new ErrorCallbacks());
IndexedDBPendingConnection connection(callbacks,
db_callbacks,
0, /* child_process_id */
transaction_id,
db_version - 1);
factory()->Open(db_name, connection, NULL /* request_context */, origin,
temp_directory.path());
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(callbacks, db_callbacks,
0, /* child_process_id */
transaction_id, db_version - 1));
factory()->Open(db_name, std::move(connection), NULL /* request_context */,
origin, temp_directory.path());
EXPECT_TRUE(callbacks->saw_error());
EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name));
}
......
......@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_data_loss_info.h"
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
#include "content/common/content_export.h"
......@@ -31,6 +32,7 @@ struct CONTENT_EXPORT IndexedDBPendingConnection {
int child_process_id;
int64_t transaction_id;
int64_t version;
IndexedDBDataLossInfo data_loss_info;
};
} // namespace content
......
......@@ -193,20 +193,18 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
test_path = idb_context->GetFilePathForTesting(kTestOrigin);
IndexedDBPendingConnection open_connection(open_callbacks,
open_db_callbacks,
0 /* child_process_id */,
0 /* host_transaction_id */,
0 /* version */);
factory->Open(base::ASCIIToUTF16("opendb"), open_connection,
std::unique_ptr<IndexedDBPendingConnection> open_connection(
new IndexedDBPendingConnection(
open_callbacks, open_db_callbacks, 0 /* child_process_id */,
0 /* host_transaction_id */, 0 /* version */));
factory->Open(base::ASCIIToUTF16("opendb"), std::move(open_connection),
NULL /* request_context */, Origin(kTestOrigin),
idb_context->data_path());
IndexedDBPendingConnection closed_connection(closed_callbacks,
closed_db_callbacks,
0 /* child_process_id */,
0 /* host_transaction_id */,
0 /* version */);
factory->Open(base::ASCIIToUTF16("closeddb"), closed_connection,
std::unique_ptr<IndexedDBPendingConnection> closed_connection(
new IndexedDBPendingConnection(
closed_callbacks, closed_db_callbacks, 0 /* child_process_id */,
0 /* host_transaction_id */, 0 /* version */));
factory->Open(base::ASCIIToUTF16("closeddb"), std::move(closed_connection),
NULL /* request_context */, Origin(kTestOrigin),
idb_context->data_path());
......@@ -274,10 +272,11 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION);
factory->Open(base::ASCIIToUTF16("db"), connection,
std::unique_ptr<IndexedDBPendingConnection> connection(
new IndexedDBPendingConnection(
callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory->Open(base::ASCIIToUTF16("db"), std::move(connection),
NULL /* request_context */, Origin(kTestOrigin),
temp_dir.path());
......
......@@ -26,12 +26,20 @@ class MockIndexedDBFactory : public IndexedDBFactory {
const url::Origin& origin,
const base::FilePath& data_directory,
net::URLRequestContext* request_context));
MOCK_METHOD5(Open,
MOCK_METHOD5(OpenProxy,
void(const base::string16& name,
const IndexedDBPendingConnection& connection,
IndexedDBPendingConnection* connection,
net::URLRequestContext* request_context,
const url::Origin& origin,
const base::FilePath& data_directory));
// Googlemock can't deal with move-only types, so *Proxy() is a workaround.
virtual void Open(const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
net::URLRequestContext* request_context,
const url::Origin& origin,
const base::FilePath& data_directory) {
OpenProxy(name, connection.get(), request_context, origin, data_directory);
}
MOCK_METHOD5(DeleteDatabase,
void(const base::string16& name,
net::URLRequestContext* request_context,
......
......@@ -899,6 +899,7 @@
'browser/indexed_db/indexed_db_context_impl.h',
'browser/indexed_db/indexed_db_cursor.cc',
'browser/indexed_db/indexed_db_cursor.h',
'browser/indexed_db/indexed_db_data_loss_info.h',
'browser/indexed_db/indexed_db_database.cc',
'browser/indexed_db/indexed_db_database.h',
'browser/indexed_db/indexed_db_database_callbacks.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment