Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_callbacks.cc
blob74c2558bf7f613e23babf7ff525fce8b03811487
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"
7 #include <algorithm>
9 #include "base/guid.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;
31 namespace content {
33 namespace {
34 const int32 kNoCursor = -1;
35 const int32 kNoDatabaseCallbacks = -1;
36 const int64 kNoTransaction = -1;
39 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
40 int32 ipc_thread_id,
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,
52 int32 ipc_thread_id,
53 int32 ipc_callbacks_id,
54 int32 ipc_cursor_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,
65 int32 ipc_thread_id,
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(
129 int64 old_version,
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)
143 return;
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(
176 ipc_thread_id_,
177 ipc_callbacks_id_,
178 ipc_database_callbacks_id_,
179 ipc_object_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();
190 if (!uuid.empty()) {
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);
195 return uuid;
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,
203 task_runner);
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);
217 return uuid;
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());
225 size_t i;
226 if (!dispatcher_host->blob_storage_context())
227 return false;
228 for (i = 0; i < blob_info.size(); ++i) {
229 (*blob_or_file_info)[i].uuid =
230 CreateBlobData(blob_info[i],
231 dispatcher_host,
232 dispatcher_host->blob_storage_context(),
233 dispatcher_host->Context()->TaskRunner());
235 return true;
238 template <class ParamType, class MsgType>
239 static void CreateBlobsAndSend(
240 ParamType* params,
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 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >*
254 blob_or_file_infos) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 DCHECK_EQ(values.size(), blob_or_file_infos->size());
258 std::vector<IndexedDBValue>::const_iterator value_iter;
259 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter;
260 for (value_iter = values.begin(), blob_iter = blob_or_file_infos->begin();
261 value_iter != values.end();
262 ++value_iter, ++blob_iter) {
263 if (!CreateAllBlobs(value_iter->blob_info, &*blob_iter, dispatcher_host))
264 return;
266 dispatcher_host->Send(
267 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params));
270 static void FillInBlobData(
271 const std::vector<IndexedDBBlobInfo>& blob_info,
272 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
273 for (std::vector<IndexedDBBlobInfo>::const_iterator iter = blob_info.begin();
274 iter != blob_info.end();
275 ++iter) {
276 if (iter->is_file()) {
277 IndexedDBMsg_BlobOrFileInfo info;
278 info.is_file = true;
279 info.mime_type = iter->type();
280 info.file_name = iter->file_name();
281 info.file_path = iter->file_path().AsUTF16Unsafe();
282 info.size = iter->size();
283 info.last_modified = iter->last_modified().ToDoubleT();
284 blob_or_file_info->push_back(info);
285 } else {
286 IndexedDBMsg_BlobOrFileInfo info;
287 info.mime_type = iter->type();
288 info.size = iter->size();
289 blob_or_file_info->push_back(info);
294 void IndexedDBCallbacks::RegisterBlobsAndSend(
295 const std::vector<IndexedDBBlobInfo>& blob_info,
296 const base::Closure& callback) {
297 std::vector<IndexedDBBlobInfo>::const_iterator iter;
298 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) {
299 if (!iter->mark_used_callback().is_null())
300 iter->mark_used_callback().Run();
302 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
303 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback);
306 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
307 const IndexedDBKey& key,
308 const IndexedDBKey& primary_key,
309 IndexedDBValue* value) {
310 DCHECK(dispatcher_host_.get());
312 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
313 DCHECK_EQ(kNoTransaction, host_transaction_id_);
314 DCHECK_EQ(kNoDatabase, ipc_database_id_);
315 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
316 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
318 int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
319 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
320 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
321 params->ipc_thread_id = ipc_thread_id_;
322 params->ipc_callbacks_id = ipc_callbacks_id_;
323 params->ipc_cursor_id = ipc_object_id;
324 params->key = key;
325 params->primary_key = primary_key;
326 if (value && !value->empty())
327 std::swap(params->value, value->bits);
328 // TODO(alecflett): Avoid a copy here: the whole params object is
329 // being copied into the message.
330 if (!value || value->blob_info.empty()) {
331 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params));
332 } else {
333 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get();
334 FillInBlobData(value->blob_info, &p->blob_or_file_info);
335 RegisterBlobsAndSend(
336 value->blob_info,
337 base::Bind(
338 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params,
339 IndexedDBMsg_CallbacksSuccessIDBCursor>,
340 base::Owned(params.release()),
341 dispatcher_host_,
342 value->blob_info,
343 base::Unretained(&p->blob_or_file_info)));
345 dispatcher_host_ = NULL;
348 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
349 const IndexedDBKey& primary_key,
350 IndexedDBValue* value) {
351 DCHECK(dispatcher_host_.get());
353 DCHECK_NE(kNoCursor, ipc_cursor_id_);
354 DCHECK_EQ(kNoTransaction, host_transaction_id_);
355 DCHECK_EQ(kNoDatabase, ipc_database_id_);
356 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
357 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
359 IndexedDBCursor* idb_cursor =
360 dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
362 DCHECK(idb_cursor);
363 if (!idb_cursor)
364 return;
366 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params(
367 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
368 params->ipc_thread_id = ipc_thread_id_;
369 params->ipc_callbacks_id = ipc_callbacks_id_;
370 params->ipc_cursor_id = ipc_cursor_id_;
371 params->key = key;
372 params->primary_key = primary_key;
373 if (value && !value->empty())
374 std::swap(params->value, value->bits);
375 // TODO(alecflett): Avoid a copy here: the whole params object is
376 // being copied into the message.
377 if (!value || value->blob_info.empty()) {
378 dispatcher_host_->Send(
379 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params));
380 } else {
381 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get();
382 FillInBlobData(value->blob_info, &p->blob_or_file_info);
383 RegisterBlobsAndSend(
384 value->blob_info,
385 base::Bind(CreateBlobsAndSend<
386 IndexedDBMsg_CallbacksSuccessCursorContinue_Params,
387 IndexedDBMsg_CallbacksSuccessCursorContinue>,
388 base::Owned(params.release()),
389 dispatcher_host_,
390 value->blob_info,
391 base::Unretained(&p->blob_or_file_info)));
393 dispatcher_host_ = NULL;
396 void IndexedDBCallbacks::OnSuccessWithPrefetch(
397 const std::vector<IndexedDBKey>& keys,
398 const std::vector<IndexedDBKey>& primary_keys,
399 std::vector<IndexedDBValue>& values) {
400 DCHECK_EQ(keys.size(), primary_keys.size());
401 DCHECK_EQ(keys.size(), values.size());
403 DCHECK(dispatcher_host_.get());
405 DCHECK_NE(kNoCursor, ipc_cursor_id_);
406 DCHECK_EQ(kNoTransaction, host_transaction_id_);
407 DCHECK_EQ(kNoDatabase, ipc_database_id_);
408 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
409 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
411 std::vector<IndexedDBKey> msgKeys;
412 std::vector<IndexedDBKey> msgPrimaryKeys;
414 for (size_t i = 0; i < keys.size(); ++i) {
415 msgKeys.push_back(keys[i]);
416 msgPrimaryKeys.push_back(primary_keys[i]);
419 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params(
420 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
421 params->ipc_thread_id = ipc_thread_id_;
422 params->ipc_callbacks_id = ipc_callbacks_id_;
423 params->ipc_cursor_id = ipc_cursor_id_;
424 params->keys = msgKeys;
425 params->primary_keys = msgPrimaryKeys;
426 std::vector<std::string>& values_bits = params->values;
427 values_bits.resize(values.size());
428 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >& values_blob_infos =
429 params->blob_or_file_infos;
430 values_blob_infos.resize(values.size());
432 bool found_blob_info = false;
433 std::vector<IndexedDBValue>::iterator iter = values.begin();
434 for (size_t i = 0; iter != values.end(); ++iter, ++i) {
435 values_bits[i].swap(iter->bits);
436 if (iter->blob_info.size()) {
437 found_blob_info = true;
438 FillInBlobData(iter->blob_info, &values_blob_infos[i]);
439 std::vector<IndexedDBBlobInfo>::const_iterator blob_iter;
440 for (blob_iter = iter->blob_info.begin();
441 blob_iter != iter->blob_info.end();
442 ++blob_iter) {
443 if (!blob_iter->mark_used_callback().is_null())
444 blob_iter->mark_used_callback().Run();
449 if (found_blob_info) {
450 BrowserThread::PostTask(
451 BrowserThread::IO,
452 FROM_HERE,
453 base::Bind(BlobLookupForCursorPrefetch,
454 base::Owned(params.release()),
455 dispatcher_host_,
456 values,
457 base::Unretained(&params->blob_or_file_infos)));
458 } else {
459 dispatcher_host_->Send(
460 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get()));
462 dispatcher_host_ = NULL;
465 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value,
466 const IndexedDBKey& key,
467 const IndexedDBKeyPath& key_path) {
468 DCHECK(dispatcher_host_.get());
470 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
471 DCHECK_EQ(kNoTransaction, host_transaction_id_);
472 DCHECK_EQ(kNoDatabase, ipc_database_id_);
473 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
474 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
476 scoped_ptr<IndexedDBMsg_CallbacksSuccessValueWithKey_Params> params(
477 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
478 params->ipc_thread_id = ipc_thread_id_;
479 params->ipc_callbacks_id = ipc_callbacks_id_;
480 params->primary_key = key;
481 params->key_path = key_path;
482 if (value && !value->empty())
483 std::swap(params->value, value->bits);
484 if (!value || value->blob_info.empty()) {
485 dispatcher_host_->Send(
486 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params));
487 } else {
488 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get();
489 FillInBlobData(value->blob_info, &p->blob_or_file_info);
490 RegisterBlobsAndSend(
491 value->blob_info,
492 base::Bind(
493 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValueWithKey_Params,
494 IndexedDBMsg_CallbacksSuccessValueWithKey>,
495 base::Owned(params.release()),
496 dispatcher_host_,
497 value->blob_info,
498 base::Unretained(&p->blob_or_file_info)));
500 dispatcher_host_ = NULL;
503 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value) {
504 DCHECK(dispatcher_host_.get());
505 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL);
506 DCHECK_EQ(kNoTransaction, host_transaction_id_);
507 DCHECK_EQ(kNoDatabase, ipc_database_id_);
508 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
509 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
511 scoped_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(
512 new IndexedDBMsg_CallbacksSuccessValue_Params());
513 params->ipc_thread_id = ipc_thread_id_;
514 params->ipc_callbacks_id = ipc_callbacks_id_;
515 if (value && !value->empty())
516 std::swap(params->value, value->bits);
517 if (!value || value->blob_info.empty()) {
518 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params));
519 } else {
520 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get();
521 FillInBlobData(value->blob_info, &p->blob_or_file_info);
522 RegisterBlobsAndSend(
523 value->blob_info,
524 base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params,
525 IndexedDBMsg_CallbacksSuccessValue>,
526 base::Owned(params.release()),
527 dispatcher_host_,
528 value->blob_info,
529 base::Unretained(&p->blob_or_file_info)));
531 dispatcher_host_ = NULL;
534 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
535 DCHECK(dispatcher_host_.get());
537 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
538 DCHECK_EQ(kNoTransaction, host_transaction_id_);
539 DCHECK_EQ(kNoDatabase, ipc_database_id_);
540 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
541 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
543 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
544 ipc_thread_id_, ipc_callbacks_id_, value));
545 dispatcher_host_ = NULL;
548 void IndexedDBCallbacks::OnSuccess(int64 value) {
549 DCHECK(dispatcher_host_.get());
551 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
552 DCHECK_EQ(kNoTransaction, host_transaction_id_);
553 DCHECK_EQ(kNoDatabase, ipc_database_id_);
554 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
555 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
557 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
558 ipc_thread_id_, ipc_callbacks_id_, value));
559 dispatcher_host_ = NULL;
562 void IndexedDBCallbacks::OnSuccess() {
563 DCHECK(dispatcher_host_.get());
565 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
566 DCHECK_EQ(kNoTransaction, host_transaction_id_);
567 DCHECK_EQ(kNoDatabase, ipc_database_id_);
568 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
569 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
571 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
572 ipc_thread_id_, ipc_callbacks_id_));
573 dispatcher_host_ = NULL;
576 } // namespace content