Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: components/offline_pages/offline_page_metadata_store_sql.cc

Issue 2329283002: [Offline pages] OPM SQL store: moving load to constructor, updating read to GetOfflinePages (Closed)
Patch Set: Addressing CR feedback Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
23 namespace { 25 namespace {
24 26
25 // This is a macro instead of a const so that 27 // This is a macro instead of a const so that
26 // it can be used inline in other SQL statements below. 28 // it can be used inline in other SQL statements below.
27 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" 29 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1"
28 30
29 // New columns should be added at the end of the list in order to avoid 31 // New columns should be added at the end of the list in order to avoid
30 // complicated table upgrade. 32 // complicated table upgrade.
31 const char kOfflinePagesColumns[] = 33 const char kOfflinePagesColumns[] =
32 "(offline_id INTEGER PRIMARY KEY NOT NULL," 34 "(offline_id INTEGER PRIMARY KEY NOT NULL,"
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } 244 }
243 if (!db->Open(path)) { 245 if (!db->Open(path)) {
244 LOG(ERROR) << "Failed to open database"; 246 LOG(ERROR) << "Failed to open database";
245 return false; 247 return false;
246 } 248 }
247 db->Preload(); 249 db->Preload();
248 250
249 return CreateSchema(db); 251 return CreateSchema(db);
250 } 252 }
251 253
254 void NotifyLoadResult(scoped_refptr<base::SingleThreadTaskRunner> runner,
255 const OfflinePageMetadataStore::LoadCallback& callback,
256 OfflinePageMetadataStore::LoadStatus status,
257 const std::vector<OfflinePageItem>& result) {
258 // TODO(bburns): Switch to SQL specific UMA metrics.
259 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
260 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
261 if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) {
262 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
263 static_cast<int32_t>(result.size()));
264 } else {
265 DVLOG(1) << "Offline pages database loading failed: " << status;
266 }
267 runner->PostTask(FROM_HERE, base::Bind(callback, status, result));
268 }
269
270 void OpenConnectionSync(sql::Connection* db,
271 scoped_refptr<base::SingleThreadTaskRunner> runner,
272 const base::FilePath& path,
273 const base::Callback<void(StoreState)>& callback) {
274 StoreState state = InitDatabase(db, path)
275 ? OfflinePageMetadataStore::LOADED
276 : OfflinePageMetadataStore::FAILED_INITIALIZATION;
277 runner->PostTask(FROM_HERE, base::Bind(callback, state));
278 }
279
280 void GetOfflinePagesSync(
281 sql::Connection* db,
282 scoped_refptr<base::SingleThreadTaskRunner> runner,
283 const OfflinePageMetadataStore::LoadCallback& callback) {
284 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME;
285
286 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
287
288 std::vector<OfflinePageItem> result;
289 while (statement.Step())
290 result.push_back(MakeOfflinePageItem(&statement));
291
292 if (statement.Succeeded()) {
293 NotifyLoadResult(runner, callback, OfflinePageMetadataStore::LOAD_SUCCEEDED,
294 result);
295 } else {
296 result.clear();
297 NotifyLoadResult(runner, callback,
298 OfflinePageMetadataStore::STORE_LOAD_FAILED, result);
299 }
300 }
301
302 void ResetSync(sql::Connection* db,
303 const base::FilePath& db_file_path,
304 scoped_refptr<base::SingleThreadTaskRunner> runner,
305 const base::Callback<void(StoreState)>& callback) {
306 // This method deletes the content of the whole store and reinitializes it.
307 bool success = db->Raze();
308 db->Close();
309 StoreState state;
310 if (success) {
311 state = InitDatabase(db, db_file_path)
312 ? OfflinePageMetadataStore::LOADED
313 : OfflinePageMetadataStore::FAILED_INITIALIZATION;
314 } else {
315 state = OfflinePageMetadataStore::FAILED_RESET;
316 }
317 runner->PostTask(FROM_HERE, base::Bind(callback, state));
318 }
319
252 } // anonymous namespace 320 } // anonymous namespace
253 321
254 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL( 322 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL(
255 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 323 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
256 const base::FilePath& path) 324 const base::FilePath& path)
257 : background_task_runner_(std::move(background_task_runner)), 325 : background_task_runner_(std::move(background_task_runner)),
258 db_file_path_(path.AppendASCII("OfflinePages.db")) {} 326 db_file_path_(path.AppendASCII("OfflinePages.db")),
327 state_(NOT_LOADED),
328 weak_ptr_factory_(this) {
329 OpenConnection();
330 }
259 331
260 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() { 332 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() {
261 if (db_.get() && 333 if (db_.get() &&
262 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) { 334 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
263 DLOG(WARNING) << "SQL database will not be deleted."; 335 DLOG(WARNING) << "SQL database will not be deleted.";
264 } 336 }
265 } 337 }
266 338
267 void OfflinePageMetadataStoreSQL::LoadSync(
268 sql::Connection* db,
269 const base::FilePath& path,
270 scoped_refptr<base::SingleThreadTaskRunner> runner,
271 const LoadCallback& callback) {
272 if (!InitDatabase(db, path)) {
273 NotifyLoadResult(runner, callback, STORE_INIT_FAILED,
274 std::vector<OfflinePageItem>());
275 return;
276 }
277
278 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME;
279
280 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
281
282 std::vector<OfflinePageItem> result;
283 while (statement.Step()) {
284 result.push_back(MakeOfflinePageItem(&statement));
285 }
286
287 if (statement.Succeeded()) {
288 NotifyLoadResult(runner, callback, LOAD_SUCCEEDED, result);
289 } else {
290 NotifyLoadResult(runner, callback, STORE_LOAD_FAILED,
291 std::vector<OfflinePageItem>());
292 }
293 }
294
295 void OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePageSync( 339 void OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePageSync(
296 const OfflinePageItem& offline_page, 340 const OfflinePageItem& offline_page,
297 sql::Connection* db, 341 sql::Connection* db,
298 scoped_refptr<base::SingleThreadTaskRunner> runner, 342 scoped_refptr<base::SingleThreadTaskRunner> runner,
299 const UpdateCallback& callback) { 343 const UpdateCallback& callback) {
300 // TODO(bburns): add UMA metrics here (and for levelDB). 344 // TODO(bburns): add UMA metrics here (and for levelDB).
301 bool ok = InsertOrReplace(db, offline_page); 345 bool ok = InsertOrReplace(db, offline_page);
302 runner->PostTask(FROM_HERE, base::Bind(callback, ok)); 346 runner->PostTask(FROM_HERE, base::Bind(callback, ok));
303 } 347 }
304 348
(...skipping 15 matching lines...) Expand all
320 if (!DeleteByOfflineId(db, offline_id)) { 364 if (!DeleteByOfflineId(db, offline_id)) {
321 runner->PostTask(FROM_HERE, base::Bind(callback, false)); 365 runner->PostTask(FROM_HERE, base::Bind(callback, false));
322 return; 366 return;
323 } 367 }
324 } 368 }
325 369
326 bool success = transaction.Commit(); 370 bool success = transaction.Commit();
327 runner->PostTask(FROM_HERE, base::Bind(callback, success)); 371 runner->PostTask(FROM_HERE, base::Bind(callback, success));
328 } 372 }
329 373
330 void OfflinePageMetadataStoreSQL::ResetSync( 374 void OfflinePageMetadataStoreSQL::GetOfflinePages(
331 std::unique_ptr<sql::Connection> db, 375 const LoadCallback& callback) {
332 scoped_refptr<base::SingleThreadTaskRunner> runner,
333 const ResetCallback& callback) {
334 const char kSql[] = "DELETE FROM " OFFLINE_PAGES_TABLE_NAME;
335 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
336 runner->PostTask(FROM_HERE, base::Bind(callback, statement.Run()));
337 }
338
339 void OfflinePageMetadataStoreSQL::NotifyLoadResult(
340 scoped_refptr<base::SingleThreadTaskRunner> runner,
341 const LoadCallback& callback,
342 LoadStatus status,
343 const std::vector<OfflinePageItem>& result) {
344 // TODO(bburns): Switch to SQL specific UMA metrics.
345 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
346 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
347 if (status == LOAD_SUCCEEDED) {
348 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
349 static_cast<int32_t>(result.size()));
350 } else {
351 DVLOG(1) << "Offline pages database loading failed: " << status;
352 }
353 runner->PostTask(FROM_HERE, base::Bind(callback, status, result));
354 }
355
356 void OfflinePageMetadataStoreSQL::Load(const LoadCallback& callback) {
357 db_.reset(new sql::Connection());
358 background_task_runner_->PostTask( 376 background_task_runner_->PostTask(
359 FROM_HERE, 377 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(),
360 base::Bind(&OfflinePageMetadataStoreSQL::LoadSync, db_.get(), 378 base::ThreadTaskRunnerHandle::Get(), callback));
361 db_file_path_, base::ThreadTaskRunnerHandle::Get(), callback));
362 } 379 }
363 380
364 void OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePage( 381 void OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePage(
365 const OfflinePageItem& offline_page, 382 const OfflinePageItem& offline_page,
366 const UpdateCallback& callback) { 383 const UpdateCallback& callback) {
367 DCHECK(db_.get()); 384 DCHECK(db_.get());
368 background_task_runner_->PostTask( 385 background_task_runner_->PostTask(
369 FROM_HERE, 386 FROM_HERE,
370 base::Bind(&OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePageSync, 387 base::Bind(&OfflinePageMetadataStoreSQL::AddOrUpdateOfflinePageSync,
371 offline_page, db_.get(), base::ThreadTaskRunnerHandle::Get(), 388 offline_page, db_.get(), base::ThreadTaskRunnerHandle::Get(),
(...skipping 14 matching lines...) Expand all
386 } 403 }
387 404
388 background_task_runner_->PostTask( 405 background_task_runner_->PostTask(
389 FROM_HERE, 406 FROM_HERE,
390 base::Bind(&OfflinePageMetadataStoreSQL::RemoveOfflinePagesSync, 407 base::Bind(&OfflinePageMetadataStoreSQL::RemoveOfflinePagesSync,
391 offline_ids, db_.get(), base::ThreadTaskRunnerHandle::Get(), 408 offline_ids, db_.get(), base::ThreadTaskRunnerHandle::Get(),
392 callback)); 409 callback));
393 } 410 }
394 411
395 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) { 412 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) {
413 if (!CheckDb(base::Bind(callback, false)))
414 return;
415
396 background_task_runner_->PostTask( 416 background_task_runner_->PostTask(
397 FROM_HERE, 417 FROM_HERE,
398 base::Bind(&OfflinePageMetadataStoreSQL::ResetSync, base::Passed(&db_), 418 base::Bind(&ResetSync, db_.get(), db_file_path_,
399 base::ThreadTaskRunnerHandle::Get(), callback)); 419 base::ThreadTaskRunnerHandle::Get(),
420 base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone,
421 weak_ptr_factory_.GetWeakPtr(), callback)));
422 }
423
424 StoreState OfflinePageMetadataStoreSQL::state() const {
425 return state_;
426 }
427
428 void OfflinePageMetadataStoreSQL::OpenConnection() {
429 DCHECK(!db_);
430 db_.reset(new sql::Connection());
431 background_task_runner_->PostTask(
432 FROM_HERE,
433 base::Bind(&OpenConnectionSync, db_.get(),
434 base::ThreadTaskRunnerHandle::Get(), db_file_path_,
435 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
436 weak_ptr_factory_.GetWeakPtr())));
437 }
438
439 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) {
440 DCHECK(db_.get());
441
442 state_ = state;
443
444 // Unfortunately we were not able to open DB connection.
445 if (state != OfflinePageMetadataStore::LOADED)
446 db_.reset();
447
448 // TODO(fgorski): This might be a place to start store recovery. Alternatively
449 // that can be attempted in the OfflinePageModel.
450 }
451
452 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback,
453 StoreState state) {
454 OnOpenConnectionDone(state);
455 callback.Run(state == LOADED);
456 }
457
458 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) {
459 DCHECK(db_.get());
460 if (!db_.get()) {
461 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
462 base::Bind(callback));
463 return false;
464 }
465 return true;
400 } 466 }
401 467
402 } // namespace offline_pages 468 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/offline_page_metadata_store_sql.h ('k') | components/offline_pages/offline_page_model_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698