123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- /*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "config.h"
- #if ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE)
- #include "InspectorIndexedDBAgent.h"
- #include "DOMStringList.h"
- #include "DOMWindow.h"
- #include "DOMWindowIndexedDatabase.h"
- #include "Document.h"
- #include "Event.h"
- #include "EventListener.h"
- #include "EventTarget.h"
- #include "ExceptionCode.h"
- #include "Frame.h"
- #include "IDBCursor.h"
- #include "IDBCursorWithValue.h"
- #include "IDBDatabase.h"
- #include "IDBDatabaseCallbacks.h"
- #include "IDBFactory.h"
- #include "IDBIndex.h"
- #include "IDBKey.h"
- #include "IDBKeyPath.h"
- #include "IDBKeyRange.h"
- #include "IDBMetadata.h"
- #include "IDBObjectStore.h"
- #include "IDBOpenDBRequest.h"
- #include "IDBPendingTransactionMonitor.h"
- #include "IDBRequest.h"
- #include "IDBTransaction.h"
- #include "InjectedScript.h"
- #include "InspectorFrontend.h"
- #include "InspectorPageAgent.h"
- #include "InspectorState.h"
- #include "InspectorValues.h"
- #include "InstrumentingAgents.h"
- #include "SecurityOrigin.h"
- #include <wtf/Vector.h>
- using WebCore::TypeBuilder::Array;
- using WebCore::TypeBuilder::IndexedDB::DatabaseWithObjectStores;
- using WebCore::TypeBuilder::IndexedDB::DataEntry;
- using WebCore::TypeBuilder::IndexedDB::Key;
- using WebCore::TypeBuilder::IndexedDB::KeyPath;
- using WebCore::TypeBuilder::IndexedDB::KeyRange;
- using WebCore::TypeBuilder::IndexedDB::ObjectStore;
- using WebCore::TypeBuilder::IndexedDB::ObjectStoreIndex;
- typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDatabaseNamesCallback RequestDatabaseNamesCallback;
- typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDatabaseCallback RequestDatabaseCallback;
- typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDataCallback RequestDataCallback;
- typedef WebCore::InspectorBackendDispatcher::CallbackBase RequestCallback;
- typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::ClearObjectStoreCallback ClearObjectStoreCallback;
- namespace WebCore {
- namespace IndexedDBAgentState {
- static const char indexedDBAgentEnabled[] = "indexedDBAgentEnabled";
- };
- namespace {
- class GetDatabaseNamesCallback : public EventListener {
- WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback);
- public:
- static PassRefPtr<GetDatabaseNamesCallback> create(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin)
- {
- return adoptRef(new GetDatabaseNamesCallback(requestCallback, securityOrigin));
- }
- virtual ~GetDatabaseNamesCallback() { }
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
- virtual void handleEvent(ScriptExecutionContext*, Event* event) OVERRIDE
- {
- if (!m_requestCallback->isActive())
- return;
- if (event->type() != eventNames().successEvent) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
- IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
- ExceptionCode ec = 0;
- RefPtr<IDBAny> requestResult = idbRequest->result(ec);
- if (ec) {
- m_requestCallback->sendFailure("Could not get result in callback.");
- return;
- }
- if (requestResult->type() != IDBAny::DOMStringListType) {
- m_requestCallback->sendFailure("Unexpected result type.");
- return;
- }
- RefPtr<DOMStringList> databaseNamesList = requestResult->domStringList();
- RefPtr<TypeBuilder::Array<String> > databaseNames = TypeBuilder::Array<String>::create();
- for (size_t i = 0; i < databaseNamesList->length(); ++i)
- databaseNames->addItem(databaseNamesList->item(i));
- m_requestCallback->sendSuccess(databaseNames.release());
- }
- private:
- GetDatabaseNamesCallback(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin)
- : EventListener(EventListener::CPPEventListenerType)
- , m_requestCallback(requestCallback)
- , m_securityOrigin(securityOrigin) { }
- RefPtr<RequestDatabaseNamesCallback> m_requestCallback;
- String m_securityOrigin;
- };
- class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> {
- public:
- ExecutableWithDatabase(ScriptExecutionContext* context)
- : m_context(context) { }
- virtual ~ExecutableWithDatabase() { };
- void start(IDBFactory*, SecurityOrigin*, const String& databaseName);
- virtual void execute(PassRefPtr<IDBDatabase>) = 0;
- virtual RequestCallback* requestCallback() = 0;
- ScriptExecutionContext* context() { return m_context; };
- private:
- ScriptExecutionContext* m_context;
- };
- class OpenDatabaseCallback : public EventListener {
- public:
- static PassRefPtr<OpenDatabaseCallback> create(ExecutableWithDatabase* executableWithDatabase)
- {
- return adoptRef(new OpenDatabaseCallback(executableWithDatabase));
- }
- virtual ~OpenDatabaseCallback() { }
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
- virtual void handleEvent(ScriptExecutionContext*, Event* event) OVERRIDE
- {
- if (event->type() != eventNames().successEvent) {
- m_executableWithDatabase->requestCallback()->sendFailure("Unexpected event type.");
- return;
- }
- IDBOpenDBRequest* idbOpenDBRequest = static_cast<IDBOpenDBRequest*>(event->target());
- ExceptionCode ec = 0;
- RefPtr<IDBAny> requestResult = idbOpenDBRequest->result(ec);
- if (ec) {
- m_executableWithDatabase->requestCallback()->sendFailure("Could not get result in callback.");
- return;
- }
- if (requestResult->type() != IDBAny::IDBDatabaseType) {
- m_executableWithDatabase->requestCallback()->sendFailure("Unexpected result type.");
- return;
- }
- RefPtr<IDBDatabase> idbDatabase = requestResult->idbDatabase();
- m_executableWithDatabase->execute(idbDatabase);
- IDBPendingTransactionMonitor::deactivateNewTransactions();
- idbDatabase->close();
- }
- private:
- OpenDatabaseCallback(ExecutableWithDatabase* executableWithDatabase)
- : EventListener(EventListener::CPPEventListenerType)
- , m_executableWithDatabase(executableWithDatabase) { }
- RefPtr<ExecutableWithDatabase> m_executableWithDatabase;
- };
- void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, const String& databaseName)
- {
- RefPtr<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this);
- ExceptionCode ec = 0;
- RefPtr<IDBOpenDBRequest> idbOpenDBRequest = idbFactory->open(context(), databaseName, ec);
- if (ec) {
- requestCallback()->sendFailure("Could not open database.");
- return;
- }
- idbOpenDBRequest->addEventListener(eventNames().successEvent, callback, false);
- }
- static PassRefPtr<IDBTransaction> transactionForDatabase(ScriptExecutionContext* scriptExecutionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly())
- {
- ExceptionCode ec = 0;
- RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(scriptExecutionContext, objectStoreName, mode, ec);
- if (ec)
- return 0;
- return idbTransaction;
- }
- static PassRefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName)
- {
- ExceptionCode ec = 0;
- RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectStoreName, ec);
- if (ec)
- return 0;
- return idbObjectStore;
- }
- static PassRefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName)
- {
- ExceptionCode ec = 0;
- RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, ec);
- if (ec)
- return 0;
- return idbIndex;
- }
- static PassRefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath)
- {
- RefPtr<KeyPath> keyPath;
- switch (idbKeyPath.type()) {
- case IDBKeyPath::NullType:
- keyPath = KeyPath::create().setType(KeyPath::Type::Null);
- break;
- case IDBKeyPath::StringType:
- keyPath = KeyPath::create().setType(KeyPath::Type::String);
- keyPath->setString(idbKeyPath.string());
- break;
- case IDBKeyPath::ArrayType: {
- keyPath = KeyPath::create().setType(KeyPath::Type::Array);
- RefPtr<TypeBuilder::Array<String> > array = TypeBuilder::Array<String>::create();
- const Vector<String>& stringArray = idbKeyPath.array();
- for (size_t i = 0; i < stringArray.size(); ++i)
- array->addItem(stringArray[i]);
- keyPath->setArray(array);
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- return keyPath.release();
- }
- class DatabaseLoader : public ExecutableWithDatabase {
- public:
- static PassRefPtr<DatabaseLoader> create(ScriptExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback)
- {
- return adoptRef(new DatabaseLoader(context, requestCallback));
- }
- virtual ~DatabaseLoader() { }
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
- const IDBDatabaseMetadata databaseMetadata = idbDatabase->metadata();
- RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore> > objectStores = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore>::create();
- for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = databaseMetadata.objectStores.begin(); it != databaseMetadata.objectStores.end(); ++it) {
- const IDBObjectStoreMetadata& objectStoreMetadata = it->value;
- RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex> > indexes = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex>::create();
- for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectStoreMetadata.indexes.begin(); it != objectStoreMetadata.indexes.end(); ++it) {
- const IDBIndexMetadata& indexMetadata = it->value;
- RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
- .setName(indexMetadata.name)
- .setKeyPath(keyPathFromIDBKeyPath(indexMetadata.keyPath))
- .setUnique(indexMetadata.unique)
- .setMultiEntry(indexMetadata.multiEntry);
- indexes->addItem(objectStoreIndex);
- }
- RefPtr<ObjectStore> objectStore = ObjectStore::create()
- .setName(objectStoreMetadata.name)
- .setKeyPath(keyPathFromIDBKeyPath(objectStoreMetadata.keyPath))
- .setAutoIncrement(objectStoreMetadata.autoIncrement)
- .setIndexes(indexes);
- objectStores->addItem(objectStore);
- }
- RefPtr<DatabaseWithObjectStores> result = DatabaseWithObjectStores::create()
- .setName(databaseMetadata.name)
- .setIntVersion(databaseMetadata.intVersion)
- .setVersion(databaseMetadata.version)
- .setObjectStores(objectStores);
- m_requestCallback->sendSuccess(result);
- }
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
- private:
- DatabaseLoader(ScriptExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback)
- : ExecutableWithDatabase(context)
- , m_requestCallback(requestCallback) { }
- RefPtr<RequestDatabaseCallback> m_requestCallback;
- };
- static PassRefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key)
- {
- RefPtr<IDBKey> idbKey;
- String type;
- if (!key->getString("type", &type))
- return 0;
- DEFINE_STATIC_LOCAL(String, number, (ASCIILiteral("number")));
- DEFINE_STATIC_LOCAL(String, string, (ASCIILiteral("string")));
- DEFINE_STATIC_LOCAL(String, date, (ASCIILiteral("date")));
- DEFINE_STATIC_LOCAL(String, array, (ASCIILiteral("array")));
- if (type == number) {
- double number;
- if (!key->getNumber("number", &number))
- return 0;
- idbKey = IDBKey::createNumber(number);
- } else if (type == string) {
- String string;
- if (!key->getString("string", &string))
- return 0;
- idbKey = IDBKey::createString(string);
- } else if (type == date) {
- double date;
- if (!key->getNumber("date", &date))
- return 0;
- idbKey = IDBKey::createDate(date);
- } else if (type == array) {
- IDBKey::KeyArray keyArray;
- RefPtr<InspectorArray> array = key->getArray("array");
- for (size_t i = 0; i < array->length(); ++i) {
- RefPtr<InspectorValue> value = array->get(i);
- RefPtr<InspectorObject> object;
- if (!value->asObject(&object))
- return 0;
- keyArray.append(idbKeyFromInspectorObject(object.get()));
- }
- idbKey = IDBKey::createArray(keyArray);
- } else
- return 0;
- return idbKey.release();
- }
- static PassRefPtr<IDBKeyRange> idbKeyRangeFromKeyRange(InspectorObject* keyRange)
- {
- RefPtr<InspectorObject> lower = keyRange->getObject("lower");
- RefPtr<IDBKey> idbLower = lower ? idbKeyFromInspectorObject(lower.get()) : 0;
- if (lower && !idbLower)
- return 0;
- RefPtr<InspectorObject> upper = keyRange->getObject("upper");
- RefPtr<IDBKey> idbUpper = upper ? idbKeyFromInspectorObject(upper.get()) : 0;
- if (upper && !idbUpper)
- return 0;
- bool lowerOpen;
- if (!keyRange->getBoolean("lowerOpen", &lowerOpen))
- return 0;
- IDBKeyRange::LowerBoundType lowerBoundType = lowerOpen ? IDBKeyRange::LowerBoundOpen : IDBKeyRange::LowerBoundClosed;
- bool upperOpen;
- if (!keyRange->getBoolean("upperOpen", &upperOpen))
- return 0;
- IDBKeyRange::UpperBoundType upperBoundType = upperOpen ? IDBKeyRange::UpperBoundOpen : IDBKeyRange::UpperBoundClosed;
- RefPtr<IDBKeyRange> idbKeyRange = IDBKeyRange::create(idbLower, idbUpper, lowerBoundType, upperBoundType);
- return idbKeyRange.release();
- }
- class DataLoader;
- class OpenCursorCallback : public EventListener {
- public:
- static PassRefPtr<OpenCursorCallback> create(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize)
- {
- return adoptRef(new OpenCursorCallback(injectedScript, requestCallback, skipCount, pageSize));
- }
- virtual ~OpenCursorCallback() { }
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
- virtual void handleEvent(ScriptExecutionContext*, Event* event) OVERRIDE
- {
- if (event->type() != eventNames().successEvent) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
- IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
- ExceptionCode ec = 0;
- RefPtr<IDBAny> requestResult = idbRequest->result(ec);
- if (ec) {
- m_requestCallback->sendFailure("Could not get result in callback.");
- return;
- }
- if (requestResult->type() == IDBAny::ScriptValueType) {
- end(false);
- return;
- }
- if (requestResult->type() != IDBAny::IDBCursorWithValueType) {
- m_requestCallback->sendFailure("Unexpected result type.");
- return;
- }
- RefPtr<IDBCursorWithValue> idbCursor = requestResult->idbCursorWithValue();
- if (m_skipCount) {
- ExceptionCode ec = 0;
- idbCursor->advance(m_skipCount, ec);
- if (ec)
- m_requestCallback->sendFailure("Could not advance cursor.");
- m_skipCount = 0;
- return;
- }
- if (m_result->length() == m_pageSize) {
- end(true);
- return;
- }
- // Continue cursor before making injected script calls, otherwise transaction might be finished.
- idbCursor->continueFunction(0, ec);
- if (ec) {
- m_requestCallback->sendFailure("Could not continue cursor.");
- return;
- }
- RefPtr<DataEntry> dataEntry = DataEntry::create()
- .setKey(m_injectedScript.wrapObject(idbCursor->key(), String()))
- .setPrimaryKey(m_injectedScript.wrapObject(idbCursor->primaryKey(), String()))
- .setValue(m_injectedScript.wrapObject(idbCursor->value(), String()));
- m_result->addItem(dataEntry);
- }
- void end(bool hasMore)
- {
- if (!m_requestCallback->isActive())
- return;
- m_requestCallback->sendSuccess(m_result.release(), hasMore);
- }
- private:
- OpenCursorCallback(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize)
- : EventListener(EventListener::CPPEventListenerType)
- , m_injectedScript(injectedScript)
- , m_requestCallback(requestCallback)
- , m_skipCount(skipCount)
- , m_pageSize(pageSize)
- {
- m_result = Array<DataEntry>::create();
- }
- InjectedScript m_injectedScript;
- RefPtr<RequestDataCallback> m_requestCallback;
- int m_skipCount;
- unsigned m_pageSize;
- RefPtr<Array<DataEntry> > m_result;
- };
- class DataLoader : public ExecutableWithDatabase {
- public:
- static PassRefPtr<DataLoader> create(ScriptExecutionContext* context, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize)
- {
- return adoptRef(new DataLoader(context, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize));
- }
- virtual ~DataLoader() { }
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
- RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), 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;
- }
- RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback, m_skipCount, m_pageSize);
- ExceptionCode ec = 0;
- 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(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), ec);
- } else
- idbRequest = idbObjectStore->openCursor(context(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), ec);
- idbRequest->addEventListener(eventNames().successEvent, openCursorCallback, false);
- }
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
- DataLoader(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize)
- : ExecutableWithDatabase(scriptExecutionContext)
- , m_requestCallback(requestCallback)
- , m_injectedScript(injectedScript)
- , m_objectStoreName(objectStoreName)
- , m_indexName(indexName)
- , m_idbKeyRange(idbKeyRange)
- , m_skipCount(skipCount)
- , m_pageSize(pageSize) { }
- RefPtr<RequestDataCallback> m_requestCallback;
- InjectedScript m_injectedScript;
- String m_objectStoreName;
- String m_indexName;
- RefPtr<IDBKeyRange> m_idbKeyRange;
- int m_skipCount;
- unsigned m_pageSize;
- };
- } // namespace
- InspectorIndexedDBAgent::InspectorIndexedDBAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorPageAgent* pageAgent)
- : InspectorBaseAgent<InspectorIndexedDBAgent>("IndexedDB", instrumentingAgents, state)
- , m_injectedScriptManager(injectedScriptManager)
- , m_pageAgent(pageAgent)
- {
- }
- InspectorIndexedDBAgent::~InspectorIndexedDBAgent()
- {
- }
- void InspectorIndexedDBAgent::clearFrontend()
- {
- disable(0);
- }
- void InspectorIndexedDBAgent::restore()
- {
- if (m_state->getBoolean(IndexedDBAgentState::indexedDBAgentEnabled)) {
- ErrorString error;
- enable(&error);
- }
- }
- void InspectorIndexedDBAgent::enable(ErrorString*)
- {
- m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, true);
- }
- void InspectorIndexedDBAgent::disable(ErrorString*)
- {
- m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, false);
- }
- static Document* assertDocument(ErrorString* errorString, Frame* frame)
- {
- Document* document = frame ? frame->document() : 0;
- if (!document)
- *errorString = "No document for given frame found";
- return document;
- }
- static IDBFactory* assertIDBFactory(ErrorString* errorString, Document* document)
- {
- DOMWindow* domWindow = document->domWindow();
- if (!domWindow) {
- *errorString = "No IndexedDB factory for given frame found";
- return 0;
- }
- IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(domWindow);
- if (!idbFactory)
- *errorString = "No IndexedDB factory for given frame found";
- return idbFactory;
- }
- void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString* errorString, const String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback> requestCallback)
- {
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
- ExceptionCode ec = 0;
- RefPtr<IDBRequest> idbRequest = idbFactory->getDatabaseNames(document, ec);
- if (ec) {
- requestCallback->sendFailure("Could not obtain database names.");
- return;
- }
- idbRequest->addEventListener(eventNames().successEvent, GetDatabaseNamesCallback::create(requestCallback, document->securityOrigin()->toRawString()), false);
- }
- void InspectorIndexedDBAgent::requestDatabase(ErrorString* errorString, const String& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCallback> requestCallback)
- {
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
- RefPtr<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, requestCallback);
- databaseLoader->start(idbFactory, document->securityOrigin(), databaseName);
- }
- void InspectorIndexedDBAgent::requestData(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const RefPtr<InspectorObject>* keyRange, PassRefPtr<RequestDataCallback> requestCallback)
- {
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
- RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRange->get()) : 0;
- if (keyRange && !idbKeyRange) {
- *errorString = "Can not parse key range.";
- return;
- }
- RefPtr<DataLoader> dataLoader = DataLoader::create(document, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize);
- dataLoader->start(idbFactory, document->securityOrigin(), databaseName);
- }
- class ClearObjectStoreListener : public EventListener {
- WTF_MAKE_NONCOPYABLE(ClearObjectStoreListener);
- public:
- static PassRefPtr<ClearObjectStoreListener> create(PassRefPtr<ClearObjectStoreCallback> requestCallback)
- {
- return adoptRef(new ClearObjectStoreListener(requestCallback));
- }
- virtual ~ClearObjectStoreListener() { }
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
- virtual void handleEvent(ScriptExecutionContext*, Event* event) OVERRIDE
- {
- if (!m_requestCallback->isActive())
- return;
- if (event->type() != eventNames().completeEvent) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
- m_requestCallback->sendSuccess();
- }
- private:
- ClearObjectStoreListener(PassRefPtr<ClearObjectStoreCallback> requestCallback)
- : EventListener(EventListener::CPPEventListenerType)
- , m_requestCallback(requestCallback)
- {
- }
- RefPtr<ClearObjectStoreCallback> m_requestCallback;
- };
- class ClearObjectStore : public ExecutableWithDatabase {
- public:
- static PassRefPtr<ClearObjectStore> create(ScriptExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
- {
- return adoptRef(new ClearObjectStore(context, objectStoreName, requestCallback));
- }
- ClearObjectStore(ScriptExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
- : ExecutableWithDatabase(context)
- , m_objectStoreName(objectStoreName)
- , m_requestCallback(requestCallback)
- {
- }
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
- RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), m_objectStoreName, IDBTransaction::modeReadWrite());
- 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;
- }
- ExceptionCode ec = 0;
- RefPtr<IDBRequest> idbRequest = idbObjectStore->clear(context(), ec);
- ASSERT(!ec);
- if (ec) {
- m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), ec));
- return;
- }
- idbTransaction->addEventListener(eventNames().completeEvent, ClearObjectStoreListener::create(m_requestCallback), false);
- }
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
- private:
- const String m_objectStoreName;
- RefPtr<ClearObjectStoreCallback> m_requestCallback;
- };
- void InspectorIndexedDBAgent::clearObjectStore(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
- {
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
- RefPtr<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, requestCallback);
- clearObjectStore->start(idbFactory, document->securityOrigin(), databaseName);
- }
- } // namespace WebCore
- #endif // ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE)
|