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"
9 #include "content/browser/indexed_db/indexed_db_connection.h"
10 #include "content/browser/indexed_db/indexed_db_cursor.h"
11 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
12 #include "content/browser/indexed_db/indexed_db_database_error.h"
13 #include "content/browser/indexed_db/indexed_db_metadata.h"
14 #include "content/common/indexed_db/indexed_db_constants.h"
15 #include "content/common/indexed_db/indexed_db_messages.h"
16 #include "webkit/browser/quota/quota_manager.h"
21 const int32 kNoCursor
= -1;
22 const int32 kNoDatabaseCallbacks
= -1;
23 const int64 kNoTransaction
= -1;
26 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
28 int32 ipc_callbacks_id
)
29 : dispatcher_host_(dispatcher_host
),
30 ipc_callbacks_id_(ipc_callbacks_id
),
31 ipc_thread_id_(ipc_thread_id
),
32 ipc_cursor_id_(kNoCursor
),
33 host_transaction_id_(kNoTransaction
),
34 ipc_database_id_(kNoDatabase
),
35 ipc_database_callbacks_id_(kNoDatabaseCallbacks
),
36 data_loss_(blink::WebIDBDataLossNone
) {}
38 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
40 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_(ipc_cursor_id
),
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
,
54 int32 ipc_database_callbacks_id
,
55 int64 host_transaction_id
,
56 const GURL
& origin_url
)
57 : dispatcher_host_(dispatcher_host
),
58 ipc_callbacks_id_(ipc_callbacks_id
),
59 ipc_thread_id_(ipc_thread_id
),
60 ipc_cursor_id_(kNoCursor
),
61 host_transaction_id_(host_transaction_id
),
62 origin_url_(origin_url
),
63 ipc_database_id_(kNoDatabase
),
64 ipc_database_callbacks_id_(ipc_database_callbacks_id
),
65 data_loss_(blink::WebIDBDataLossNone
) {}
67 IndexedDBCallbacks::~IndexedDBCallbacks() {}
69 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError
& error
) {
70 DCHECK(dispatcher_host_
.get());
72 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksError(
73 ipc_thread_id_
, ipc_callbacks_id_
, error
.code(), error
.message()));
74 dispatcher_host_
= NULL
;
77 void IndexedDBCallbacks::OnSuccess(const std::vector
<base::string16
>& value
) {
78 DCHECK(dispatcher_host_
.get());
80 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
81 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
82 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
83 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
84 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
86 std::vector
<base::string16
> list
;
87 for (unsigned i
= 0; i
< value
.size(); ++i
)
88 list
.push_back(value
[i
]);
90 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessStringList(
91 ipc_thread_id_
, ipc_callbacks_id_
, list
));
92 dispatcher_host_
= NULL
;
95 void IndexedDBCallbacks::OnBlocked(int64 existing_version
) {
96 DCHECK(dispatcher_host_
.get());
98 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
99 // No transaction/db callbacks for DeleteDatabase.
100 DCHECK_EQ(kNoTransaction
== host_transaction_id_
,
101 kNoDatabaseCallbacks
== ipc_database_callbacks_id_
);
102 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
104 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksIntBlocked(
105 ipc_thread_id_
, ipc_callbacks_id_
, existing_version
));
108 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss
,
109 std::string data_loss_message
) {
110 DCHECK_NE(blink::WebIDBDataLossNone
, data_loss
);
111 data_loss_
= data_loss
;
112 data_loss_message_
= data_loss_message
;
115 void IndexedDBCallbacks::OnUpgradeNeeded(
117 scoped_ptr
<IndexedDBConnection
> connection
,
118 const IndexedDBDatabaseMetadata
& metadata
) {
119 DCHECK(dispatcher_host_
.get());
121 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
122 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
123 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
124 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
126 dispatcher_host_
->RegisterTransactionId(host_transaction_id_
, origin_url_
);
127 int32 ipc_database_id
=
128 dispatcher_host_
->Add(connection
.release(), ipc_thread_id_
, origin_url_
);
129 if (ipc_database_id
< 0)
131 ipc_database_id_
= ipc_database_id
;
132 IndexedDBMsg_CallbacksUpgradeNeeded_Params params
;
133 params
.ipc_thread_id
= ipc_thread_id_
;
134 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
135 params
.ipc_database_id
= ipc_database_id
;
136 params
.ipc_database_callbacks_id
= ipc_database_callbacks_id_
;
137 params
.old_version
= old_version
;
138 params
.idb_metadata
= IndexedDBDispatcherHost::ConvertMetadata(metadata
);
139 params
.data_loss
= data_loss_
;
140 params
.data_loss_message
= data_loss_message_
;
141 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params
));
144 void IndexedDBCallbacks::OnSuccess(scoped_ptr
<IndexedDBConnection
> connection
,
145 const IndexedDBDatabaseMetadata
& metadata
) {
146 DCHECK(dispatcher_host_
.get());
148 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
149 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
150 DCHECK_NE(ipc_database_id_
== kNoDatabase
, !connection
);
151 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
153 scoped_refptr
<IndexedDBCallbacks
> self(this);
155 int32 ipc_object_id
= kNoDatabase
;
156 // Only register if the connection was not previously sent in OnUpgradeNeeded.
157 if (ipc_database_id_
== kNoDatabase
) {
158 ipc_object_id
= dispatcher_host_
->Add(
159 connection
.release(), ipc_thread_id_
, origin_url_
);
162 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
165 ipc_database_callbacks_id_
,
167 IndexedDBDispatcherHost::ConvertMetadata(metadata
)));
168 dispatcher_host_
= NULL
;
171 void IndexedDBCallbacks::OnSuccess(scoped_refptr
<IndexedDBCursor
> cursor
,
172 const IndexedDBKey
& key
,
173 const IndexedDBKey
& primary_key
,
174 std::string
* value
) {
175 DCHECK(dispatcher_host_
.get());
177 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
178 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
179 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
180 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
181 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
183 int32 ipc_object_id
= dispatcher_host_
->Add(cursor
.get());
184 IndexedDBMsg_CallbacksSuccessIDBCursor_Params params
;
185 params
.ipc_thread_id
= ipc_thread_id_
;
186 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
187 params
.ipc_cursor_id
= ipc_object_id
;
189 params
.primary_key
= primary_key
;
190 if (value
&& !value
->empty())
191 std::swap(params
.value
, *value
);
192 // TODO(alecflett): Avoid a copy here: the whole params object is
193 // being copied into the message.
194 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(params
));
196 dispatcher_host_
= NULL
;
199 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& key
,
200 const IndexedDBKey
& primary_key
,
201 std::string
* value
) {
202 DCHECK(dispatcher_host_
.get());
204 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
205 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
206 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
207 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
208 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
210 IndexedDBCursor
* idb_cursor
=
211 dispatcher_host_
->GetCursorFromId(ipc_cursor_id_
);
216 IndexedDBMsg_CallbacksSuccessCursorContinue_Params params
;
217 params
.ipc_thread_id
= ipc_thread_id_
;
218 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
219 params
.ipc_cursor_id
= ipc_cursor_id_
;
221 params
.primary_key
= primary_key
;
222 if (value
&& !value
->empty())
223 std::swap(params
.value
, *value
);
224 // TODO(alecflett): Avoid a copy here: the whole params object is
225 // being copied into the message.
226 dispatcher_host_
->Send(
227 new IndexedDBMsg_CallbacksSuccessCursorContinue(params
));
228 dispatcher_host_
= NULL
;
231 void IndexedDBCallbacks::OnSuccessWithPrefetch(
232 const std::vector
<IndexedDBKey
>& keys
,
233 const std::vector
<IndexedDBKey
>& primary_keys
,
234 const std::vector
<std::string
>& values
) {
235 DCHECK_EQ(keys
.size(), primary_keys
.size());
236 DCHECK_EQ(keys
.size(), values
.size());
238 DCHECK(dispatcher_host_
.get());
240 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
241 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
242 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
243 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
244 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
246 std::vector
<IndexedDBKey
> msgKeys
;
247 std::vector
<IndexedDBKey
> msgPrimaryKeys
;
249 for (size_t i
= 0; i
< keys
.size(); ++i
) {
250 msgKeys
.push_back(keys
[i
]);
251 msgPrimaryKeys
.push_back(primary_keys
[i
]);
254 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params params
;
255 params
.ipc_thread_id
= ipc_thread_id_
;
256 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
257 params
.ipc_cursor_id
= ipc_cursor_id_
;
258 params
.keys
= msgKeys
;
259 params
.primary_keys
= msgPrimaryKeys
;
260 params
.values
= values
;
261 dispatcher_host_
->Send(
262 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(params
));
263 dispatcher_host_
= NULL
;
266 void IndexedDBCallbacks::OnSuccess(std::string
* value
,
267 const IndexedDBKey
& key
,
268 const IndexedDBKeyPath
& key_path
) {
269 DCHECK(dispatcher_host_
.get());
271 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
272 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
273 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
274 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
275 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
277 std::string value_copy
;
278 if (value
&& !value
->empty())
279 std::swap(value_copy
, *value
);
281 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValueWithKey(
284 // TODO(alecflett): Avoid a copy here.
288 dispatcher_host_
= NULL
;
291 void IndexedDBCallbacks::OnSuccess(std::string
* value
) {
292 DCHECK(dispatcher_host_
.get());
294 DCHECK(kNoCursor
== ipc_cursor_id_
|| value
== NULL
);
295 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
296 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
297 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
298 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
300 std::string value_copy
;
301 if (value
&& !value
->empty())
302 std::swap(value_copy
, *value
);
304 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValue(
307 // TODO(alecflett): avoid a copy here.
309 dispatcher_host_
= NULL
;
312 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& value
) {
313 DCHECK(dispatcher_host_
.get());
315 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
316 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
317 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
318 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
319 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
321 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
322 ipc_thread_id_
, ipc_callbacks_id_
, value
));
323 dispatcher_host_
= NULL
;
326 void IndexedDBCallbacks::OnSuccess(int64 value
) {
327 DCHECK(dispatcher_host_
.get());
329 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
330 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
331 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
332 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
333 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
335 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessInteger(
336 ipc_thread_id_
, ipc_callbacks_id_
, value
));
337 dispatcher_host_
= NULL
;
340 void IndexedDBCallbacks::OnSuccess() {
341 DCHECK(dispatcher_host_
.get());
343 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
344 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
345 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
346 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
347 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
349 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
350 ipc_thread_id_
, ipc_callbacks_id_
));
351 dispatcher_host_
= NULL
;
354 } // namespace content