- add sources.
[platform/framework/web/crosswalk.git] / src / sync / syncable / on_disk_directory_backing_store.cc
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.
4
5 #include "sync/syncable/on_disk_directory_backing_store.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/metrics/histogram.h"
10 #include "sync/syncable/syncable-inl.h"
11
12 namespace syncer {
13 namespace syncable {
14
15 namespace {
16
17 enum HistogramResultEnum {
18   FIRST_TRY_SUCCESS,
19   SECOND_TRY_SUCCESS,
20   SECOND_TRY_FAILURE,
21   RESULT_COUNT
22 };
23
24 }  // namespace
25
26 OnDiskDirectoryBackingStore::OnDiskDirectoryBackingStore(
27     const std::string& dir_name, const base::FilePath& backing_filepath)
28     : DirectoryBackingStore(dir_name),
29       allow_failure_for_test_(false),
30       backing_filepath_(backing_filepath) {
31   db_->set_exclusive_locking();
32   db_->set_page_size(4096);
33 }
34
35 OnDiskDirectoryBackingStore::~OnDiskDirectoryBackingStore() { }
36
37 DirOpenResult OnDiskDirectoryBackingStore::TryLoad(
38     Directory::MetahandlesMap* handles_map,
39     JournalIndex* delete_journals,
40     Directory::KernelLoadInfo* kernel_load_info) {
41   DCHECK(CalledOnValidThread());
42   if (!db_->is_open()) {
43     if (!db_->Open(backing_filepath_))
44       return FAILED_OPEN_DATABASE;
45   }
46
47   if (!InitializeTables())
48     return FAILED_OPEN_DATABASE;
49
50   if (!DropDeletedEntries())
51     return FAILED_DATABASE_CORRUPT;
52   if (!LoadEntries(handles_map))
53     return FAILED_DATABASE_CORRUPT;
54   if (!LoadDeleteJournals(delete_journals))
55     return FAILED_DATABASE_CORRUPT;
56   if (!LoadInfo(kernel_load_info))
57     return FAILED_DATABASE_CORRUPT;
58   if (!VerifyReferenceIntegrity(handles_map))
59     return FAILED_DATABASE_CORRUPT;
60
61   return OPENED;
62
63 }
64
65 DirOpenResult OnDiskDirectoryBackingStore::Load(
66     Directory::MetahandlesMap* handles_map,
67     JournalIndex* delete_journals,
68     Directory::KernelLoadInfo* kernel_load_info) {
69   DirOpenResult result = TryLoad(handles_map, delete_journals,
70                                  kernel_load_info);
71   if (result == OPENED) {
72     UMA_HISTOGRAM_ENUMERATION(
73         "Sync.DirectoryOpenResult", FIRST_TRY_SUCCESS, RESULT_COUNT);
74     return OPENED;
75   }
76
77   ReportFirstTryOpenFailure();
78
79   // The fallback: delete the current database and return a fresh one.  We can
80   // fetch the user's data from the cloud.
81   STLDeleteValues(handles_map);
82   STLDeleteElements(delete_journals);
83   db_.reset(new sql::Connection);
84   // TODO: Manually propagating the default database settings is
85   // brittle.  Either have a helper to set these up (or generate a new
86   // connection), or add something like Reset() to sql::Connection.
87   db_->set_exclusive_locking();
88   db_->set_page_size(4096);
89   db_->set_histogram_tag("SyncDirectory");
90   base::DeleteFile(backing_filepath_, false);
91
92   result = TryLoad(handles_map, delete_journals, kernel_load_info);
93   if (result == OPENED) {
94     UMA_HISTOGRAM_ENUMERATION(
95         "Sync.DirectoryOpenResult", SECOND_TRY_SUCCESS, RESULT_COUNT);
96   } else {
97     UMA_HISTOGRAM_ENUMERATION(
98         "Sync.DirectoryOpenResult", SECOND_TRY_FAILURE, RESULT_COUNT);
99   }
100
101   return result;
102 }
103
104 void OnDiskDirectoryBackingStore::ReportFirstTryOpenFailure() {
105   // In debug builds, the last thing we want is to silently clear the database.
106   // It's full of evidence that might help us determine what went wrong.  It
107   // might be sqlite's fault, but it could also be a bug in sync.  We crash
108   // immediately so a developer can investigate.
109   //
110   // Developers: If you're not interested in debugging this right now, just move
111   // aside the 'Sync Data' directory in your profile.  This is similar to what
112   // the code would do if this DCHECK were disabled.
113   NOTREACHED() << "Crashing to preserve corrupt sync database";
114 }
115
116 }  // namespace syncable
117 }  // namespace syncer