1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/indexed_db/indexed_db_dispatcher.h"
7 #include "base/format_macros.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/threading/thread_local.h"
11 #include "content/child/indexed_db/indexed_db_key_builders.h"
12 #include "content/child/indexed_db/proxy_webidbcursor_impl.h"
13 #include "content/child/indexed_db/proxy_webidbdatabase_impl.h"
14 #include "content/child/thread_safe_sender.h"
15 #include "content/common/indexed_db/indexed_db_messages.h"
16 #include "ipc/ipc_channel.h"
17 #include "third_party/WebKit/public/platform/WebIDBDatabaseCallbacks.h"
18 #include "third_party/WebKit/public/platform/WebIDBDatabaseError.h"
19 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
21 using WebKit::WebData
;
22 using WebKit::WebIDBCallbacks
;
23 using WebKit::WebIDBDatabase
;
24 using WebKit::WebIDBDatabaseCallbacks
;
25 using WebKit::WebIDBDatabaseError
;
26 using WebKit::WebIDBKey
;
27 using WebKit::WebIDBMetadata
;
28 using WebKit::WebString
;
29 using WebKit::WebVector
;
30 using base::ThreadLocalPointer
;
31 using webkit_glue::WorkerTaskRunner
;
34 static base::LazyInstance
<ThreadLocalPointer
<IndexedDBDispatcher
> >::Leaky
35 g_idb_dispatcher_tls
= LAZY_INSTANCE_INITIALIZER
;
39 IndexedDBDispatcher
* const kHasBeenDeleted
=
40 reinterpret_cast<IndexedDBDispatcher
*>(0x1);
42 int32
CurrentWorkerId() {
43 return WorkerTaskRunner::Instance()->CurrentWorkerId();
45 } // unnamed namespace
47 const size_t kMaxIDBValueSizeInBytes
= 64 * 1024 * 1024;
49 IndexedDBDispatcher::IndexedDBDispatcher(ThreadSafeSender
* thread_safe_sender
)
50 : thread_safe_sender_(thread_safe_sender
) {
51 g_idb_dispatcher_tls
.Pointer()->Set(this);
54 IndexedDBDispatcher::~IndexedDBDispatcher() {
55 // Clear any pending callbacks - which may result in dispatch requests -
56 // before marking the dispatcher as deleted.
57 pending_callbacks_
.Clear();
58 pending_database_callbacks_
.Clear();
60 DCHECK(pending_callbacks_
.IsEmpty());
61 DCHECK(pending_database_callbacks_
.IsEmpty());
63 g_idb_dispatcher_tls
.Pointer()->Set(kHasBeenDeleted
);
66 IndexedDBDispatcher
* IndexedDBDispatcher::ThreadSpecificInstance(
67 ThreadSafeSender
* thread_safe_sender
) {
68 if (g_idb_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
) {
69 NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher.";
70 g_idb_dispatcher_tls
.Pointer()->Set(NULL
);
72 if (g_idb_dispatcher_tls
.Pointer()->Get())
73 return g_idb_dispatcher_tls
.Pointer()->Get();
75 IndexedDBDispatcher
* dispatcher
= new IndexedDBDispatcher(thread_safe_sender
);
76 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
77 webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher
);
81 void IndexedDBDispatcher::OnWorkerRunLoopStopped() { delete this; }
83 WebIDBMetadata
IndexedDBDispatcher::ConvertMetadata(
84 const IndexedDBDatabaseMetadata
& idb_metadata
) {
85 WebIDBMetadata web_metadata
;
86 web_metadata
.id
= idb_metadata
.id
;
87 web_metadata
.name
= idb_metadata
.name
;
88 web_metadata
.version
= idb_metadata
.version
;
89 web_metadata
.intVersion
= idb_metadata
.int_version
;
90 web_metadata
.maxObjectStoreId
= idb_metadata
.max_object_store_id
;
91 web_metadata
.objectStores
=
92 WebVector
<WebIDBMetadata::ObjectStore
>(idb_metadata
.object_stores
.size());
94 for (size_t i
= 0; i
< idb_metadata
.object_stores
.size(); ++i
) {
95 const IndexedDBObjectStoreMetadata
& idb_store_metadata
=
96 idb_metadata
.object_stores
[i
];
97 WebIDBMetadata::ObjectStore
& web_store_metadata
=
98 web_metadata
.objectStores
[i
];
100 web_store_metadata
.id
= idb_store_metadata
.id
;
101 web_store_metadata
.name
= idb_store_metadata
.name
;
102 web_store_metadata
.keyPath
=
103 WebIDBKeyPathBuilder::Build(idb_store_metadata
.keyPath
);
104 web_store_metadata
.autoIncrement
= idb_store_metadata
.autoIncrement
;
105 web_store_metadata
.maxIndexId
= idb_store_metadata
.max_index_id
;
106 web_store_metadata
.indexes
=
107 WebVector
<WebIDBMetadata::Index
>(idb_store_metadata
.indexes
.size());
109 for (size_t j
= 0; j
< idb_store_metadata
.indexes
.size(); ++j
) {
110 const IndexedDBIndexMetadata
& idb_index_metadata
=
111 idb_store_metadata
.indexes
[j
];
112 WebIDBMetadata::Index
& web_index_metadata
= web_store_metadata
.indexes
[j
];
114 web_index_metadata
.id
= idb_index_metadata
.id
;
115 web_index_metadata
.name
= idb_index_metadata
.name
;
116 web_index_metadata
.keyPath
=
117 WebIDBKeyPathBuilder::Build(idb_index_metadata
.keyPath
);
118 web_index_metadata
.unique
= idb_index_metadata
.unique
;
119 web_index_metadata
.multiEntry
= idb_index_metadata
.multiEntry
;
126 void IndexedDBDispatcher::OnMessageReceived(const IPC::Message
& msg
) {
128 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher
, msg
)
129 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBCursor
,
131 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorAdvance
,
132 OnSuccessCursorContinue
)
133 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue
,
134 OnSuccessCursorContinue
)
135 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorPrefetch
,
136 OnSuccessCursorPrefetch
)
137 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase
,
138 OnSuccessIDBDatabase
)
139 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey
,
140 OnSuccessIndexedDBKey
)
141 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessStringList
,
143 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValue
, OnSuccessValue
)
144 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValueWithKey
,
145 OnSuccessValueWithKey
)
146 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessInteger
, OnSuccessInteger
)
147 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessUndefined
,
149 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError
, OnError
)
150 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksIntBlocked
, OnIntBlocked
)
151 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksUpgradeNeeded
, OnUpgradeNeeded
)
152 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksForcedClose
,
154 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksIntVersionChange
,
156 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksAbort
, OnAbort
)
157 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksComplete
, OnComplete
)
158 IPC_MESSAGE_UNHANDLED(handled
= false)
159 IPC_END_MESSAGE_MAP()
160 // If a message gets here, IndexedDBMessageFilter already determined that it
161 // is an IndexedDB message.
162 DCHECK(handled
) << "Didn't handle a message defined at line "
163 << IPC_MESSAGE_ID_LINE(msg
.type());
166 bool IndexedDBDispatcher::Send(IPC::Message
* msg
) {
167 return thread_safe_sender_
->Send(msg
);
170 void IndexedDBDispatcher::RequestIDBCursorAdvance(
172 WebIDBCallbacks
* callbacks_ptr
,
173 int32 ipc_cursor_id
) {
174 // Reset all cursor prefetch caches except for this cursor.
175 ResetCursorPrefetchCaches(ipc_cursor_id
);
177 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
179 int32 ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
180 Send(new IndexedDBHostMsg_CursorAdvance(
181 ipc_cursor_id
, CurrentWorkerId(), ipc_callbacks_id
, count
));
184 void IndexedDBDispatcher::RequestIDBCursorContinue(
185 const IndexedDBKey
& key
,
186 WebIDBCallbacks
* callbacks_ptr
,
187 int32 ipc_cursor_id
) {
188 // Reset all cursor prefetch caches except for this cursor.
189 ResetCursorPrefetchCaches(ipc_cursor_id
);
191 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
193 int32 ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
194 Send(new IndexedDBHostMsg_CursorContinue(
195 ipc_cursor_id
, CurrentWorkerId(), ipc_callbacks_id
, key
));
198 void IndexedDBDispatcher::RequestIDBCursorPrefetch(
200 WebIDBCallbacks
* callbacks_ptr
,
201 int32 ipc_cursor_id
) {
202 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
204 int32 ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
205 Send(new IndexedDBHostMsg_CursorPrefetch(
206 ipc_cursor_id
, CurrentWorkerId(), ipc_callbacks_id
, n
));
209 void IndexedDBDispatcher::RequestIDBCursorPrefetchReset(int used_prefetches
,
210 int unused_prefetches
,
211 int32 ipc_cursor_id
) {
212 Send(new IndexedDBHostMsg_CursorPrefetchReset(
213 ipc_cursor_id
, used_prefetches
, unused_prefetches
));
216 void IndexedDBDispatcher::RequestIDBFactoryOpen(
217 const string16
& name
,
219 int64 transaction_id
,
220 WebIDBCallbacks
* callbacks_ptr
,
221 WebIDBDatabaseCallbacks
* database_callbacks_ptr
,
222 const std::string
& database_identifier
) {
223 ResetCursorPrefetchCaches();
224 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
225 scoped_ptr
<WebIDBDatabaseCallbacks
> database_callbacks(
226 database_callbacks_ptr
);
228 IndexedDBHostMsg_FactoryOpen_Params params
;
229 params
.ipc_thread_id
= CurrentWorkerId();
230 params
.ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
231 params
.ipc_database_callbacks_id
=
232 pending_database_callbacks_
.Add(database_callbacks
.release());
233 params
.database_identifier
= database_identifier
;
235 params
.transaction_id
= transaction_id
;
236 params
.version
= version
;
237 Send(new IndexedDBHostMsg_FactoryOpen(params
));
240 void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames(
241 WebIDBCallbacks
* callbacks_ptr
,
242 const std::string
& database_identifier
) {
243 ResetCursorPrefetchCaches();
244 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
246 IndexedDBHostMsg_FactoryGetDatabaseNames_Params params
;
247 params
.ipc_thread_id
= CurrentWorkerId();
248 params
.ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
249 params
.database_identifier
= database_identifier
;
250 Send(new IndexedDBHostMsg_FactoryGetDatabaseNames(params
));
253 void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
254 const string16
& name
,
255 WebIDBCallbacks
* callbacks_ptr
,
256 const std::string
& database_identifier
) {
257 ResetCursorPrefetchCaches();
258 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
260 IndexedDBHostMsg_FactoryDeleteDatabase_Params params
;
261 params
.ipc_thread_id
= CurrentWorkerId();
262 params
.ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
263 params
.database_identifier
= database_identifier
;
265 Send(new IndexedDBHostMsg_FactoryDeleteDatabase(params
));
268 void IndexedDBDispatcher::RequestIDBDatabaseClose(
269 int32 ipc_database_id
,
270 int32 ipc_database_callbacks_id
) {
271 ResetCursorPrefetchCaches();
272 Send(new IndexedDBHostMsg_DatabaseClose(ipc_database_id
));
273 // There won't be pending database callbacks if the transaction was aborted in
274 // the initial upgradeneeded event handler.
275 if (pending_database_callbacks_
.Lookup(ipc_database_callbacks_id
))
276 pending_database_callbacks_
.Remove(ipc_database_callbacks_id
);
279 void IndexedDBDispatcher::RequestIDBDatabaseCreateTransaction(
280 int32 ipc_database_id
,
281 int64 transaction_id
,
282 WebIDBDatabaseCallbacks
* database_callbacks_ptr
,
283 WebVector
<long long> object_store_ids
,
284 unsigned short mode
) {
285 scoped_ptr
<WebIDBDatabaseCallbacks
> database_callbacks(
286 database_callbacks_ptr
);
287 IndexedDBHostMsg_DatabaseCreateTransaction_Params params
;
288 params
.ipc_thread_id
= CurrentWorkerId();
289 params
.ipc_database_id
= ipc_database_id
;
290 params
.transaction_id
= transaction_id
;
291 params
.ipc_database_callbacks_id
=
292 pending_database_callbacks_
.Add(database_callbacks
.release());
293 params
.object_store_ids
294 .assign(object_store_ids
.data(),
295 object_store_ids
.data() + object_store_ids
.size());
298 Send(new IndexedDBHostMsg_DatabaseCreateTransaction(params
));
301 void IndexedDBDispatcher::RequestIDBDatabaseGet(
302 int32 ipc_database_id
,
303 int64 transaction_id
,
304 int64 object_store_id
,
306 const IndexedDBKeyRange
& key_range
,
308 WebIDBCallbacks
* callbacks
) {
309 ResetCursorPrefetchCaches();
310 IndexedDBHostMsg_DatabaseGet_Params params
;
311 init_params(params
, callbacks
);
312 params
.ipc_database_id
= ipc_database_id
;
313 params
.transaction_id
= transaction_id
;
314 params
.object_store_id
= object_store_id
;
315 params
.index_id
= index_id
;
316 params
.key_range
= key_range
;
317 params
.key_only
= key_only
;
318 Send(new IndexedDBHostMsg_DatabaseGet(params
));
321 void IndexedDBDispatcher::RequestIDBDatabasePut(
322 int32 ipc_database_id
,
323 int64 transaction_id
,
324 int64 object_store_id
,
325 const WebData
& value
,
326 const IndexedDBKey
& key
,
327 WebIDBDatabase::PutMode put_mode
,
328 WebIDBCallbacks
* callbacks
,
329 const WebVector
<long long>& index_ids
,
330 const WebVector
<WebVector
<WebIDBKey
> >& index_keys
) {
332 if (value
.size() > kMaxIDBValueSizeInBytes
) {
333 callbacks
->onError(WebIDBDatabaseError(
334 WebKit::WebIDBDatabaseExceptionUnknownError
,
335 WebString::fromUTF8(base::StringPrintf(
336 "The serialized value is too large"
337 " (size=%" PRIuS
" bytes, max=%" PRIuS
" bytes).",
339 kMaxIDBValueSizeInBytes
).c_str())));
343 ResetCursorPrefetchCaches();
344 IndexedDBHostMsg_DatabasePut_Params params
;
345 init_params(params
, callbacks
);
346 params
.ipc_database_id
= ipc_database_id
;
347 params
.transaction_id
= transaction_id
;
348 params
.object_store_id
= object_store_id
;
350 params
.value
.assign(value
.data(), value
.data() + value
.size());
352 params
.put_mode
= put_mode
;
354 COMPILE_ASSERT(sizeof(params
.index_ids
[0]) == sizeof(index_ids
[0]),
357 .assign(index_ids
.data(), index_ids
.data() + index_ids
.size());
359 params
.index_keys
.resize(index_keys
.size());
360 for (size_t i
= 0; i
< index_keys
.size(); ++i
) {
361 params
.index_keys
[i
].resize(index_keys
[i
].size());
362 for (size_t j
= 0; j
< index_keys
[i
].size(); ++j
) {
363 params
.index_keys
[i
][j
] =
364 IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys
[i
][j
]));
367 Send(new IndexedDBHostMsg_DatabasePut(params
));
370 void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor(
371 int32 ipc_database_id
,
372 int64 transaction_id
,
373 int64 object_store_id
,
375 const IndexedDBKeyRange
& key_range
,
376 unsigned short direction
,
378 WebIDBDatabase::TaskType task_type
,
379 WebIDBCallbacks
* callbacks
) {
380 ResetCursorPrefetchCaches();
381 IndexedDBHostMsg_DatabaseOpenCursor_Params params
;
382 init_params(params
, callbacks
);
383 params
.ipc_database_id
= ipc_database_id
;
384 params
.transaction_id
= transaction_id
;
385 params
.object_store_id
= object_store_id
;
386 params
.index_id
= index_id
;
387 params
.key_range
= key_range
;
388 params
.direction
= direction
;
389 params
.key_only
= key_only
;
390 params
.task_type
= task_type
;
391 Send(new IndexedDBHostMsg_DatabaseOpenCursor(params
));
394 void IndexedDBDispatcher::RequestIDBDatabaseCount(
395 int32 ipc_database_id
,
396 int64 transaction_id
,
397 int64 object_store_id
,
399 const IndexedDBKeyRange
& key_range
,
400 WebIDBCallbacks
* callbacks
) {
401 ResetCursorPrefetchCaches();
402 IndexedDBHostMsg_DatabaseCount_Params params
;
403 init_params(params
, callbacks
);
404 params
.ipc_database_id
= ipc_database_id
;
405 params
.transaction_id
= transaction_id
;
406 params
.object_store_id
= object_store_id
;
407 params
.index_id
= index_id
;
408 params
.key_range
= key_range
;
409 Send(new IndexedDBHostMsg_DatabaseCount(params
));
412 void IndexedDBDispatcher::RequestIDBDatabaseDeleteRange(
413 int32 ipc_database_id
,
414 int64 transaction_id
,
415 int64 object_store_id
,
416 const IndexedDBKeyRange
& key_range
,
417 WebIDBCallbacks
* callbacks
) {
418 ResetCursorPrefetchCaches();
419 IndexedDBHostMsg_DatabaseDeleteRange_Params params
;
420 init_params(params
, callbacks
);
421 params
.ipc_database_id
= ipc_database_id
;
422 params
.transaction_id
= transaction_id
;
423 params
.object_store_id
= object_store_id
;
424 params
.key_range
= key_range
;
425 Send(new IndexedDBHostMsg_DatabaseDeleteRange(params
));
428 void IndexedDBDispatcher::RequestIDBDatabaseClear(
429 int32 ipc_database_id
,
430 int64 transaction_id
,
431 int64 object_store_id
,
432 WebIDBCallbacks
* callbacks_ptr
) {
433 scoped_ptr
<WebIDBCallbacks
> callbacks(callbacks_ptr
);
434 int32 ipc_callbacks_id
= pending_callbacks_
.Add(callbacks
.release());
435 Send(new IndexedDBHostMsg_DatabaseClear(CurrentWorkerId(),
442 void IndexedDBDispatcher::CursorDestroyed(int32 ipc_cursor_id
) {
443 cursors_
.erase(ipc_cursor_id
);
446 void IndexedDBDispatcher::DatabaseDestroyed(int32 ipc_database_id
) {
447 DCHECK_EQ(databases_
.count(ipc_database_id
), 1u);
448 databases_
.erase(ipc_database_id
);
451 void IndexedDBDispatcher::OnSuccessIDBDatabase(
453 int32 ipc_callbacks_id
,
454 int32 ipc_database_callbacks_id
,
456 const IndexedDBDatabaseMetadata
& idb_metadata
) {
457 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
458 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
461 WebIDBMetadata
metadata(ConvertMetadata(idb_metadata
));
462 // If an upgrade was performed, count will be non-zero.
463 if (!databases_
.count(ipc_object_id
))
464 databases_
[ipc_object_id
] = new RendererWebIDBDatabaseImpl(
465 ipc_object_id
, ipc_database_callbacks_id
, thread_safe_sender_
.get());
466 DCHECK_EQ(databases_
.count(ipc_object_id
), 1u);
467 callbacks
->onSuccess(databases_
[ipc_object_id
], metadata
);
468 pending_callbacks_
.Remove(ipc_callbacks_id
);
471 void IndexedDBDispatcher::OnSuccessIndexedDBKey(int32 ipc_thread_id
,
472 int32 ipc_callbacks_id
,
473 const IndexedDBKey
& key
) {
474 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
475 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
478 callbacks
->onSuccess(WebIDBKeyBuilder::Build(key
));
479 pending_callbacks_
.Remove(ipc_callbacks_id
);
482 void IndexedDBDispatcher::OnSuccessStringList(
484 int32 ipc_callbacks_id
,
485 const std::vector
<string16
>& value
) {
486 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
487 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
490 callbacks
->onSuccess(WebVector
<WebString
>(value
));
491 pending_callbacks_
.Remove(ipc_callbacks_id
);
494 void IndexedDBDispatcher::OnSuccessValue(int32 ipc_thread_id
,
495 int32 ipc_callbacks_id
,
496 const std::string
& value
) {
497 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
498 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
503 web_value
.assign(&*value
.begin(), value
.size());
504 callbacks
->onSuccess(web_value
);
505 pending_callbacks_
.Remove(ipc_callbacks_id
);
508 void IndexedDBDispatcher::OnSuccessValueWithKey(
510 int32 ipc_callbacks_id
,
511 const std::string
& value
,
512 const IndexedDBKey
& primary_key
,
513 const IndexedDBKeyPath
& key_path
) {
514 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
515 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
520 web_value
.assign(&*value
.begin(), value
.size());
521 callbacks
->onSuccess(web_value
,
522 WebIDBKeyBuilder::Build(primary_key
),
523 WebIDBKeyPathBuilder::Build(key_path
));
524 pending_callbacks_
.Remove(ipc_callbacks_id
);
527 void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id
,
528 int32 ipc_callbacks_id
,
530 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
531 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
534 callbacks
->onSuccess(value
);
535 pending_callbacks_
.Remove(ipc_callbacks_id
);
538 void IndexedDBDispatcher::OnSuccessUndefined(int32 ipc_thread_id
,
539 int32 ipc_callbacks_id
) {
540 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
541 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
544 callbacks
->onSuccess();
545 pending_callbacks_
.Remove(ipc_callbacks_id
);
548 void IndexedDBDispatcher::OnSuccessOpenCursor(
549 const IndexedDBMsg_CallbacksSuccessIDBCursor_Params
& p
) {
550 DCHECK_EQ(p
.ipc_thread_id
, CurrentWorkerId());
551 int32 ipc_callbacks_id
= p
.ipc_callbacks_id
;
552 int32 ipc_object_id
= p
.ipc_cursor_id
;
553 const IndexedDBKey
& key
= p
.key
;
554 const IndexedDBKey
& primary_key
= p
.primary_key
;
557 web_value
.assign(&*p
.value
.begin(), p
.value
.size());
559 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
563 RendererWebIDBCursorImpl
* cursor
=
564 new RendererWebIDBCursorImpl(ipc_object_id
, thread_safe_sender_
.get());
565 cursors_
[ipc_object_id
] = cursor
;
566 callbacks
->onSuccess(cursor
, WebIDBKeyBuilder::Build(key
),
567 WebIDBKeyBuilder::Build(primary_key
), web_value
);
569 pending_callbacks_
.Remove(ipc_callbacks_id
);
572 void IndexedDBDispatcher::OnSuccessCursorContinue(
573 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params
& p
) {
574 DCHECK_EQ(p
.ipc_thread_id
, CurrentWorkerId());
575 int32 ipc_callbacks_id
= p
.ipc_callbacks_id
;
576 int32 ipc_cursor_id
= p
.ipc_cursor_id
;
577 const IndexedDBKey
& key
= p
.key
;
578 const IndexedDBKey
& primary_key
= p
.primary_key
;
579 const std::string
& value
= p
.value
;
581 RendererWebIDBCursorImpl
* cursor
= cursors_
[ipc_cursor_id
];
584 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
590 web_value
.assign(&*value
.begin(), value
.size());
591 callbacks
->onSuccess(WebIDBKeyBuilder::Build(key
),
592 WebIDBKeyBuilder::Build(primary_key
), web_value
);
594 pending_callbacks_
.Remove(ipc_callbacks_id
);
597 void IndexedDBDispatcher::OnSuccessCursorPrefetch(
598 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params
& p
) {
599 DCHECK_EQ(p
.ipc_thread_id
, CurrentWorkerId());
600 int32 ipc_callbacks_id
= p
.ipc_callbacks_id
;
601 int32 ipc_cursor_id
= p
.ipc_cursor_id
;
602 const std::vector
<IndexedDBKey
>& keys
= p
.keys
;
603 const std::vector
<IndexedDBKey
>& primary_keys
= p
.primary_keys
;
604 std::vector
<WebData
> values(p
.values
.size());
605 for (size_t i
= 0; i
< p
.values
.size(); ++i
) {
606 if (p
.values
[i
].size())
607 values
[i
].assign(&*p
.values
[i
].begin(), p
.values
[i
].size());
609 RendererWebIDBCursorImpl
* cursor
= cursors_
[ipc_cursor_id
];
611 cursor
->SetPrefetchData(keys
, primary_keys
, values
);
613 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
615 cursor
->CachedContinue(callbacks
);
616 pending_callbacks_
.Remove(ipc_callbacks_id
);
619 void IndexedDBDispatcher::OnIntBlocked(int32 ipc_thread_id
,
620 int32 ipc_callbacks_id
,
621 int64 existing_version
) {
622 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
623 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
625 callbacks
->onBlocked(existing_version
);
628 void IndexedDBDispatcher::OnUpgradeNeeded(
629 const IndexedDBMsg_CallbacksUpgradeNeeded_Params
& p
) {
630 DCHECK_EQ(p
.ipc_thread_id
, CurrentWorkerId());
631 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(p
.ipc_callbacks_id
);
633 WebIDBMetadata
metadata(ConvertMetadata(p
.idb_metadata
));
634 DCHECK(!databases_
.count(p
.ipc_database_id
));
635 databases_
[p
.ipc_database_id
] =
636 new RendererWebIDBDatabaseImpl(p
.ipc_database_id
,
637 p
.ipc_database_callbacks_id
,
638 thread_safe_sender_
.get());
639 callbacks
->onUpgradeNeeded(
641 databases_
[p
.ipc_database_id
],
643 static_cast<WebIDBCallbacks::DataLoss
>(p
.data_loss
));
646 void IndexedDBDispatcher::OnError(int32 ipc_thread_id
,
647 int32 ipc_callbacks_id
,
649 const string16
& message
) {
650 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
651 WebIDBCallbacks
* callbacks
= pending_callbacks_
.Lookup(ipc_callbacks_id
);
655 callbacks
->onError(WebIDBDatabaseError(code
));
657 callbacks
->onError(WebIDBDatabaseError(code
, message
));
658 pending_callbacks_
.Remove(ipc_callbacks_id
);
661 void IndexedDBDispatcher::OnAbort(int32 ipc_thread_id
,
662 int32 ipc_database_callbacks_id
,
663 int64 transaction_id
,
665 const string16
& message
) {
666 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
667 WebIDBDatabaseCallbacks
* callbacks
=
668 pending_database_callbacks_
.Lookup(ipc_database_callbacks_id
);
672 callbacks
->onAbort(transaction_id
, WebIDBDatabaseError(code
));
674 callbacks
->onAbort(transaction_id
, WebIDBDatabaseError(code
, message
));
677 void IndexedDBDispatcher::OnComplete(int32 ipc_thread_id
,
678 int32 ipc_database_callbacks_id
,
679 int64 transaction_id
) {
680 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
681 WebIDBDatabaseCallbacks
* callbacks
=
682 pending_database_callbacks_
.Lookup(ipc_database_callbacks_id
);
685 callbacks
->onComplete(transaction_id
);
688 void IndexedDBDispatcher::OnForcedClose(int32 ipc_thread_id
,
689 int32 ipc_database_callbacks_id
) {
690 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
691 WebIDBDatabaseCallbacks
* callbacks
=
692 pending_database_callbacks_
.Lookup(ipc_database_callbacks_id
);
695 callbacks
->onForcedClose();
698 void IndexedDBDispatcher::OnIntVersionChange(int32 ipc_thread_id
,
699 int32 ipc_database_callbacks_id
,
702 DCHECK_EQ(ipc_thread_id
, CurrentWorkerId());
703 WebIDBDatabaseCallbacks
* callbacks
=
704 pending_database_callbacks_
.Lookup(ipc_database_callbacks_id
);
705 // callbacks would be NULL if a versionchange event is received after close
709 callbacks
->onVersionChange(old_version
, new_version
);
712 void IndexedDBDispatcher::ResetCursorPrefetchCaches(
713 int32 ipc_exception_cursor_id
) {
714 typedef std::map
<int32
, RendererWebIDBCursorImpl
*>::iterator Iterator
;
715 for (Iterator i
= cursors_
.begin(); i
!= cursors_
.end(); ++i
) {
716 if (i
->first
== ipc_exception_cursor_id
)
718 i
->second
->ResetPrefetchCache();
722 } // namespace content