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

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

Issue 2489443002: Move all components/offline_pages/ files into component/offline_pages/core (Closed)
Patch Set: update Created 4 years, 1 month 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/offline_pages/offline_page_metadata_store_sql.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "components/offline_pages/offline_page_item.h"
17 #include "sql/connection.h"
18 #include "sql/statement.h"
19 #include "sql/transaction.h"
20
21 namespace offline_pages {
22
23 namespace {
24
25 // This is a macro instead of a const so that
26 // it can be used inline in other SQL statements below.
27 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1"
28
29 bool CreateOfflinePagesTable(sql::Connection* db) {
30 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME
31 "(offline_id INTEGER PRIMARY KEY NOT NULL,"
32 " creation_time INTEGER NOT NULL,"
33 " file_size INTEGER NOT NULL,"
34 " last_access_time INTEGER NOT NULL,"
35 " access_count INTEGER NOT NULL,"
36 " expiration_time INTEGER NOT NULL DEFAULT 0,"
37 " client_namespace VARCHAR NOT NULL,"
38 " client_id VARCHAR NOT NULL,"
39 " online_url VARCHAR NOT NULL,"
40 " file_path VARCHAR NOT NULL,"
41 " title VARCHAR NOT NULL DEFAULT '',"
42 " original_url VARCHAR NOT NULL DEFAULT ''"
43 ")";
44 return db->Execute(kSql);
45 }
46
47 bool UpgradeWithQuery(sql::Connection* db, const char* upgrade_sql) {
48 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME
49 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) {
50 return false;
51 }
52 if (!CreateOfflinePagesTable(db))
53 return false;
54 if (!db->Execute(upgrade_sql))
55 return false;
56 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME))
57 return false;
58 return true;
59 }
60
61 bool UpgradeFrom52(sql::Connection* db) {
62 const char kSql[] =
63 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME
64 " (offline_id, creation_time, file_size, last_access_time, "
65 "access_count, client_namespace, client_id, "
66 "online_url, file_path) "
67 "SELECT "
68 "offline_id, creation_time, file_size, last_access_time, "
69 "access_count, client_namespace, client_id, "
70 "online_url, file_path "
71 "FROM temp_" OFFLINE_PAGES_TABLE_NAME;
72 return UpgradeWithQuery(db, kSql);
73 }
74
75 bool UpgradeFrom53(sql::Connection* db) {
76 const char kSql[] =
77 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME
78 " (offline_id, creation_time, file_size, last_access_time, "
79 "access_count, expiration_time, client_namespace, client_id, "
80 "online_url, file_path) "
81 "SELECT "
82 "offline_id, creation_time, file_size, last_access_time, "
83 "access_count, expiration_time, client_namespace, client_id, "
84 "online_url, file_path "
85 "FROM temp_" OFFLINE_PAGES_TABLE_NAME;
86 return UpgradeWithQuery(db, kSql);
87 }
88
89 bool UpgradeFrom54(sql::Connection* db) {
90 const char kSql[] =
91 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME
92 " (offline_id, creation_time, file_size, last_access_time, "
93 "access_count, expiration_time, client_namespace, client_id, "
94 "online_url, file_path, title) "
95 "SELECT "
96 "offline_id, creation_time, file_size, last_access_time, "
97 "access_count, expiration_time, client_namespace, client_id, "
98 "online_url, file_path, title "
99 "FROM temp_" OFFLINE_PAGES_TABLE_NAME;
100 return UpgradeWithQuery(db, kSql);
101 }
102
103 bool UpgradeFrom55(sql::Connection* db) {
104 const char kSql[] =
105 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME
106 " (offline_id, creation_time, file_size, last_access_time, "
107 "access_count, expiration_time, client_namespace, client_id, "
108 "online_url, file_path, title) "
109 "SELECT "
110 "offline_id, creation_time, file_size, last_access_time, "
111 "access_count, expiration_time, client_namespace, client_id, "
112 "online_url, file_path, title "
113 "FROM temp_" OFFLINE_PAGES_TABLE_NAME;
114 return UpgradeWithQuery(db, kSql);
115 }
116
117 bool CreateSchema(sql::Connection* db) {
118 // If you create a transaction but don't Commit() it is automatically
119 // rolled back by its destructor when it falls out of scope.
120 sql::Transaction transaction(db);
121 if (!transaction.Begin())
122 return false;
123
124 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) {
125 if (!CreateOfflinePagesTable(db))
126 return false;
127 }
128
129 // Upgrade section. Details are described in the header file.
130 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) {
131 if (!UpgradeFrom52(db))
132 return false;
133 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) {
134 if (!UpgradeFrom53(db))
135 return false;
136 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) {
137 if (!UpgradeFrom54(db))
138 return false;
139 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "original_url")) {
140 if (!UpgradeFrom55(db))
141 return false;
142 }
143
144 // TODO(fgorski): Add indices here.
145 return transaction.Commit();
146 }
147
148 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) {
149 static const char kSql[] =
150 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?";
151 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
152 statement.BindInt64(0, offline_id);
153 return statement.Run();
154 }
155
156 base::FilePath GetPathFromUTF8String(const std::string& path_string) {
157 #if defined(OS_POSIX)
158 return base::FilePath(path_string);
159 #elif defined(OS_WIN)
160 return base::FilePath(base::UTF8ToWide(path_string));
161 #else
162 #error Unknown OS
163 #endif
164 }
165
166 std::string GetUTF8StringFromPath(const base::FilePath& path) {
167 #if defined(OS_POSIX)
168 return path.value();
169 #elif defined(OS_WIN)
170 return base::WideToUTF8(path.value());
171 #else
172 #error Unknown OS
173 #endif
174 }
175
176 // Create an offline page item from a SQL result. Expects complete rows with
177 // all columns present.
178 OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) {
179 int64_t id = statement->ColumnInt64(0);
180 base::Time creation_time =
181 base::Time::FromInternalValue(statement->ColumnInt64(1));
182 int64_t file_size = statement->ColumnInt64(2);
183 base::Time last_access_time =
184 base::Time::FromInternalValue(statement->ColumnInt64(3));
185 int access_count = statement->ColumnInt(4);
186 base::Time expiration_time =
187 base::Time::FromInternalValue(statement->ColumnInt64(5));
188 ClientId client_id(statement->ColumnString(6), statement->ColumnString(7));
189 GURL url(statement->ColumnString(8));
190 base::FilePath path(GetPathFromUTF8String(statement->ColumnString(9)));
191 base::string16 title = statement->ColumnString16(10);
192 GURL original_url(statement->ColumnString(11));
193
194 OfflinePageItem item(url, id, client_id, path, file_size, creation_time);
195 item.last_access_time = last_access_time;
196 item.access_count = access_count;
197 item.expiration_time = expiration_time;
198 item.title = title;
199 item.original_url = original_url;
200 return item;
201 }
202
203 ItemActionStatus Insert(sql::Connection* db, const OfflinePageItem& item) {
204 // Using 'INSERT OR FAIL' or 'INSERT OR ABORT' in the query below causes debug
205 // builds to DLOG.
206 const char kSql[] =
207 "INSERT OR IGNORE INTO " OFFLINE_PAGES_TABLE_NAME
208 " (offline_id, online_url, client_namespace, client_id, file_path, "
209 "file_size, creation_time, last_access_time, access_count, "
210 "expiration_time, title, original_url)"
211 " VALUES "
212 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
213
214 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
215 statement.BindInt64(0, item.offline_id);
216 statement.BindString(1, item.url.spec());
217 statement.BindString(2, item.client_id.name_space);
218 statement.BindString(3, item.client_id.id);
219 statement.BindString(4, GetUTF8StringFromPath(item.file_path));
220 statement.BindInt64(5, item.file_size);
221 statement.BindInt64(6, item.creation_time.ToInternalValue());
222 statement.BindInt64(7, item.last_access_time.ToInternalValue());
223 statement.BindInt(8, item.access_count);
224 statement.BindInt64(9, item.expiration_time.ToInternalValue());
225 statement.BindString16(10, item.title);
226 statement.BindString(11, item.original_url.spec());
227 if (!statement.Run())
228 return ItemActionStatus::STORE_ERROR;
229 if (db->GetLastChangeCount() == 0)
230 return ItemActionStatus::ALREADY_EXISTS;
231 return ItemActionStatus::SUCCESS;
232 }
233
234 bool Update(sql::Connection* db, const OfflinePageItem& item) {
235 const char kSql[] =
236 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME
237 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?,"
238 " file_size = ?, creation_time = ?, last_access_time = ?,"
239 " access_count = ?, expiration_time = ?, title = ?, original_url = ?"
240 " WHERE offline_id = ?";
241
242 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
243 statement.BindString(0, item.url.spec());
244 statement.BindString(1, item.client_id.name_space);
245 statement.BindString(2, item.client_id.id);
246 statement.BindString(3, GetUTF8StringFromPath(item.file_path));
247 statement.BindInt64(4, item.file_size);
248 statement.BindInt64(5, item.creation_time.ToInternalValue());
249 statement.BindInt64(6, item.last_access_time.ToInternalValue());
250 statement.BindInt(7, item.access_count);
251 statement.BindInt64(8, item.expiration_time.ToInternalValue());
252 statement.BindString16(9, item.title);
253 statement.BindString(10, item.original_url.spec());
254 statement.BindInt64(11, item.offline_id);
255 return statement.Run() && db->GetLastChangeCount() > 0;
256 }
257
258 bool InitDatabase(sql::Connection* db, base::FilePath path) {
259 db->set_page_size(4096);
260 db->set_cache_size(500);
261 db->set_histogram_tag("OfflinePageMetadata");
262 db->set_exclusive_locking();
263
264 base::File::Error err;
265 if (!base::CreateDirectoryAndGetError(path.DirName(), &err)) {
266 LOG(ERROR) << "Failed to create offline pages db directory: "
267 << base::File::ErrorToString(err);
268 return false;
269 }
270 if (!db->Open(path)) {
271 LOG(ERROR) << "Failed to open database";
272 return false;
273 }
274 db->Preload();
275
276 return CreateSchema(db);
277 }
278
279 void NotifyLoadResult(scoped_refptr<base::SingleThreadTaskRunner> runner,
280 const OfflinePageMetadataStore::LoadCallback& callback,
281 OfflinePageMetadataStore::LoadStatus status,
282 const std::vector<OfflinePageItem>& result) {
283 // TODO(fgorski): Switch to SQL specific UMA metrics.
284 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
285 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
286 if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) {
287 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
288 static_cast<int32_t>(result.size()));
289 } else {
290 DVLOG(1) << "Offline pages database loading failed: " << status;
291 }
292 runner->PostTask(FROM_HERE, base::Bind(callback, status, result));
293 }
294
295 void OpenConnectionSync(sql::Connection* db,
296 scoped_refptr<base::SingleThreadTaskRunner> runner,
297 const base::FilePath& path,
298 const base::Callback<void(StoreState)>& callback) {
299 StoreState state =
300 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING;
301 runner->PostTask(FROM_HERE, base::Bind(callback, state));
302 }
303
304 bool GetPageByOfflineIdSync(sql::Connection* db,
305 int64_t offline_id,
306 OfflinePageItem* item) {
307 const char kSql[] =
308 "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id = ?";
309 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
310 statement.BindInt64(0, offline_id);
311
312 if (statement.Step()) {
313 *item = MakeOfflinePageItem(&statement);
314 return true;
315 }
316
317 return false;
318 }
319
320 void GetOfflinePagesSync(
321 sql::Connection* db,
322 scoped_refptr<base::SingleThreadTaskRunner> runner,
323 const OfflinePageMetadataStore::LoadCallback& callback) {
324 const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME;
325
326 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
327
328 std::vector<OfflinePageItem> result;
329 while (statement.Step())
330 result.push_back(MakeOfflinePageItem(&statement));
331
332 if (statement.Succeeded()) {
333 NotifyLoadResult(runner, callback, OfflinePageMetadataStore::LOAD_SUCCEEDED,
334 result);
335 } else {
336 result.clear();
337 NotifyLoadResult(runner, callback,
338 OfflinePageMetadataStore::STORE_LOAD_FAILED, result);
339 }
340 }
341
342 void AddOfflinePageSync(sql::Connection* db,
343 scoped_refptr<base::SingleThreadTaskRunner> runner,
344 const OfflinePageItem& offline_page,
345 const OfflinePageMetadataStore::AddCallback& callback) {
346 ItemActionStatus status = Insert(db, offline_page);
347 runner->PostTask(FROM_HERE, base::Bind(callback, status));
348 }
349
350 void PostStoreUpdateResultForIds(
351 scoped_refptr<base::SingleThreadTaskRunner> runner,
352 StoreState store_state,
353 const std::vector<int64_t>& offline_ids,
354 ItemActionStatus action_status,
355 const OfflinePageMetadataStore::UpdateCallback& callback) {
356 std::unique_ptr<OfflinePagesUpdateResult> result(
357 new OfflinePagesUpdateResult(store_state));
358 for (const auto& offline_id : offline_ids)
359 result->item_statuses.push_back(std::make_pair(offline_id, action_status));
360 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result)));
361 }
362
363 void PostStoreErrorForAllPages(
364 scoped_refptr<base::SingleThreadTaskRunner> runner,
365 const std::vector<OfflinePageItem>& pages,
366 const OfflinePageMetadataStore::UpdateCallback& callback) {
367 std::vector<int64_t> offline_ids;
368 for (const auto& page : pages)
369 offline_ids.push_back(page.offline_id);
370 PostStoreUpdateResultForIds(runner, StoreState::LOADED, offline_ids,
371 ItemActionStatus::STORE_ERROR, callback);
372 }
373
374 void PostStoreErrorForAllIds(
375 scoped_refptr<base::SingleThreadTaskRunner> runner,
376 const std::vector<int64_t>& offline_ids,
377 const OfflinePageMetadataStore::UpdateCallback& callback) {
378 PostStoreUpdateResultForIds(runner, StoreState::LOADED, offline_ids,
379 ItemActionStatus::STORE_ERROR, callback);
380 }
381
382 void UpdateOfflinePagesSync(
383 sql::Connection* db,
384 scoped_refptr<base::SingleThreadTaskRunner> runner,
385 const std::vector<OfflinePageItem>& pages,
386 const OfflinePageMetadataStore::UpdateCallback& callback) {
387 std::unique_ptr<OfflinePagesUpdateResult> result(
388 new OfflinePagesUpdateResult(StoreState::LOADED));
389
390 sql::Transaction transaction(db);
391 if (!transaction.Begin()) {
392 PostStoreErrorForAllPages(runner, pages, callback);
393 return;
394 }
395
396 for (const auto& page : pages) {
397 if (Update(db, page)) {
398 result->updated_items.push_back(page);
399 result->item_statuses.push_back(
400 std::make_pair(page.offline_id, ItemActionStatus::SUCCESS));
401 } else {
402 result->item_statuses.push_back(
403 std::make_pair(page.offline_id, ItemActionStatus::NOT_FOUND));
404 }
405 }
406
407 if (!transaction.Commit()) {
408 PostStoreErrorForAllPages(runner, pages, callback);
409 return;
410 }
411 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result)));
412 }
413
414 void RemoveOfflinePagesSync(
415 const std::vector<int64_t>& offline_ids,
416 sql::Connection* db,
417 scoped_refptr<base::SingleThreadTaskRunner> runner,
418 const OfflinePageMetadataStore::UpdateCallback& callback) {
419 // TODO(fgorski): Perhaps add metrics here.
420 std::unique_ptr<OfflinePagesUpdateResult> result(
421 new OfflinePagesUpdateResult(StoreState::LOADED));
422
423 // If you create a transaction but don't Commit() it is automatically
424 // rolled back by its destructor when it falls out of scope.
425 sql::Transaction transaction(db);
426 if (!transaction.Begin()) {
427 PostStoreErrorForAllIds(runner, offline_ids, callback);
428 return;
429 }
430
431 for (int64_t offline_id : offline_ids) {
432 OfflinePageItem page;
433 ItemActionStatus status;
434 if (!GetPageByOfflineIdSync(db, offline_id, &page)) {
435 status = ItemActionStatus::NOT_FOUND;
436 } else if (!DeleteByOfflineId(db, offline_id)) {
437 status = ItemActionStatus::STORE_ERROR;
438 } else {
439 status = ItemActionStatus::SUCCESS;
440 result->updated_items.push_back(page);
441 }
442
443 result->item_statuses.push_back(std::make_pair(offline_id, status));
444 }
445
446 if (!transaction.Commit()) {
447 PostStoreErrorForAllIds(runner, offline_ids, callback);
448 return;
449 }
450
451 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result)));
452 }
453
454 void ResetSync(sql::Connection* db,
455 const base::FilePath& db_file_path,
456 scoped_refptr<base::SingleThreadTaskRunner> runner,
457 const base::Callback<void(StoreState)>& callback) {
458 // This method deletes the content of the whole store and reinitializes it.
459 bool success = db->Raze();
460 db->Close();
461 StoreState state;
462 if (success) {
463 state = InitDatabase(db, db_file_path) ? StoreState::LOADED
464 : StoreState::FAILED_LOADING;
465 } else {
466 state = StoreState::FAILED_RESET;
467 }
468 runner->PostTask(FROM_HERE, base::Bind(callback, state));
469 }
470
471 } // anonymous namespace
472
473 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL(
474 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
475 const base::FilePath& path)
476 : background_task_runner_(std::move(background_task_runner)),
477 db_file_path_(path.AppendASCII("OfflinePages.db")),
478 state_(StoreState::NOT_LOADED),
479 weak_ptr_factory_(this) {
480 OpenConnection();
481 }
482
483 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() {
484 if (db_.get() &&
485 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
486 DLOG(WARNING) << "SQL database will not be deleted.";
487 }
488 }
489
490 void OfflinePageMetadataStoreSQL::GetOfflinePages(
491 const LoadCallback& callback) {
492 if (!CheckDb(base::Bind(
493 callback, STORE_INIT_FAILED, std::vector<OfflinePageItem>()))) {
494 return;
495 }
496
497 background_task_runner_->PostTask(
498 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(),
499 base::ThreadTaskRunnerHandle::Get(), callback));
500 }
501
502 void OfflinePageMetadataStoreSQL::AddOfflinePage(
503 const OfflinePageItem& offline_page,
504 const AddCallback& callback) {
505 if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR)))
506 return;
507
508 background_task_runner_->PostTask(
509 FROM_HERE,
510 base::Bind(&AddOfflinePageSync, db_.get(),
511 base::ThreadTaskRunnerHandle::Get(), offline_page, callback));
512 }
513
514 void OfflinePageMetadataStoreSQL::UpdateOfflinePages(
515 const std::vector<OfflinePageItem>& pages,
516 const UpdateCallback& callback) {
517 if (!db_.get()) {
518 PostStoreErrorForAllPages(base::ThreadTaskRunnerHandle::Get(), pages,
519 callback);
520 return;
521 }
522
523 background_task_runner_->PostTask(
524 FROM_HERE,
525 base::Bind(&UpdateOfflinePagesSync, db_.get(),
526 base::ThreadTaskRunnerHandle::Get(), pages, callback));
527 }
528
529 void OfflinePageMetadataStoreSQL::RemoveOfflinePages(
530 const std::vector<int64_t>& offline_ids,
531 const UpdateCallback& callback) {
532 DCHECK(db_.get());
533
534 if (offline_ids.empty()) {
535 // Nothing to do, but post a callback instead of calling directly
536 // to preserve the async style behavior to prevent bugs.
537 PostStoreUpdateResultForIds(
538 base::ThreadTaskRunnerHandle::Get(), state(), offline_ids,
539 ItemActionStatus::NOT_FOUND /* will be ignored */, callback);
540 return;
541 }
542
543 background_task_runner_->PostTask(
544 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(),
545 base::ThreadTaskRunnerHandle::Get(), callback));
546 }
547
548 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) {
549 if (!CheckDb(base::Bind(callback, false)))
550 return;
551
552 background_task_runner_->PostTask(
553 FROM_HERE,
554 base::Bind(&ResetSync, db_.get(), db_file_path_,
555 base::ThreadTaskRunnerHandle::Get(),
556 base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone,
557 weak_ptr_factory_.GetWeakPtr(), callback)));
558 }
559
560 StoreState OfflinePageMetadataStoreSQL::state() const {
561 return state_;
562 }
563
564 void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state,
565 bool reset_db) {
566 state_ = state;
567 if (reset_db)
568 db_.reset(nullptr);
569 }
570
571 void OfflinePageMetadataStoreSQL::OpenConnection() {
572 DCHECK(!db_);
573 db_.reset(new sql::Connection());
574 background_task_runner_->PostTask(
575 FROM_HERE,
576 base::Bind(&OpenConnectionSync, db_.get(),
577 base::ThreadTaskRunnerHandle::Get(), db_file_path_,
578 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
579 weak_ptr_factory_.GetWeakPtr())));
580 }
581
582 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) {
583 DCHECK(db_.get());
584
585 state_ = state;
586
587 // Unfortunately we were not able to open DB connection.
588 if (state != StoreState::LOADED)
589 db_.reset();
590
591 // TODO(fgorski): This might be a place to start store recovery. Alternatively
592 // that can be attempted in the OfflinePageModel.
593 }
594
595 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback,
596 StoreState state) {
597 OnOpenConnectionDone(state);
598 callback.Run(state == StoreState::LOADED);
599 }
600
601 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) {
602 if (!db_.get() || state_ != StoreState::LOADED) {
603 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
604 return false;
605 }
606 return true;
607 }
608
609 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698