Chromium Code Reviews| 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/offline_page_metadata_store_sql.h" | 5 #include "components/offline_pages/offline_page_metadata_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/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/sequenced_task_runner.h" | 13 #include "base/sequenced_task_runner.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "components/offline_pages/offline_page_item.h" | 16 #include "components/offline_pages/offline_page_item.h" |
| 17 #include "sql/connection.h" | 17 #include "sql/connection.h" |
| 18 #include "sql/statement.h" | 18 #include "sql/statement.h" |
| 19 #include "sql/transaction.h" | 19 #include "sql/transaction.h" |
| 20 | 20 |
| 21 namespace offline_pages { | 21 namespace offline_pages { |
| 22 | 22 |
| 23 using StoreState = OfflinePageMetadataStore::StoreState; | |
| 24 using ItemActionStatus = OfflinePageMetadataStore::ItemActionStatus; | |
| 25 | |
| 26 namespace { | 23 namespace { |
| 27 | 24 |
| 28 // This is a macro instead of a const so that | 25 // This is a macro instead of a const so that |
| 29 // it can be used inline in other SQL statements below. | 26 // it can be used inline in other SQL statements below. |
| 30 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" | 27 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" |
| 31 | 28 |
| 32 bool CreateOfflinePagesTable(sql::Connection* db) { | 29 bool CreateOfflinePagesTable(sql::Connection* db) { |
| 33 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME | 30 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME |
| 34 "(offline_id INTEGER PRIMARY KEY NOT NULL," | 31 "(offline_id INTEGER PRIMARY KEY NOT NULL," |
| 35 " creation_time INTEGER NOT NULL," | 32 " creation_time INTEGER NOT NULL," |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 statement.BindInt(8, item.access_count); | 203 statement.BindInt(8, item.access_count); |
| 207 statement.BindInt64(9, item.expiration_time.ToInternalValue()); | 204 statement.BindInt64(9, item.expiration_time.ToInternalValue()); |
| 208 statement.BindString16(10, item.title); | 205 statement.BindString16(10, item.title); |
| 209 if (!statement.Run()) | 206 if (!statement.Run()) |
| 210 return ItemActionStatus::STORE_ERROR; | 207 return ItemActionStatus::STORE_ERROR; |
| 211 if (db->GetLastChangeCount() == 0) | 208 if (db->GetLastChangeCount() == 0) |
| 212 return ItemActionStatus::ALREADY_EXISTS; | 209 return ItemActionStatus::ALREADY_EXISTS; |
| 213 return ItemActionStatus::SUCCESS; | 210 return ItemActionStatus::SUCCESS; |
| 214 } | 211 } |
| 215 | 212 |
| 216 bool InsertOrReplace(sql::Connection* db, const OfflinePageItem& item) { | 213 bool Update(sql::Connection* db, const OfflinePageItem& item) { |
| 217 const char kSql[] = | 214 const char kSql[] = |
| 218 "INSERT OR REPLACE INTO " OFFLINE_PAGES_TABLE_NAME | 215 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME |
| 219 " (offline_id, online_url, client_namespace, client_id, file_path, " | 216 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?," |
| 220 "file_size, creation_time, last_access_time, access_count, " | 217 " file_size = ?, creation_time = ?, last_access_time = ?," |
| 221 "expiration_time, title)" | 218 " access_count = ?, expiration_time = ?, title = ?" |
| 222 " VALUES " | 219 " WHERE offline_id = ?"; |
| 223 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | |
| 224 | 220 |
| 225 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 221 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 226 statement.BindInt64(0, item.offline_id); | 222 statement.BindString(0, item.url.spec()); |
| 227 statement.BindString(1, item.url.spec()); | 223 statement.BindString(1, item.client_id.name_space); |
| 228 statement.BindString(2, item.client_id.name_space); | 224 statement.BindString(2, item.client_id.id); |
| 229 statement.BindString(3, item.client_id.id); | 225 statement.BindString(3, GetUTF8StringFromPath(item.file_path)); |
| 230 statement.BindString(4, GetUTF8StringFromPath(item.file_path)); | 226 statement.BindInt64(4, item.file_size); |
| 231 statement.BindInt64(5, item.file_size); | 227 statement.BindInt64(5, item.creation_time.ToInternalValue()); |
| 232 statement.BindInt64(6, item.creation_time.ToInternalValue()); | 228 statement.BindInt64(6, item.last_access_time.ToInternalValue()); |
| 233 statement.BindInt64(7, item.last_access_time.ToInternalValue()); | 229 statement.BindInt(7, item.access_count); |
| 234 statement.BindInt(8, item.access_count); | 230 statement.BindInt64(8, item.expiration_time.ToInternalValue()); |
| 235 statement.BindInt64(9, item.expiration_time.ToInternalValue()); | 231 statement.BindString16(9, item.title); |
| 236 statement.BindString16(10, item.title); | 232 statement.BindInt64(10, item.offline_id); |
| 237 return statement.Run(); | 233 return statement.Run() && db->GetLastChangeCount() > 0; |
| 238 } | 234 } |
| 239 | 235 |
| 240 bool InitDatabase(sql::Connection* db, base::FilePath path) { | 236 bool InitDatabase(sql::Connection* db, base::FilePath path) { |
| 241 db->set_page_size(4096); | 237 db->set_page_size(4096); |
| 242 db->set_cache_size(500); | 238 db->set_cache_size(500); |
| 243 db->set_histogram_tag("OfflinePageMetadata"); | 239 db->set_histogram_tag("OfflinePageMetadata"); |
| 244 db->set_exclusive_locking(); | 240 db->set_exclusive_locking(); |
| 245 | 241 |
| 246 base::File::Error err; | 242 base::File::Error err; |
| 247 if (!base::CreateDirectoryAndGetError(path.DirName(), &err)) { | 243 if (!base::CreateDirectoryAndGetError(path.DirName(), &err)) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 271 } else { | 267 } else { |
| 272 DVLOG(1) << "Offline pages database loading failed: " << status; | 268 DVLOG(1) << "Offline pages database loading failed: " << status; |
| 273 } | 269 } |
| 274 runner->PostTask(FROM_HERE, base::Bind(callback, status, result)); | 270 runner->PostTask(FROM_HERE, base::Bind(callback, status, result)); |
| 275 } | 271 } |
| 276 | 272 |
| 277 void OpenConnectionSync(sql::Connection* db, | 273 void OpenConnectionSync(sql::Connection* db, |
| 278 scoped_refptr<base::SingleThreadTaskRunner> runner, | 274 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 279 const base::FilePath& path, | 275 const base::FilePath& path, |
| 280 const base::Callback<void(StoreState)>& callback) { | 276 const base::Callback<void(StoreState)>& callback) { |
| 281 StoreState state = InitDatabase(db, path) | 277 StoreState state = |
| 282 ? OfflinePageMetadataStore::LOADED | 278 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING; |
| 283 : OfflinePageMetadataStore::FAILED_INITIALIZATION; | |
| 284 runner->PostTask(FROM_HERE, base::Bind(callback, state)); | 279 runner->PostTask(FROM_HERE, base::Bind(callback, state)); |
| 285 } | 280 } |
| 286 | 281 |
| 282 bool GetPageByOfflineIdSync(sql::Connection* db, | |
| 283 int64_t offline_id, | |
| 284 OfflinePageItem* item) { | |
| 285 const char kSql[] = | |
| 286 "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id = ?"; | |
|
dewittj
2016/09/23 17:21:35
is 'SELECT *' discouraged in Chromium? It has bee
| |
| 287 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | |
| 288 statement.BindInt64(0, offline_id); | |
| 289 | |
| 290 if (statement.Step()) { | |
| 291 *item = MakeOfflinePageItem(&statement); | |
| 292 return true; | |
| 293 } | |
| 294 | |
| 295 return false; | |
| 296 } | |
| 297 | |
| 287 void GetOfflinePagesSync( | 298 void GetOfflinePagesSync( |
| 288 sql::Connection* db, | 299 sql::Connection* db, |
| 289 scoped_refptr<base::SingleThreadTaskRunner> runner, | 300 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 290 const OfflinePageMetadataStore::LoadCallback& callback) { | 301 const OfflinePageMetadataStore::LoadCallback& callback) { |
| 291 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME; | 302 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME; |
| 292 | 303 |
| 293 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 304 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 294 | 305 |
| 295 std::vector<OfflinePageItem> result; | 306 std::vector<OfflinePageItem> result; |
| 296 while (statement.Step()) | 307 while (statement.Step()) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 307 } | 318 } |
| 308 | 319 |
| 309 void AddOfflinePageSync(sql::Connection* db, | 320 void AddOfflinePageSync(sql::Connection* db, |
| 310 scoped_refptr<base::SingleThreadTaskRunner> runner, | 321 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 311 const OfflinePageItem& offline_page, | 322 const OfflinePageItem& offline_page, |
| 312 const OfflinePageMetadataStore::AddCallback& callback) { | 323 const OfflinePageMetadataStore::AddCallback& callback) { |
| 313 ItemActionStatus status = Insert(db, offline_page); | 324 ItemActionStatus status = Insert(db, offline_page); |
| 314 runner->PostTask(FROM_HERE, base::Bind(callback, status)); | 325 runner->PostTask(FROM_HERE, base::Bind(callback, status)); |
| 315 } | 326 } |
| 316 | 327 |
| 328 void PostStoreUpdateResultForIds( | |
| 329 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 330 StoreState store_state, | |
| 331 const std::vector<int64_t>& offline_ids, | |
| 332 ItemActionStatus action_status, | |
| 333 const OfflinePageMetadataStore::UpdateCallback& callback) { | |
| 334 std::unique_ptr<StoreUpdateResult> result(new StoreUpdateResult(store_state)); | |
| 335 for (const auto& offline_id : offline_ids) | |
| 336 result->item_statuses.push_back(std::make_pair(offline_id, action_status)); | |
| 337 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); | |
| 338 } | |
| 339 | |
| 340 void PostStoreErrorForAllPages( | |
| 341 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 342 const std::vector<OfflinePageItem>& pages, | |
| 343 const OfflinePageMetadataStore::UpdateCallback& callback) { | |
| 344 std::vector<int64_t> offline_ids; | |
| 345 for (const auto& page : pages) | |
| 346 offline_ids.push_back(page.offline_id); | |
| 347 PostStoreUpdateResultForIds(runner, StoreState::LOADED, offline_ids, | |
| 348 ItemActionStatus::STORE_ERROR, callback); | |
| 349 } | |
| 350 | |
| 351 void PostStoreErrorForAllIds( | |
| 352 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 353 const std::vector<int64_t>& offline_ids, | |
| 354 const OfflinePageMetadataStore::UpdateCallback& callback) { | |
| 355 PostStoreUpdateResultForIds(runner, StoreState::LOADED, offline_ids, | |
| 356 ItemActionStatus::STORE_ERROR, callback); | |
| 357 } | |
| 358 | |
| 317 void UpdateOfflinePagesSync( | 359 void UpdateOfflinePagesSync( |
| 318 sql::Connection* db, | 360 sql::Connection* db, |
| 319 scoped_refptr<base::SingleThreadTaskRunner> runner, | 361 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 320 const std::vector<OfflinePageItem>& pages, | 362 const std::vector<OfflinePageItem>& pages, |
| 321 const OfflinePageMetadataStore::UpdateCallback& callback) { | 363 const OfflinePageMetadataStore::UpdateCallback& callback) { |
| 322 // TODO(fgorski): Update the callback to provide information about all items | 364 std::unique_ptr<StoreUpdateResult> result( |
| 323 // and not just a high level boolean. | 365 new StoreUpdateResult(StoreState::LOADED)); |
| 366 | |
| 324 sql::Transaction transaction(db); | 367 sql::Transaction transaction(db); |
| 325 if (!transaction.Begin()) { | 368 if (!transaction.Begin()) { |
| 326 runner->PostTask(FROM_HERE, base::Bind(callback, false)); | 369 PostStoreErrorForAllPages(runner, pages, callback); |
| 327 return; | 370 return; |
| 328 } | 371 } |
| 329 | 372 |
| 330 // TODO(fgorski): Switch to only accept updates and not create new items. | 373 for (const auto& page : pages) { |
| 331 for (auto& page : pages) | 374 if (Update(db, page)) { |
| 332 InsertOrReplace(db, page); | 375 result->updated_items.push_back(page); |
| 376 result->item_statuses.push_back( | |
| 377 std::make_pair(page.offline_id, ItemActionStatus::SUCCESS)); | |
| 378 } else { | |
| 379 result->item_statuses.push_back( | |
| 380 std::make_pair(page.offline_id, ItemActionStatus::NOT_FOUND)); | |
| 381 } | |
| 382 } | |
| 333 | 383 |
| 334 bool result = transaction.Commit(); | 384 if (!transaction.Commit()) { |
| 335 runner->PostTask(FROM_HERE, base::Bind(callback, result)); | 385 PostStoreErrorForAllPages(runner, pages, callback); |
| 386 return; | |
| 387 } | |
| 388 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); | |
| 336 } | 389 } |
| 337 | 390 |
| 338 void RemoveOfflinePagesSync( | 391 void RemoveOfflinePagesSync( |
| 339 const std::vector<int64_t>& offline_ids, | 392 const std::vector<int64_t>& offline_ids, |
| 340 sql::Connection* db, | 393 sql::Connection* db, |
| 341 scoped_refptr<base::SingleThreadTaskRunner> runner, | 394 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 342 const OfflinePageMetadataStore::UpdateCallback& callback) { | 395 const OfflinePageMetadataStore::UpdateCallback& callback) { |
| 343 // TODO(bburns): add UMA metrics here (and for levelDB). | 396 // TODO(fgorski): Perhaps add metrics here. |
| 397 std::unique_ptr<StoreUpdateResult> result( | |
| 398 new StoreUpdateResult(StoreState::LOADED)); | |
| 344 | 399 |
| 345 // If you create a transaction but don't Commit() it is automatically | 400 // If you create a transaction but don't Commit() it is automatically |
| 346 // rolled back by its destructor when it falls out of scope. | 401 // rolled back by its destructor when it falls out of scope. |
| 347 sql::Transaction transaction(db); | 402 sql::Transaction transaction(db); |
| 348 if (!transaction.Begin()) { | 403 if (!transaction.Begin()) { |
| 349 runner->PostTask(FROM_HERE, base::Bind(callback, false)); | 404 PostStoreErrorForAllIds(runner, offline_ids, callback); |
| 350 return; | 405 return; |
| 351 } | 406 } |
| 352 | 407 |
| 353 for (auto offline_id : offline_ids) { | 408 for (int64_t offline_id : offline_ids) { |
| 354 if (!DeleteByOfflineId(db, offline_id)) { | 409 OfflinePageItem page; |
| 355 runner->PostTask(FROM_HERE, base::Bind(callback, false)); | 410 ItemActionStatus status; |
| 356 return; | 411 if (!GetPageByOfflineIdSync(db, offline_id, &page)) { |
| 412 status = ItemActionStatus::NOT_FOUND; | |
| 413 } else if (!DeleteByOfflineId(db, offline_id)) { | |
| 414 status = ItemActionStatus::STORE_ERROR; | |
| 415 } else { | |
| 416 status = ItemActionStatus::SUCCESS; | |
| 417 result->updated_items.push_back(page); | |
| 357 } | 418 } |
| 419 | |
| 420 result->item_statuses.push_back(std::make_pair(offline_id, status)); | |
| 358 } | 421 } |
| 359 | 422 |
| 360 bool success = transaction.Commit(); | 423 if (!transaction.Commit()) { |
| 361 runner->PostTask(FROM_HERE, base::Bind(callback, success)); | 424 PostStoreErrorForAllIds(runner, offline_ids, callback); |
| 425 return; | |
| 426 } | |
| 427 | |
| 428 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); | |
| 362 } | 429 } |
| 363 | 430 |
| 364 void ResetSync(sql::Connection* db, | 431 void ResetSync(sql::Connection* db, |
| 365 const base::FilePath& db_file_path, | 432 const base::FilePath& db_file_path, |
| 366 scoped_refptr<base::SingleThreadTaskRunner> runner, | 433 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 367 const base::Callback<void(StoreState)>& callback) { | 434 const base::Callback<void(StoreState)>& callback) { |
| 368 // This method deletes the content of the whole store and reinitializes it. | 435 // This method deletes the content of the whole store and reinitializes it. |
| 369 bool success = db->Raze(); | 436 bool success = db->Raze(); |
| 370 db->Close(); | 437 db->Close(); |
| 371 StoreState state; | 438 StoreState state; |
| 372 if (success) { | 439 if (success) { |
| 373 state = InitDatabase(db, db_file_path) | 440 state = InitDatabase(db, db_file_path) ? StoreState::LOADED |
| 374 ? OfflinePageMetadataStore::LOADED | 441 : StoreState::FAILED_LOADING; |
| 375 : OfflinePageMetadataStore::FAILED_INITIALIZATION; | |
| 376 } else { | 442 } else { |
| 377 state = OfflinePageMetadataStore::FAILED_RESET; | 443 state = StoreState::FAILED_RESET; |
| 378 } | 444 } |
| 379 runner->PostTask(FROM_HERE, base::Bind(callback, state)); | 445 runner->PostTask(FROM_HERE, base::Bind(callback, state)); |
| 380 } | 446 } |
| 381 | 447 |
| 382 } // anonymous namespace | 448 } // anonymous namespace |
| 383 | 449 |
| 384 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL( | 450 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL( |
| 385 scoped_refptr<base::SequencedTaskRunner> background_task_runner, | 451 scoped_refptr<base::SequencedTaskRunner> background_task_runner, |
| 386 const base::FilePath& path) | 452 const base::FilePath& path) |
| 387 : background_task_runner_(std::move(background_task_runner)), | 453 : background_task_runner_(std::move(background_task_runner)), |
| 388 db_file_path_(path.AppendASCII("OfflinePages.db")), | 454 db_file_path_(path.AppendASCII("OfflinePages.db")), |
| 389 state_(NOT_LOADED), | 455 state_(StoreState::NOT_LOADED), |
| 390 weak_ptr_factory_(this) { | 456 weak_ptr_factory_(this) { |
| 391 OpenConnection(); | 457 OpenConnection(); |
| 392 } | 458 } |
| 393 | 459 |
| 394 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() { | 460 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() { |
| 395 if (db_.get() && | 461 if (db_.get() && |
| 396 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) { | 462 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) { |
| 397 DLOG(WARNING) << "SQL database will not be deleted."; | 463 DLOG(WARNING) << "SQL database will not be deleted."; |
| 398 } | 464 } |
| 399 } | 465 } |
| 400 | 466 |
| 401 void OfflinePageMetadataStoreSQL::GetOfflinePages( | 467 void OfflinePageMetadataStoreSQL::GetOfflinePages( |
| 402 const LoadCallback& callback) { | 468 const LoadCallback& callback) { |
| 403 if (!CheckDb(base::Bind( | 469 if (!CheckDb(base::Bind( |
| 404 callback, STORE_INIT_FAILED, std::vector<OfflinePageItem>()))) { | 470 callback, STORE_INIT_FAILED, std::vector<OfflinePageItem>()))) { |
| 405 return; | 471 return; |
| 406 } | 472 } |
| 407 | 473 |
| 408 background_task_runner_->PostTask( | 474 background_task_runner_->PostTask( |
| 409 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(), | 475 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(), |
| 410 base::ThreadTaskRunnerHandle::Get(), callback)); | 476 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 411 } | 477 } |
| 412 | 478 |
| 413 void OfflinePageMetadataStoreSQL::AddOfflinePage( | 479 void OfflinePageMetadataStoreSQL::AddOfflinePage( |
| 414 const OfflinePageItem& offline_page, | 480 const OfflinePageItem& offline_page, |
| 415 const AddCallback& callback) { | 481 const AddCallback& callback) { |
| 416 if (!CheckDb(base::Bind(callback, STORE_ERROR))) | 482 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR))) |
| 417 return; | 483 return; |
| 418 | 484 |
| 419 background_task_runner_->PostTask( | 485 background_task_runner_->PostTask( |
| 420 FROM_HERE, | 486 FROM_HERE, |
| 421 base::Bind(&AddOfflinePageSync, db_.get(), | 487 base::Bind(&AddOfflinePageSync, db_.get(), |
| 422 base::ThreadTaskRunnerHandle::Get(), offline_page, callback)); | 488 base::ThreadTaskRunnerHandle::Get(), offline_page, callback)); |
| 423 } | 489 } |
| 424 | 490 |
| 425 void OfflinePageMetadataStoreSQL::UpdateOfflinePages( | 491 void OfflinePageMetadataStoreSQL::UpdateOfflinePages( |
| 426 const std::vector<OfflinePageItem>& pages, | 492 const std::vector<OfflinePageItem>& pages, |
| 427 const UpdateCallback& callback) { | 493 const UpdateCallback& callback) { |
| 428 if (!CheckDb(base::Bind(callback, false))) | 494 if (!db_.get()) { |
| 495 PostStoreErrorForAllPages(base::ThreadTaskRunnerHandle::Get(), pages, | |
| 496 callback); | |
| 429 return; | 497 return; |
| 498 } | |
| 430 | 499 |
| 431 background_task_runner_->PostTask( | 500 background_task_runner_->PostTask( |
| 432 FROM_HERE, | 501 FROM_HERE, |
| 433 base::Bind(&UpdateOfflinePagesSync, db_.get(), | 502 base::Bind(&UpdateOfflinePagesSync, db_.get(), |
| 434 base::ThreadTaskRunnerHandle::Get(), pages, callback)); | 503 base::ThreadTaskRunnerHandle::Get(), pages, callback)); |
| 435 } | 504 } |
| 436 | 505 |
| 437 void OfflinePageMetadataStoreSQL::RemoveOfflinePages( | 506 void OfflinePageMetadataStoreSQL::RemoveOfflinePages( |
| 438 const std::vector<int64_t>& offline_ids, | 507 const std::vector<int64_t>& offline_ids, |
| 439 const UpdateCallback& callback) { | 508 const UpdateCallback& callback) { |
| 440 DCHECK(db_.get()); | 509 DCHECK(db_.get()); |
| 441 | 510 |
| 442 if (offline_ids.empty()) { | 511 if (offline_ids.empty()) { |
| 443 // Nothing to do, but post a callback instead of calling directly | 512 // Nothing to do, but post a callback instead of calling directly |
| 444 // to preserve the async style behavior to prevent bugs. | 513 // to preserve the async style behavior to prevent bugs. |
| 445 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 514 PostStoreUpdateResultForIds( |
| 446 base::Bind(callback, true)); | 515 base::ThreadTaskRunnerHandle::Get(), state(), offline_ids, |
| 516 ItemActionStatus::NOT_FOUND /* will be ignored */, callback); | |
| 447 return; | 517 return; |
| 448 } | 518 } |
| 449 | 519 |
| 450 background_task_runner_->PostTask( | 520 background_task_runner_->PostTask( |
| 451 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(), | 521 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(), |
| 452 base::ThreadTaskRunnerHandle::Get(), callback)); | 522 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 453 } | 523 } |
| 454 | 524 |
| 455 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) { | 525 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) { |
| 456 if (!CheckDb(base::Bind(callback, false))) | 526 if (!CheckDb(base::Bind(callback, false))) |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 485 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone, | 555 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone, |
| 486 weak_ptr_factory_.GetWeakPtr()))); | 556 weak_ptr_factory_.GetWeakPtr()))); |
| 487 } | 557 } |
| 488 | 558 |
| 489 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) { | 559 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) { |
| 490 DCHECK(db_.get()); | 560 DCHECK(db_.get()); |
| 491 | 561 |
| 492 state_ = state; | 562 state_ = state; |
| 493 | 563 |
| 494 // Unfortunately we were not able to open DB connection. | 564 // Unfortunately we were not able to open DB connection. |
| 495 if (state != OfflinePageMetadataStore::LOADED) | 565 if (state != StoreState::LOADED) |
| 496 db_.reset(); | 566 db_.reset(); |
| 497 | 567 |
| 498 // TODO(fgorski): This might be a place to start store recovery. Alternatively | 568 // TODO(fgorski): This might be a place to start store recovery. Alternatively |
| 499 // that can be attempted in the OfflinePageModel. | 569 // that can be attempted in the OfflinePageModel. |
| 500 } | 570 } |
| 501 | 571 |
| 502 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback, | 572 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback, |
| 503 StoreState state) { | 573 StoreState state) { |
| 504 OnOpenConnectionDone(state); | 574 OnOpenConnectionDone(state); |
| 505 callback.Run(state == LOADED); | 575 callback.Run(state == StoreState::LOADED); |
| 506 } | 576 } |
| 507 | 577 |
| 508 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { | 578 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { |
| 509 if (!db_.get() || state_ != LOADED) { | 579 if (!db_.get() || state_ != StoreState::LOADED) { |
| 510 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 580 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 511 base::Bind(callback)); | 581 base::Bind(callback)); |
| 512 return false; | 582 return false; |
| 513 } | 583 } |
| 514 return true; | 584 return true; |
| 515 } | 585 } |
| 516 | 586 |
| 517 } // namespace offline_pages | 587 } // namespace offline_pages |
| OLD | NEW |