| 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 |