OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/utility/importer/firefox_importer.h" | 5 #include "chrome/utility/importer/firefox_importer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/files/file_enumerator.h" | 9 #include "base/files/file_enumerator.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 sql::Connection db; | 157 sql::Connection db; |
158 if (!db.Open(file)) | 158 if (!db.Open(file)) |
159 return; | 159 return; |
160 | 160 |
161 // |visit_type| represent the transition type of URLs (typed, click, | 161 // |visit_type| represent the transition type of URLs (typed, click, |
162 // redirect, bookmark, etc.) We eliminate some URLs like sub-frames and | 162 // redirect, bookmark, etc.) We eliminate some URLs like sub-frames and |
163 // redirects, since we don't want them to appear in history. | 163 // redirects, since we don't want them to appear in history. |
164 // Firefox transition types are defined in: | 164 // Firefox transition types are defined in: |
165 // toolkit/components/places/public/nsINavHistoryService.idl | 165 // toolkit/components/places/public/nsINavHistoryService.idl |
166 const char* query = "SELECT h.url, h.title, h.visit_count, " | 166 const char query[] = |
167 "h.hidden, h.typed, v.visit_date " | 167 "SELECT h.url, h.title, h.visit_count, " |
168 "FROM moz_places h JOIN moz_historyvisits v " | 168 "h.hidden, h.typed, v.visit_date " |
169 "ON h.id = v.place_id " | 169 "FROM moz_places h JOIN moz_historyvisits v " |
170 "WHERE v.visit_type <= 3"; | 170 "ON h.id = v.place_id " |
| 171 "WHERE v.visit_type <= 3"; |
171 | 172 |
172 sql::Statement s(db.GetUniqueStatement(query)); | 173 sql::Statement s(db.GetUniqueStatement(query)); |
173 | 174 |
174 std::vector<ImporterURLRow> rows; | 175 std::vector<ImporterURLRow> rows; |
175 while (s.Step() && !cancelled()) { | 176 while (s.Step() && !cancelled()) { |
176 GURL url(s.ColumnString(0)); | 177 GURL url(s.ColumnString(0)); |
177 | 178 |
178 // Filter out unwanted URLs. | 179 // Filter out unwanted URLs. |
179 if (!CanImportURL(url)) | 180 if (!CanImportURL(url)) |
180 continue; | 181 continue; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 for (size_t i = 0; i < count; ++i) | 225 for (size_t i = 0; i < count; ++i) |
225 GetWholeBookmarkFolder(&db, &list, i, NULL); | 226 GetWholeBookmarkFolder(&db, &list, i, NULL); |
226 | 227 |
227 std::vector<ImportedBookmarkEntry> bookmarks; | 228 std::vector<ImportedBookmarkEntry> bookmarks; |
228 std::vector<importer::URLKeywordInfo> url_keywords; | 229 std::vector<importer::URLKeywordInfo> url_keywords; |
229 FaviconMap favicon_map; | 230 FaviconMap favicon_map; |
230 | 231 |
231 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based | 232 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based |
232 // keywords yet. We won't include them in the list. | 233 // keywords yet. We won't include them in the list. |
233 std::set<int> post_keyword_ids; | 234 std::set<int> post_keyword_ids; |
234 const char* query = "SELECT b.id FROM moz_bookmarks b " | 235 const char query[] = |
| 236 "SELECT b.id FROM moz_bookmarks b " |
235 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " | 237 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " |
236 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " | 238 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " |
237 "WHERE aa.name = 'bookmarkProperties/POSTData'"; | 239 "WHERE aa.name = 'bookmarkProperties/POSTData'"; |
238 sql::Statement s(db.GetUniqueStatement(query)); | 240 sql::Statement s(db.GetUniqueStatement(query)); |
239 | 241 |
240 if (!s.is_valid()) | 242 if (!s.is_valid()) |
241 return; | 243 return; |
242 | 244 |
243 while (s.Step() && !cancelled()) | 245 while (s.Step() && !cancelled()) |
244 post_keyword_ids.insert(s.ColumnInt(0)); | 246 post_keyword_ids.insert(s.ColumnInt(0)); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // Since Firefox 3.5, search engines are no longer stored in search.sqlite. | 432 // Since Firefox 3.5, search engines are no longer stored in search.sqlite. |
431 // Instead, search.json is used for storing search engines. | 433 // Instead, search.json is used for storing search engines. |
432 GetSearchEnginesXMLDataFromJSON(search_engine_data); | 434 GetSearchEnginesXMLDataFromJSON(search_engine_data); |
433 return; | 435 return; |
434 } | 436 } |
435 | 437 |
436 sql::Connection db; | 438 sql::Connection db; |
437 if (!db.Open(file)) | 439 if (!db.Open(file)) |
438 return; | 440 return; |
439 | 441 |
440 const char* query = "SELECT engineid FROM engine_data " | 442 const char query[] = |
441 "WHERE engineid NOT IN " | 443 "SELECT engineid FROM engine_data " |
442 "(SELECT engineid FROM engine_data " | 444 "WHERE engineid NOT IN " |
443 "WHERE name='hidden') " | 445 "(SELECT engineid FROM engine_data " |
444 "ORDER BY value ASC"; | 446 "WHERE name='hidden') " |
| 447 "ORDER BY value ASC"; |
445 | 448 |
446 sql::Statement s(db.GetUniqueStatement(query)); | 449 sql::Statement s(db.GetUniqueStatement(query)); |
447 if (!s.is_valid()) | 450 if (!s.is_valid()) |
448 return; | 451 return; |
449 | 452 |
450 const base::FilePath searchplugins_path(FILE_PATH_LITERAL("searchplugins")); | 453 const base::FilePath searchplugins_path(FILE_PATH_LITERAL("searchplugins")); |
451 // Search engine definitions are XMLs stored in two directories. Default | 454 // Search engine definitions are XMLs stored in two directories. Default |
452 // engines are in the app directory (app_path_) and custom engines are | 455 // engines are in the app directory (app_path_) and custom engines are |
453 // in the profile directory (source_path_). | 456 // in the profile directory (source_path_). |
454 | 457 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 } | 635 } |
633 | 636 |
634 void FirefoxImporter::LoadRootNodeID(sql::Connection* db, | 637 void FirefoxImporter::LoadRootNodeID(sql::Connection* db, |
635 int* toolbar_folder_id, | 638 int* toolbar_folder_id, |
636 int* menu_folder_id, | 639 int* menu_folder_id, |
637 int* unsorted_folder_id) { | 640 int* unsorted_folder_id) { |
638 static const char* kToolbarFolderName = "toolbar"; | 641 static const char* kToolbarFolderName = "toolbar"; |
639 static const char* kMenuFolderName = "menu"; | 642 static const char* kMenuFolderName = "menu"; |
640 static const char* kUnsortedFolderName = "unfiled"; | 643 static const char* kUnsortedFolderName = "unfiled"; |
641 | 644 |
642 const char* query = "SELECT root_name, folder_id FROM moz_bookmarks_roots"; | 645 const char query[] = "SELECT root_name, folder_id FROM moz_bookmarks_roots"; |
643 sql::Statement s(db->GetUniqueStatement(query)); | 646 sql::Statement s(db->GetUniqueStatement(query)); |
644 | 647 |
645 while (s.Step()) { | 648 while (s.Step()) { |
646 std::string folder = s.ColumnString(0); | 649 std::string folder = s.ColumnString(0); |
647 int id = s.ColumnInt(1); | 650 int id = s.ColumnInt(1); |
648 if (folder == kToolbarFolderName) | 651 if (folder == kToolbarFolderName) |
649 *toolbar_folder_id = id; | 652 *toolbar_folder_id = id; |
650 else if (folder == kMenuFolderName) | 653 else if (folder == kMenuFolderName) |
651 *menu_folder_id = id; | 654 *menu_folder_id = id; |
652 else if (folder == kUnsortedFolderName) | 655 else if (folder == kUnsortedFolderName) |
653 *unsorted_folder_id = id; | 656 *unsorted_folder_id = id; |
654 } | 657 } |
655 } | 658 } |
656 | 659 |
657 void FirefoxImporter::LoadLivemarkIDs(sql::Connection* db, | 660 void FirefoxImporter::LoadLivemarkIDs(sql::Connection* db, |
658 std::set<int>* livemark) { | 661 std::set<int>* livemark) { |
659 static const char* kFeedAnnotation = "livemark/feedURI"; | 662 static const char* kFeedAnnotation = "livemark/feedURI"; |
660 livemark->clear(); | 663 livemark->clear(); |
661 | 664 |
662 const char* query = "SELECT b.item_id " | 665 const char query[] = |
663 "FROM moz_anno_attributes a " | 666 "SELECT b.item_id " |
664 "JOIN moz_items_annos b ON a.id = b.anno_attribute_id " | 667 "FROM moz_anno_attributes a " |
665 "WHERE a.name = ? "; | 668 "JOIN moz_items_annos b ON a.id = b.anno_attribute_id " |
| 669 "WHERE a.name = ? "; |
666 sql::Statement s(db->GetUniqueStatement(query)); | 670 sql::Statement s(db->GetUniqueStatement(query)); |
667 s.BindString(0, kFeedAnnotation); | 671 s.BindString(0, kFeedAnnotation); |
668 | 672 |
669 while (s.Step() && !cancelled()) | 673 while (s.Step() && !cancelled()) |
670 livemark->insert(s.ColumnInt(0)); | 674 livemark->insert(s.ColumnInt(0)); |
671 } | 675 } |
672 | 676 |
673 void FirefoxImporter::GetTopBookmarkFolder(sql::Connection* db, | 677 void FirefoxImporter::GetTopBookmarkFolder(sql::Connection* db, |
674 int folder_id, | 678 int folder_id, |
675 BookmarkList* list) { | 679 BookmarkList* list) { |
676 const char* query = "SELECT b.title " | 680 const char query[] = |
677 "FROM moz_bookmarks b " | 681 "SELECT b.title " |
678 "WHERE b.type = 2 AND b.id = ? " | 682 "FROM moz_bookmarks b " |
679 "ORDER BY b.position"; | 683 "WHERE b.type = 2 AND b.id = ? " |
| 684 "ORDER BY b.position"; |
680 sql::Statement s(db->GetUniqueStatement(query)); | 685 sql::Statement s(db->GetUniqueStatement(query)); |
681 s.BindInt(0, folder_id); | 686 s.BindInt(0, folder_id); |
682 | 687 |
683 if (s.Step()) { | 688 if (s.Step()) { |
684 BookmarkItem* item = new BookmarkItem; | 689 BookmarkItem* item = new BookmarkItem; |
685 item->parent = -1; // The top level folder has no parent. | 690 item->parent = -1; // The top level folder has no parent. |
686 item->id = folder_id; | 691 item->id = folder_id; |
687 item->title = s.ColumnString16(0); | 692 item->title = s.ColumnString16(0); |
688 item->type = TYPE_FOLDER; | 693 item->type = TYPE_FOLDER; |
689 item->favicon = 0; | 694 item->favicon = 0; |
690 item->empty_folder = true; | 695 item->empty_folder = true; |
691 list->push_back(item); | 696 list->push_back(item); |
692 } | 697 } |
693 } | 698 } |
694 | 699 |
695 void FirefoxImporter::GetWholeBookmarkFolder(sql::Connection* db, | 700 void FirefoxImporter::GetWholeBookmarkFolder(sql::Connection* db, |
696 BookmarkList* list, | 701 BookmarkList* list, |
697 size_t position, | 702 size_t position, |
698 bool* empty_folder) { | 703 bool* empty_folder) { |
699 if (position >= list->size()) { | 704 if (position >= list->size()) { |
700 NOTREACHED(); | 705 NOTREACHED(); |
701 return; | 706 return; |
702 } | 707 } |
703 | 708 |
704 const char* query = "SELECT b.id, h.url, COALESCE(b.title, h.title), " | 709 const char query[] = |
705 "b.type, k.keyword, b.dateAdded, h.favicon_id " | 710 "SELECT b.id, h.url, COALESCE(b.title, h.title), " |
706 "FROM moz_bookmarks b " | 711 "b.type, k.keyword, b.dateAdded, h.favicon_id " |
707 "LEFT JOIN moz_places h ON b.fk = h.id " | 712 "FROM moz_bookmarks b " |
708 "LEFT JOIN moz_keywords k ON k.id = b.keyword_id " | 713 "LEFT JOIN moz_places h ON b.fk = h.id " |
709 "WHERE b.type IN (1,2) AND b.parent = ? " | 714 "LEFT JOIN moz_keywords k ON k.id = b.keyword_id " |
710 "ORDER BY b.position"; | 715 "WHERE b.type IN (1,2) AND b.parent = ? " |
| 716 "ORDER BY b.position"; |
711 sql::Statement s(db->GetUniqueStatement(query)); | 717 sql::Statement s(db->GetUniqueStatement(query)); |
712 s.BindInt(0, (*list)[position]->id); | 718 s.BindInt(0, (*list)[position]->id); |
713 | 719 |
714 BookmarkList temp_list; | 720 BookmarkList temp_list; |
715 while (s.Step()) { | 721 while (s.Step()) { |
716 BookmarkItem* item = new BookmarkItem; | 722 BookmarkItem* item = new BookmarkItem; |
717 item->parent = static_cast<int>(position); | 723 item->parent = static_cast<int>(position); |
718 item->id = s.ColumnInt(0); | 724 item->id = s.ColumnInt(0); |
719 item->url = GURL(s.ColumnString(1)); | 725 item->url = GURL(s.ColumnString(1)); |
720 item->title = s.ColumnString16(2); | 726 item->title = s.ColumnString16(2); |
(...skipping 15 matching lines...) Expand all Loading... |
736 // Recursive add bookmarks in sub-folders. | 742 // Recursive add bookmarks in sub-folders. |
737 if ((*i)->type == TYPE_FOLDER) | 743 if ((*i)->type == TYPE_FOLDER) |
738 GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder); | 744 GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder); |
739 } | 745 } |
740 } | 746 } |
741 | 747 |
742 void FirefoxImporter::LoadFavicons( | 748 void FirefoxImporter::LoadFavicons( |
743 sql::Connection* db, | 749 sql::Connection* db, |
744 const FaviconMap& favicon_map, | 750 const FaviconMap& favicon_map, |
745 std::vector<ImportedFaviconUsage>* favicons) { | 751 std::vector<ImportedFaviconUsage>* favicons) { |
746 const char* query = "SELECT url, data FROM moz_favicons WHERE id=?"; | 752 const char query[] = "SELECT url, data FROM moz_favicons WHERE id=?"; |
747 sql::Statement s(db->GetUniqueStatement(query)); | 753 sql::Statement s(db->GetUniqueStatement(query)); |
748 | 754 |
749 if (!s.is_valid()) | 755 if (!s.is_valid()) |
750 return; | 756 return; |
751 | 757 |
752 for (FaviconMap::const_iterator i = favicon_map.begin(); | 758 for (FaviconMap::const_iterator i = favicon_map.begin(); |
753 i != favicon_map.end(); ++i) { | 759 i != favicon_map.end(); ++i) { |
754 s.BindInt64(0, i->first); | 760 s.BindInt64(0, i->first); |
755 if (s.Step()) { | 761 if (s.Step()) { |
756 ImportedFaviconUsage usage; | 762 ImportedFaviconUsage usage; |
757 | 763 |
758 usage.favicon_url = GURL(s.ColumnString(0)); | 764 usage.favicon_url = GURL(s.ColumnString(0)); |
759 if (!usage.favicon_url.is_valid()) | 765 if (!usage.favicon_url.is_valid()) |
760 continue; // Don't bother importing favicons with invalid URLs. | 766 continue; // Don't bother importing favicons with invalid URLs. |
761 | 767 |
762 std::vector<unsigned char> data; | 768 std::vector<unsigned char> data; |
763 s.ColumnBlobAsVector(1, &data); | 769 s.ColumnBlobAsVector(1, &data); |
764 if (data.empty()) | 770 if (data.empty()) |
765 continue; // Data definitely invalid. | 771 continue; // Data definitely invalid. |
766 | 772 |
767 if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) | 773 if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) |
768 continue; // Unable to decode. | 774 continue; // Unable to decode. |
769 | 775 |
770 usage.urls = i->second; | 776 usage.urls = i->second; |
771 favicons->push_back(usage); | 777 favicons->push_back(usage); |
772 } | 778 } |
773 s.Reset(true); | 779 s.Reset(true); |
774 } | 780 } |
775 } | 781 } |
OLD | NEW |