OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/offline_pages/background/request_queue_store_sql.h" | 5 #include "components/offline_pages/background/request_queue_store_sql.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/sequenced_task_runner.h" | 12 #include "base/sequenced_task_runner.h" |
13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
14 #include "components/offline_pages/background/save_page_request.h" | 14 #include "components/offline_pages/background/save_page_request.h" |
15 #include "sql/connection.h" | 15 #include "sql/connection.h" |
16 #include "sql/statement.h" | 16 #include "sql/statement.h" |
17 #include "sql/transaction.h" | 17 #include "sql/transaction.h" |
18 | 18 |
19 namespace offline_pages { | 19 namespace offline_pages { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
| 23 using UpdateStatus = RequestQueueStore::UpdateStatus; |
| 24 |
23 // This is a macro instead of a const so that | 25 // This is a macro instead of a const so that |
24 // it can be used inline in other SQL statements below. | 26 // it can be used inline in other SQL statements below. |
25 #define REQUEST_QUEUE_TABLE_NAME "request_queue_v1" | 27 #define REQUEST_QUEUE_TABLE_NAME "request_queue_v1" |
26 const bool kUserRequested = true; | 28 const bool kUserRequested = true; |
27 | 29 |
28 bool CreateRequestQueueTable(sql::Connection* db) { | 30 bool CreateRequestQueueTable(sql::Connection* db) { |
29 const char kSql[] = "CREATE TABLE IF NOT EXISTS " REQUEST_QUEUE_TABLE_NAME | 31 const char kSql[] = "CREATE TABLE IF NOT EXISTS " REQUEST_QUEUE_TABLE_NAME |
30 " (request_id INTEGER PRIMARY KEY NOT NULL," | 32 " (request_id INTEGER PRIMARY KEY NOT NULL," |
31 " creation_time INTEGER NOT NULL," | 33 " creation_time INTEGER NOT NULL," |
32 " activation_time INTEGER NOT NULL DEFAULT 0," | 34 " activation_time INTEGER NOT NULL DEFAULT 0," |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 210 |
209 if (!transaction.Commit()) { | 211 if (!transaction.Commit()) { |
210 requests.clear(); | 212 requests.clear(); |
211 BuildFailedResultList(request_ids, results); | 213 BuildFailedResultList(request_ids, results); |
212 return false; | 214 return false; |
213 } | 215 } |
214 | 216 |
215 return true; | 217 return true; |
216 } | 218 } |
217 | 219 |
| 220 ItemActionStatus Insert(sql::Connection* db, const SavePageRequest& request) { |
| 221 const char kSql[] = |
| 222 "INSERT OR IGNORE INTO " REQUEST_QUEUE_TABLE_NAME |
| 223 " (request_id, creation_time, activation_time," |
| 224 " last_attempt_time, started_attempt_count, completed_attempt_count," |
| 225 " state, url, client_namespace, client_id)" |
| 226 " VALUES " |
| 227 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
| 228 |
| 229 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 230 statement.BindInt64(0, request.request_id()); |
| 231 statement.BindInt64(1, request.creation_time().ToInternalValue()); |
| 232 statement.BindInt64(2, request.activation_time().ToInternalValue()); |
| 233 statement.BindInt64(3, request.last_attempt_time().ToInternalValue()); |
| 234 statement.BindInt64(4, request.started_attempt_count()); |
| 235 statement.BindInt64(5, request.completed_attempt_count()); |
| 236 statement.BindInt64(6, static_cast<int64_t>(request.request_state())); |
| 237 statement.BindString(7, request.url().spec()); |
| 238 statement.BindString(8, request.client_id().name_space); |
| 239 statement.BindString(9, request.client_id().id); |
| 240 |
| 241 if (!statement.Run()) |
| 242 return ItemActionStatus::STORE_ERROR; |
| 243 if (db->GetLastChangeCount() == 0) |
| 244 return ItemActionStatus::ALREADY_EXISTS; |
| 245 return ItemActionStatus::SUCCESS; |
| 246 } |
| 247 |
218 RequestQueueStore::UpdateStatus InsertOrReplace( | 248 RequestQueueStore::UpdateStatus InsertOrReplace( |
219 sql::Connection* db, | 249 sql::Connection* db, |
220 const SavePageRequest& request) { | 250 const SavePageRequest& request) { |
221 // In order to use the enums in the Bind* methods, keep the order of fields | 251 // In order to use the enums in the Bind* methods, keep the order of fields |
222 // the same as in the definition/select query. | 252 // the same as in the definition/select query. |
223 const char kInsertSql[] = | 253 const char kInsertSql[] = |
224 "INSERT OR REPLACE INTO " REQUEST_QUEUE_TABLE_NAME | 254 "INSERT OR REPLACE INTO " REQUEST_QUEUE_TABLE_NAME |
225 " (request_id, creation_time, activation_time, last_attempt_time, " | 255 " (request_id, creation_time, activation_time, last_attempt_time, " |
226 " started_attempt_count, completed_attempt_count, state, url, " | 256 " started_attempt_count, completed_attempt_count, state, url, " |
227 " client_namespace, client_id) " | 257 " client_namespace, client_id) " |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 304 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
275 | 305 |
276 std::vector<std::unique_ptr<SavePageRequest>> requests; | 306 std::vector<std::unique_ptr<SavePageRequest>> requests; |
277 while (statement.Step()) | 307 while (statement.Step()) |
278 requests.push_back(MakeSavePageRequest(statement)); | 308 requests.push_back(MakeSavePageRequest(statement)); |
279 | 309 |
280 runner->PostTask(FROM_HERE, base::Bind(callback, statement.Succeeded(), | 310 runner->PostTask(FROM_HERE, base::Bind(callback, statement.Succeeded(), |
281 base::Passed(&requests))); | 311 base::Passed(&requests))); |
282 } | 312 } |
283 | 313 |
| 314 void AddRequestSync(sql::Connection* db, |
| 315 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 316 const SavePageRequest& request, |
| 317 const RequestQueueStore::AddCallback& callback) { |
| 318 // TODO(fgorski): add UMA metrics here. |
| 319 ItemActionStatus status = Insert(db, request); |
| 320 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
| 321 } |
| 322 |
284 void AddOrUpdateRequestSync(sql::Connection* db, | 323 void AddOrUpdateRequestSync(sql::Connection* db, |
285 scoped_refptr<base::SingleThreadTaskRunner> runner, | 324 scoped_refptr<base::SingleThreadTaskRunner> runner, |
286 const SavePageRequest& request, | 325 const SavePageRequest& request, |
287 const RequestQueueStore::UpdateCallback& callback) { | 326 const RequestQueueStore::UpdateCallback& callback) { |
288 // TODO(fgorski): add UMA metrics here. | 327 // TODO(fgorski): add UMA metrics here. |
289 RequestQueueStore::UpdateStatus status = InsertOrReplace(db, request); | 328 RequestQueueStore::UpdateStatus status = InsertOrReplace(db, request); |
290 runner->PostTask(FROM_HERE, base::Bind(callback, status)); | 329 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
291 } | 330 } |
292 | 331 |
293 void RemoveRequestsSync(sql::Connection* db, | 332 void RemoveRequestsSync(sql::Connection* db, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 DCHECK(db_.get()); | 408 DCHECK(db_.get()); |
370 std::vector<std::unique_ptr<SavePageRequest>> requests; | 409 std::vector<std::unique_ptr<SavePageRequest>> requests; |
371 if (!CheckDb(base::Bind(callback, false, base::Passed(&requests)))) | 410 if (!CheckDb(base::Bind(callback, false, base::Passed(&requests)))) |
372 return; | 411 return; |
373 | 412 |
374 background_task_runner_->PostTask( | 413 background_task_runner_->PostTask( |
375 FROM_HERE, base::Bind(&GetRequestsSync, db_.get(), | 414 FROM_HERE, base::Bind(&GetRequestsSync, db_.get(), |
376 base::ThreadTaskRunnerHandle::Get(), callback)); | 415 base::ThreadTaskRunnerHandle::Get(), callback)); |
377 } | 416 } |
378 | 417 |
| 418 void RequestQueueStoreSQL::AddRequest(const SavePageRequest& request, |
| 419 const AddCallback& callback) { |
| 420 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR))) |
| 421 return; |
| 422 |
| 423 background_task_runner_->PostTask( |
| 424 FROM_HERE, |
| 425 base::Bind(&AddRequestSync, db_.get(), |
| 426 base::ThreadTaskRunnerHandle::Get(), request, callback)); |
| 427 } |
| 428 |
379 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, | 429 void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, |
380 const UpdateCallback& callback) { | 430 const UpdateCallback& callback) { |
381 DCHECK(db_.get()); | 431 DCHECK(db_.get()); |
382 if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) | 432 if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) |
383 return; | 433 return; |
384 | 434 |
385 background_task_runner_->PostTask( | 435 background_task_runner_->PostTask( |
386 FROM_HERE, | 436 FROM_HERE, |
387 base::Bind(&AddOrUpdateRequestSync, db_.get(), | 437 base::Bind(&AddOrUpdateRequestSync, db_.get(), |
388 base::ThreadTaskRunnerHandle::Get(), request, callback)); | 438 base::ThreadTaskRunnerHandle::Get(), request, callback)); |
389 } | 439 } |
390 | 440 |
391 // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. | |
392 void RequestQueueStoreSQL::RemoveRequests( | 441 void RequestQueueStoreSQL::RemoveRequests( |
393 const std::vector<int64_t>& request_ids, | 442 const std::vector<int64_t>& request_ids, |
394 const RemoveCallback& callback) { | 443 const RemoveCallback& callback) { |
395 // Set up a failed set of results in case we fail the DB check. | 444 // Set up a failed set of results in case we fail the DB check. |
396 RequestQueue::UpdateMultipleRequestResults results; | 445 RequestQueue::UpdateMultipleRequestResults results; |
397 for (int64_t request_id : request_ids) { | 446 for (int64_t request_id : request_ids) { |
398 results.push_back(std::make_pair( | 447 results.push_back(std::make_pair( |
399 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); | 448 request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); |
400 } | 449 } |
401 | 450 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 } | 509 } |
461 | 510 |
462 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, | 511 void RequestQueueStoreSQL::OnResetDone(const ResetCallback& callback, |
463 bool success) { | 512 bool success) { |
464 // Complete connection initialization post reset. | 513 // Complete connection initialization post reset. |
465 OnOpenConnectionDone(success); | 514 OnOpenConnectionDone(success); |
466 callback.Run(success); | 515 callback.Run(success); |
467 } | 516 } |
468 | 517 |
469 } // namespace offline_pages | 518 } // namespace offline_pages |
OLD | NEW |