1 // Copyright (c) 2012 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/browser/indexed_db/indexed_db_callbacks.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "content/browser/child_process_security_policy_impl.h"
13 #include "content/browser/fileapi/fileapi_message_filter.h"
14 #include "content/browser/indexed_db/indexed_db_blob_info.h"
15 #include "content/browser/indexed_db/indexed_db_connection.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
17 #include "content/browser/indexed_db/indexed_db_cursor.h"
18 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
19 #include "content/browser/indexed_db/indexed_db_database_error.h"
20 #include "content/browser/indexed_db/indexed_db_metadata.h"
21 #include "content/browser/indexed_db/indexed_db_value.h"
22 #include "content/common/indexed_db/indexed_db_constants.h"
23 #include "content/common/indexed_db/indexed_db_messages.h"
24 #include "webkit/browser/blob/blob_storage_context.h"
25 #include "webkit/browser/quota/quota_manager.h"
26 #include "webkit/common/blob/blob_data.h"
27 #include "webkit/common/blob/shareable_file_reference.h"
29 using webkit_blob::ShareableFileReference;
34 const int32 kNoCursor = -1;
35 const int32 kNoDatabaseCallbacks = -1;
36 const int64 kNoTransaction = -1;
39 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
41 int32 ipc_callbacks_id)
42 : dispatcher_host_(dispatcher_host),
43 ipc_callbacks_id_(ipc_callbacks_id),
44 ipc_thread_id_(ipc_thread_id),
45 ipc_cursor_id_(kNoCursor),
46 host_transaction_id_(kNoTransaction),
47 ipc_database_id_(kNoDatabase),
48 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
49 data_loss_(blink::WebIDBDataLossNone) {}
51 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
53 int32 ipc_callbacks_id,
55 : dispatcher_host_(dispatcher_host),
56 ipc_callbacks_id_(ipc_callbacks_id),
57 ipc_thread_id_(ipc_thread_id),
58 ipc_cursor_id_(ipc_cursor_id),
59 host_transaction_id_(kNoTransaction),
60 ipc_database_id_(kNoDatabase),
61 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
62 data_loss_(blink::WebIDBDataLossNone) {}
64 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
66 int32 ipc_callbacks_id,
67 int32 ipc_database_callbacks_id,
68 int64 host_transaction_id,
69 const GURL& origin_url)
70 : dispatcher_host_(dispatcher_host),
71 ipc_callbacks_id_(ipc_callbacks_id),
72 ipc_thread_id_(ipc_thread_id),
73 ipc_cursor_id_(kNoCursor),
74 host_transaction_id_(host_transaction_id),
75 origin_url_(origin_url),
76 ipc_database_id_(kNoDatabase),
77 ipc_database_callbacks_id_(ipc_database_callbacks_id),
78 data_loss_(blink::WebIDBDataLossNone) {}
80 IndexedDBCallbacks::~IndexedDBCallbacks() {}
82 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
83 DCHECK(dispatcher_host_.get());
85 dispatcher_host_->Send(new IndexedDBMsg_CallbacksError(
86 ipc_thread_id_, ipc_callbacks_id_, error.code(), error.message()));
87 dispatcher_host_ = NULL;
90 void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
91 DCHECK(dispatcher_host_.get());
93 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
94 DCHECK_EQ(kNoTransaction, host_transaction_id_);
95 DCHECK_EQ(kNoDatabase, ipc_database_id_);
96 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
97 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
99 std::vector<base::string16> list;
100 for (unsigned i = 0; i < value.size(); ++i)
101 list.push_back(value[i]);
103 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessStringList(
104 ipc_thread_id_, ipc_callbacks_id_, list));
105 dispatcher_host_ = NULL;
108 void IndexedDBCallbacks::OnBlocked(int64 existing_version) {
109 DCHECK(dispatcher_host_.get());
111 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
112 // No transaction/db callbacks for DeleteDatabase.
113 DCHECK_EQ(kNoTransaction == host_transaction_id_,
114 kNoDatabaseCallbacks == ipc_database_callbacks_id_);
115 DCHECK_EQ(kNoDatabase, ipc_database_id_);
117 dispatcher_host_->Send(new IndexedDBMsg_CallbacksIntBlocked(
118 ipc_thread_id_, ipc_callbacks_id_, existing_version));
121 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss,
122 std::string data_loss_message) {
123 DCHECK_NE(blink::WebIDBDataLossNone, data_loss);
124 data_loss_ = data_loss;
125 data_loss_message_ = data_loss_message;
128 void IndexedDBCallbacks::OnUpgradeNeeded(
130 scoped_ptr<IndexedDBConnection> connection,
131 const IndexedDBDatabaseMetadata& metadata) {
132 DCHECK(dispatcher_host_.get());
134 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
135 DCHECK_NE(kNoTransaction, host_transaction_id_);
136 DCHECK_EQ(kNoDatabase, ipc_database_id_);
137 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
139 dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_url_);
140 int32 ipc_database_id =
141 dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_url_);
142 if (ipc_database_id < 0)
144 ipc_database_id_ = ipc_database_id;
145 IndexedDBMsg_CallbacksUpgradeNeeded_Params params;
146 params.ipc_thread_id = ipc_thread_id_;
147 params.ipc_callbacks_id = ipc_callbacks_id_;
148 params.ipc_database_id = ipc_database_id;
149 params.ipc_database_callbacks_id = ipc_database_callbacks_id_;
150 params.old_version = old_version;
151 params.idb_metadata = IndexedDBDispatcherHost::ConvertMetadata(metadata);
152 params.data_loss = data_loss_;
153 params.data_loss_message = data_loss_message_;
154 dispatcher_host_->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params));
157 void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
158 const IndexedDBDatabaseMetadata& metadata) {
159 DCHECK(dispatcher_host_.get());
161 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
162 DCHECK_NE(kNoTransaction, host_transaction_id_);
163 DCHECK_NE(ipc_database_id_ == kNoDatabase, !connection);
164 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
166 scoped_refptr<IndexedDBCallbacks> self(this);
168 int32 ipc_object_id = kNoDatabase;
169 // Only register if the connection was not previously sent in OnUpgradeNeeded.
170 if (ipc_database_id_ == kNoDatabase) {
171 ipc_object_id = dispatcher_host_->Add(
172 connection.release(), ipc_thread_id_, origin_url_);
175 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
178 ipc_database_callbacks_id_,
180 IndexedDBDispatcherHost::ConvertMetadata(metadata)));
181 dispatcher_host_ = NULL;
184 static std::string CreateBlobData(
185 const IndexedDBBlobInfo& blob_info,
186 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
187 webkit_blob::BlobStorageContext* blob_storage_context,
188 base::TaskRunner* task_runner) {
189 std::string uuid = blob_info.uuid();
191 // We're sending back a live blob, not a reference into our backing store.
192 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle(
193 blob_storage_context->GetBlobDataFromUUID(uuid));
194 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle);
197 scoped_refptr<ShareableFileReference> shareable_file =
198 ShareableFileReference::Get(blob_info.file_path());
199 if (!shareable_file.get()) {
200 shareable_file = ShareableFileReference::GetOrCreate(
201 blob_info.file_path(),
202 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
204 if (!blob_info.release_callback().is_null())
205 shareable_file->AddFinalReleaseCallback(blob_info.release_callback());
208 uuid = base::GenerateGUID();
209 scoped_refptr<webkit_blob::BlobData> blob_data =
210 new webkit_blob::BlobData(uuid);
211 blob_data->AppendFile(
212 blob_info.file_path(), 0, blob_info.size(), blob_info.last_modified());
213 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle(
214 blob_storage_context->AddFinishedBlob(blob_data.get()));
215 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle);
220 static bool CreateAllBlobs(
221 const std::vector<IndexedDBBlobInfo>& blob_info,
222 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info,
223 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) {
224 DCHECK_EQ(blob_info.size(), blob_or_file_info->size());
226 if (!dispatcher_host->blob_storage_context())
228 for (i = 0; i < blob_info.size(); ++i) {
229 (*blob_or_file_info)[i].uuid =
230 CreateBlobData(blob_info[i],
232 dispatcher_host->blob_storage_context(),
233 dispatcher_host->Context()->TaskRunner());
238 template <class ParamType, class MsgType>
239 static void CreateBlobsAndSend(
241 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
242 const std::vector<IndexedDBBlobInfo>& blob_info,
243 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
245 if (CreateAllBlobs(blob_info, blob_or_file_info, dispatcher_host))
246 dispatcher_host->Send(new MsgType(*params));
249 static void BlobLookupForCursorPrefetch(
250 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params* params,
251 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
252 const std::vector<IndexedDBValue>& values) {
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
254 DCHECK_EQ(values.size(), params->blob_or_file_infos.size());
256 std::vector<IndexedDBValue>::const_iterator value_iter;
257 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter;
258 for (value_iter = values.begin(), blob_iter =
259 params->blob_or_file_infos.begin(); value_iter != values.end();
260 ++value_iter, ++blob_iter) {
261 if (!CreateAllBlobs(value_iter->blob_info, &*blob_iter, dispatcher_host))
264 dispatcher_host->Send(
265 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params));
268 static void FillInBlobData(
269 const std::vector<IndexedDBBlobInfo>& blob_info,
270 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
271 for (std::vector<IndexedDBBlobInfo>::const_iterator iter = blob_info.begin();
272 iter != blob_info.end();
274 if (iter->is_file()) {
275 IndexedDBMsg_BlobOrFileInfo info;
277 info.mime_type = iter->type();
278 info.file_name = iter->file_name();
279 info.file_path = iter->file_path().AsUTF16Unsafe();
280 info.size = iter->size();
281 info.last_modified = iter->last_modified().ToDoubleT();
282 blob_or_file_info->push_back(info);
284 IndexedDBMsg_BlobOrFileInfo info;
285 info.mime_type = iter->type();
286 info.size = iter->size();
287 blob_or_file_info->push_back(info);
292 void IndexedDBCallbacks::RegisterBlobsAndSend(
293 const std::vector<IndexedDBBlobInfo>& blob_info,
294 const base::Closure& callback) {
295 std::vector<IndexedDBBlobInfo>::const_iterator iter;
296 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) {
297 if (!iter->mark_used_callback().is_null())
298 iter->mark_used_callback().Run();
300 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
301 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback);
304 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
305 const IndexedDBKey& key,
306 const IndexedDBKey& primary_key,
307 IndexedDBValue* value) {
308 DCHECK(dispatcher_host_.get());
310 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
311 DCHECK_EQ(kNoTransaction, host_transaction_id_);
312 DCHECK_EQ(kNoDatabase, ipc_database_id_);
313 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
314 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
316 int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
317 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
318 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
319 params->ipc_thread_id = ipc_thread_id_;
320 params->ipc_callbacks_id = ipc_callbacks_id_;
321 params->ipc_cursor_id = ipc_object_id;
323 params->primary_key = primary_key;
324 if (value && !value->empty())
325 std::swap(params->value, value->bits);
326 // TODO(alecflett): Avoid a copy here: the whole params object is
327 // being copied into the message.
328 if (!value || value->blob_info.empty()) {
329 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params));
331 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get();
332 FillInBlobData(value->blob_info, &p->blob_or_file_info);
333 RegisterBlobsAndSend(
336 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params,
337 IndexedDBMsg_CallbacksSuccessIDBCursor>,
338 base::Owned(params.release()),
341 base::Unretained(&p->blob_or_file_info)));
343 dispatcher_host_ = NULL;
346 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
347 const IndexedDBKey& primary_key,
348 IndexedDBValue* value) {
349 DCHECK(dispatcher_host_.get());
351 DCHECK_NE(kNoCursor, ipc_cursor_id_);
352 DCHECK_EQ(kNoTransaction, host_transaction_id_);
353 DCHECK_EQ(kNoDatabase, ipc_database_id_);
354 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
355 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
357 IndexedDBCursor* idb_cursor =
358 dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
364 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params(
365 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
366 params->ipc_thread_id = ipc_thread_id_;
367 params->ipc_callbacks_id = ipc_callbacks_id_;
368 params->ipc_cursor_id = ipc_cursor_id_;
370 params->primary_key = primary_key;
371 if (value && !value->empty())
372 std::swap(params->value, value->bits);
373 // TODO(alecflett): Avoid a copy here: the whole params object is
374 // being copied into the message.
375 if (!value || value->blob_info.empty()) {
376 dispatcher_host_->Send(
377 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params));
379 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get();
380 FillInBlobData(value->blob_info, &p->blob_or_file_info);
381 RegisterBlobsAndSend(
383 base::Bind(CreateBlobsAndSend<
384 IndexedDBMsg_CallbacksSuccessCursorContinue_Params,
385 IndexedDBMsg_CallbacksSuccessCursorContinue>,
386 base::Owned(params.release()),
389 base::Unretained(&p->blob_or_file_info)));
391 dispatcher_host_ = NULL;
394 void IndexedDBCallbacks::OnSuccessWithPrefetch(
395 const std::vector<IndexedDBKey>& keys,
396 const std::vector<IndexedDBKey>& primary_keys,
397 std::vector<IndexedDBValue>& values) {
398 DCHECK_EQ(keys.size(), primary_keys.size());
399 DCHECK_EQ(keys.size(), values.size());
401 DCHECK(dispatcher_host_.get());
403 DCHECK_NE(kNoCursor, ipc_cursor_id_);
404 DCHECK_EQ(kNoTransaction, host_transaction_id_);
405 DCHECK_EQ(kNoDatabase, ipc_database_id_);
406 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
407 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
409 std::vector<IndexedDBKey> msgKeys;
410 std::vector<IndexedDBKey> msgPrimaryKeys;
412 for (size_t i = 0; i < keys.size(); ++i) {
413 msgKeys.push_back(keys[i]);
414 msgPrimaryKeys.push_back(primary_keys[i]);
417 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params(
418 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
419 params->ipc_thread_id = ipc_thread_id_;
420 params->ipc_callbacks_id = ipc_callbacks_id_;
421 params->ipc_cursor_id = ipc_cursor_id_;
422 params->keys = msgKeys;
423 params->primary_keys = msgPrimaryKeys;
424 std::vector<std::string>& values_bits = params->values;
425 values_bits.resize(values.size());
426 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >& values_blob_infos =
427 params->blob_or_file_infos;
428 values_blob_infos.resize(values.size());
430 bool found_blob_info = false;
431 std::vector<IndexedDBValue>::iterator iter = values.begin();
432 for (size_t i = 0; iter != values.end(); ++iter, ++i) {
433 values_bits[i].swap(iter->bits);
434 if (iter->blob_info.size()) {
435 found_blob_info = true;
436 FillInBlobData(iter->blob_info, &values_blob_infos[i]);
437 std::vector<IndexedDBBlobInfo>::const_iterator blob_iter;
438 for (blob_iter = iter->blob_info.begin();
439 blob_iter != iter->blob_info.end();
441 if (!blob_iter->mark_used_callback().is_null())
442 blob_iter->mark_used_callback().Run();
447 if (found_blob_info) {
448 BrowserThread::PostTask(
451 base::Bind(BlobLookupForCursorPrefetch,
452 base::Owned(params.release()),
456 dispatcher_host_->Send(
457 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get()));
459 dispatcher_host_ = NULL;
462 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value,
463 const IndexedDBKey& key,
464 const IndexedDBKeyPath& key_path) {
465 DCHECK(dispatcher_host_.get());
467 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
468 DCHECK_EQ(kNoTransaction, host_transaction_id_);
469 DCHECK_EQ(kNoDatabase, ipc_database_id_);
470 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
471 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
473 scoped_ptr<IndexedDBMsg_CallbacksSuccessValueWithKey_Params> params(
474 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
475 params->ipc_thread_id = ipc_thread_id_;
476 params->ipc_callbacks_id = ipc_callbacks_id_;
477 params->primary_key = key;
478 params->key_path = key_path;
479 if (value && !value->empty())
480 std::swap(params->value, value->bits);
481 if (!value || value->blob_info.empty()) {
482 dispatcher_host_->Send(
483 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params));
485 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get();
486 FillInBlobData(value->blob_info, &p->blob_or_file_info);
487 RegisterBlobsAndSend(
490 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValueWithKey_Params,
491 IndexedDBMsg_CallbacksSuccessValueWithKey>,
492 base::Owned(params.release()),
495 base::Unretained(&p->blob_or_file_info)));
497 dispatcher_host_ = NULL;
500 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value) {
501 DCHECK(dispatcher_host_.get());
502 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL);
503 DCHECK_EQ(kNoTransaction, host_transaction_id_);
504 DCHECK_EQ(kNoDatabase, ipc_database_id_);
505 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
506 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
508 scoped_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(
509 new IndexedDBMsg_CallbacksSuccessValue_Params());
510 params->ipc_thread_id = ipc_thread_id_;
511 params->ipc_callbacks_id = ipc_callbacks_id_;
512 if (value && !value->empty())
513 std::swap(params->value, value->bits);
514 if (!value || value->blob_info.empty()) {
515 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params));
517 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get();
518 FillInBlobData(value->blob_info, &p->blob_or_file_info);
519 RegisterBlobsAndSend(
521 base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params,
522 IndexedDBMsg_CallbacksSuccessValue>,
523 base::Owned(params.release()),
526 base::Unretained(&p->blob_or_file_info)));
528 dispatcher_host_ = NULL;
531 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
532 DCHECK(dispatcher_host_.get());
534 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
535 DCHECK_EQ(kNoTransaction, host_transaction_id_);
536 DCHECK_EQ(kNoDatabase, ipc_database_id_);
537 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
538 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
540 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
541 ipc_thread_id_, ipc_callbacks_id_, value));
542 dispatcher_host_ = NULL;
545 void IndexedDBCallbacks::OnSuccess(int64 value) {
546 DCHECK(dispatcher_host_.get());
548 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
549 DCHECK_EQ(kNoTransaction, host_transaction_id_);
550 DCHECK_EQ(kNoDatabase, ipc_database_id_);
551 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
552 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
554 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
555 ipc_thread_id_, ipc_callbacks_id_, value));
556 dispatcher_host_ = NULL;
559 void IndexedDBCallbacks::OnSuccess() {
560 DCHECK(dispatcher_host_.get());
562 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
563 DCHECK_EQ(kNoTransaction, host_transaction_id_);
564 DCHECK_EQ(kNoDatabase, ipc_database_id_);
565 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
566 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
568 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
569 ipc_thread_id_, ipc_callbacks_id_));
570 dispatcher_host_ = NULL;
573 } // namespace content