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

Side by Side Diff: chrome/utility/importer/firefox_places_factory.cc

Issue 2451223004: Improve Firefox importer to handle all Firefox profiles. (Closed)
Patch Set: 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
« no previous file with comments | « chrome/utility/importer/firefox_places_factory.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "chrome/utility/importer/favicon_reencode.h"
6 #include "chrome/utility/importer/firefox_places_factory.h"
7 #include "firefox_places_factory.h"
8
9 FirefoxPlaces::FirefoxPlaces(const base::FilePath& places_path)
10 : places_path_(places_path) {
11 db_.Open(places_path);
12 }
13
14 bool FirefoxPlaces::LoadBookmarks(BookmarkList* bookmarks) {
15 // Get the bookmark folders that we are interested in.
16 int toolbar_folder_id = GetFolderId(FolderType::TOOLBAR);
17 int menu_folder_id = GetFolderId(FolderType::MENU);
18 int unsorted_folder_id = GetFolderId(FolderType::UNSORTED);
19
20 GetTopBookmarkFolder(toolbar_folder_id, bookmarks);
21 GetTopBookmarkFolder(menu_folder_id, bookmarks);
22 GetTopBookmarkFolder(unsorted_folder_id, bookmarks);
23 auto num_folders = bookmarks->size();
24 for (size_t i = 0; i < num_folders; ++i)
25 GetWholeBookmarkFolder(bookmarks, i, NULL);
26 return true;
27 }
28
29 bool FirefoxPlaces::LoadHistory(std::vector<ImporterURLRow>* rows) {
30 // |visit_type| represent the transition type of URLs (typed, click,
31 // redirect, bookmark, etc.) We eliminate some URLs like sub-frames and
32 // redirects, since we don't want them to appear in history.
33 // Firefox transition types are defined in:
34 // toolkit/components/places/public/nsINavHistoryService.idl
35 const char query[] =
36 "SELECT h.url, h.title, h.visit_count, "
37 "h.hidden, h.typed, v.visit_date "
38 "FROM moz_places h JOIN moz_historyvisits v "
39 "ON h.id = v.place_id "
40 "WHERE v.visit_type <= 3";
41
42 sql::Statement s(db_.GetUniqueStatement(query));
43
44 while (s.Step()) {
45 GURL url(s.ColumnString(0));
46
47 ImporterURLRow row(url);
48 row.title = s.ColumnString16(1);
49 row.visit_count = s.ColumnInt(2);
50 row.hidden = s.ColumnInt(3) == 1;
51 row.typed_count = s.ColumnInt(4);
52 row.last_visit = base::Time::FromTimeT(s.ColumnInt64(5) / 1000000);
53
54 rows->push_back(row);
55 }
56 return true;
57 }
58
59 bool FirefoxPlaces::LoadPostKeywordIds(PostKeywordIds* post_keyword_ids) {
60 const char query[] =
61 "SELECT b.id FROM moz_bookmarks b "
62 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id "
63 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id "
64 "WHERE aa.name = 'bookmarkProperties/POSTData'";
65 sql::Statement s(db_.GetUniqueStatement(query));
66
67 if (!s.is_valid())
68 return false;
69
70 while (s.Step())
71 post_keyword_ids->insert(s.ColumnInt(0));
72 return true;
73 }
74
75 bool FirefoxPlaces::LoadLivemarkIds(LivemarkIds* livemark_ids) {
76 static const char kFeedAnnotation[] = "livemark/feedURI";
77 livemark_ids->clear();
78
79 const char query[] =
80 "SELECT b.item_id "
81 "FROM moz_anno_attributes a "
82 "JOIN moz_items_annos b ON a.id = b.anno_attribute_id "
83 "WHERE a.name = ? ";
84 sql::Statement s(db_.GetUniqueStatement(query));
85 s.BindString(0, kFeedAnnotation);
86
87 while (s.Step())
88 livemark_ids->insert(s.ColumnInt(0));
89 return true;
90 }
91
92 int FirefoxPlaces::GetFolderId(FolderType folder_type) {
93 return -1;
94 }
95
96 bool FirefoxPlaces::LoadFavicons(const FaviconMap& favicon_map,
97 favicon_base::FaviconUsageDataList* favicons) {
98 const char query[] = "SELECT url, data FROM moz_favicons WHERE id=?";
99 sql::Statement s(db_.GetUniqueStatement(query));
100
101 if (!s.is_valid())
102 return false;
103
104 for (FaviconMap::const_iterator i = favicon_map.begin();
105 i != favicon_map.end(); ++i) {
106 s.BindInt64(0, i->first);
107 if (s.Step()) {
108 favicon_base::FaviconUsageData usage;
109
110 usage.favicon_url = GURL(s.ColumnString(0));
111 if (!usage.favicon_url.is_valid())
112 continue; // Don't bother importing favicons with invalid URLs.
113
114 std::vector<unsigned char> data;
115 s.ColumnBlobAsVector(1, &data);
116 if (data.empty())
117 continue; // Data definitely invalid.
118
119 if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data))
120 continue; // Unable to decode.
121
122 usage.urls = i->second;
123 favicons->push_back(usage);
124 }
125 s.Reset(true);
126 }
127 return true;
128 }
129
130 void FirefoxPlaces::GetTopBookmarkFolder(int folder_id, BookmarkList* list) {
131 const char query[] =
132 "SELECT b.title "
133 "FROM moz_bookmarks b "
134 "WHERE b.type = 2 AND b.id = ? "
135 "ORDER BY b.position";
136 sql::Statement s(db_.GetUniqueStatement(query));
137 s.BindInt(0, folder_id);
138
139 if (s.Step()) {
140 BookmarkItem* item = new BookmarkItem;
141 item->parent = -1; // The top level folder has no parent.
142 item->id = folder_id;
143 item->title = s.ColumnString16(0);
144 item->type = TYPE_FOLDER;
145 item->favicon = 0;
146 item->empty_folder = true;
147 list->push_back(item);
148 }
149 }
150
151 void FirefoxPlaces::GetWholeBookmarkFolder(BookmarkList* list,
152 size_t position,
153 bool* empty_folder) {
154 if (position >= list->size()) {
155 NOTREACHED();
156 return;
157 }
158
159 const char query[] =
160 "SELECT b.id, h.url, COALESCE(b.title, h.title), "
161 "b.type, k.keyword, b.dateAdded, h.favicon_id "
162 "FROM moz_bookmarks b "
163 "LEFT JOIN moz_places h ON b.fk = h.id "
164 "LEFT JOIN moz_keywords k ON k.id = b.keyword_id "
165 "WHERE b.type IN (1,2) AND b.parent = ? "
166 "ORDER BY b.position";
167 sql::Statement s(db_.GetUniqueStatement(query));
168 s.BindInt(0, (*list)[position]->id);
169
170 BookmarkList temp_list;
171 while (s.Step()) {
172 BookmarkItem* item = new BookmarkItem;
173 item->parent = static_cast<int>(position);
174 item->id = s.ColumnInt(0);
175 item->url = GURL(s.ColumnString(1));
176 item->title = s.ColumnString16(2);
177 item->type = static_cast<BookmarkItemType>(s.ColumnInt(3));
178 item->keyword = s.ColumnString(4);
179 item->date_added = base::Time::FromTimeT(s.ColumnInt64(5) / 1000000);
180 item->favicon = s.ColumnInt64(6);
181 item->empty_folder = true;
182
183 temp_list.push_back(item);
184 if (empty_folder != NULL)
185 *empty_folder = false;
186 }
187
188 // Appends all items to the list.
189 for (BookmarkList::iterator i = temp_list.begin(); i != temp_list.end();
190 ++i) {
191 list->push_back(*i);
192 // Recursive add bookmarks in sub-folders.
193 if ((*i)->type == TYPE_FOLDER)
194 GetWholeBookmarkFolder(list, list->size() - 1, &(*i)->empty_folder);
195 }
196 }
197
198 // FirefoxPlacesV11
199 FirefoxPlacesV11::FirefoxPlacesV11(const base::FilePath& places_path)
200 : FirefoxPlaces(places_path) {}
201
202 int FirefoxPlacesV11::GetFolderId(FolderType folder_type) {
203 int folder_id = -1;
204 switch (folder_type) {
205 case FolderType::ROOT:
206 folder_id = LoadNodeIDByName("root");
207 break;
208 case FolderType::MENU:
209 folder_id = LoadNodeIDByName("menu");
210 break;
211 case FolderType::TOOLBAR:
212 folder_id = LoadNodeIDByName("toolbar");
213 break;
214 case FolderType::TAGS:
215 folder_id = LoadNodeIDByName("tags");
216 break;
217 case FolderType::UNSORTED:
218 folder_id = LoadNodeIDByName("unfiled");
219 break;
220 default:
221 folder_id = -1;
222 break;
223 }
224 return folder_id;
225 }
226
227 int FirefoxPlacesV11::LoadNodeIDByName(const std::string& name) {
228 const char query[] =
229 "SELECT folder_id "
230 "FROM moz_bookmarks_roots "
231 "WHERE root_name = ?";
232 sql::Statement s(db_.GetUniqueStatement(query));
233 s.BindString(0, name);
234 if (!s.Step())
235 return -1;
236 return s.ColumnInt(0);
237 }
238
239 // FirefoxPlacesV25
240 FirefoxPlacesV25::FirefoxPlacesV25(const base::FilePath& places_path)
241 : FirefoxPlaces(places_path) {}
242
243 int FirefoxPlacesV25::LoadNodeIDByGUID(const std::string& GUID) {
244 const char query[] =
245 "SELECT id "
246 "FROM moz_bookmarks "
247 "WHERE guid = ?";
248 sql::Statement s(db_.GetUniqueStatement(query));
249 s.BindString(0, GUID);
250
251 if (!s.Step())
252 return -1;
253 return s.ColumnInt(0);
254 }
255
256 int FirefoxPlacesV25::GetFolderId(FolderType folder_type) {
257 int folder_id = -1;
258 switch (folder_type) {
259 case FolderType::ROOT:
260 folder_id = LoadNodeIDByGUID("root________");
261 break;
262 case FolderType::MENU:
263 folder_id = LoadNodeIDByGUID("menu________");
264 break;
265 case FolderType::TOOLBAR:
266 folder_id = LoadNodeIDByGUID("toolbar_____");
267 break;
268 case FolderType::TAGS:
269 folder_id = LoadNodeIDByGUID("tags________");
270 break;
271 case FolderType::UNSORTED:
272 folder_id = LoadNodeIDByGUID("unfiled_____");
273 break;
274 default:
275 folder_id = -1;
276 break;
277 }
278 return folder_id;
279 }
280
281 std::unique_ptr<FirefoxPlaces> FirefoxPlacesFactory::GetForProfile(
282 const base::FilePath& profile_path) {
283 base::FilePath places_path = profile_path.AppendASCII("places.sqlite");
284 if (!base::PathExists(places_path))
285 return std::unique_ptr<FirefoxPlaces>();
286
287 sql::Connection db;
288 if (!db.Open(places_path))
289 return std::unique_ptr<FirefoxPlaces>();
290
291 const std::string schema_version_query{"PRAGMA user_version"};
292 sql::Statement s(db.GetUniqueStatement(schema_version_query.c_str()));
293 if (!s.is_valid())
294 return std::unique_ptr<FirefoxPlaces>();
295
296 s.Step();
297 int schema_version = s.ColumnInt(0);
298 s.Clear();
299 db.Close();
300
301 if (schema_version >= 25) {
302 return std::unique_ptr<FirefoxPlaces>(new FirefoxPlacesV25(places_path));
303 } else if (schema_version >= 11) {
304 return std::unique_ptr<FirefoxPlaces>(new FirefoxPlacesV11(places_path));
305 } else {
306 return std::unique_ptr<FirefoxPlaces>(); // Same as Firefox, we don't
307 // support schemas earlier than
308 // 11.
309 }
310 }
OLDNEW
« no previous file with comments | « chrome/utility/importer/firefox_places_factory.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698