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

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

Issue 1694863003: Refactor the offline page storage to include client namespace and id. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move id generation to C++, add DB migration Created 4 years, 9 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_impl.h" 5 #include "components/offline_pages/offline_page_metadata_store_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "components/leveldb_proto/proto_database_impl.h" 20 #include "components/leveldb_proto/proto_database_impl.h"
21 #include "components/offline_pages/offline_page_item.h" 21 #include "components/offline_pages/offline_page_item.h"
22 #include "components/offline_pages/offline_page_model.h"
22 #include "components/offline_pages/proto/offline_pages.pb.h" 23 #include "components/offline_pages/proto/offline_pages.pb.h"
23 #include "third_party/leveldatabase/env_chromium.h" 24 #include "third_party/leveldatabase/env_chromium.h"
24 #include "third_party/leveldatabase/src/include/leveldb/db.h" 25 #include "third_party/leveldatabase/src/include/leveldb/db.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
27 using leveldb_proto::ProtoDatabase; 28 using leveldb_proto::ProtoDatabase;
28 29
29 namespace { 30 namespace {
30 // Statistics are logged to UMA with this string as part of histogram name. They 31 // Statistics are logged to UMA with this string as part of histogram name. They
31 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this 32 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this
32 // needs to synchronize with histograms.xml, AND will also become incompatible 33 // needs to synchronize with histograms.xml, AND will also become incompatible
33 // with older browsers still reporting the previous values. 34 // with older browsers still reporting the previous values.
34 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore"; 35 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore";
35 } 36 }
36 37
37 namespace offline_pages { 38 namespace offline_pages {
38 namespace { 39 namespace {
39 40
40 void OfflinePageItemToEntry(const OfflinePageItem& item, 41 void OfflinePageItemToEntry(const OfflinePageItem& item,
41 offline_pages::OfflinePageEntry* item_proto) { 42 offline_pages::OfflinePageEntry* item_proto) {
42 DCHECK(item_proto); 43 DCHECK(item_proto);
43 item_proto->set_url(item.url.spec()); 44 item_proto->set_url(item.url.spec());
44 item_proto->set_bookmark_id(item.bookmark_id); 45 item_proto->set_offline_id(item.offline_id);
46 // TODO(bburns): switch this to offline id when we stop passing bookmark
47 // id down.
48 item_proto->set_deprecated_bookmark_id(item.offline_id);
Dmitry Titov 2016/02/25 03:31:52 Do we need this now? Looks like not.
bburns 2016/02/26 00:14:35 Done.
45 item_proto->set_version(item.version); 49 item_proto->set_version(item.version);
46 std::string path_string; 50 std::string path_string;
47 #if defined(OS_POSIX) 51 #if defined(OS_POSIX)
48 path_string = item.file_path.value(); 52 path_string = item.file_path.value();
49 #elif defined(OS_WIN) 53 #elif defined(OS_WIN)
50 path_string = base::WideToUTF8(item.file_path.value()); 54 path_string = base::WideToUTF8(item.file_path.value());
51 #endif 55 #endif
52 item_proto->set_file_path(path_string); 56 item_proto->set_file_path(path_string);
53 item_proto->set_file_size(item.file_size); 57 item_proto->set_file_size(item.file_size);
54 item_proto->set_creation_time(item.creation_time.ToInternalValue()); 58 item_proto->set_creation_time(item.creation_time.ToInternalValue());
55 item_proto->set_last_access_time(item.last_access_time.ToInternalValue()); 59 item_proto->set_last_access_time(item.last_access_time.ToInternalValue());
56 item_proto->set_access_count(item.access_count); 60 item_proto->set_access_count(item.access_count);
57 item_proto->set_flags( 61 item_proto->set_flags(
58 static_cast<::offline_pages::OfflinePageEntry_Flags>(item.flags)); 62 static_cast<::offline_pages::OfflinePageEntry_Flags>(item.flags));
63 item_proto->set_client_id_name_space(item.client_id.name_space);
64 item_proto->set_client_id(item.client_id.id);
59 } 65 }
60 66
61 bool OfflinePageItemFromEntry(const offline_pages::OfflinePageEntry& item_proto, 67 bool OfflinePageItemFromEntry(const offline_pages::OfflinePageEntry& item_proto,
62 OfflinePageItem* item) { 68 OfflinePageItem* item) {
63 DCHECK(item); 69 DCHECK(item);
64 if (!item_proto.has_url() || !item_proto.has_bookmark_id() || 70 bool has_offline_id =
65 !item_proto.has_version() || !item_proto.has_file_path()) { 71 item_proto.has_offline_id() || item_proto.has_deprecated_bookmark_id();
72 if (!item_proto.has_url() || !has_offline_id || !item_proto.has_version() ||
73 !item_proto.has_file_path()) {
66 return false; 74 return false;
67 } 75 }
68 item->url = GURL(item_proto.url()); 76 item->url = GURL(item_proto.url());
69 item->bookmark_id = item_proto.bookmark_id(); 77 item->offline_id = item_proto.offline_id();
70 item->version = item_proto.version(); 78 item->version = item_proto.version();
71 #if defined(OS_POSIX) 79 #if defined(OS_POSIX)
72 item->file_path = base::FilePath(item_proto.file_path()); 80 item->file_path = base::FilePath(item_proto.file_path());
73 #elif defined(OS_WIN) 81 #elif defined(OS_WIN)
74 item->file_path = base::FilePath(base::UTF8ToWide(item_proto.file_path())); 82 item->file_path = base::FilePath(base::UTF8ToWide(item_proto.file_path()));
75 #endif 83 #endif
76 if (item_proto.has_file_size()) { 84 if (item_proto.has_file_size()) {
77 item->file_size = item_proto.file_size(); 85 item->file_size = item_proto.file_size();
78 } 86 }
79 if (item_proto.has_creation_time()) { 87 if (item_proto.has_creation_time()) {
80 item->creation_time = 88 item->creation_time =
81 base::Time::FromInternalValue(item_proto.creation_time()); 89 base::Time::FromInternalValue(item_proto.creation_time());
82 } 90 }
83 if (item_proto.has_last_access_time()) { 91 if (item_proto.has_last_access_time()) {
84 item->last_access_time = 92 item->last_access_time =
85 base::Time::FromInternalValue(item_proto.last_access_time()); 93 base::Time::FromInternalValue(item_proto.last_access_time());
86 } 94 }
87 if (item_proto.has_access_count()) { 95 if (item_proto.has_access_count()) {
88 item->access_count = item_proto.access_count(); 96 item->access_count = item_proto.access_count();
89 } 97 }
90 if (item_proto.has_flags()) { 98 if (item_proto.has_flags()) {
91 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags()); 99 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags());
92 } 100 }
101 item->client_id.name_space = item_proto.client_id_name_space();
102 item->client_id.id = item_proto.client_id();
103
104 // Legacy storage.
Dmitry Titov 2016/02/25 03:31:52 Lets move this client_id initialization to the pie
bburns 2016/02/26 00:14:35 Done.
105 if (item_proto.has_deprecated_bookmark_id()) {
106 item->client_id.name_space = offline_pages::BOOKMARK_NAMESPACE;
107 item->client_id.id =
108 base::Int64ToString(item_proto.deprecated_bookmark_id());
109 }
93 return true; 110 return true;
94 } 111 }
95 112
96 } // namespace 113 } // namespace
97 114
98 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl( 115 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl(
99 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 116 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
100 const base::FilePath& database_dir) 117 const base::FilePath& database_dir)
101 : background_task_runner_(background_task_runner), 118 : background_task_runner_(background_task_runner),
102 database_dir_(database_dir), 119 database_dir_(database_dir),
(...skipping 30 matching lines...) Expand all
133 callback)); 150 callback));
134 } 151 }
135 152
136 void OfflinePageMetadataStoreImpl::LoadDone( 153 void OfflinePageMetadataStoreImpl::LoadDone(
137 const LoadCallback& callback, 154 const LoadCallback& callback,
138 bool success, 155 bool success,
139 scoped_ptr<std::vector<OfflinePageEntry>> entries) { 156 scoped_ptr<std::vector<OfflinePageEntry>> entries) {
140 DCHECK(entries); 157 DCHECK(entries);
141 158
142 std::vector<OfflinePageItem> result; 159 std::vector<OfflinePageItem> result;
160 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_update(
161 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
162 scoped_ptr<std::vector<std::string>> keys_to_remove(
163 new std::vector<std::string>());
164
143 LoadStatus status = LOAD_SUCCEEDED; 165 LoadStatus status = LOAD_SUCCEEDED;
144 166
145 if (success) { 167 if (success) {
146 for (const auto& entry : *entries) { 168 for (auto& entry : *entries) {
147 OfflinePageItem item; 169 OfflinePageItem item;
148 if (!OfflinePageItemFromEntry(entry, &item)) { 170 if (!OfflinePageItemFromEntry(entry, &item)) {
149 status = DATA_PARSING_FAILED; 171 status = DATA_PARSING_FAILED;
150 result.clear(); 172 result.clear();
151 break; 173 break;
152 } 174 }
175 if (!entry.has_offline_id()) {
Dmitry Titov 2016/02/25 03:31:52 Lets add a comment in front of this, telling it's
bburns 2016/02/26 00:14:35 Done.
176 entry.set_offline_id(OfflinePageModel::GenerateOfflineId());
177 item.offline_id = entry.offline_id();
178 entries_to_update->push_back(
179 std::make_pair(base::Int64ToString(entry.offline_id()), entry));
180 keys_to_remove->push_back(
181 base::Int64ToString(entry.deprecated_bookmark_id()));
182 }
153 result.push_back(item); 183 result.push_back(item);
154 } 184 }
155
156 } else { 185 } else {
157 status = STORE_LOAD_FAILED; 186 status = STORE_LOAD_FAILED;
158 } 187 }
159 188
160 NotifyLoadResult(callback, status, result); 189 if (status == LOAD_SUCCEEDED && entries_to_update->size() > 0) {
190 UpdateEntries(std::move(entries_to_update), std::move(keys_to_remove),
191 base::Bind(&OfflinePageMetadataStoreImpl::DatabaseUpdateDone,
192 weak_ptr_factory_.GetWeakPtr(), callback, status,
193 std::move(result)));
194 } else {
195 NotifyLoadResult(callback, status, result);
196 }
161 } 197 }
162 198
163 void OfflinePageMetadataStoreImpl::NotifyLoadResult( 199 void OfflinePageMetadataStoreImpl::NotifyLoadResult(
164 const LoadCallback& callback, 200 const LoadCallback& callback,
165 LoadStatus status, 201 LoadStatus status,
166 const std::vector<OfflinePageItem>& result) { 202 const std::vector<OfflinePageItem>& result) {
167 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", 203 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus",
168 status, 204 status,
169 OfflinePageMetadataStore::LOAD_STATUS_COUNT); 205 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
170 if (status == LOAD_SUCCEEDED) { 206 if (status == LOAD_SUCCEEDED) {
171 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size()); 207 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size());
172 } else { 208 } else {
173 DVLOG(1) << "Offline pages database loading failed: " << status; 209 DVLOG(1) << "Offline pages database loading failed: " << status;
174 database_.reset(); 210 database_.reset();
175 } 211 }
176 callback.Run(status, result); 212 callback.Run(status, result);
177 } 213 }
178 214
179 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage( 215 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage(
180 const OfflinePageItem& offline_page_item, 216 const OfflinePageItem& offline_page_item,
181 const UpdateCallback& callback) { 217 const UpdateCallback& callback) {
182 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 218 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
183 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 219 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
184 scoped_ptr<std::vector<std::string>> keys_to_remove( 220 scoped_ptr<std::vector<std::string>> keys_to_remove(
185 new std::vector<std::string>()); 221 new std::vector<std::string>());
186 222
187 OfflinePageEntry offline_page_proto; 223 OfflinePageEntry offline_page_proto;
188 OfflinePageItemToEntry(offline_page_item, &offline_page_proto); 224 OfflinePageItemToEntry(offline_page_item, &offline_page_proto);
189 entries_to_save->push_back( 225
190 std::make_pair(base::Int64ToString(offline_page_item.bookmark_id), 226 entries_to_save->push_back(std::make_pair(
191 offline_page_proto)); 227 base::Int64ToString(offline_page_item.offline_id), offline_page_proto));
192 228
193 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove), 229 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
194 callback); 230 callback);
195 } 231 }
196 232
197 void OfflinePageMetadataStoreImpl::RemoveOfflinePages( 233 void OfflinePageMetadataStoreImpl::RemoveOfflinePages(
198 const std::vector<int64_t>& bookmark_ids, 234 const std::vector<int64_t>& offline_ids,
199 const UpdateCallback& callback) { 235 const UpdateCallback& callback) {
200 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 236 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
201 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 237 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
202 scoped_ptr<std::vector<std::string>> keys_to_remove( 238 scoped_ptr<std::vector<std::string>> keys_to_remove(
203 new std::vector<std::string>()); 239 new std::vector<std::string>());
204 240
205 for (int64_t id : bookmark_ids) 241 for (int64_t id : offline_ids)
206 keys_to_remove->push_back(base::Int64ToString(id)); 242 keys_to_remove->push_back(base::Int64ToString(id));
207 243
208 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove), 244 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
209 callback); 245 callback);
210 } 246 }
211 247
212 void OfflinePageMetadataStoreImpl::UpdateEntries( 248 void OfflinePageMetadataStoreImpl::UpdateEntries(
213 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save, 249 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save,
214 scoped_ptr<std::vector<std::string>> keys_to_remove, 250 scoped_ptr<std::vector<std::string>> keys_to_remove,
215 const UpdateCallback& callback) { 251 const UpdateCallback& callback) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 285 }
250 286
251 void OfflinePageMetadataStoreImpl::ResetDone( 287 void OfflinePageMetadataStoreImpl::ResetDone(
252 const ResetCallback& callback, 288 const ResetCallback& callback,
253 bool success) { 289 bool success) {
254 database_.reset(); 290 database_.reset();
255 weak_ptr_factory_.InvalidateWeakPtrs(); 291 weak_ptr_factory_.InvalidateWeakPtrs();
256 callback.Run(success); 292 callback.Run(success);
257 } 293 }
258 294
295 void OfflinePageMetadataStoreImpl::DatabaseUpdateDone(
296 const OfflinePageMetadataStore::LoadCallback& cb,
297 LoadStatus status,
298 const std::vector<OfflinePageItem>& result,
299 bool success) {
300 // If the update failed, log and keep going. We'll try to
301 // update next time.
302 if (!success) {
303 LOG(ERROR) << "Failed to update database";
304 }
305 NotifyLoadResult(cb, status, result);
306 }
307
259 } // namespace offline_pages 308 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698