- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / indexed_db / indexed_db_callbacks.cc
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.
4
5 #include "content/browser/indexed_db/indexed_db_callbacks.h"
6
7 #include <algorithm>
8
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"
16
17 using WebKit::WebIDBCallbacks;
18
19 namespace content {
20
21 namespace {
22 const int32 kNoCursor = -1;
23 const int32 kNoDatabase = -1;
24 const int32 kNoDatabaseCallbacks = -1;
25 const int64 kNoTransaction = -1;
26 }
27
28 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
29                                        int32 ipc_thread_id,
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) {}
38
39 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
40                                        int32 ipc_thread_id,
41                                        int32 ipc_callbacks_id,
42                                        int32 ipc_cursor_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) {}
50
51 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
52                                        int32 ipc_thread_id,
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
66 IndexedDBCallbacks::~IndexedDBCallbacks() {}
67
68 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
69   DCHECK(dispatcher_host_.get());
70
71   dispatcher_host_->Send(new IndexedDBMsg_CallbacksError(
72       ipc_thread_id_, ipc_callbacks_id_, error.code(), error.message()));
73   dispatcher_host_ = NULL;
74 }
75
76 void IndexedDBCallbacks::OnSuccess(const std::vector<string16>& value) {
77   DCHECK(dispatcher_host_.get());
78
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_);
83
84   std::vector<string16> list;
85   for (unsigned i = 0; i < value.size(); ++i)
86     list.push_back(value[i]);
87
88   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessStringList(
89       ipc_thread_id_, ipc_callbacks_id_, list));
90   dispatcher_host_ = NULL;
91 }
92
93 void IndexedDBCallbacks::OnBlocked(int64 existing_version) {
94   DCHECK(dispatcher_host_.get());
95
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_);
101
102   dispatcher_host_->Send(new IndexedDBMsg_CallbacksIntBlocked(
103       ipc_thread_id_, ipc_callbacks_id_, existing_version));
104 }
105
106 void IndexedDBCallbacks::OnUpgradeNeeded(
107     int64 old_version,
108     scoped_ptr<IndexedDBConnection> connection,
109     const IndexedDBDatabaseMetadata& metadata,
110     WebIDBCallbacks::DataLoss data_loss,
111     std::string data_loss_message) {
112   DCHECK(dispatcher_host_.get());
113
114   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
115   DCHECK_NE(kNoTransaction, host_transaction_id_);
116   DCHECK_EQ(kNoDatabase, ipc_database_id_);
117   DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
118
119   dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_url_);
120   int32 ipc_database_id =
121       dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_url_);
122   if (ipc_database_id < 0)
123     return;
124   ipc_database_id_ = ipc_database_id;
125   IndexedDBMsg_CallbacksUpgradeNeeded_Params params;
126   params.ipc_thread_id = ipc_thread_id_;
127   params.ipc_callbacks_id = ipc_callbacks_id_;
128   params.ipc_database_id = ipc_database_id;
129   params.ipc_database_callbacks_id = ipc_database_callbacks_id_;
130   params.old_version = old_version;
131   params.idb_metadata = IndexedDBDispatcherHost::ConvertMetadata(metadata);
132   params.data_loss = data_loss;
133   params.data_loss_message = data_loss_message;
134   dispatcher_host_->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params));
135 }
136
137 void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
138                                    const IndexedDBDatabaseMetadata& metadata) {
139   DCHECK(dispatcher_host_.get());
140
141   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
142   DCHECK_NE(kNoTransaction, host_transaction_id_);
143   DCHECK_NE(ipc_database_id_ == kNoDatabase, !connection);
144   DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
145
146   scoped_refptr<IndexedDBCallbacks> self(this);
147
148   int32 ipc_object_id = ipc_database_id_;
149   if (ipc_object_id == kNoDatabase) {
150     ipc_object_id = dispatcher_host_->Add(
151         connection.release(), ipc_thread_id_, origin_url_);
152   }
153
154   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
155       ipc_thread_id_,
156       ipc_callbacks_id_,
157       ipc_database_callbacks_id_,
158       ipc_object_id,
159       IndexedDBDispatcherHost::ConvertMetadata(metadata)));
160   dispatcher_host_ = NULL;
161 }
162
163 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
164                                    const IndexedDBKey& key,
165                                    const IndexedDBKey& primary_key,
166                                    std::string* value) {
167   DCHECK(dispatcher_host_.get());
168
169   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
170   DCHECK_EQ(kNoTransaction, host_transaction_id_);
171   DCHECK_EQ(kNoDatabase, ipc_database_id_);
172   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
173
174   int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
175   IndexedDBMsg_CallbacksSuccessIDBCursor_Params params;
176   params.ipc_thread_id = ipc_thread_id_;
177   params.ipc_callbacks_id = ipc_callbacks_id_;
178   params.ipc_cursor_id = ipc_object_id;
179   params.key = key;
180   params.primary_key = primary_key;
181   if (value && !value->empty())
182     std::swap(params.value, *value);
183   // TODO(alecflett): Avoid a copy here: the whole params object is
184   // being copied into the message.
185   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(params));
186
187   dispatcher_host_ = NULL;
188 }
189
190 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
191                                    const IndexedDBKey& primary_key,
192                                    std::string* value) {
193   DCHECK(dispatcher_host_.get());
194
195   DCHECK_NE(kNoCursor, ipc_cursor_id_);
196   DCHECK_EQ(kNoTransaction, host_transaction_id_);
197   DCHECK_EQ(kNoDatabase, ipc_database_id_);
198   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
199
200   IndexedDBCursor* idb_cursor =
201       dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
202
203   DCHECK(idb_cursor);
204   if (!idb_cursor)
205     return;
206   IndexedDBMsg_CallbacksSuccessCursorContinue_Params params;
207   params.ipc_thread_id = ipc_thread_id_;
208   params.ipc_callbacks_id = ipc_callbacks_id_;
209   params.ipc_cursor_id = ipc_cursor_id_;
210   params.key = key;
211   params.primary_key = primary_key;
212   if (value && !value->empty())
213     std::swap(params.value, *value);
214   // TODO(alecflett): Avoid a copy here: the whole params object is
215   // being copied into the message.
216   dispatcher_host_->Send(
217       new IndexedDBMsg_CallbacksSuccessCursorContinue(params));
218   dispatcher_host_ = NULL;
219 }
220
221 void IndexedDBCallbacks::OnSuccessWithPrefetch(
222     const std::vector<IndexedDBKey>& keys,
223     const std::vector<IndexedDBKey>& primary_keys,
224     const std::vector<std::string>& values) {
225   DCHECK_EQ(keys.size(), primary_keys.size());
226   DCHECK_EQ(keys.size(), values.size());
227
228   DCHECK(dispatcher_host_.get());
229
230   DCHECK_NE(kNoCursor, ipc_cursor_id_);
231   DCHECK_EQ(kNoTransaction, host_transaction_id_);
232   DCHECK_EQ(kNoDatabase, ipc_database_id_);
233   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
234
235   std::vector<IndexedDBKey> msgKeys;
236   std::vector<IndexedDBKey> msgPrimaryKeys;
237
238   for (size_t i = 0; i < keys.size(); ++i) {
239     msgKeys.push_back(keys[i]);
240     msgPrimaryKeys.push_back(primary_keys[i]);
241   }
242
243   IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params params;
244   params.ipc_thread_id = ipc_thread_id_;
245   params.ipc_callbacks_id = ipc_callbacks_id_;
246   params.ipc_cursor_id = ipc_cursor_id_;
247   params.keys = msgKeys;
248   params.primary_keys = msgPrimaryKeys;
249   params.values = values;
250   dispatcher_host_->Send(
251       new IndexedDBMsg_CallbacksSuccessCursorPrefetch(params));
252   dispatcher_host_ = NULL;
253 }
254
255 void IndexedDBCallbacks::OnSuccess(std::string* value,
256                                    const IndexedDBKey& key,
257                                    const IndexedDBKeyPath& key_path) {
258   DCHECK(dispatcher_host_.get());
259
260   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
261   DCHECK_EQ(kNoTransaction, host_transaction_id_);
262   DCHECK_EQ(kNoDatabase, ipc_database_id_);
263   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
264
265   std::string value_copy;
266   if (value && !value->empty())
267     std::swap(value_copy, *value);
268
269   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValueWithKey(
270       ipc_thread_id_,
271       ipc_callbacks_id_,
272       // TODO(alecflett): Avoid a copy here.
273       value_copy,
274       key,
275       key_path));
276   dispatcher_host_ = NULL;
277 }
278
279 void IndexedDBCallbacks::OnSuccess(std::string* value) {
280   DCHECK(dispatcher_host_.get());
281
282   DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL);
283   DCHECK_EQ(kNoTransaction, host_transaction_id_);
284   DCHECK_EQ(kNoDatabase, ipc_database_id_);
285   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
286
287   std::string value_copy;
288   if (value && !value->empty())
289     std::swap(value_copy, *value);
290
291   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(
292       ipc_thread_id_,
293       ipc_callbacks_id_,
294       // TODO(alecflett): avoid a copy here.
295       value_copy));
296   dispatcher_host_ = NULL;
297 }
298
299 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
300   DCHECK(dispatcher_host_.get());
301
302   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
303   DCHECK_EQ(kNoTransaction, host_transaction_id_);
304   DCHECK_EQ(kNoDatabase, ipc_database_id_);
305   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
306
307   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
308       ipc_thread_id_, ipc_callbacks_id_, value));
309   dispatcher_host_ = NULL;
310 }
311
312 void IndexedDBCallbacks::OnSuccess(int64 value) {
313   DCHECK(dispatcher_host_.get());
314
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
320   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
321       ipc_thread_id_, ipc_callbacks_id_, value));
322   dispatcher_host_ = NULL;
323 }
324
325 void IndexedDBCallbacks::OnSuccess() {
326   DCHECK(dispatcher_host_.get());
327
328   DCHECK_EQ(kNoCursor, ipc_cursor_id_);
329   DCHECK_EQ(kNoTransaction, host_transaction_id_);
330   DCHECK_EQ(kNoDatabase, ipc_database_id_);
331   DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
332
333   dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
334       ipc_thread_id_, ipc_callbacks_id_));
335   dispatcher_host_ = NULL;
336 }
337
338 }  // namespace content