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 std::string data_loss_message) {
112 DCHECK(dispatcher_host_.get());
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_);
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)
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));
137 void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
138 const IndexedDBDatabaseMetadata& metadata) {
139 DCHECK(dispatcher_host_.get());
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_);
146 scoped_refptr<IndexedDBCallbacks> self(this);
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_);
154 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
157 ipc_database_callbacks_id_,
159 IndexedDBDispatcherHost::ConvertMetadata(metadata)));
160 dispatcher_host_ = NULL;
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());
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_);
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;
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));
187 dispatcher_host_ = NULL;
190 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
191 const IndexedDBKey& primary_key,
192 std::string* value) {
193 DCHECK(dispatcher_host_.get());
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_);
200 IndexedDBCursor* idb_cursor =
201 dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
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_;
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;
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());
228 DCHECK(dispatcher_host_.get());
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_);
235 std::vector<IndexedDBKey> msgKeys;
236 std::vector<IndexedDBKey> msgPrimaryKeys;
238 for (size_t i = 0; i < keys.size(); ++i) {
239 msgKeys.push_back(keys[i]);
240 msgPrimaryKeys.push_back(primary_keys[i]);
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;
255 void IndexedDBCallbacks::OnSuccess(std::string* value,
256 const IndexedDBKey& key,
257 const IndexedDBKeyPath& key_path) {
258 DCHECK(dispatcher_host_.get());
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_);
265 std::string value_copy;
266 if (value && !value->empty())
267 std::swap(value_copy, *value);
269 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValueWithKey(
272 // TODO(alecflett): Avoid a copy here.
276 dispatcher_host_ = NULL;
279 void IndexedDBCallbacks::OnSuccess(std::string* value) {
280 DCHECK(dispatcher_host_.get());
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_);
287 std::string value_copy;
288 if (value && !value->empty())
289 std::swap(value_copy, *value);
291 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(
294 // TODO(alecflett): avoid a copy here.
296 dispatcher_host_ = NULL;
299 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
300 DCHECK(dispatcher_host_.get());
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_);
307 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
308 ipc_thread_id_, ipc_callbacks_id_, value));
309 dispatcher_host_ = NULL;
312 void IndexedDBCallbacks::OnSuccess(int64 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_);
320 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
321 ipc_thread_id_, ipc_callbacks_id_, value));
322 dispatcher_host_ = NULL;
325 void IndexedDBCallbacks::OnSuccess() {
326 DCHECK(dispatcher_host_.get());
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_);
333 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
334 ipc_thread_id_, ipc_callbacks_id_));
335 dispatcher_host_ = NULL;
338 } // namespace content