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

Unified Diff: chrome/browser/history/starred_url_database.cc

Issue 10870029: Remove legacy migration code that coupled history and bookmarks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More android fixes. Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/history/starred_url_database.cc
diff --git a/chrome/browser/history/starred_url_database.cc b/chrome/browser/history/starred_url_database.cc
deleted file mode 100644
index 7b981668adbc4fb3489be1dfbcea905f0f509e2d..0000000000000000000000000000000000000000
--- a/chrome/browser/history/starred_url_database.cc
+++ /dev/null
@@ -1,661 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/history/starred_url_database.h"
-
-#include "base/file_util.h"
-#include "base/json/json_writer.h"
-#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "base/stl_util.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/bookmarks/bookmark_codec.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/history/history.h"
-#include "sql/statement.h"
-
-// The following table is used to store star (aka bookmark) information. This
-// class derives from URLDatabase, which has its own schema.
-//
-// starred
-// id Unique identifier (primary key) for the entry.
-// type Type of entry, if 0 this corresponds to a URL, 1 for
-// a system folder, 2 for a user created folder, 3 for
-// other. Note that 4 (synced) will never appear in the
-// database because it was added after this storage was
-// deprecated.
-// url_id ID of the url, only valid if type == 0
-// group_id ID of the folder, only valid if type != 0. This id comes
-// from the UI and is NOT the same as id.
-// title User assigned title.
-// date_added Creation date.
-// visual_order Visual order within parent.
-// parent_id Folder ID of the parent this entry is contained in, if 0
-// entry is not in a folder.
-// date_modified Time the folder was last modified. See comments in
-// StarredEntry::date_folder_modified
-// NOTE: group_id and parent_id come from the UI, id is assigned by the
-// db.
-
-namespace history {
-
-namespace {
-
-// Fields used by FillInStarredEntry.
-#define STAR_FIELDS \
- " starred.id, starred.type, starred.title, starred.date_added, " \
- "starred.visual_order, starred.parent_id, urls.url, urls.id, " \
- "starred.group_id, starred.date_modified "
-const char kHistoryStarFields[] = STAR_FIELDS;
-
-void FillInStarredEntry(const sql::Statement& s, StarredEntry* entry) {
- DCHECK(entry);
- entry->id = s.ColumnInt64(0);
- switch (s.ColumnInt(1)) {
- case 0:
- entry->type = history::StarredEntry::URL;
- entry->url = GURL(s.ColumnString(6));
- break;
- case 1:
- entry->type = history::StarredEntry::BOOKMARK_BAR;
- break;
- case 2:
- entry->type = history::StarredEntry::USER_FOLDER;
- break;
- case 3:
- entry->type = history::StarredEntry::OTHER;
- break;
- default:
- NOTREACHED();
- break;
- }
- entry->title = s.ColumnString16(2);
- entry->date_added = base::Time::FromInternalValue(s.ColumnInt64(3));
- entry->visual_order = s.ColumnInt(4);
- entry->parent_folder_id = s.ColumnInt64(5);
- entry->url_id = s.ColumnInt64(7);
- entry->folder_id = s.ColumnInt64(8);
- entry->date_folder_modified = base::Time::FromInternalValue(s.ColumnInt64(9));
-}
-
-// Resets the properties of |node| from the supplied |entry|.
-void ResetBookmarkNode(const history::StarredEntry& entry,
- BookmarkNode* node) {
- DCHECK(entry.type != history::StarredEntry::URL ||
- entry.url == node->url());
-
- node->set_date_added(entry.date_added);
- node->set_date_folder_modified(entry.date_folder_modified);
- node->SetTitle(entry.title);
-
- switch (entry.type) {
- case history::StarredEntry::URL:
- node->set_type(BookmarkNode::URL);
- break;
- case history::StarredEntry::USER_FOLDER:
- node->set_type(BookmarkNode::FOLDER);
- break;
- case history::StarredEntry::BOOKMARK_BAR:
- node->set_type(BookmarkNode::BOOKMARK_BAR);
- break;
- case history::StarredEntry::OTHER:
- node->set_type(BookmarkNode::OTHER_NODE);
- break;
- case history::StarredEntry::MOBILE:
- node->set_type(BookmarkNode::MOBILE);
- break;
- default:
- NOTREACHED();
- break;
- }
-}
-
-} // namespace
-
-// static
-const int64 StarredURLDatabase::kBookmarkBarID = 1;
-
-StarredURLDatabase::StarredURLDatabase(sql::Connection* db)
- : db_(db) {
-}
-
-StarredURLDatabase::~StarredURLDatabase() {
-}
-
-bool StarredURLDatabase::MigrateBookmarksToFile(const FilePath& path) {
- if (!GetDB().DoesTableExist("starred"))
- return true;
-
- if (EnsureStarredIntegrity() && !MigrateBookmarksToFileImpl(path)) {
- NOTREACHED() << " Bookmarks migration failed";
- return false;
- }
-
- if (!GetDB().Execute("DROP TABLE starred")) {
- NOTREACHED() << "Unable to drop starred table";
- return false;
- }
- return true;
-}
-
-bool StarredURLDatabase::GetAllStarredEntries(
- std::vector<StarredEntry>* entries) {
- DCHECK(entries);
- std::string sql = "SELECT ";
- sql.append(kHistoryStarFields);
- sql.append("FROM starred LEFT JOIN urls ON starred.url_id = urls.id ");
- sql += "ORDER BY parent_id, visual_order";
-
- sql::Statement s(GetDB().GetUniqueStatement(sql.c_str()));
- if (!s.is_valid())
- return false;
-
- history::StarredEntry entry;
- while (s.Step()) {
- FillInStarredEntry(s, &entry);
- // Reset the url for non-url types. This is needed as we're reusing the
- // same entry for the loop.
- if (entry.type != history::StarredEntry::URL)
- entry.url = GURL();
- entries->push_back(entry);
- }
- return true;
-}
-
-sql::Connection& StarredURLDatabase::GetDB() {
- return *db_;
-}
-
-bool StarredURLDatabase::EnsureStarredIntegrity() {
- std::set<StarredNode*> roots;
- std::set<StarID> folders_with_duplicate_ids;
- std::set<StarredNode*> unparented_urls;
- std::set<StarID> empty_url_ids;
-
- if (!BuildStarNodes(&roots, &folders_with_duplicate_ids, &unparented_urls,
- &empty_url_ids)) {
- return false;
- }
-
- bool valid = EnsureStarredIntegrityImpl(&roots, folders_with_duplicate_ids,
- &unparented_urls, empty_url_ids);
-
- STLDeleteElements(&roots);
- STLDeleteElements(&unparented_urls);
- return valid;
-}
-
-bool StarredURLDatabase::UpdateStarredEntryRow(StarID star_id,
- const string16& title,
- UIStarID parent_folder_id,
- int visual_order,
- base::Time date_modified) {
- DCHECK(star_id && visual_order >= 0);
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "UPDATE starred SET title=?, parent_id=?, visual_order=?, "
- "date_modified=? WHERE id=?"));
- statement.BindString16(0, title);
- statement.BindInt64(1, parent_folder_id);
- statement.BindInt(2, visual_order);
- statement.BindInt64(3, date_modified.ToInternalValue());
- statement.BindInt64(4, star_id);
-
- return statement.Run();
-}
-
-bool StarredURLDatabase::AdjustStarredVisualOrder(UIStarID parent_folder_id,
- int start_visual_order,
- int delta) {
- DCHECK(parent_folder_id && start_visual_order >= 0);
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "UPDATE starred SET visual_order=visual_order+? "
- "WHERE parent_id=? AND visual_order >= ?"));
- statement.BindInt(0, delta);
- statement.BindInt64(1, parent_folder_id);
- statement.BindInt(2, start_visual_order);
-
- return statement.Run();
-}
-
-StarID StarredURLDatabase::CreateStarredEntryRow(URLID url_id,
- UIStarID folder_id,
- UIStarID parent_folder_id,
- const string16& title,
- const base::Time& date_added,
- int visual_order,
- StarredEntry::Type type) {
- DCHECK(visual_order >= 0 &&
- (type != history::StarredEntry::URL || url_id));
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "INSERT INTO starred "
- "(type, url_id, group_id, title, date_added, visual_order, parent_id, "
- "date_modified) VALUES (?,?,?,?,?,?,?,?)"));
-
- switch (type) {
- case history::StarredEntry::URL:
- statement.BindInt(0, 0);
- break;
- case history::StarredEntry::BOOKMARK_BAR:
- statement.BindInt(0, 1);
- break;
- case history::StarredEntry::USER_FOLDER:
- statement.BindInt(0, 2);
- break;
- case history::StarredEntry::OTHER:
- statement.BindInt(0, 3);
- break;
- default:
- NOTREACHED();
- }
- statement.BindInt64(1, url_id);
- statement.BindInt64(2, folder_id);
- statement.BindString16(3, title);
- statement.BindInt64(4, date_added.ToInternalValue());
- statement.BindInt(5, visual_order);
- statement.BindInt64(6, parent_folder_id);
- statement.BindInt64(7, base::Time().ToInternalValue());
-
- if (statement.Run())
- return GetDB().GetLastInsertRowId();
- return 0;
-}
-
-bool StarredURLDatabase::DeleteStarredEntryRow(StarID star_id) {
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "DELETE FROM starred WHERE id=?"));
- statement.BindInt64(0, star_id);
-
- return statement.Run();
-}
-
-bool StarredURLDatabase::GetStarredEntry(StarID star_id, StarredEntry* entry) {
- DCHECK(entry && star_id);
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "SELECT" STAR_FIELDS "FROM starred LEFT JOIN urls ON "
- "starred.url_id = urls.id WHERE starred.id=?"));
- statement.BindInt64(0, star_id);
-
- if (statement.Step()) {
- FillInStarredEntry(statement, entry);
- return true;
- }
- return false;
-}
-
-StarID StarredURLDatabase::CreateStarredEntry(StarredEntry* entry) {
- entry->id = 0; // Ensure 0 for failure case.
-
- // Adjust the visual order when we are inserting it somewhere.
- if (entry->parent_folder_id)
- AdjustStarredVisualOrder(entry->parent_folder_id, entry->visual_order, 1);
-
- // Insert the new entry.
- switch (entry->type) {
- case StarredEntry::USER_FOLDER:
- entry->id = CreateStarredEntryRow(0, entry->folder_id,
- entry->parent_folder_id, entry->title, entry->date_added,
- entry->visual_order, entry->type);
- break;
-
- case StarredEntry::URL: {
- // Get the row for this URL.
- URLRow url_row;
- if (!GetRowForURL(entry->url, &url_row)) {
- // Create a new URL row for this entry.
- url_row = URLRow(entry->url);
- url_row.set_title(entry->title);
- url_row.set_hidden(false);
- entry->url_id = this->AddURL(url_row);
- } else {
- entry->url_id = url_row.id(); // The caller doesn't have to set this.
- }
-
- // Create the star entry referring to the URL row.
- entry->id = CreateStarredEntryRow(entry->url_id, entry->folder_id,
- entry->parent_folder_id, entry->title, entry->date_added,
- entry->visual_order, entry->type);
-
- // Update the URL row to refer to this new starred entry.
- UpdateURLRow(entry->url_id, url_row);
- break;
- }
-
- default:
- NOTREACHED();
- break;
- }
- return entry->id;
-}
-
-UIStarID StarredURLDatabase::GetMaxFolderID() {
- sql::Statement max_folder_id_statement(GetDB().GetUniqueStatement(
- "SELECT MAX(group_id) FROM starred"));
-
- if (!max_folder_id_statement.Step()) {
- return 0;
- }
- return max_folder_id_statement.ColumnInt64(0);
-}
-
-bool StarredURLDatabase::BuildStarNodes(
- std::set<StarredURLDatabase::StarredNode*>* roots,
- std::set<StarID>* folders_with_duplicate_ids,
- std::set<StarredNode*>* unparented_urls,
- std::set<StarID>* empty_url_ids) {
- std::vector<StarredEntry> star_entries;
- if (!GetAllStarredEntries(&star_entries)) {
- NOTREACHED() << "Unable to get bookmarks from database";
- return false;
- }
-
- // Create the folder/bookmark-bar/other nodes.
- std::map<UIStarID, StarredNode*> folder_id_to_node_map;
- for (size_t i = 0; i < star_entries.size(); ++i) {
- if (star_entries[i].type != StarredEntry::URL) {
- if (folder_id_to_node_map.find(star_entries[i].folder_id) !=
- folder_id_to_node_map.end()) {
- // There's already a folder with this ID.
- folders_with_duplicate_ids->insert(star_entries[i].id);
- } else {
- // Create the node and update the mapping.
- StarredNode* node = new StarredNode(star_entries[i]);
- folder_id_to_node_map[star_entries[i].folder_id] = node;
- }
- }
- }
-
- // Iterate again, creating nodes for URL bookmarks and parenting all
- // bookmarks/folders. In addition populate the empty_url_ids with all entries
- // of type URL that have an empty URL.
- std::map<StarID, StarredNode*> id_to_node_map;
- for (size_t i = 0; i < star_entries.size(); ++i) {
- if (star_entries[i].type == StarredEntry::URL) {
- if (star_entries[i].url.is_empty()) {
- empty_url_ids->insert(star_entries[i].id);
- } else if (!star_entries[i].parent_folder_id ||
- folder_id_to_node_map.find(star_entries[i].parent_folder_id) ==
- folder_id_to_node_map.end()) {
- // This entry has no parent, or we couldn't find the parent.
- StarredNode* node = new StarredNode(star_entries[i]);
- unparented_urls->insert(node);
- } else {
- // Add the node to its parent.
- StarredNode* parent =
- folder_id_to_node_map[star_entries[i].parent_folder_id];
- StarredNode* node = new StarredNode(star_entries[i]);
- parent->Add(node, parent->child_count());
- }
- } else if (folders_with_duplicate_ids->find(star_entries[i].id) ==
- folders_with_duplicate_ids->end()) {
- // The entry is a folder (or bookmark bar/other node) that isn't
- // marked as a duplicate.
- if (!star_entries[i].parent_folder_id ||
- folder_id_to_node_map.find(star_entries[i].parent_folder_id) ==
- folder_id_to_node_map.end()) {
- // Entry has no parent, or the parent wasn't found.
- roots->insert(folder_id_to_node_map[star_entries[i].folder_id]);
- } else {
- // Parent the folder node.
- StarredNode* parent =
- folder_id_to_node_map[star_entries[i].parent_folder_id];
- StarredNode* node = folder_id_to_node_map[star_entries[i].folder_id];
- if (!node->HasAncestor(parent) && !parent->HasAncestor(node)) {
- parent->Add(node, parent->child_count());
- } else {
- // The node has a cycle. Add it to the list of roots so the cycle is
- // broken.
- roots->insert(node);
- }
- }
- }
- }
- return true;
-}
-
-StarredURLDatabase::StarredNode* StarredURLDatabase::GetNodeByType(
- const std::set<StarredURLDatabase::StarredNode*>& nodes,
- StarredEntry::Type type) {
- for (std::set<StarredNode*>::const_iterator i = nodes.begin();
- i != nodes.end(); ++i) {
- if ((*i)->value.type == type)
- return *i;
- }
- return NULL;
-}
-
-bool StarredURLDatabase::EnsureVisualOrder(
- StarredURLDatabase::StarredNode* node) {
- for (int i = 0; i < node->child_count(); ++i) {
- if (node->GetChild(i)->value.visual_order != i) {
- StarredEntry& entry = node->GetChild(i)->value;
- entry.visual_order = i;
- LOG(WARNING) << "Bookmark visual order is wrong";
- if (!UpdateStarredEntryRow(entry.id, entry.title, entry.parent_folder_id,
- i, entry.date_folder_modified)) {
- NOTREACHED() << "Unable to update visual order";
- return false;
- }
- }
- if (!EnsureVisualOrder(node->GetChild(i)))
- return false;
- }
- return true;
-}
-
-bool StarredURLDatabase::EnsureStarredIntegrityImpl(
- std::set<StarredURLDatabase::StarredNode*>* roots,
- const std::set<StarID>& folders_with_duplicate_ids,
- std::set<StarredNode*>* unparented_urls,
- const std::set<StarID>& empty_url_ids) {
- // Make sure the bookmark bar entry exists.
- StarredNode* bookmark_node =
- GetNodeByType(*roots, StarredEntry::BOOKMARK_BAR);
- if (!bookmark_node) {
- LOG(WARNING) << "No bookmark bar folder in database";
- // If there is no bookmark bar entry in the db things are really
- // screwed. Return false, which won't trigger migration and we'll just
- // drop the tables.
- return false;
- }
-
- // Make sure the other node exists.
- StarredNode* other_node = GetNodeByType(*roots, StarredEntry::OTHER);
- if (!other_node) {
- LOG(WARNING) << "No bookmark other folder in database";
- StarredEntry entry;
- entry.folder_id = GetMaxFolderID() + 1;
- if (entry.folder_id == 1) {
- NOTREACHED() << "Unable to get new id for other bookmarks folder";
- return false;
- }
- entry.id = CreateStarredEntryRow(
- 0, entry.folder_id, 0, UTF8ToUTF16("other"), base::Time::Now(), 0,
- history::StarredEntry::OTHER);
- if (!entry.id) {
- NOTREACHED() << "Unable to create other bookmarks folder";
- return false;
- }
- entry.type = StarredEntry::OTHER;
- StarredNode* other_node = new StarredNode(entry);
- roots->insert(other_node);
- }
-
- // We could potentially make sure only one folder with type
- // BOOKMARK_BAR/OTHER, but history backend enforces this.
-
- // Nuke any entries with no url.
- for (std::set<StarID>::const_iterator i = empty_url_ids.begin();
- i != empty_url_ids.end(); ++i) {
- LOG(WARNING) << "Bookmark exists with no URL";
- if (!DeleteStarredEntryRow(*i)) {
- NOTREACHED() << "Unable to delete bookmark";
- return false;
- }
- }
-
- // Make sure the visual order of the nodes is correct.
- for (std::set<StarredNode*>::const_iterator i = roots->begin();
- i != roots->end(); ++i) {
- if (!EnsureVisualOrder(*i))
- return false;
- }
-
- // Move any unparented bookmarks to the bookmark bar.
- {
- std::set<StarredNode*>::iterator i = unparented_urls->begin();
- while (i != unparented_urls->end()) {
- LOG(WARNING) << "Bookmark not in a bookmark folder found";
- if (!Move(*i, bookmark_node))
- return false;
- unparented_urls->erase(i++);
- }
- }
-
- // Nuke any folders with duplicate ids. A duplicate id means there are two
- // folders in the starred table with the same folder_id. We only keep the
- // first folder, all other folders are removed.
- for (std::set<StarID>::const_iterator i = folders_with_duplicate_ids.begin();
- i != folders_with_duplicate_ids.end(); ++i) {
- LOG(WARNING) << "Duplicate folder id in bookmark database";
- if (!DeleteStarredEntryRow(*i)) {
- NOTREACHED() << "Unable to delete folder";
- return false;
- }
- }
-
- // Move unparented user folders back to the bookmark bar.
- {
- std::set<StarredNode*>::iterator i = roots->begin();
- while (i != roots->end()) {
- if ((*i)->value.type == StarredEntry::USER_FOLDER) {
- LOG(WARNING) << "Bookmark folder not on bookmark bar found";
- if (!Move(*i, bookmark_node))
- return false;
- roots->erase(i++);
- } else {
- ++i;
- }
- }
- }
-
- return true;
-}
-
-bool StarredURLDatabase::Move(StarredNode* source, StarredNode* new_parent) {
- history::StarredEntry& entry = source->value;
- entry.visual_order = new_parent->child_count();
- entry.parent_folder_id = new_parent->value.folder_id;
- if (!UpdateStarredEntryRow(entry.id, entry.title,
- entry.parent_folder_id, entry.visual_order,
- entry.date_folder_modified)) {
- NOTREACHED() << "Unable to move folder";
- return false;
- }
- new_parent->Add(source, new_parent->child_count());
- return true;
-}
-
-bool StarredURLDatabase::MigrateBookmarksToFileImpl(const FilePath& path) {
- std::vector<history::StarredEntry> entries;
- if (!GetAllStarredEntries(&entries))
- return false;
-
- // Create the bookmark bar and other folder nodes.
- history::StarredEntry entry;
- entry.type = history::StarredEntry::BOOKMARK_BAR;
- BookmarkNode bookmark_bar_node(0, GURL());
- ResetBookmarkNode(entry, &bookmark_bar_node);
- entry.type = history::StarredEntry::OTHER;
- BookmarkNode other_node(0, GURL());
- ResetBookmarkNode(entry, &other_node);
- // NOTE(yfriedman): We don't do anything with the mobile node because it won't
- // ever exist in the starred node DB. We only need to create it to pass to
- // "encode".
- entry.type = history::StarredEntry::MOBILE;
- BookmarkNode mobile_node(0, GURL());
- ResetBookmarkNode(entry, &mobile_node);
-
- std::map<history::UIStarID, history::StarID> folder_id_to_id_map;
- typedef std::map<history::StarID, BookmarkNode*> IDToNodeMap;
- IDToNodeMap id_to_node_map;
-
- history::UIStarID other_folder_folder_id = 0;
- history::StarID other_folder_id = 0;
-
- // Iterate through the entries building a mapping between folder_id and id.
- for (std::vector<history::StarredEntry>::const_iterator i = entries.begin();
- i != entries.end(); ++i) {
- if (i->type != history::StarredEntry::URL) {
- folder_id_to_id_map[i->folder_id] = i->id;
- if (i->type == history::StarredEntry::OTHER) {
- other_folder_id = i->id;
- other_folder_folder_id = i->folder_id;
- }
- }
- }
-
- // Register the bookmark bar and other folder nodes in the maps.
- id_to_node_map[kBookmarkBarID] = &bookmark_bar_node;
- folder_id_to_id_map[kBookmarkBarID] = kBookmarkBarID;
- if (other_folder_folder_id) {
- id_to_node_map[other_folder_id] = &other_node;
- folder_id_to_id_map[other_folder_folder_id] = other_folder_id;
- }
-
- // Iterate through the entries again creating the nodes.
- for (std::vector<history::StarredEntry>::iterator i = entries.begin();
- i != entries.end(); ++i) {
- if (!i->parent_folder_id) {
- DCHECK(i->type == history::StarredEntry::BOOKMARK_BAR ||
- i->type == history::StarredEntry::MOBILE ||
- i->type == history::StarredEntry::OTHER);
- // Only entries with no parent should be the bookmark bar and other
- // bookmarks folders.
- continue;
- }
-
- BookmarkNode* node = id_to_node_map[i->id];
- if (!node) {
- // Creating a node results in creating the parent. As such, it is
- // possible for the node representing a folder to have been created before
- // encountering the details.
-
- // The created nodes are owned by the root node.
- node = new BookmarkNode(i->url);
- id_to_node_map[i->id] = node;
- }
- ResetBookmarkNode(*i, node);
-
- DCHECK(folder_id_to_id_map.find(i->parent_folder_id) !=
- folder_id_to_id_map.end());
- history::StarID parent_id = folder_id_to_id_map[i->parent_folder_id];
- BookmarkNode* parent = id_to_node_map[parent_id];
- if (!parent) {
- // Haven't encountered the parent yet, create it now.
- parent = new BookmarkNode(GURL());
- id_to_node_map[parent_id] = parent;
- }
-
- // Add the node to its parent. |entries| is ordered by parent then
- // visual order so that we know we maintain visual order by always adding
- // to the end.
- parent->Add(node, parent->child_count());
- }
-
- // Save to file.
- BookmarkCodec encoder;
- scoped_ptr<Value> encoded_bookmarks(
- encoder.Encode(&bookmark_bar_node, &other_node, &mobile_node));
- std::string content;
- base::JSONWriter::WriteWithOptions(encoded_bookmarks.get(),
- base::JSONWriter::OPTIONS_PRETTY_PRINT,
- &content);
-
- return (file_util::WriteFile(path, content.c_str(),
- static_cast<int>(content.length())) != -1);
-}
-
-} // namespace history
« no previous file with comments | « chrome/browser/history/starred_url_database.h ('k') | chrome/browser/history/starred_url_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698