Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Side by Side Diff: Source/core/inspector/InspectorIndexedDBAgent.cpp

Issue 148253005: DevTools: remove references to modules/indexeddb from core/inspector (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "core/inspector/InspectorIndexedDBAgent.h"
33
34 #include "bindings/v8/ExceptionState.h"
35 #include "bindings/v8/ExceptionStatePlaceholder.h"
36 #include "bindings/v8/ScriptController.h"
37 #include "core/dom/DOMStringList.h"
38 #include "core/dom/Document.h"
39 #include "core/events/Event.h"
40 #include "core/events/EventListener.h"
41 #include "core/inspector/InjectedScript.h"
42 #include "core/inspector/InspectorPageAgent.h"
43 #include "core/inspector/InspectorState.h"
44 #include "core/frame/Frame.h"
45 #include "modules/indexeddb/DOMWindowIndexedDatabase.h"
46 #include "modules/indexeddb/IDBCursor.h"
47 #include "modules/indexeddb/IDBCursorWithValue.h"
48 #include "modules/indexeddb/IDBDatabase.h"
49 #include "modules/indexeddb/IDBFactory.h"
50 #include "modules/indexeddb/IDBIndex.h"
51 #include "modules/indexeddb/IDBKey.h"
52 #include "modules/indexeddb/IDBKeyPath.h"
53 #include "modules/indexeddb/IDBKeyRange.h"
54 #include "modules/indexeddb/IDBMetadata.h"
55 #include "modules/indexeddb/IDBObjectStore.h"
56 #include "modules/indexeddb/IDBOpenDBRequest.h"
57 #include "modules/indexeddb/IDBPendingTransactionMonitor.h"
58 #include "modules/indexeddb/IDBRequest.h"
59 #include "modules/indexeddb/IDBTransaction.h"
60 #include "platform/JSONValues.h"
61 #include "platform/weborigin/SecurityOrigin.h"
62 #include "public/platform/WebIDBCursor.h"
63 #include "wtf/Vector.h"
64
65 using WebCore::TypeBuilder::Array;
66 using WebCore::TypeBuilder::IndexedDB::DatabaseWithObjectStores;
67 using WebCore::TypeBuilder::IndexedDB::DataEntry;
68 using WebCore::TypeBuilder::IndexedDB::Key;
69 using WebCore::TypeBuilder::IndexedDB::KeyPath;
70 using WebCore::TypeBuilder::IndexedDB::KeyRange;
71 using WebCore::TypeBuilder::IndexedDB::ObjectStore;
72 using WebCore::TypeBuilder::IndexedDB::ObjectStoreIndex;
73
74 typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDat abaseNamesCallback RequestDatabaseNamesCallback;
75 typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDat abaseCallback RequestDatabaseCallback;
76 typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDat aCallback RequestDataCallback;
77 typedef WebCore::InspectorBackendDispatcher::CallbackBase RequestCallback;
78 typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::ClearObjec tStoreCallback ClearObjectStoreCallback;
79
80 namespace WebCore {
81
82 namespace IndexedDBAgentState {
83 static const char indexedDBAgentEnabled[] = "indexedDBAgentEnabled";
84 };
85
86 namespace {
87
88 class GetDatabaseNamesCallback FINAL : public EventListener {
89 WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback);
90 public:
91 static PassRefPtr<GetDatabaseNamesCallback> create(PassRefPtr<RequestDatabas eNamesCallback> requestCallback, const String& securityOrigin)
92 {
93 return adoptRef(new GetDatabaseNamesCallback(requestCallback, securityOr igin));
94 }
95
96 virtual ~GetDatabaseNamesCallback() { }
97
98 virtual bool operator==(const EventListener& other) OVERRIDE
99 {
100 return this == &other;
101 }
102
103 virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
104 {
105 if (!m_requestCallback->isActive())
106 return;
107 if (event->type() != EventTypeNames::success) {
108 m_requestCallback->sendFailure("Unexpected event type.");
109 return;
110 }
111
112 IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
113 RefPtr<IDBAny> requestResult = idbRequest->resultAsAny();
114 if (requestResult->type() != IDBAny::DOMStringListType) {
115 m_requestCallback->sendFailure("Unexpected result type.");
116 return;
117 }
118
119 RefPtr<DOMStringList> databaseNamesList = requestResult->domStringList() ;
120 RefPtr<TypeBuilder::Array<String> > databaseNames = TypeBuilder::Array<S tring>::create();
121 for (size_t i = 0; i < databaseNamesList->length(); ++i)
122 databaseNames->addItem(databaseNamesList->item(i));
123 m_requestCallback->sendSuccess(databaseNames.release());
124 }
125
126 private:
127 GetDatabaseNamesCallback(PassRefPtr<RequestDatabaseNamesCallback> requestCal lback, const String& securityOrigin)
128 : EventListener(EventListener::CPPEventListenerType)
129 , m_requestCallback(requestCallback)
130 , m_securityOrigin(securityOrigin) { }
131 RefPtr<RequestDatabaseNamesCallback> m_requestCallback;
132 String m_securityOrigin;
133 };
134
135 class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> {
136 public:
137 ExecutableWithDatabase(ExecutionContext* context)
138 : m_context(context) { }
139 virtual ~ExecutableWithDatabase() { };
140 void start(IDBFactory*, SecurityOrigin*, const String& databaseName);
141 virtual void execute(PassRefPtr<IDBDatabase>) = 0;
142 virtual RequestCallback* requestCallback() = 0;
143 ExecutionContext* context() { return m_context; };
144 private:
145 ExecutionContext* m_context;
146 };
147
148 class OpenDatabaseCallback FINAL : public EventListener {
149 public:
150 static PassRefPtr<OpenDatabaseCallback> create(ExecutableWithDatabase* execu tableWithDatabase)
151 {
152 return adoptRef(new OpenDatabaseCallback(executableWithDatabase));
153 }
154
155 virtual ~OpenDatabaseCallback() { }
156
157 virtual bool operator==(const EventListener& other) OVERRIDE
158 {
159 return this == &other;
160 }
161
162 virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
163 {
164 if (event->type() != EventTypeNames::success) {
165 m_executableWithDatabase->requestCallback()->sendFailure("Unexpected event type.");
166 return;
167 }
168
169 IDBOpenDBRequest* idbOpenDBRequest = static_cast<IDBOpenDBRequest*>(even t->target());
170 RefPtr<IDBAny> requestResult = idbOpenDBRequest->resultAsAny();
171 if (requestResult->type() != IDBAny::IDBDatabaseType) {
172 m_executableWithDatabase->requestCallback()->sendFailure("Unexpected result type.");
173 return;
174 }
175
176 RefPtr<IDBDatabase> idbDatabase = requestResult->idbDatabase();
177 m_executableWithDatabase->execute(idbDatabase);
178 IDBPendingTransactionMonitor::deactivateNewTransactions();
179 idbDatabase->close();
180 }
181
182 private:
183 OpenDatabaseCallback(ExecutableWithDatabase* executableWithDatabase)
184 : EventListener(EventListener::CPPEventListenerType)
185 , m_executableWithDatabase(executableWithDatabase) { }
186 RefPtr<ExecutableWithDatabase> m_executableWithDatabase;
187 };
188
189 void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, cons t String& databaseName)
190 {
191 RefPtr<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this);
192 TrackExceptionState exceptionState;
193 RefPtr<IDBOpenDBRequest> idbOpenDBRequest = idbFactory->open(context(), data baseName, exceptionState);
194 if (exceptionState.hadException()) {
195 requestCallback()->sendFailure("Could not open database.");
196 return;
197 }
198 idbOpenDBRequest->addEventListener(EventTypeNames::success, callback, false) ;
199 }
200
201 static PassRefPtr<IDBTransaction> transactionForDatabase(ExecutionContext* execu tionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const Stri ng& mode = IDBTransaction::modeReadOnly())
202 {
203 TrackExceptionState exceptionState;
204 RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(executionCo ntext, objectStoreName, mode, exceptionState);
205 if (exceptionState.hadException())
206 return 0;
207 return idbTransaction;
208 }
209
210 static PassRefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbT ransaction, const String& objectStoreName)
211 {
212 TrackExceptionState exceptionState;
213 RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectSt oreName, exceptionState);
214 if (exceptionState.hadException())
215 return 0;
216 return idbObjectStore;
217 }
218
219 static PassRefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName)
220 {
221 TrackExceptionState exceptionState;
222 RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, exceptionState) ;
223 if (exceptionState.hadException())
224 return 0;
225 return idbIndex;
226 }
227
228 static PassRefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath)
229 {
230 RefPtr<KeyPath> keyPath;
231 switch (idbKeyPath.type()) {
232 case IDBKeyPath::NullType:
233 keyPath = KeyPath::create().setType(KeyPath::Type::Null);
234 break;
235 case IDBKeyPath::StringType:
236 keyPath = KeyPath::create().setType(KeyPath::Type::String);
237 keyPath->setString(idbKeyPath.string());
238 break;
239 case IDBKeyPath::ArrayType: {
240 keyPath = KeyPath::create().setType(KeyPath::Type::Array);
241 RefPtr<TypeBuilder::Array<String> > array = TypeBuilder::Array<String>:: create();
242 const Vector<String>& stringArray = idbKeyPath.array();
243 for (size_t i = 0; i < stringArray.size(); ++i)
244 array->addItem(stringArray[i]);
245 keyPath->setArray(array);
246 break;
247 }
248 default:
249 ASSERT_NOT_REACHED();
250 }
251
252 return keyPath.release();
253 }
254
255 class DatabaseLoader FINAL : public ExecutableWithDatabase {
256 public:
257 static PassRefPtr<DatabaseLoader> create(ExecutionContext* context, PassRefP tr<RequestDatabaseCallback> requestCallback)
258 {
259 return adoptRef(new DatabaseLoader(context, requestCallback));
260 }
261
262 virtual ~DatabaseLoader() { }
263
264 virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) OVERRIDE
265 {
266 RefPtr<IDBDatabase> idbDatabase = prpDatabase;
267 if (!requestCallback()->isActive())
268 return;
269
270 const IDBDatabaseMetadata databaseMetadata = idbDatabase->metadata();
271
272 RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore> > objectS tores = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore>::create();
273
274 for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = databaseMe tadata.objectStores.begin(); it != databaseMetadata.objectStores.end(); ++it) {
275 const IDBObjectStoreMetadata& objectStoreMetadata = it->value;
276
277 RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex> > indexes = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex>::create ();
278
279 for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectSto reMetadata.indexes.begin(); it != objectStoreMetadata.indexes.end(); ++it) {
280 const IDBIndexMetadata& indexMetadata = it->value;
281
282 RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::cr eate()
283 .setName(indexMetadata.name)
284 .setKeyPath(keyPathFromIDBKeyPath(indexMetadata.keyPath))
285 .setUnique(indexMetadata.unique)
286 .setMultiEntry(indexMetadata.multiEntry);
287 indexes->addItem(objectStoreIndex);
288 }
289
290 RefPtr<ObjectStore> objectStore = ObjectStore::create()
291 .setName(objectStoreMetadata.name)
292 .setKeyPath(keyPathFromIDBKeyPath(objectStoreMetadata.keyPath))
293 .setAutoIncrement(objectStoreMetadata.autoIncrement)
294 .setIndexes(indexes);
295 objectStores->addItem(objectStore);
296 }
297 RefPtr<DatabaseWithObjectStores> result = DatabaseWithObjectStores::crea te()
298 .setName(databaseMetadata.name)
299 .setIntVersion(databaseMetadata.intVersion)
300 .setVersion(databaseMetadata.version)
301 .setObjectStores(objectStores);
302
303 m_requestCallback->sendSuccess(result);
304 }
305
306 virtual RequestCallback* requestCallback() OVERRIDE { return m_requestCallba ck.get(); }
307 private:
308 DatabaseLoader(ExecutionContext* context, PassRefPtr<RequestDatabaseCallback > requestCallback)
309 : ExecutableWithDatabase(context)
310 , m_requestCallback(requestCallback) { }
311 RefPtr<RequestDatabaseCallback> m_requestCallback;
312 };
313
314 static PassRefPtr<IDBKey> idbKeyFromInspectorObject(JSONObject* key)
315 {
316 RefPtr<IDBKey> idbKey;
317
318 String type;
319 if (!key->getString("type", &type))
320 return 0;
321
322 DEFINE_STATIC_LOCAL(String, number, ("number"));
323 DEFINE_STATIC_LOCAL(String, string, ("string"));
324 DEFINE_STATIC_LOCAL(String, date, ("date"));
325 DEFINE_STATIC_LOCAL(String, array, ("array"));
326
327 if (type == number) {
328 double number;
329 if (!key->getNumber("number", &number))
330 return 0;
331 idbKey = IDBKey::createNumber(number);
332 } else if (type == string) {
333 String string;
334 if (!key->getString("string", &string))
335 return 0;
336 idbKey = IDBKey::createString(string);
337 } else if (type == date) {
338 double date;
339 if (!key->getNumber("date", &date))
340 return 0;
341 idbKey = IDBKey::createDate(date);
342 } else if (type == array) {
343 IDBKey::KeyArray keyArray;
344 RefPtr<JSONArray> array = key->getArray("array");
345 for (size_t i = 0; i < array->length(); ++i) {
346 RefPtr<JSONValue> value = array->get(i);
347 RefPtr<JSONObject> object;
348 if (!value->asObject(&object))
349 return 0;
350 keyArray.append(idbKeyFromInspectorObject(object.get()));
351 }
352 idbKey = IDBKey::createArray(keyArray);
353 } else
354 return 0;
355
356 return idbKey.release();
357 }
358
359 static PassRefPtr<IDBKeyRange> idbKeyRangeFromKeyRange(JSONObject* keyRange)
360 {
361 RefPtr<JSONObject> lower = keyRange->getObject("lower");
362 RefPtr<IDBKey> idbLower = lower ? idbKeyFromInspectorObject(lower.get()) : 0 ;
363 if (lower && !idbLower)
364 return 0;
365
366 RefPtr<JSONObject> upper = keyRange->getObject("upper");
367 RefPtr<IDBKey> idbUpper = upper ? idbKeyFromInspectorObject(upper.get()) : 0 ;
368 if (upper && !idbUpper)
369 return 0;
370
371 bool lowerOpen;
372 if (!keyRange->getBoolean("lowerOpen", &lowerOpen))
373 return 0;
374 IDBKeyRange::LowerBoundType lowerBoundType = lowerOpen ? IDBKeyRange::LowerB oundOpen : IDBKeyRange::LowerBoundClosed;
375
376 bool upperOpen;
377 if (!keyRange->getBoolean("upperOpen", &upperOpen))
378 return 0;
379 IDBKeyRange::UpperBoundType upperBoundType = upperOpen ? IDBKeyRange::UpperB oundOpen : IDBKeyRange::UpperBoundClosed;
380
381 RefPtr<IDBKeyRange> idbKeyRange = IDBKeyRange::create(idbLower, idbUpper, lo werBoundType, upperBoundType);
382 return idbKeyRange.release();
383 }
384
385 class DataLoader;
386
387 class OpenCursorCallback FINAL : public EventListener {
388 public:
389 static PassRefPtr<OpenCursorCallback> create(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSiz e)
390 {
391 return adoptRef(new OpenCursorCallback(injectedScript, requestCallback, skipCount, pageSize));
392 }
393
394 virtual ~OpenCursorCallback() { }
395
396 virtual bool operator==(const EventListener& other) OVERRIDE
397 {
398 return this == &other;
399 }
400
401 virtual void handleEvent(ExecutionContext* context, Event* event) OVERRIDE
402 {
403 if (event->type() != EventTypeNames::success) {
404 m_requestCallback->sendFailure("Unexpected event type.");
405 return;
406 }
407
408 IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
409 RefPtr<IDBAny> requestResult = idbRequest->resultAsAny();
410 if (requestResult->type() == IDBAny::BufferType) {
411 end(false);
412 return;
413 }
414 if (requestResult->type() != IDBAny::IDBCursorWithValueType) {
415 m_requestCallback->sendFailure("Unexpected result type.");
416 return;
417 }
418
419 RefPtr<IDBCursorWithValue> idbCursor = requestResult->idbCursorWithValue ();
420
421 if (m_skipCount) {
422 TrackExceptionState exceptionState;
423 idbCursor->advance(m_skipCount, exceptionState);
424 if (exceptionState.hadException())
425 m_requestCallback->sendFailure("Could not advance cursor.");
426 m_skipCount = 0;
427 return;
428 }
429
430 if (m_result->length() == m_pageSize) {
431 end(true);
432 return;
433 }
434
435 // Continue cursor before making injected script calls, otherwise transa ction might be finished.
436 TrackExceptionState exceptionState;
437 idbCursor->continueFunction(0, 0, exceptionState);
438 if (exceptionState.hadException()) {
439 m_requestCallback->sendFailure("Could not continue cursor.");
440 return;
441 }
442
443 RefPtr<DataEntry> dataEntry = DataEntry::create()
444 .setKey(m_injectedScript.wrapObject(idbCursor->key(context), String( )))
445 .setPrimaryKey(m_injectedScript.wrapObject(idbCursor->primaryKey(con text), String()))
446 .setValue(m_injectedScript.wrapObject(idbCursor->value(context), Str ing()));
447 m_result->addItem(dataEntry);
448
449 }
450
451 void end(bool hasMore)
452 {
453 if (!m_requestCallback->isActive())
454 return;
455 m_requestCallback->sendSuccess(m_result.release(), hasMore);
456 }
457
458 private:
459 OpenCursorCallback(InjectedScript injectedScript, PassRefPtr<RequestDataCall back> requestCallback, int skipCount, unsigned pageSize)
460 : EventListener(EventListener::CPPEventListenerType)
461 , m_injectedScript(injectedScript)
462 , m_requestCallback(requestCallback)
463 , m_skipCount(skipCount)
464 , m_pageSize(pageSize)
465 {
466 m_result = Array<DataEntry>::create();
467 }
468 InjectedScript m_injectedScript;
469 RefPtr<RequestDataCallback> m_requestCallback;
470 int m_skipCount;
471 unsigned m_pageSize;
472 RefPtr<Array<DataEntry> > m_result;
473 };
474
475 class DataLoader FINAL : public ExecutableWithDatabase {
476 public:
477 static PassRefPtr<DataLoader> create(ExecutionContext* context, PassRefPtr<R equestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKe yRange, int skipCount, unsigned pageSize)
478 {
479 return adoptRef(new DataLoader(context, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize));
480 }
481
482 virtual ~DataLoader() { }
483
484 virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) OVERRIDE
485 {
486 RefPtr<IDBDatabase> idbDatabase = prpDatabase;
487 if (!requestCallback()->isActive())
488 return;
489 RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context() , idbDatabase.get(), m_objectStoreName);
490 if (!idbTransaction) {
491 m_requestCallback->sendFailure("Could not get transaction");
492 return;
493 }
494 RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTra nsaction.get(), m_objectStoreName);
495 if (!idbObjectStore) {
496 m_requestCallback->sendFailure("Could not get object store");
497 return;
498 }
499
500 RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::crea te(m_injectedScript, m_requestCallback, m_skipCount, m_pageSize);
501
502 RefPtr<IDBRequest> idbRequest;
503 if (!m_indexName.isEmpty()) {
504 RefPtr<IDBIndex> idbIndex = indexForObjectStore(idbObjectStore.get() , m_indexName);
505 if (!idbIndex) {
506 m_requestCallback->sendFailure("Could not get index");
507 return;
508 }
509
510 idbRequest = idbIndex->openCursor(context(), PassRefPtr<IDBKeyRange> (m_idbKeyRange), blink::WebIDBCursor::Next);
511 } else {
512 idbRequest = idbObjectStore->openCursor(context(), PassRefPtr<IDBKey Range>(m_idbKeyRange), blink::WebIDBCursor::Next);
513 }
514 idbRequest->addEventListener(EventTypeNames::success, openCursorCallback , false);
515 }
516
517 virtual RequestCallback* requestCallback() OVERRIDE { return m_requestCallba ck.get(); }
518 DataLoader(ExecutionContext* executionContext, PassRefPtr<RequestDataCallbac k> requestCallback, const InjectedScript& injectedScript, const String& objectSt oreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipC ount, unsigned pageSize)
519 : ExecutableWithDatabase(executionContext)
520 , m_requestCallback(requestCallback)
521 , m_injectedScript(injectedScript)
522 , m_objectStoreName(objectStoreName)
523 , m_indexName(indexName)
524 , m_idbKeyRange(idbKeyRange)
525 , m_skipCount(skipCount)
526 , m_pageSize(pageSize) { }
527 RefPtr<RequestDataCallback> m_requestCallback;
528 InjectedScript m_injectedScript;
529 String m_objectStoreName;
530 String m_indexName;
531 RefPtr<IDBKeyRange> m_idbKeyRange;
532 int m_skipCount;
533 unsigned m_pageSize;
534 };
535
536 } // namespace
537
538 InspectorIndexedDBAgent::InspectorIndexedDBAgent(InjectedScriptManager* injected ScriptManager, InspectorPageAgent* pageAgent)
539 : InspectorBaseAgent<InspectorIndexedDBAgent>("IndexedDB")
540 , m_injectedScriptManager(injectedScriptManager)
541 , m_pageAgent(pageAgent)
542 {
543 }
544
545 InspectorIndexedDBAgent::~InspectorIndexedDBAgent()
546 {
547 }
548
549 void InspectorIndexedDBAgent::clearFrontend()
550 {
551 disable(0);
552 }
553
554 void InspectorIndexedDBAgent::restore()
555 {
556 if (m_state->getBoolean(IndexedDBAgentState::indexedDBAgentEnabled)) {
557 ErrorString error;
558 enable(&error);
559 }
560 }
561
562 void InspectorIndexedDBAgent::enable(ErrorString*)
563 {
564 m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, true);
565 }
566
567 void InspectorIndexedDBAgent::disable(ErrorString*)
568 {
569 m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, false);
570 }
571
572 static Document* assertDocument(ErrorString* errorString, Frame* frame)
573 {
574 Document* document = frame ? frame->document() : 0;
575
576 if (!document)
577 *errorString = "No document for given frame found";
578
579 return document;
580 }
581
582 static IDBFactory* assertIDBFactory(ErrorString* errorString, Document* document )
583 {
584 DOMWindow* domWindow = document->domWindow();
585 if (!domWindow) {
586 *errorString = "No IndexedDB factory for given frame found";
587 return 0;
588 }
589 IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(domWindow);
590
591 if (!idbFactory)
592 *errorString = "No IndexedDB factory for given frame found";
593
594 return idbFactory;
595 }
596
597 void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString* errorString, con st String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback> requestCallb ack)
598 {
599 Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
600 Document* document = assertDocument(errorString, frame);
601 if (!document)
602 return;
603 IDBFactory* idbFactory = assertIDBFactory(errorString, document);
604 if (!idbFactory)
605 return;
606
607 // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
608 v8::HandleScope handleScope(toIsolate(frame));
609 v8::Handle<v8::Context> context = document->frame()->script().mainWorldConte xt();
610 ASSERT(!context.IsEmpty());
611 v8::Context::Scope contextScope(context);
612
613 TrackExceptionState exceptionState;
614 RefPtr<IDBRequest> idbRequest = idbFactory->getDatabaseNames(document, excep tionState);
615 if (exceptionState.hadException()) {
616 requestCallback->sendFailure("Could not obtain database names.");
617 return;
618 }
619 idbRequest->addEventListener(EventTypeNames::success, GetDatabaseNamesCallba ck::create(requestCallback, document->securityOrigin()->toRawString()), false);
620 }
621
622 void InspectorIndexedDBAgent::requestDatabase(ErrorString* errorString, const St ring& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCall back> requestCallback)
623 {
624 Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
625 Document* document = assertDocument(errorString, frame);
626 if (!document)
627 return;
628 IDBFactory* idbFactory = assertIDBFactory(errorString, document);
629 if (!idbFactory)
630 return;
631
632 // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
633 v8::HandleScope handleScope(toIsolate(frame));
634 v8::Handle<v8::Context> context = document->frame()->script().mainWorldConte xt();
635 ASSERT(!context.IsEmpty());
636 v8::Context::Scope contextScope(context);
637
638 RefPtr<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, req uestCallback);
639 databaseLoader->start(idbFactory, document->securityOrigin(), databaseName);
640 }
641
642 void InspectorIndexedDBAgent::requestData(ErrorString* errorString, const String & securityOrigin, const String& databaseName, const String& objectStoreName, con st String& indexName, int skipCount, int pageSize, const RefPtr<JSONObject>* key Range, PassRefPtr<RequestDataCallback> requestCallback)
643 {
644 Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
645 Document* document = assertDocument(errorString, frame);
646 if (!document)
647 return;
648 IDBFactory* idbFactory = assertIDBFactory(errorString, document);
649 if (!idbFactory)
650 return;
651
652 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m ainWorldScriptState(frame));
653
654 RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRang e->get()) : 0;
655 if (keyRange && !idbKeyRange) {
656 *errorString = "Can not parse key range.";
657 return;
658 }
659
660 // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
661 v8::HandleScope handleScope(toIsolate(frame));
662 v8::Handle<v8::Context> context = document->frame()->script().mainWorldConte xt();
663 ASSERT(!context.IsEmpty());
664 v8::Context::Scope contextScope(context);
665
666 RefPtr<DataLoader> dataLoader = DataLoader::create(document, requestCallback , injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize);
667 dataLoader->start(idbFactory, document->securityOrigin(), databaseName);
668 }
669
670 class ClearObjectStoreListener FINAL : public EventListener {
671 WTF_MAKE_NONCOPYABLE(ClearObjectStoreListener);
672 public:
673 static PassRefPtr<ClearObjectStoreListener> create(PassRefPtr<ClearObjectSto reCallback> requestCallback)
674 {
675 return adoptRef(new ClearObjectStoreListener(requestCallback));
676 }
677
678 virtual ~ClearObjectStoreListener() { }
679
680 virtual bool operator==(const EventListener& other) OVERRIDE
681 {
682 return this == &other;
683 }
684
685 virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
686 {
687 if (!m_requestCallback->isActive())
688 return;
689 if (event->type() != EventTypeNames::complete) {
690 m_requestCallback->sendFailure("Unexpected event type.");
691 return;
692 }
693
694 m_requestCallback->sendSuccess();
695 }
696 private:
697 ClearObjectStoreListener(PassRefPtr<ClearObjectStoreCallback> requestCallbac k)
698 : EventListener(EventListener::CPPEventListenerType)
699 , m_requestCallback(requestCallback)
700 {
701 }
702
703 RefPtr<ClearObjectStoreCallback> m_requestCallback;
704 };
705
706
707 class ClearObjectStore FINAL : public ExecutableWithDatabase {
708 public:
709 static PassRefPtr<ClearObjectStore> create(ExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
710 {
711 return adoptRef(new ClearObjectStore(context, objectStoreName, requestCa llback));
712 }
713
714 ClearObjectStore(ExecutionContext* context, const String& objectStoreName, P assRefPtr<ClearObjectStoreCallback> requestCallback)
715 : ExecutableWithDatabase(context)
716 , m_objectStoreName(objectStoreName)
717 , m_requestCallback(requestCallback)
718 {
719 }
720
721 virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) OVERRIDE
722 {
723 RefPtr<IDBDatabase> idbDatabase = prpDatabase;
724 if (!requestCallback()->isActive())
725 return;
726 RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context() , idbDatabase.get(), m_objectStoreName, IDBTransaction::modeReadWrite());
727 if (!idbTransaction) {
728 m_requestCallback->sendFailure("Could not get transaction");
729 return;
730 }
731 RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTra nsaction.get(), m_objectStoreName);
732 if (!idbObjectStore) {
733 m_requestCallback->sendFailure("Could not get object store");
734 return;
735 }
736
737 TrackExceptionState exceptionState;
738 RefPtr<IDBRequest> idbRequest = idbObjectStore->clear(context(), excepti onState);
739 ASSERT(!exceptionState.hadException());
740 if (exceptionState.hadException()) {
741 ExceptionCode ec = exceptionState.code();
742 m_requestCallback->sendFailure(String::format("Could not clear objec t store '%s': %d", m_objectStoreName.utf8().data(), ec));
743 return;
744 }
745 idbTransaction->addEventListener(EventTypeNames::complete, ClearObjectSt oreListener::create(m_requestCallback), false);
746 }
747
748 virtual RequestCallback* requestCallback() OVERRIDE { return m_requestCallba ck.get(); }
749 private:
750 const String m_objectStoreName;
751 RefPtr<ClearObjectStoreCallback> m_requestCallback;
752 };
753
754 void InspectorIndexedDBAgent::clearObjectStore(ErrorString* errorString, const S tring& securityOrigin, const String& databaseName, const String& objectStoreName , PassRefPtr<ClearObjectStoreCallback> requestCallback)
755 {
756 Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
757 Document* document = assertDocument(errorString, frame);
758 if (!document)
759 return;
760 IDBFactory* idbFactory = assertIDBFactory(errorString, document);
761 if (!idbFactory)
762 return;
763
764 // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
765 v8::HandleScope handleScope(toIsolate(frame));
766 v8::Handle<v8::Context> context = document->frame()->script().mainWorldConte xt();
767 ASSERT(!context.IsEmpty());
768 v8::Context::Scope contextScope(context);
769
770 RefPtr<ClearObjectStore> clearObjectStore = ClearObjectStore::create(documen t, objectStoreName, requestCallback);
771 clearObjectStore->start(idbFactory, document->securityOrigin(), databaseName );
772 }
773
774 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698