Commit f79c6fe7 authored by Andreas Butler's avatar Andreas Butler Committed by Commit Bot

Reimplementing getDatabaseNames() as databases() for indexeddb.

Change-Id: I88a0fe75383bb9712478580a7bd60a145e2d89ba
Bug: 1228492
Reviewed-on: https://chromium-review.googlesource.com/c/1228492
Commit-Queue: Andreas Butler <andreasbutler@google.com>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Reviewed-by: default avatarChase Phillips <cmp@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600863}
parent 6bc8e421
...@@ -141,6 +141,8 @@ class IndexedDBCallbacks::IOThreadHelper { ...@@ -141,6 +141,8 @@ class IndexedDBCallbacks::IOThreadHelper {
~IOThreadHelper(); ~IOThreadHelper();
void SendError(const IndexedDBDatabaseError& error); void SendError(const IndexedDBDatabaseError& error);
void SendSuccessNamesAndVersionsList(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions);
void SendSuccessStringList(const std::vector<base::string16>& value); void SendSuccessStringList(const std::vector<base::string16>& value);
void SendBlocked(int64_t existing_version); void SendBlocked(int64_t existing_version);
void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection, void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection,
...@@ -236,6 +238,20 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { ...@@ -236,6 +238,20 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
} }
} }
void IndexedDBCallbacks::OnSuccess(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!complete_);
DCHECK(io_helper_);
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessNamesAndVersionsList,
base::Unretained(io_helper_.get()),
std::move(names_and_versions)));
complete_ = true;
}
void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!complete_); DCHECK(!complete_);
...@@ -526,6 +542,18 @@ void IndexedDBCallbacks::IOThreadHelper::SendError( ...@@ -526,6 +542,18 @@ void IndexedDBCallbacks::IOThreadHelper::SendError(
callbacks_->Error(error.code(), error.message()); callbacks_->Error(error.code(), error.message());
} }
void IndexedDBCallbacks::IOThreadHelper::SendSuccessNamesAndVersionsList(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!callbacks_)
return;
if (!dispatcher_host_) {
OnConnectionError();
return;
}
callbacks_->SuccessNamesAndVersionsList(std::move(names_and_versions));
}
void IndexedDBCallbacks::IOThreadHelper::SendSuccessStringList( void IndexedDBCallbacks::IOThreadHelper::SendSuccessStringList(
const std::vector<base::string16>& value) { const std::vector<base::string16>& value) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
......
...@@ -53,6 +53,10 @@ class CONTENT_EXPORT IndexedDBCallbacks ...@@ -53,6 +53,10 @@ class CONTENT_EXPORT IndexedDBCallbacks
virtual void OnError(const IndexedDBDatabaseError& error); virtual void OnError(const IndexedDBDatabaseError& error);
// IndexedDBFactory::databases
virtual void OnSuccess(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions);
// IndexedDBFactory::GetDatabaseNames // IndexedDBFactory::GetDatabaseNames
virtual void OnSuccess(const std::vector<base::string16>& string); virtual void OnSuccess(const std::vector<base::string16>& string);
......
...@@ -94,6 +94,9 @@ class IndexedDBDispatcherHost::IDBSequenceHelper { ...@@ -94,6 +94,9 @@ class IndexedDBDispatcherHost::IDBSequenceHelper {
indexed_db_context_(std::move(indexed_db_context)) {} indexed_db_context_(std::move(indexed_db_context)) {}
~IDBSequenceHelper() {} ~IDBSequenceHelper() {}
void GetDatabaseInfoOnIDBThread(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin);
void GetDatabaseNamesOnIDBThread(scoped_refptr<IndexedDBCallbacks> callbacks, void GetDatabaseNamesOnIDBThread(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin); const url::Origin& origin);
void OpenOnIDBThread( void OpenOnIDBThread(
...@@ -165,6 +168,24 @@ void IndexedDBDispatcherHost::RenderProcessExited( ...@@ -165,6 +168,24 @@ void IndexedDBDispatcherHost::RenderProcessExited(
base::Unretained(this))); base::Unretained(this)));
} }
void IndexedDBDispatcherHost::GetDatabaseInfo(
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info,
const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!IsValidOrigin(origin)) {
mojo::ReportBadMessage(kInvalidOrigin);
return;
}
scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
this->AsWeakPtr(), origin, std::move(callbacks_info), IDBTaskRunner()));
IDBTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&IDBSequenceHelper::GetDatabaseInfoOnIDBThread,
base::Unretained(idb_helper_),
std::move(callbacks), origin));
}
void IndexedDBDispatcherHost::GetDatabaseNames( void IndexedDBDispatcherHost::GetDatabaseNames(
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info, blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info,
const url::Origin& origin) { const url::Origin& origin) {
...@@ -281,6 +302,16 @@ base::SequencedTaskRunner* IndexedDBDispatcherHost::IDBTaskRunner() const { ...@@ -281,6 +302,16 @@ base::SequencedTaskRunner* IndexedDBDispatcherHost::IDBTaskRunner() const {
return indexed_db_context_->TaskRunner(); return indexed_db_context_->TaskRunner();
} }
void IndexedDBDispatcherHost::IDBSequenceHelper::GetDatabaseInfoOnIDBThread(
scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin) {
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksInCurrentSequence());
base::FilePath indexed_db_path = indexed_db_context_->data_path();
indexed_db_context_->GetIDBFactory()->GetDatabaseInfo(callbacks, origin,
indexed_db_path);
}
void IndexedDBDispatcherHost::IDBSequenceHelper::GetDatabaseNamesOnIDBThread( void IndexedDBDispatcherHost::IDBSequenceHelper::GetDatabaseNamesOnIDBThread(
scoped_refptr<IndexedDBCallbacks> callbacks, scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin) { const url::Origin& origin) {
......
...@@ -82,6 +82,9 @@ class CONTENT_EXPORT IndexedDBDispatcherHost ...@@ -82,6 +82,9 @@ class CONTENT_EXPORT IndexedDBDispatcherHost
~IndexedDBDispatcherHost() override; ~IndexedDBDispatcherHost() override;
// blink::mojom::IDBFactory implementation: // blink::mojom::IDBFactory implementation:
void GetDatabaseInfo(
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info,
const url::Origin& origin) override;
void GetDatabaseNames( void GetDatabaseNames(
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info, blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info,
const url::Origin& origin) override; const url::Origin& origin) override;
......
...@@ -38,7 +38,9 @@ class CONTENT_EXPORT IndexedDBFactory ...@@ -38,7 +38,9 @@ class CONTENT_EXPORT IndexedDBFactory
virtual void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier, virtual void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier,
bool forced_close) = 0; bool forced_close) = 0;
virtual void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
const base::FilePath& data_directory) = 0;
virtual void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks, virtual void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& data_directory) = 0; const base::FilePath& data_directory) = 0;
......
...@@ -399,6 +399,50 @@ void IndexedDBFactoryImpl::ReportOutstandingBlobs(const Origin& origin, ...@@ -399,6 +399,50 @@ void IndexedDBFactoryImpl::ReportOutstandingBlobs(const Origin& origin,
} }
} }
void IndexedDBFactoryImpl::GetDatabaseInfo(
scoped_refptr<IndexedDBCallbacks> callbacks,
const Origin& origin,
const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseInfo");
// TODO(dmurph): Plumb data_loss back to script eventually?
IndexedDBDataLossInfo data_loss_info;
bool disk_full;
leveldb::Status s;
// TODO(dmurph): Handle this error
scoped_refptr<IndexedDBBackingStore> backing_store =
OpenBackingStore(origin, data_directory, &data_loss_info, &disk_full, &s);
if (!backing_store.get()) {
IndexedDBDatabaseError error(
blink::kWebIDBDatabaseExceptionUnknownError,
ASCIIToUTF16("Internal error opening backing store for "
"indexedDB.databases()."));
callbacks->OnError(error);
if (s.IsCorruption())
HandleBackingStoreCorruption(origin, error);
return;
}
IndexedDBMetadataCoding metadata_coding;
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions;
s = metadata_coding.ReadDatabaseNamesAndVersions(
backing_store->db(), backing_store->origin_identifier(),
&names_and_versions);
if (!s.ok()) {
DLOG(ERROR) << "Internal error getting database info";
IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError,
"Internal error opening backing store for "
"indexedDB.databases().");
callbacks->OnError(error);
backing_store = nullptr;
if (s.IsCorruption())
HandleBackingStoreCorruption(origin, error);
return;
}
callbacks->OnSuccess(std::move(names_and_versions));
backing_store = nullptr;
ReleaseBackingStore(origin, false /* immediate */);
}
void IndexedDBFactoryImpl::GetDatabaseNames( void IndexedDBFactoryImpl::GetDatabaseNames(
scoped_refptr<IndexedDBCallbacks> callbacks, scoped_refptr<IndexedDBCallbacks> callbacks,
const Origin& origin, const Origin& origin,
......
...@@ -52,7 +52,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory { ...@@ -52,7 +52,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
// content::IndexedDBFactory overrides: // content::IndexedDBFactory overrides:
void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier, void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier,
bool forced_close) override; bool forced_close) override;
void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
const base::FilePath& data_directory) override;
void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks, void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& data_directory) override; const base::FilePath& data_directory) override;
......
...@@ -18,6 +18,7 @@ using base::StringPiece; ...@@ -18,6 +18,7 @@ using base::StringPiece;
using blink::IndexedDBDatabaseMetadata; using blink::IndexedDBDatabaseMetadata;
using blink::IndexedDBIndexMetadata; using blink::IndexedDBIndexMetadata;
using blink::IndexedDBKeyPath; using blink::IndexedDBKeyPath;
using blink::mojom::IDBNameAndVersionPtr;
using blink::IndexedDBObjectStoreMetadata; using blink::IndexedDBObjectStoreMetadata;
using leveldb::Status; using leveldb::Status;
...@@ -324,15 +325,16 @@ Status ReadObjectStores( ...@@ -324,15 +325,16 @@ Status ReadObjectStores(
} }
template <typename DatabaseOrTransaction> template <typename DatabaseOrTransaction>
Status ReadDatabaseNamesInternal(DatabaseOrTransaction* db_or_transaction, Status ReadDatabaseNamesAndVersionsInternal(
const std::string& origin_identifier, DatabaseOrTransaction* db_or_transaction,
std::vector<base::string16>* names) { const std::string& origin_identifier,
std::vector<blink::mojom::IDBNameAndVersionPtr>* names_and_versions) {
const std::string start_key = const std::string start_key =
DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier);
const std::string stop_key = const std::string stop_key =
DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier);
DCHECK(names->empty()); DCHECK(names_and_versions->empty());
std::unique_ptr<LevelDBIterator> it = CreateIterator(db_or_transaction); std::unique_ptr<LevelDBIterator> it = CreateIterator(db_or_transaction);
Status s; Status s;
for (s = it->Seek(start_key); for (s = it->Seek(start_key);
...@@ -343,7 +345,7 @@ Status ReadDatabaseNamesInternal(DatabaseOrTransaction* db_or_transaction, ...@@ -343,7 +345,7 @@ Status ReadDatabaseNamesInternal(DatabaseOrTransaction* db_or_transaction,
DatabaseNameKey database_name_key; DatabaseNameKey database_name_key;
if (!DatabaseNameKey::Decode(&slice, &database_name_key) || if (!DatabaseNameKey::Decode(&slice, &database_name_key) ||
!slice.empty()) { !slice.empty()) {
// TODO(dmurph): Change UMA name to ReadDatabaseNames. // TODO(dmurph): Change UMA name to ReadDatabaseNamesAndVersionsInternal.
INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
continue; continue;
} }
...@@ -369,10 +371,11 @@ Status ReadDatabaseNamesInternal(DatabaseOrTransaction* db_or_transaction, ...@@ -369,10 +371,11 @@ Status ReadDatabaseNamesInternal(DatabaseOrTransaction* db_or_transaction,
} }
// Ignore stale metadata from failed initial opens. // Ignore stale metadata from failed initial opens.
if (database_version != IndexedDBDatabaseMetadata::DEFAULT_VERSION) if (database_version != IndexedDBDatabaseMetadata::DEFAULT_VERSION) {
names->push_back(database_name_key.database_name()); names_and_versions->push_back(blink::mojom::IDBNameAndVersion::New(
database_name_key.database_name(), database_version));
}
} }
if (!s.ok()) if (!s.ok())
INTERNAL_READ_ERROR(GET_DATABASE_NAMES); INTERNAL_READ_ERROR(GET_DATABASE_NAMES);
...@@ -453,18 +456,38 @@ Status ReadMetadataForDatabaseNameInternal( ...@@ -453,18 +456,38 @@ Status ReadMetadataForDatabaseNameInternal(
IndexedDBMetadataCoding::IndexedDBMetadataCoding() = default; IndexedDBMetadataCoding::IndexedDBMetadataCoding() = default;
IndexedDBMetadataCoding::~IndexedDBMetadataCoding() = default; IndexedDBMetadataCoding::~IndexedDBMetadataCoding() = default;
Status IndexedDBMetadataCoding::ReadDatabaseNamesAndVersions(
LevelDBDatabase* db,
const std::string& origin_identifier,
std::vector<blink::mojom::IDBNameAndVersionPtr>* names_and_versions) {
return ReadDatabaseNamesAndVersionsInternal(db, origin_identifier,
names_and_versions);
}
Status IndexedDBMetadataCoding::ReadDatabaseNames( Status IndexedDBMetadataCoding::ReadDatabaseNames(
LevelDBDatabase* db, LevelDBDatabase* db,
const std::string& origin_identifier, const std::string& origin_identifier,
std::vector<base::string16>* names) { std::vector<base::string16>* names) {
return ReadDatabaseNamesInternal(db, origin_identifier, names); std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions;
Status s = ReadDatabaseNamesAndVersionsInternal(db, origin_identifier,
&names_and_versions);
for (const blink::mojom::IDBNameAndVersionPtr& nav : names_and_versions) {
names->push_back(nav->name);
}
return s;
} }
Status IndexedDBMetadataCoding::ReadDatabaseNames( Status IndexedDBMetadataCoding::ReadDatabaseNames(
LevelDBTransaction* transaction, LevelDBTransaction* transaction,
const std::string& origin_identifier, const std::string& origin_identifier,
std::vector<base::string16>* names) { std::vector<base::string16>* names) {
return ReadDatabaseNamesInternal(transaction, origin_identifier, names); std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions;
Status s = ReadDatabaseNamesAndVersionsInternal(
transaction, origin_identifier, &names_and_versions);
for (const blink::mojom::IDBNameAndVersionPtr& nav : names_and_versions) {
names->push_back(nav->name);
}
return s;
} }
Status IndexedDBMetadataCoding::ReadMetadataForDatabaseName( Status IndexedDBMetadataCoding::ReadMetadataForDatabaseName(
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h" #include "third_party/leveldatabase/src/include/leveldb/status.h"
namespace blink { namespace blink {
...@@ -47,6 +48,12 @@ class CONTENT_EXPORT IndexedDBMetadataCoding { ...@@ -47,6 +48,12 @@ class CONTENT_EXPORT IndexedDBMetadataCoding {
const std::string& origin_identifier, const std::string& origin_identifier,
std::vector<base::string16>* names); std::vector<base::string16>* names);
// Reads in the list of database names and versions for the given origin.
virtual leveldb::Status ReadDatabaseNamesAndVersions(
LevelDBDatabase* db,
const std::string& origin_identifier,
std::vector<blink::mojom::IDBNameAndVersionPtr>* names_and_versions);
// Reads in metadata for the database and all object stores & indices. // Reads in metadata for the database and all object stores & indices.
// Note: the database name is not populated in |metadata|. // Note: the database name is not populated in |metadata|.
virtual leveldb::Status ReadMetadataForDatabaseName( virtual leveldb::Status ReadMetadataForDatabaseName(
......
...@@ -25,6 +25,10 @@ class MockIndexedDBFactory : public IndexedDBFactory { ...@@ -25,6 +25,10 @@ class MockIndexedDBFactory : public IndexedDBFactory {
void(scoped_refptr<IndexedDBCallbacks> callbacks, void(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& data_directory)); const base::FilePath& data_directory));
MOCK_METHOD3(GetDatabaseInfo,
void(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
const base::FilePath& data_directory));
MOCK_METHOD4( MOCK_METHOD4(
OpenProxy, OpenProxy,
void(const base::string16& name, void(const base::string16& name,
......
...@@ -29,6 +29,9 @@ class MockMojoIndexedDBCallbacks : public blink::mojom::IDBCallbacks { ...@@ -29,6 +29,9 @@ class MockMojoIndexedDBCallbacks : public blink::mojom::IDBCallbacks {
MOCK_METHOD2(Error, void(int32_t code, const base::string16& message)); MOCK_METHOD2(Error, void(int32_t code, const base::string16& message));
MOCK_METHOD1(SuccessNamesAndVersionsList,
void(std::vector<blink::mojom::IDBNameAndVersionPtr> list));
MOCK_METHOD1(SuccessStringList, MOCK_METHOD1(SuccessStringList,
void(const std::vector<base::string16>& value)); void(const std::vector<base::string16>& value));
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_metadata.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_metadata.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_name_and_version.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h"
using blink::IndexedDBDatabaseMetadata; using blink::IndexedDBDatabaseMetadata;
...@@ -20,6 +21,7 @@ using blink::WebData; ...@@ -20,6 +21,7 @@ using blink::WebData;
using blink::WebIDBCallbacks; using blink::WebIDBCallbacks;
using blink::WebIDBDatabase; using blink::WebIDBDatabase;
using blink::WebIDBMetadata; using blink::WebIDBMetadata;
using blink::WebIDBNameAndVersion;
using blink::WebIDBValue; using blink::WebIDBValue;
using blink::WebString; using blink::WebString;
using blink::WebVector; using blink::WebVector;
...@@ -75,6 +77,12 @@ WebIDBValue ConvertReturnValue(const blink::mojom::IDBReturnValuePtr& value) { ...@@ -75,6 +77,12 @@ WebIDBValue ConvertReturnValue(const blink::mojom::IDBReturnValuePtr& value) {
return web_value; return web_value;
} }
WebIDBNameAndVersion ConvertNameVersion(
const blink::mojom::IDBNameAndVersionPtr& name_and_version) {
return WebIDBNameAndVersion(WebString::FromUTF16(name_and_version->name),
name_and_version->version);
}
} // namespace } // namespace
// static // static
...@@ -122,6 +130,17 @@ void IndexedDBCallbacksImpl::Error(int32_t code, ...@@ -122,6 +130,17 @@ void IndexedDBCallbacksImpl::Error(int32_t code,
callbacks_.reset(); callbacks_.reset();
} }
void IndexedDBCallbacksImpl::SuccessNamesAndVersionsList(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions) {
WebVector<WebIDBNameAndVersion> web_names_and_versions;
web_names_and_versions.reserve(names_and_versions.size());
for (const blink::mojom::IDBNameAndVersionPtr& name_version :
names_and_versions)
web_names_and_versions.emplace_back(ConvertNameVersion(name_version));
callbacks_->OnSuccess(web_names_and_versions);
callbacks_.reset();
}
void IndexedDBCallbacksImpl::SuccessStringList( void IndexedDBCallbacksImpl::SuccessStringList(
const std::vector<base::string16>& value) { const std::vector<base::string16>& value) {
WebVector<WebString> web_value(value.size()); WebVector<WebString> web_value(value.size());
......
...@@ -37,6 +37,9 @@ class IndexedDBCallbacksImpl : public blink::mojom::IDBCallbacks { ...@@ -37,6 +37,9 @@ class IndexedDBCallbacksImpl : public blink::mojom::IDBCallbacks {
// blink::mojom::IDBCallbacks implementation: // blink::mojom::IDBCallbacks implementation:
void Error(int32_t code, const base::string16& message) override; void Error(int32_t code, const base::string16& message) override;
void SuccessNamesAndVersionsList(
std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions)
override;
void SuccessStringList(const std::vector<base::string16>& value) override; void SuccessStringList(const std::vector<base::string16>& value) override;
void Blocked(int64_t existing_version) override; void Blocked(int64_t existing_version) override;
void UpgradeNeeded(blink::mojom::IDBDatabaseAssociatedPtrInfo database_info, void UpgradeNeeded(blink::mojom::IDBDatabaseAssociatedPtrInfo database_info,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_metadata.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_metadata.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_name_and_version.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h"
#include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/public/web/web_heap.h"
...@@ -30,6 +31,8 @@ class MockWebIDBCallbacks : public blink::WebIDBCallbacks { ...@@ -30,6 +31,8 @@ class MockWebIDBCallbacks : public blink::WebIDBCallbacks {
const blink::WebIDBKey& primaryKey, const blink::WebIDBKey& primaryKey,
const blink::WebIDBValue& value)); const blink::WebIDBValue& value));
MOCK_METHOD1(OnSuccess,
void(const blink::WebVector<blink::WebIDBNameAndVersion>&));
MOCK_METHOD1(OnSuccess, void(const blink::WebVector<blink::WebString>&)); MOCK_METHOD1(OnSuccess, void(const blink::WebVector<blink::WebString>&));
void OnSuccess(blink::WebIDBCursor* cursor, void OnSuccess(blink::WebIDBCursor* cursor,
......
...@@ -29,6 +29,17 @@ WebIDBFactoryImpl::WebIDBFactoryImpl(IDBFactoryPtrInfo factory_info) ...@@ -29,6 +29,17 @@ WebIDBFactoryImpl::WebIDBFactoryImpl(IDBFactoryPtrInfo factory_info)
WebIDBFactoryImpl::~WebIDBFactoryImpl() = default; WebIDBFactoryImpl::~WebIDBFactoryImpl() = default;
void WebIDBFactoryImpl::GetDatabaseInfo(
WebIDBCallbacks* callbacks,
const WebSecurityOrigin& origin,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), IndexedDBCallbacksImpl::kNoTransaction,
nullptr);
factory_->GetDatabaseInfo(GetCallbacksProxy(std::move(callbacks_impl)),
url::Origin(origin));
}
void WebIDBFactoryImpl::GetDatabaseNames( void WebIDBFactoryImpl::GetDatabaseNames(
WebIDBCallbacks* callbacks, WebIDBCallbacks* callbacks,
const WebSecurityOrigin& origin, const WebSecurityOrigin& origin,
......
...@@ -27,6 +27,10 @@ class WebIDBFactoryImpl : public blink::WebIDBFactory { ...@@ -27,6 +27,10 @@ class WebIDBFactoryImpl : public blink::WebIDBFactory {
~WebIDBFactoryImpl() override; ~WebIDBFactoryImpl() override;
// See WebIDBFactory.h for documentation on these functions. // See WebIDBFactory.h for documentation on these functions.
void GetDatabaseInfo(
blink::WebIDBCallbacks* callbacks,
const blink::WebSecurityOrigin& origin,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
void GetDatabaseNames( void GetDatabaseNames(
blink::WebIDBCallbacks* callbacks, blink::WebIDBCallbacks* callbacks,
const blink::WebSecurityOrigin& origin, const blink::WebSecurityOrigin& origin,
......
// META: script=support.js
async_test( async function(t) {
let made_database_check = t.step_func(async function() {
let idb_databases_promise = await indexedDB.databases();
assert_true(
idb_databases_promise.some(
e => e.name == "TestDatabase" && e.version == 1),
"Call to databases() did not find database.");
t.done();
});
delete_then_open(t, "TestDatabase", ()=>{}, made_database_check);
}, "Report one database test.");
async_test( function(t) {
let done_making_databases_callback = t.step_func(async function() {
let idb_databases_promise = await indexedDB.databases();
assert_true(
idb_databases_promise.some(
e => e.name == "TestDatabase1" && e.version == 1),
"Call to databases() did not find database.");
assert_true(
idb_databases_promise.some(
e => e.name == "TestDatabase2" && e.version == 1),
"Call to databases() did not find database.");
assert_true(
idb_databases_promise.some(
e => e.name == "TestDatabase3" && e.version == 1),
"Call to databases() did not find database.");
t.done();
});
let make_databases_barrier = create_barrier(done_making_databases_callback);
delete_then_open(t, "TestDatabase1", ()=>{}, make_databases_barrier(t));
delete_then_open(t, "TestDatabase2", ()=>{}, make_databases_barrier(t));
delete_then_open(t, "TestDatabase3", ()=>{}, make_databases_barrier(t));
}, "Report multiple databases test.");
async_test( function(t) {
let delete_request = indexedDB.deleteDatabase("NonExistentDatabase");
delete_request.onsuccess = t.step_func(async function() {
let idb_databases_promise = await indexedDB.databases();
assert_false(
idb_databases_promise.some(
e => e.name == "NonExistentDatabase"),
"Call to databases() found excluded database.");
t.done();
});
}, "Don't report nonexistant databases test.");
done();
...@@ -192,3 +192,49 @@ function keep_alive(tx, store_name) { ...@@ -192,3 +192,49 @@ function keep_alive(tx, store_name) {
pin = false; pin = false;
}; };
} }
/**
* Ensures that indexeddb database specified by db_name is deleted, and then
* opens a connection to that database.
*
* @param t: the testing script state
* @param db_name: name of database to delete then create
* @param upgrade_func: function to be called if db_name needs upgrading
* @param body_func: function to be called upon successful deletion
* and creation of db_name
*/
function delete_then_open(t, db_name, upgrade_func, body_func) {
var delete_request = indexedDB.deleteDatabase(db_name);
delete_request.onerror = t.unreached_func('deleteDatabase should not fail');
delete_request.onsuccess = t.step_func(function(e) {
var open_request = indexedDB.open(db_name);
open_request.onupgradeneeded = t.step_func(function() {
upgrade_func(t, open_request.result, open_request);
});
open_request.onsuccess = t.step_func(function() {
body_func(t, open_request.result);
});
});
}
/**
* Creates a barrier that one calls
*
* @param callback: function to be called after barrier is passed
*/
function create_barrier(callback) {
var count = 0;
var called = false;
return function(t) {
assert_false(called, "Barrier already used.");
++count;
return t.step_func(function() {
--count;
if (count === 0) {
assert_false(called, "Barrier already used.");
called = true;
callback();
}
});
}
}
...@@ -562,6 +562,7 @@ interface IDBFactory ...@@ -562,6 +562,7 @@ interface IDBFactory
attribute @@toStringTag attribute @@toStringTag
method cmp method cmp
method constructor method constructor
method databases
method deleteDatabase method deleteDatabase
method open method open
interface IDBIndex interface IDBIndex
......
...@@ -504,6 +504,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -504,6 +504,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] method cmp [Worker] method cmp
[Worker] method constructor [Worker] method constructor
[Worker] method databases
[Worker] method deleteDatabase [Worker] method deleteDatabase
[Worker] method open [Worker] method open
[Worker] interface IDBIndex [Worker] interface IDBIndex
......
...@@ -3891,6 +3891,7 @@ interface IDBFactory ...@@ -3891,6 +3891,7 @@ interface IDBFactory
attribute @@toStringTag attribute @@toStringTag
method cmp method cmp
method constructor method constructor
method databases
method deleteDatabase method deleteDatabase
method open method open
interface IDBIndex interface IDBIndex
......
...@@ -499,6 +499,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -499,6 +499,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] method cmp [Worker] method cmp
[Worker] method constructor [Worker] method constructor
[Worker] method databases
[Worker] method deleteDatabase [Worker] method deleteDatabase
[Worker] method open [Worker] method open
[Worker] interface IDBIndex [Worker] interface IDBIndex
......
...@@ -138,6 +138,7 @@ source_set("blink_headers") { ...@@ -138,6 +138,7 @@ source_set("blink_headers") {
"platform/modules/indexeddb/web_idb_key_path.h", "platform/modules/indexeddb/web_idb_key_path.h",
"platform/modules/indexeddb/web_idb_key_range.h", "platform/modules/indexeddb/web_idb_key_range.h",
"platform/modules/indexeddb/web_idb_metadata.h", "platform/modules/indexeddb/web_idb_metadata.h",
"platform/modules/indexeddb/web_idb_name_and_version.h",
"platform/modules/indexeddb/web_idb_observation.h", "platform/modules/indexeddb/web_idb_observation.h",
"platform/modules/indexeddb/web_idb_value.h", "platform/modules/indexeddb/web_idb_value.h",
"platform/modules/installedapp/web_related_application.h", "platform/modules/installedapp/web_related_application.h",
......
...@@ -131,6 +131,11 @@ struct IDBDatabaseMetadata { ...@@ -131,6 +131,11 @@ struct IDBDatabaseMetadata {
array<IDBObjectStoreMetadata> object_stores; array<IDBObjectStoreMetadata> object_stores;
}; };
struct IDBNameAndVersion {
mojo_base.mojom.String16 name;
int64 version;
};
struct IDBIndexKeys { struct IDBIndexKeys {
int64 index_id; int64 index_id;
array<IDBKey> index_keys; array<IDBKey> index_keys;
...@@ -188,6 +193,9 @@ struct IDBObserverChanges { ...@@ -188,6 +193,9 @@ struct IDBObserverChanges {
interface IDBCallbacks { interface IDBCallbacks {
Error(int32 code, mojo_base.mojom.String16 message); Error(int32 code, mojo_base.mojom.String16 message);
// Factory::GetDatabaseInfo
SuccessNamesAndVersionsList(array<IDBNameAndVersion> value);
// Factory::GetDatabaseNames // Factory::GetDatabaseNames
SuccessStringList(array<mojo_base.mojom.String16> value); SuccessStringList(array<mojo_base.mojom.String16> value);
...@@ -345,6 +353,7 @@ interface IDBDatabase { ...@@ -345,6 +353,7 @@ interface IDBDatabase {
}; };
interface IDBFactory { interface IDBFactory {
GetDatabaseInfo(associated IDBCallbacks callbacks, url.mojom.Origin origin);
GetDatabaseNames(associated IDBCallbacks callbacks, url.mojom.Origin origin); GetDatabaseNames(associated IDBCallbacks callbacks, url.mojom.Origin origin);
Open(associated IDBCallbacks callbacks, Open(associated IDBCallbacks callbacks,
associated IDBDatabaseCallbacks database_callbacks, associated IDBDatabaseCallbacks database_callbacks,
......
...@@ -37,6 +37,7 @@ class WebIDBDatabase; ...@@ -37,6 +37,7 @@ class WebIDBDatabase;
class WebIDBDatabaseError; class WebIDBDatabaseError;
class WebIDBKey; class WebIDBKey;
struct WebIDBMetadata; struct WebIDBMetadata;
struct WebIDBNameAndVersion;
class WebIDBValue; class WebIDBValue;
class WebIDBCallbacks { class WebIDBCallbacks {
...@@ -45,6 +46,7 @@ class WebIDBCallbacks { ...@@ -45,6 +46,7 @@ class WebIDBCallbacks {
// Pointers transfer ownership. // Pointers transfer ownership.
virtual void OnError(const WebIDBDatabaseError&) = 0; virtual void OnError(const WebIDBDatabaseError&) = 0;
virtual void OnSuccess(const WebVector<WebIDBNameAndVersion>&) = 0;
virtual void OnSuccess(const WebVector<WebString>&) = 0; virtual void OnSuccess(const WebVector<WebString>&) = 0;
virtual void OnSuccess(WebIDBCursor*, virtual void OnSuccess(WebIDBCursor*,
WebIDBKey, WebIDBKey,
......
...@@ -47,6 +47,9 @@ class WebIDBFactory { ...@@ -47,6 +47,9 @@ class WebIDBFactory {
public: public:
virtual ~WebIDBFactory() = default; virtual ~WebIDBFactory() = default;
virtual void GetDatabaseInfo(WebIDBCallbacks*,
const WebSecurityOrigin&,
scoped_refptr<base::SingleThreadTaskRunner>) = 0;
virtual void GetDatabaseNames( virtual void GetDatabaseNames(
WebIDBCallbacks*, WebIDBCallbacks*,
const WebSecurityOrigin&, const WebSecurityOrigin&,
......
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_NAME_AND_VERSION_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_NAME_AND_VERSION_H_
#include "third_party/blink/public/platform/web_string.h"
namespace blink {
struct WebIDBNameAndVersion {
enum { kNoVersion = -1 };
WebString name;
int64_t version;
WebIDBNameAndVersion() : version(kNoVersion) {}
WebIDBNameAndVersion(WebString name, int64_t version)
: name(name), version(version) {}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_NAME_AND_VERSION_H_
...@@ -267,6 +267,7 @@ jumbo_source_set("unit_tests") { ...@@ -267,6 +267,7 @@ jumbo_source_set("unit_tests") {
"eventsource/event_source_parser_test.cc", "eventsource/event_source_parser_test.cc",
"filesystem/dom_file_system_base_test.cc", "filesystem/dom_file_system_base_test.cc",
"filesystem/file_writer_test.cc", "filesystem/file_writer_test.cc",
"indexeddb/idb_factory_test.cc",
"indexeddb/idb_key_path_test.cc", "indexeddb/idb_key_path_test.cc",
"indexeddb/idb_request_test.cc", "indexeddb/idb_request_test.cc",
"indexeddb/idb_test_helper.cc", "indexeddb/idb_test_helper.cc",
...@@ -274,6 +275,8 @@ jumbo_source_set("unit_tests") { ...@@ -274,6 +275,8 @@ jumbo_source_set("unit_tests") {
"indexeddb/idb_value_wrapping_test.cc", "indexeddb/idb_value_wrapping_test.cc",
"indexeddb/mock_web_idb_database.cc", "indexeddb/mock_web_idb_database.cc",
"indexeddb/mock_web_idb_database.h", "indexeddb/mock_web_idb_database.h",
"indexeddb/mock_web_idb_factory.cc",
"indexeddb/mock_web_idb_factory.h",
"manifest/image_resource_type_converters_test.cc", "manifest/image_resource_type_converters_test.cc",
"media_controls/elements/media_control_animated_arrow_container_element_test.cc", "media_controls/elements/media_control_animated_arrow_container_element_test.cc",
"media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc", "media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc",
......
// Copyright 2018 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.
// Spec pull-request for addition:
// https://github.com/w3c/IndexedDB/pull/240/commits
dictionary IDBDatabaseInfo {
DOMString name;
unsigned long long version;
};
...@@ -29,32 +29,155 @@ ...@@ -29,32 +29,155 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_factory.h" #include "third_party/blink/renderer/modules/indexeddb/idb_factory.h"
#include <memory> #include <memory>
#include <utility>
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_callbacks.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_name_and_version.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/indexed_db_names.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_info.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_tracing.h" #include "third_party/blink/renderer/modules/indexeddb/idb_tracing.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db_client.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_client.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink { namespace blink {
namespace {
class WebIDBGetDBNamesCallbacksImpl : public WebIDBCallbacks {
public:
// static
static std::unique_ptr<WebIDBGetDBNamesCallbacksImpl> Create(
ScriptPromiseResolver* promise_resolver) {
return base::WrapUnique(
new WebIDBGetDBNamesCallbacksImpl(promise_resolver));
}
WebIDBGetDBNamesCallbacksImpl(ScriptPromiseResolver* promise_resolver)
: promise_resolver_(promise_resolver) {
probe::AsyncTaskScheduled(
ExecutionContext::From(promise_resolver_->GetScriptState()),
IndexedDBNames::IndexedDB, this);
}
~WebIDBGetDBNamesCallbacksImpl() override {
if (promise_resolver_) {
probe::AsyncTaskCanceled(
ExecutionContext::From(promise_resolver_->GetScriptState()), this);
promise_resolver_->Reject(
DOMException::Create(DOMExceptionCode::kUnknownError,
"An unexpected shutdown occured before the "
"databases() promise could be resolved"));
}
}
void OnError(const WebIDBDatabaseError& error) override {
if (!promise_resolver_)
return;
probe::AsyncTask async_task(
ExecutionContext::From(promise_resolver_->GetScriptState()), this,
"error");
promise_resolver_->Reject(
DOMException::Create(DOMExceptionCode::kUnknownError,
"The databases() promise was rejected."));
promise_resolver_.Clear();
}
void OnSuccess(const WebVector<WebIDBNameAndVersion>&
web_database_name_and_version_list) override {
if (!promise_resolver_)
return;
HeapVector<IDBDatabaseInfo> database_name_and_version_list;
for (size_t i = 0; i < web_database_name_and_version_list.size(); ++i) {
IDBDatabaseInfo idb_info;
idb_info.setName(web_database_name_and_version_list[i].name);
idb_info.setVersion(web_database_name_and_version_list[i].version);
database_name_and_version_list.push_back(idb_info);
}
probe::AsyncTask async_task(
ExecutionContext::From(promise_resolver_->GetScriptState()), this,
"success");
promise_resolver_->Resolve(database_name_and_version_list);
promise_resolver_.Clear();
}
void OnSuccess(const WebVector<WebString>&) override { NOTREACHED(); }
void OnSuccess(WebIDBCursor* cursor,
WebIDBKey key,
WebIDBKey primary_key,
WebIDBValue value) override {
NOTREACHED();
}
void OnSuccess(WebIDBDatabase* backend,
const WebIDBMetadata& metadata) override {
NOTREACHED();
}
void OnSuccess(WebIDBKey key) override { NOTREACHED(); }
void OnSuccess(WebIDBValue value) override { NOTREACHED(); }
void OnSuccess(WebVector<WebIDBValue> values) override { NOTREACHED(); }
void OnSuccess(long long value) override { NOTREACHED(); }
void OnSuccess() override { NOTREACHED(); }
void OnSuccess(WebIDBKey key,
WebIDBKey primary_key,
WebIDBValue value) override {
NOTREACHED();
}
void OnBlocked(long long old_version) override { NOTREACHED(); }
void OnUpgradeNeeded(long long old_version,
WebIDBDatabase* database,
const WebIDBMetadata& metadata,
unsigned short data_loss,
WebString data_loss_message) override {
NOTREACHED();
}
void Detach() override { NOTREACHED(); }
private:
Persistent<ScriptPromiseResolver> promise_resolver_;
};
} // namespace
static const char kPermissionDeniedErrorMessage[] = static const char kPermissionDeniedErrorMessage[] =
"The user denied permission to access the database."; "The user denied permission to access the database.";
IDBFactory::IDBFactory() = default; IDBFactory::IDBFactory() = default;
IDBFactory::IDBFactory(std::unique_ptr<WebIDBFactory> web_idb_factory)
: web_idb_factory_(std::move(web_idb_factory)) {}
static bool IsContextValid(ExecutionContext* context) { static bool IsContextValid(ExecutionContext* context) {
DCHECK(IsA<Document>(context) || context->IsWorkerGlobalScope()); DCHECK(IsA<Document>(context) || context->IsWorkerGlobalScope());
if (auto* document = DynamicTo<Document>(context)) if (auto* document = DynamicTo<Document>(context))
...@@ -68,6 +191,19 @@ WebIDBFactory* IDBFactory::GetFactory() { ...@@ -68,6 +191,19 @@ WebIDBFactory* IDBFactory::GetFactory() {
return web_idb_factory_.get(); return web_idb_factory_.get();
} }
ScriptPromise IDBFactory::GetDatabaseInfo(ScriptState* script_state,
ExceptionState& exception_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
GetFactory()->GetDatabaseInfo(
WebIDBGetDBNamesCallbacksImpl::Create(resolver).release(),
WebSecurityOrigin(
ExecutionContext::From(script_state)->GetSecurityOrigin()),
ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kInternalIndexedDB));
ScriptPromise promise = resolver->Promise();
return promise;
}
IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state, IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state,
ExceptionState& exception_state) { ExceptionState& exception_state) {
IDB_TRACE("IDBFactory::getDatabaseNamesRequestSetup"); IDB_TRACE("IDBFactory::getDatabaseNamesRequestSetup");
......
...@@ -25,11 +25,14 @@ ...@@ -25,11 +25,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h" #include "third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
...@@ -39,11 +42,15 @@ namespace blink { ...@@ -39,11 +42,15 @@ namespace blink {
class ExceptionState; class ExceptionState;
class ScriptState; class ScriptState;
class IDBFactory final : public ScriptWrappable { class MODULES_EXPORT IDBFactory final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
public: public:
static IDBFactory* Create() { return new IDBFactory(); } static IDBFactory* Create() { return new IDBFactory(); }
static IDBFactory* CreateForTest(
std::unique_ptr<WebIDBFactory> web_idb_factory) {
return new IDBFactory(std::move(web_idb_factory));
}
// Implement the IDBFactory IDL // Implement the IDBFactory IDL
IDBOpenDBRequest* open(ScriptState*, const String& name, ExceptionState&); IDBOpenDBRequest* open(ScriptState*, const String& name, ExceptionState&);
...@@ -65,8 +72,11 @@ class IDBFactory final : public ScriptWrappable { ...@@ -65,8 +72,11 @@ class IDBFactory final : public ScriptWrappable {
const String& name, const String& name,
ExceptionState&); ExceptionState&);
ScriptPromise GetDatabaseInfo(ScriptState*, ExceptionState&);
private: private:
IDBFactory(); IDBFactory();
IDBFactory(std::unique_ptr<WebIDBFactory>);
WebIDBFactory* GetFactory(); WebIDBFactory* GetFactory();
......
...@@ -29,13 +29,19 @@ ...@@ -29,13 +29,19 @@
Exposed=(Window,Worker) Exposed=(Window,Worker)
] interface IDBFactory { ] interface IDBFactory {
[ [
NewObject, NewObject,
CallWith=ScriptState, CallWith=ScriptState,
Measure, Measure,
RaisesException RaisesException
] IDBOpenDBRequest open(DOMString name, ] IDBOpenDBRequest open(DOMString name,
optional [EnforceRange] unsigned long long version); optional [EnforceRange] unsigned long long version);
[NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name); [NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name);
[CallWith=ScriptState, RaisesException] short cmp(any first, any second); [CallWith=ScriptState, RaisesException] short cmp(any first, any second);
[
CallWith=ScriptState,
ImplementedAs=GetDatabaseInfo,
RaisesException,
RuntimeEnabled=IDBGetDatabases
] Promise<sequence<IDBDatabaseInfo>> databases();
}; };
// Copyright 2018 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 "third_party/blink/renderer/modules/indexeddb/idb_factory.h"
#include <memory>
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_name_and_version.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
namespace {
class TestHelperFunction : public ScriptFunction {
public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
bool* called_flag) {
auto* self = new TestHelperFunction(script_state, called_flag);
return self->BindToV8Function();
}
private:
TestHelperFunction(ScriptState* script_state, bool* called_flag)
: ScriptFunction(script_state), called_flag_(called_flag) {}
ScriptValue Call(ScriptValue value) override {
*called_flag_ = true;
return value;
}
bool* called_flag_;
};
class IDBFactoryTest : public testing::Test {
protected:
IDBFactoryTest() {}
~IDBFactoryTest() override {}
};
ACTION_TEMPLATE(SaveUniquePointer,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(unique_pointer)) {
*unique_pointer = base::WrapUnique(std::get<k>(args));
}
TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksResolvesPromise) {
V8TestingScope scope;
std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create();
std::unique_ptr<WebIDBCallbacks> wc;
EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_))
.Times(1)
.WillOnce(SaveUniquePointer<0>(&wc));
IDBFactory* factory = IDBFactory::CreateForTest(std::move(web_factory));
DummyExceptionStateForTesting exception_state;
ScriptPromise promise =
factory->GetDatabaseInfo(scope.GetScriptState(), exception_state);
bool on_fulfilled = false;
bool on_rejected = false;
promise.Then(
TestHelperFunction::CreateFunction(scope.GetScriptState(), &on_fulfilled),
TestHelperFunction::CreateFunction(scope.GetScriptState(), &on_rejected));
EXPECT_FALSE(on_fulfilled);
EXPECT_FALSE(on_rejected);
const WebVector<WebIDBNameAndVersion> wv;
wc->OnSuccess(wv);
EXPECT_FALSE(on_fulfilled);
EXPECT_FALSE(on_rejected);
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
EXPECT_TRUE(on_fulfilled);
EXPECT_FALSE(on_rejected);
}
TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksRejectsPromise) {
V8TestingScope scope;
std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create();
std::unique_ptr<WebIDBCallbacks> wc;
EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_))
.Times(1)
.WillOnce(SaveUniquePointer<0>(&wc));
IDBFactory* factory = IDBFactory::CreateForTest(std::move(web_factory));
DummyExceptionStateForTesting exception_state;
ScriptPromise promise =
factory->GetDatabaseInfo(scope.GetScriptState(), exception_state);
bool on_fulfilled = false;
bool on_rejected = false;
promise.Then(
TestHelperFunction::CreateFunction(scope.GetScriptState(), &on_fulfilled),
TestHelperFunction::CreateFunction(scope.GetScriptState(), &on_rejected));
EXPECT_FALSE(on_fulfilled);
EXPECT_FALSE(on_rejected);
const WebVector<WebIDBNameAndVersion> wv;
wc->OnError(WebIDBDatabaseError(1));
EXPECT_FALSE(on_fulfilled);
EXPECT_FALSE(on_rejected);
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
EXPECT_FALSE(on_fulfilled);
EXPECT_TRUE(on_rejected);
}
} // namespace
} // namespace blink
// Copyright 2018 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 "third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h"
#include <memory>
#include "base/memory/ptr_util.h"
namespace blink {
MockWebIDBFactory::MockWebIDBFactory() = default;
MockWebIDBFactory::~MockWebIDBFactory() = default;
std::unique_ptr<MockWebIDBFactory> MockWebIDBFactory::Create() {
return base::WrapUnique(new MockWebIDBFactory());
}
} // namespace blink
// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_MOCK_WEB_IDB_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_MOCK_WEB_IDB_FACTORY_H_
#include <gmock/gmock.h>
#include <memory>
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_security_origin.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace blink {
class WebIDBCallbacks;
class WebIDBDatabaseCallbacks;
class WebSecurityOrigin;
class WebString;
class MockWebIDBFactory : public testing::StrictMock<blink::WebIDBFactory> {
public:
~MockWebIDBFactory() override;
static std::unique_ptr<MockWebIDBFactory> Create();
MOCK_METHOD3(GetDatabaseInfo,
void(WebIDBCallbacks*,
const WebSecurityOrigin&,
scoped_refptr<base::SingleThreadTaskRunner>));
MOCK_METHOD3(GetDatabaseNames,
void(WebIDBCallbacks*,
const WebSecurityOrigin&,
scoped_refptr<base::SingleThreadTaskRunner>));
MOCK_METHOD7(Open,
void(const WebString& name,
long long version,
long long transaction_id,
WebIDBCallbacks*,
WebIDBDatabaseCallbacks*,
const WebSecurityOrigin&,
scoped_refptr<base::SingleThreadTaskRunner>));
MOCK_METHOD5(DeleteDatabase,
void(const WebString& name,
WebIDBCallbacks*,
const WebSecurityOrigin&,
bool force_close,
scoped_refptr<base::SingleThreadTaskRunner>));
private:
MockWebIDBFactory();
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_MOCK_WEB_IDB_FACTORY_H_
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_error.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_name_and_version.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/probe/core_probes.h"
...@@ -51,6 +52,7 @@ using blink::WebIDBDatabaseError; ...@@ -51,6 +52,7 @@ using blink::WebIDBDatabaseError;
using blink::WebIDBKey; using blink::WebIDBKey;
using blink::WebIDBKeyPath; using blink::WebIDBKeyPath;
using blink::WebIDBMetadata; using blink::WebIDBMetadata;
using blink::WebIDBNameAndVersion;
using blink::WebIDBValue; using blink::WebIDBValue;
using blink::WebVector; using blink::WebVector;
...@@ -87,6 +89,12 @@ void WebIDBCallbacksImpl::OnError(const WebIDBDatabaseError& error) { ...@@ -87,6 +89,12 @@ void WebIDBCallbacksImpl::OnError(const WebIDBDatabaseError& error) {
static_cast<DOMExceptionCode>(error.Code()), error.Message())); static_cast<DOMExceptionCode>(error.Code()), error.Message()));
} }
void WebIDBCallbacksImpl::OnSuccess(
const WebVector<WebIDBNameAndVersion>& web_name_and_version_list) {
// Only implemented in idb_factory.cc for the promise-based databases() call.
NOTREACHED();
}
void WebIDBCallbacksImpl::OnSuccess( void WebIDBCallbacksImpl::OnSuccess(
const WebVector<WebString>& web_string_list) { const WebVector<WebString>& web_string_list) {
if (!request_) if (!request_)
......
...@@ -43,6 +43,7 @@ class WebIDBDatabase; ...@@ -43,6 +43,7 @@ class WebIDBDatabase;
class WebIDBDatabaseError; class WebIDBDatabaseError;
class WebIDBKey; class WebIDBKey;
struct WebIDBMetadata; struct WebIDBMetadata;
struct WebIDBNameAndVersion;
class WebIDBValue; class WebIDBValue;
class WebIDBCallbacksImpl final : public WebIDBCallbacks { class WebIDBCallbacksImpl final : public WebIDBCallbacks {
...@@ -55,6 +56,7 @@ class WebIDBCallbacksImpl final : public WebIDBCallbacks { ...@@ -55,6 +56,7 @@ class WebIDBCallbacksImpl final : public WebIDBCallbacks {
// Pointers transfer ownership. // Pointers transfer ownership.
void OnError(const WebIDBDatabaseError&) override; void OnError(const WebIDBDatabaseError&) override;
void OnSuccess(const WebVector<WebIDBNameAndVersion>&) override;
void OnSuccess(const WebVector<WebString>&) override; void OnSuccess(const WebVector<WebString>&) override;
void OnSuccess(WebIDBCursor*, void OnSuccess(WebIDBCursor*,
WebIDBKey, WebIDBKey,
......
...@@ -541,6 +541,7 @@ modules_dictionary_idl_files = ...@@ -541,6 +541,7 @@ modules_dictionary_idl_files =
"imagecapture/constrain_point_2d_parameters.idl", "imagecapture/constrain_point_2d_parameters.idl",
"imagecapture/photo_settings.idl", "imagecapture/photo_settings.idl",
"imagecapture/point_2d.idl", "imagecapture/point_2d.idl",
"indexeddb/idb_database_info.idl",
"indexeddb/idb_index_parameters.idl", "indexeddb/idb_index_parameters.idl",
"indexeddb/idb_object_store_parameters.idl", "indexeddb/idb_object_store_parameters.idl",
"indexeddb/idb_observer_init.idl", "indexeddb/idb_observer_init.idl",
......
...@@ -584,6 +584,10 @@ ...@@ -584,6 +584,10 @@
name: "HTMLImportsStyleApplication", name: "HTMLImportsStyleApplication",
status: "stable", status: "stable",
}, },
{
name: "IDBGetDatabases",
status: "experimental",
},
{ {
name: "IDBObserver", name: "IDBObserver",
status: "experimental", status: "experimental",
......
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