Modified: trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp (200201 => 200202)
--- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp 2016-04-28 18:41:50 UTC (rev 200201)
+++ trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp 2016-04-28 18:47:20 UTC (rev 200202)
@@ -96,7 +96,7 @@
: m_context(context) { }
virtual ~ExecutableWithDatabase() { };
void start(IDBFactory*, SecurityOrigin*, const String& databaseName);
- virtual void execute() = 0;
+ virtual void execute(IDBDatabase&) = 0;
virtual RequestCallback& requestCallback() = 0;
ScriptExecutionContext* context() { return m_context; };
private:
@@ -135,9 +135,8 @@
return;
}
- // FIXME (webkit.org/b/154686) - Reimplement this.
- m_executableWithDatabase->requestCallback().sendFailure("Modern IDB is not supported yet");
- return;
+ m_executableWithDatabase->execute(*databaseResult);
+ databaseResult->close();
}
private:
@@ -165,6 +164,67 @@
idbOpenDBRequest->addEventListener(eventNames().successEvent, WTFMove(callback), false);
}
+
+static RefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath)
+{
+ RefPtr<KeyPath> keyPath;
+ switch (idbKeyPath.type()) {
+ case IndexedDB::KeyPathType::Null:
+ keyPath = KeyPath::create()
+ .setType(KeyPath::Type::Null)
+ .release();
+ break;
+ case IndexedDB::KeyPathType::String:
+ keyPath = KeyPath::create()
+ .setType(KeyPath::Type::String)
+ .release();
+ keyPath->setString(idbKeyPath.string());
+
+ break;
+ case IndexedDB::KeyPathType::Array: {
+ auto array = Inspector::Protocol::Array<String>::create();
+ for (auto& string : idbKeyPath.array())
+ array->addItem(string);
+ keyPath = KeyPath::create()
+ .setType(KeyPath::Type::Array)
+ .release();
+ keyPath->setArray(WTFMove(array));
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return keyPath;
+}
+
+static RefPtr<IDBTransaction> transactionForDatabase(ScriptExecutionContext* scriptExecutionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly())
+{
+ ExceptionCodeWithMessage ec;
+ RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(scriptExecutionContext, objectStoreName, mode, ec);
+ if (ec.code)
+ return nullptr;
+ return idbTransaction;
+}
+
+static RefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName)
+{
+ ExceptionCodeWithMessage ec;
+ RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectStoreName, ec);
+ if (ec.code)
+ return nullptr;
+ return idbObjectStore;
+}
+
+static RefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName)
+{
+ ExceptionCodeWithMessage ec;
+ RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, ec);
+ if (ec.code)
+ return nullptr;
+ return idbIndex;
+}
+
class DatabaseLoader : public ExecutableWithDatabase {
public:
static Ref<DatabaseLoader> create(ScriptExecutionContext* context, Ref<RequestDatabaseCallback>&& requestCallback)
@@ -174,12 +234,48 @@
virtual ~DatabaseLoader() { }
- void execute() override
+ void execute(IDBDatabase& database) override
{
if (!requestCallback().isActive())
return;
+
+ auto& databaseInfo = database.info();
+ auto objectStores = Inspector::Protocol::Array<Inspector::Protocol::IndexedDB::ObjectStore>::create();
+ auto objectStoreNames = databaseInfo.objectStoreNames();
+ for (auto& name : objectStoreNames) {
+ auto* objectStoreInfo = databaseInfo.infoForExistingObjectStore(name);
+ if (!objectStoreInfo)
+ continue;
- // FIXME (webkit.org/b/154686) - Reimplement this.
+ auto indexes = Inspector::Protocol::Array<Inspector::Protocol::IndexedDB::ObjectStoreIndex>::create();
+
+ for (auto& indexInfo : objectStoreInfo->indexMap().values()) {
+ Ref<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
+ .setName(indexInfo.name())
+ .setKeyPath(keyPathFromIDBKeyPath(indexInfo.keyPath()))
+ .setUnique(indexInfo.unique())
+ .setMultiEntry(indexInfo.multiEntry())
+ .release();
+ indexes->addItem(WTFMove(objectStoreIndex));
+ }
+
+ Ref<ObjectStore> objectStore = ObjectStore::create()
+ .setName(objectStoreInfo->name())
+ .setKeyPath(keyPathFromIDBKeyPath(objectStoreInfo->keyPath()))
+ .setAutoIncrement(objectStoreInfo->autoIncrement())
+ .setIndexes(WTFMove(indexes))
+ .release();
+
+ objectStores->addItem(WTFMove(objectStore));
+ }
+
+ Ref<DatabaseWithObjectStores> result = DatabaseWithObjectStores::create()
+ .setName(databaseInfo.name())
+ .setVersion(databaseInfo.version())
+ .setObjectStores(WTFMove(objectStores))
+ .release();
+
+ m_requestCallback->sendSuccess(WTFMove(result));
}
RequestCallback& requestCallback() override { return m_requestCallback.get(); }
@@ -372,12 +468,42 @@
virtual ~DataLoader() { }
- void execute() override
+ void execute(IDBDatabase& database) override
{
if (!requestCallback().isActive())
return;
+ RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), &database, m_objectStoreName);
+ if (!idbTransaction) {
+ m_requestCallback->sendFailure("Could not get transaction");
+ return;
+ }
+ RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
+ if (!idbObjectStore) {
+ m_requestCallback->sendFailure("Could not get object store");
+ return;
+ }
- // FIXME (webkit.org/b/154686) - Reimplement this.
+ Ref<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback.copyRef(), 0, m_pageSize);
+
+ ExceptionCodeWithMessage ec;
+ RefPtr<IDBRequest> idbRequest;
+ if (!m_indexName.isEmpty()) {
+ RefPtr<IDBIndex> idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName);
+ if (!idbIndex) {
+ m_requestCallback->sendFailure("Could not get index");
+ return;
+ }
+
+ idbRequest = idbIndex->openCursor(*context(), m_idbKeyRange.get(), IDBCursor::directionNext(), ec);
+ } else
+ idbRequest = idbObjectStore->openCursor(*context(), m_idbKeyRange.get(), IDBCursor::directionNext(), ec);
+
+ if (!idbRequest) {
+ m_requestCallback->sendFailure("Could not open cursor to populate database data");
+ return;
+ }
+
+ idbRequest->addEventListener(eventNames().successEvent, WTFMove(openCursorCallback), false);
}
RequestCallback& requestCallback() override { return m_requestCallback.get(); }
@@ -560,7 +686,6 @@
Ref<ClearObjectStoreCallback> m_requestCallback;
};
-
class ClearObjectStore : public ExecutableWithDatabase {
public:
static Ref<ClearObjectStore> create(ScriptExecutionContext* context, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& requestCallback)
@@ -575,12 +700,30 @@
{
}
- void execute() override
+ void execute(IDBDatabase& database) override
{
if (!requestCallback().isActive())
return;
- // FIXME (webkit.org/b/154686) - Reimplement this.
+ RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), &database, m_objectStoreName);
+ if (!idbTransaction) {
+ m_requestCallback->sendFailure("Could not get transaction");
+ return;
+ }
+ RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
+ if (!idbObjectStore) {
+ m_requestCallback->sendFailure("Could not get object store");
+ return;
+ }
+
+ ExceptionCodeWithMessage ec;
+ RefPtr<IDBRequest> idbRequest = idbObjectStore->clear(*context(), ec);
+ ASSERT(!ec.code);
+ if (ec.code) {
+ m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), ec.code));
+ return;
+ }
+ idbTransaction->addEventListener(eventNames().completeEvent, ClearObjectStoreListener::create(m_requestCallback.copyRef()), false);
}
RequestCallback& requestCallback() override { return m_requestCallback.get(); }