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_messages.h"
15 #include "webkit/browser/quota/quota_manager.h"
17 using WebKit::WebIDBCallbacks
;
22 const int32 kNoCursor
= -1;
23 const int32 kNoDatabase
= -1;
24 const int32 kNoDatabaseCallbacks
= -1;
25 const int64 kNoTransaction
= -1;
28 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
30 int32 ipc_callbacks_id
)
31 : dispatcher_host_(dispatcher_host
),
32 ipc_callbacks_id_(ipc_callbacks_id
),
33 ipc_thread_id_(ipc_thread_id
),
34 ipc_cursor_id_(kNoCursor
),
35 host_transaction_id_(kNoTransaction
),
36 ipc_database_id_(kNoDatabase
),
37 ipc_database_callbacks_id_(kNoDatabaseCallbacks
) {}
39 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
41 int32 ipc_callbacks_id
,
43 : dispatcher_host_(dispatcher_host
),
44 ipc_callbacks_id_(ipc_callbacks_id
),
45 ipc_thread_id_(ipc_thread_id
),
46 ipc_cursor_id_(ipc_cursor_id
),
47 host_transaction_id_(kNoTransaction
),
48 ipc_database_id_(kNoDatabase
),
49 ipc_database_callbacks_id_(kNoDatabaseCallbacks
) {}
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
) {}
66 IndexedDBCallbacks::~IndexedDBCallbacks() {}
68 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError
& error
) {
69 DCHECK(dispatcher_host_
.get());
71 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksError(
72 ipc_thread_id_
, ipc_callbacks_id_
, error
.code(), error
.message()));
73 dispatcher_host_
= NULL
;
76 void IndexedDBCallbacks::OnSuccess(const std::vector
<string16
>& value
) {
77 DCHECK(dispatcher_host_
.get());
79 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
80 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
81 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
82 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
84 std::vector
<string16
> list
;
85 for (unsigned i
= 0; i
< value
.size(); ++i
)
86 list
.push_back(value
[i
]);
88 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessStringList(
89 ipc_thread_id_
, ipc_callbacks_id_
, list
));
90 dispatcher_host_
= NULL
;
93 void IndexedDBCallbacks::OnBlocked(int64 existing_version
) {
94 DCHECK(dispatcher_host_
.get());
96 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
97 // No transaction/db callbacks for DeleteDatabase.
98 DCHECK_EQ(kNoTransaction
== host_transaction_id_
,
99 kNoDatabaseCallbacks
== ipc_database_callbacks_id_
);
100 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
102 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksIntBlocked(
103 ipc_thread_id_
, ipc_callbacks_id_
, existing_version
));
106 void IndexedDBCallbacks::OnUpgradeNeeded(
108 scoped_ptr
<IndexedDBConnection
> connection
,
109 const IndexedDBDatabaseMetadata
& metadata
,
110 WebIDBCallbacks::DataLoss data_loss
) {
111 DCHECK(dispatcher_host_
.get());
113 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
114 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
115 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
116 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
118 dispatcher_host_
->RegisterTransactionId(host_transaction_id_
, origin_url_
);
119 int32 ipc_database_id
=
120 dispatcher_host_
->Add(connection
.release(), ipc_thread_id_
, origin_url_
);
121 if (ipc_database_id
< 0)
123 ipc_database_id_
= ipc_database_id
;
124 IndexedDBMsg_CallbacksUpgradeNeeded_Params params
;
125 params
.ipc_thread_id
= ipc_thread_id_
;
126 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
127 params
.ipc_database_id
= ipc_database_id
;
128 params
.ipc_database_callbacks_id
= ipc_database_callbacks_id_
;
129 params
.old_version
= old_version
;
130 params
.idb_metadata
= IndexedDBDispatcherHost::ConvertMetadata(metadata
);
131 params
.data_loss
= data_loss
;
132 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params
));
135 void IndexedDBCallbacks::OnSuccess(scoped_ptr
<IndexedDBConnection
> connection
,
136 const IndexedDBDatabaseMetadata
& metadata
) {
137 DCHECK(dispatcher_host_
.get());
139 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
140 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
141 DCHECK_NE(ipc_database_id_
== kNoDatabase
, !connection
);
142 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
144 scoped_refptr
<IndexedDBCallbacks
> self(this);
146 int32 ipc_object_id
= ipc_database_id_
;
147 if (ipc_object_id
== kNoDatabase
) {
148 ipc_object_id
= dispatcher_host_
->Add(
149 connection
.release(), ipc_thread_id_
, origin_url_
);
152 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
155 ipc_database_callbacks_id_
,
157 IndexedDBDispatcherHost::ConvertMetadata(metadata
)));
158 dispatcher_host_
= NULL
;
161 void IndexedDBCallbacks::OnSuccess(scoped_refptr
<IndexedDBCursor
> cursor
,
162 const IndexedDBKey
& key
,
163 const IndexedDBKey
& primary_key
,
164 std::string
* value
) {
165 DCHECK(dispatcher_host_
.get());
167 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
168 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
169 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
170 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
172 int32 ipc_object_id
= dispatcher_host_
->Add(cursor
.get());
173 IndexedDBMsg_CallbacksSuccessIDBCursor_Params params
;
174 params
.ipc_thread_id
= ipc_thread_id_
;
175 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
176 params
.ipc_cursor_id
= ipc_object_id
;
178 params
.primary_key
= primary_key
;
179 if (value
&& !value
->empty())
180 std::swap(params
.value
, *value
);
181 // TODO(alecflett): Avoid a copy here: the whole params object is
182 // being copied into the message.
183 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(params
));
185 dispatcher_host_
= NULL
;
188 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& key
,
189 const IndexedDBKey
& primary_key
,
190 std::string
* value
) {
191 DCHECK(dispatcher_host_
.get());
193 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
194 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
195 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
196 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
198 IndexedDBCursor
* idb_cursor
=
199 dispatcher_host_
->GetCursorFromId(ipc_cursor_id_
);
204 IndexedDBMsg_CallbacksSuccessCursorContinue_Params params
;
205 params
.ipc_thread_id
= ipc_thread_id_
;
206 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
207 params
.ipc_cursor_id
= ipc_cursor_id_
;
209 params
.primary_key
= primary_key
;
210 if (value
&& !value
->empty())
211 std::swap(params
.value
, *value
);
212 // TODO(alecflett): Avoid a copy here: the whole params object is
213 // being copied into the message.
214 dispatcher_host_
->Send(
215 new IndexedDBMsg_CallbacksSuccessCursorContinue(params
));
216 dispatcher_host_
= NULL
;
219 void IndexedDBCallbacks::OnSuccessWithPrefetch(
220 const std::vector
<IndexedDBKey
>& keys
,
221 const std::vector
<IndexedDBKey
>& primary_keys
,
222 const std::vector
<std::string
>& values
) {
223 DCHECK_EQ(keys
.size(), primary_keys
.size());
224 DCHECK_EQ(keys
.size(), values
.size());
226 DCHECK(dispatcher_host_
.get());
228 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
229 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
230 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
231 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
233 std::vector
<IndexedDBKey
> msgKeys
;
234 std::vector
<IndexedDBKey
> msgPrimaryKeys
;
236 for (size_t i
= 0; i
< keys
.size(); ++i
) {
237 msgKeys
.push_back(keys
[i
]);
238 msgPrimaryKeys
.push_back(primary_keys
[i
]);
241 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params params
;
242 params
.ipc_thread_id
= ipc_thread_id_
;
243 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
244 params
.ipc_cursor_id
= ipc_cursor_id_
;
245 params
.keys
= msgKeys
;
246 params
.primary_keys
= msgPrimaryKeys
;
247 params
.values
= values
;
248 dispatcher_host_
->Send(
249 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(params
));
250 dispatcher_host_
= NULL
;
253 void IndexedDBCallbacks::OnSuccess(std::string
* value
,
254 const IndexedDBKey
& key
,
255 const IndexedDBKeyPath
& key_path
) {
256 DCHECK(dispatcher_host_
.get());
258 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
259 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
260 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
261 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
263 std::string value_copy
;
264 if (value
&& !value
->empty())
265 std::swap(value_copy
, *value
);
267 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValueWithKey(
270 // TODO(alecflett): Avoid a copy here.
274 dispatcher_host_
= NULL
;
277 void IndexedDBCallbacks::OnSuccess(std::string
* value
) {
278 DCHECK(dispatcher_host_
.get());
280 DCHECK(kNoCursor
== ipc_cursor_id_
|| value
== NULL
);
281 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
282 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
283 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
285 std::string value_copy
;
286 if (value
&& !value
->empty())
287 std::swap(value_copy
, *value
);
289 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValue(
292 // TODO(alecflett): avoid a copy here.
294 dispatcher_host_
= NULL
;
297 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& value
) {
298 DCHECK(dispatcher_host_
.get());
300 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
301 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
302 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
303 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
305 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
306 ipc_thread_id_
, ipc_callbacks_id_
, value
));
307 dispatcher_host_
= NULL
;
310 void IndexedDBCallbacks::OnSuccess(int64 value
) {
311 DCHECK(dispatcher_host_
.get());
313 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
314 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
315 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
316 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
318 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessInteger(
319 ipc_thread_id_
, ipc_callbacks_id_
, value
));
320 dispatcher_host_
= NULL
;
323 void IndexedDBCallbacks::OnSuccess() {
324 DCHECK(dispatcher_host_
.get());
326 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
327 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
328 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
329 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
331 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
332 ipc_thread_id_
, ipc_callbacks_id_
));
333 dispatcher_host_
= NULL
;
336 } // namespace content