1// Copyright (c) 2012 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/browser/history/android/bookmark_model_sql_handler.h"
6
7#include "base/logging.h"
8#include "chrome/browser/bookmarks/bookmark_model_factory.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/profiles/profile_manager.h"
11#include "components/bookmarks/browser/bookmark_model.h"
12#include "components/bookmarks/browser/bookmark_utils.h"
13#include "components/history/core/browser/url_database.h"
14#include "content/public/browser/browser_thread.h"
15
16using base::Time;
17using content::BrowserThread;
18
19namespace history {
20
21namespace {
22
23// The interesting columns of this handler.
24const HistoryAndBookmarkRow::ColumnID kInterestingColumns[] = {
25    HistoryAndBookmarkRow::BOOKMARK, HistoryAndBookmarkRow::TITLE };
26
27} // namespace
28
29BookmarkModelSQLHandler::Task::Task() {
30}
31
32void BookmarkModelSQLHandler::Task::AddBookmarkToMobileFolder(
33    const GURL& url,
34    const base::string16& title) {
35  BookmarkModel* bookmark_model = GetBookmarkModel();
36  if (!bookmark_model)
37    return;
38  const BookmarkNode* mobile_node = bookmark_model->mobile_node();
39  if (mobile_node)
40    bookmark_model->AddURL(mobile_node, 0, title, url);
41}
42
43void BookmarkModelSQLHandler::Task::AddBookmark(const GURL& url,
44                                                const base::string16& title,
45                                                int64 parent_id) {
46  BookmarkModel* bookmark_model = GetBookmarkModel();
47  if (!bookmark_model)
48    return;
49  const BookmarkNode* parent =
50      bookmarks::GetBookmarkNodeByID(bookmark_model, parent_id);
51  if (parent)
52    bookmark_model->AddURL(parent, 0, title, url);
53}
54
55void BookmarkModelSQLHandler::Task::RemoveBookmark(const GURL& url) {
56  BookmarkModel* bookmark_model = GetBookmarkModel();
57  if (!bookmark_model)
58    return;
59  std::vector<const BookmarkNode*> nodes;
60  bookmark_model->GetNodesByURL(url, &nodes);
61  for (std::vector<const BookmarkNode*>::iterator i = nodes.begin();
62       i != nodes.end(); ++i) {
63    const BookmarkNode* parent_node = (*i)->parent();
64    bookmark_model->Remove(parent_node, parent_node->GetIndexOf(*i));
65  }
66}
67
68void BookmarkModelSQLHandler::Task::UpdateBookmarkTitle(
69    const GURL& url,
70    const base::string16& title) {
71  BookmarkModel* bookmark_model = GetBookmarkModel();
72  if (!bookmark_model)
73    return;
74  std::vector<const BookmarkNode*> nodes;
75  bookmark_model->GetNodesByURL(url, &nodes);
76  for (std::vector<const BookmarkNode*>::iterator i = nodes.begin();
77       i != nodes.end(); ++i) {
78    bookmark_model->SetTitle(*i, title);
79  }
80}
81
82
83BookmarkModelSQLHandler::Task::~Task() {
84}
85
86BookmarkModel* BookmarkModelSQLHandler::Task::GetBookmarkModel() {
87  Profile* profile = ProfileManager::GetLastUsedProfile();
88  if (!profile)
89    return NULL;
90  return BookmarkModelFactory::GetForProfile(profile);
91}
92
93BookmarkModelSQLHandler::BookmarkModelSQLHandler(
94    URLDatabase* url_database)
95    : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
96      url_database_(url_database) {
97}
98
99BookmarkModelSQLHandler::~BookmarkModelSQLHandler() {
100}
101
102bool BookmarkModelSQLHandler::Update(const HistoryAndBookmarkRow& row,
103                                     const TableIDRows& ids_set) {
104  for (TableIDRows::const_iterator i = ids_set.begin();
105      i != ids_set.end(); ++i) {
106    if (row.is_value_set_explicitly(HistoryAndBookmarkRow::BOOKMARK)) {
107      if (row.is_bookmark()) {
108        URLRow url_row;
109        if (!url_database_->GetURLRow(i->url_id, &url_row))
110          return false;
111        if (row.is_value_set_explicitly(HistoryAndBookmarkRow::PARENT_ID)) {
112          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
113              &BookmarkModelSQLHandler::Task::AddBookmark,
114              scoped_refptr<BookmarkModelSQLHandler::Task>(
115                  new BookmarkModelSQLHandler::Task()),
116              i->url, url_row.title(), row.parent_id()));
117        } else {
118          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
119              &BookmarkModelSQLHandler::Task::AddBookmarkToMobileFolder,
120              scoped_refptr<BookmarkModelSQLHandler::Task>(
121                  new BookmarkModelSQLHandler::Task()),
122              i->url, url_row.title()));
123        }
124      } else {
125        BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
126            &BookmarkModelSQLHandler::Task::RemoveBookmark,
127            scoped_refptr<BookmarkModelSQLHandler::Task>(
128                new BookmarkModelSQLHandler::Task()),
129            i->url));
130      }
131    } else if (row.is_value_set_explicitly(HistoryAndBookmarkRow::TITLE)) {
132      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
133          &BookmarkModelSQLHandler::Task::UpdateBookmarkTitle,
134          scoped_refptr<BookmarkModelSQLHandler::Task>(
135              new BookmarkModelSQLHandler::Task()),
136          i->url, row.title()));
137    }
138  }
139  return true;
140}
141
142bool BookmarkModelSQLHandler::Delete(const TableIDRows& ids_set) {
143  for (TableIDRows::const_iterator i = ids_set.begin();
144       i != ids_set.end(); ++i) {
145    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
146        &BookmarkModelSQLHandler::Task::RemoveBookmark,
147        scoped_refptr<BookmarkModelSQLHandler::Task>(
148            new BookmarkModelSQLHandler::Task()),
149        i->url));
150  }
151  return true;
152}
153
154bool BookmarkModelSQLHandler::Insert(HistoryAndBookmarkRow* row) {
155  DCHECK(row->is_value_set_explicitly(HistoryAndBookmarkRow::URL));
156  if (!row->is_value_set_explicitly(HistoryAndBookmarkRow::BOOKMARK) ||
157      !row->is_bookmark())
158    return true;
159  if (row->is_value_set_explicitly(HistoryAndBookmarkRow::PARENT_ID)) {
160    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
161        &BookmarkModelSQLHandler::Task::AddBookmark,
162        scoped_refptr<BookmarkModelSQLHandler::Task>(
163            new BookmarkModelSQLHandler::Task()),
164        row->url(), row->title(), row->parent_id()));
165  } else {
166    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
167        &BookmarkModelSQLHandler::Task::AddBookmarkToMobileFolder,
168        scoped_refptr<BookmarkModelSQLHandler::Task>(
169            new BookmarkModelSQLHandler::Task()),
170        row->url(), row->title()));
171  }
172  return true;
173}
174
175}  // namespace history
176