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.h"
9#include "chrome/browser/bookmarks/bookmark_model_factory.h"
10#include "chrome/browser/bookmarks/bookmark_service.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/history/url_database.h"
13#include "chrome/browser/profiles/profile_manager.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 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 string16& title,
45                                                int64 parent_id) {
46  BookmarkModel* bookmark_model = GetBookmarkModel();
47  if (!bookmark_model)
48    return;
49  const BookmarkNode* parent = bookmark_model->GetNodeByID(parent_id);
50  if (parent)
51    bookmark_model->AddURL(parent, 0, title, url);
52}
53
54void BookmarkModelSQLHandler::Task::RemoveBookmark(const GURL& url) {
55  BookmarkModel* bookmark_model = GetBookmarkModel();
56  if (!bookmark_model)
57    return;
58  std::vector<const BookmarkNode*> nodes;
59  bookmark_model->GetNodesByURL(url, &nodes);
60  for (std::vector<const BookmarkNode*>::iterator i = nodes.begin();
61       i != nodes.end(); ++i) {
62    const BookmarkNode* parent_node = (*i)->parent();
63    bookmark_model->Remove(parent_node, parent_node->GetIndexOf(*i));
64  }
65}
66
67void BookmarkModelSQLHandler::Task::UpdateBookmarkTitle(const GURL& url,
68                                                        const string16&title) {
69  BookmarkModel* bookmark_model = GetBookmarkModel();
70  if (!bookmark_model)
71    return;
72  std::vector<const BookmarkNode*> nodes;
73  bookmark_model->GetNodesByURL(url, &nodes);
74  for (std::vector<const BookmarkNode*>::iterator i = nodes.begin();
75       i != nodes.end(); ++i) {
76    bookmark_model->SetTitle(*i, title);
77  }
78}
79
80
81BookmarkModelSQLHandler::Task::~Task() {
82}
83
84BookmarkModel* BookmarkModelSQLHandler::Task::GetBookmarkModel() {
85  Profile* profile = ProfileManager::GetLastUsedProfile();
86  if (!profile)
87    return NULL;
88  return BookmarkModelFactory::GetForProfile(profile);
89}
90
91BookmarkModelSQLHandler::BookmarkModelSQLHandler(
92    URLDatabase* url_database)
93    : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
94      url_database_(url_database) {
95}
96
97BookmarkModelSQLHandler::~BookmarkModelSQLHandler() {
98}
99
100bool BookmarkModelSQLHandler::Update(const HistoryAndBookmarkRow& row,
101                                     const TableIDRows& ids_set) {
102  for (TableIDRows::const_iterator i = ids_set.begin();
103      i != ids_set.end(); ++i) {
104    if (row.is_value_set_explicitly(HistoryAndBookmarkRow::BOOKMARK)) {
105      if (row.is_bookmark()) {
106        URLRow url_row;
107        if (!url_database_->GetURLRow(i->url_id, &url_row))
108          return false;
109        if (row.is_value_set_explicitly(HistoryAndBookmarkRow::PARENT_ID)) {
110          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
111              &BookmarkModelSQLHandler::Task::AddBookmark,
112              scoped_refptr<BookmarkModelSQLHandler::Task>(
113                  new BookmarkModelSQLHandler::Task()),
114              i->url, url_row.title(), row.parent_id()));
115        } else {
116          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
117              &BookmarkModelSQLHandler::Task::AddBookmarkToMobileFolder,
118              scoped_refptr<BookmarkModelSQLHandler::Task>(
119                  new BookmarkModelSQLHandler::Task()),
120              i->url, url_row.title()));
121        }
122      } else {
123        BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
124            &BookmarkModelSQLHandler::Task::RemoveBookmark,
125            scoped_refptr<BookmarkModelSQLHandler::Task>(
126                new BookmarkModelSQLHandler::Task()),
127            i->url));
128      }
129    } else if (row.is_value_set_explicitly(HistoryAndBookmarkRow::TITLE)) {
130      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
131          &BookmarkModelSQLHandler::Task::UpdateBookmarkTitle,
132          scoped_refptr<BookmarkModelSQLHandler::Task>(
133              new BookmarkModelSQLHandler::Task()),
134          i->url, row.title()));
135    }
136  }
137  return true;
138}
139
140bool BookmarkModelSQLHandler::Delete(const TableIDRows& ids_set) {
141  for (TableIDRows::const_iterator i = ids_set.begin();
142       i != ids_set.end(); ++i) {
143    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
144        &BookmarkModelSQLHandler::Task::RemoveBookmark,
145        scoped_refptr<BookmarkModelSQLHandler::Task>(
146            new BookmarkModelSQLHandler::Task()),
147        i->url));
148  }
149  return true;
150}
151
152bool BookmarkModelSQLHandler::Insert(HistoryAndBookmarkRow* row) {
153  DCHECK(row->is_value_set_explicitly(HistoryAndBookmarkRow::URL));
154  if (!row->is_value_set_explicitly(HistoryAndBookmarkRow::BOOKMARK) ||
155      !row->is_bookmark())
156    return true;
157  if (row->is_value_set_explicitly(HistoryAndBookmarkRow::PARENT_ID)) {
158    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
159        &BookmarkModelSQLHandler::Task::AddBookmark,
160        scoped_refptr<BookmarkModelSQLHandler::Task>(
161            new BookmarkModelSQLHandler::Task()),
162        row->url(), row->title(), row->parent_id()));
163  } else {
164    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
165        &BookmarkModelSQLHandler::Task::AddBookmarkToMobileFolder,
166        scoped_refptr<BookmarkModelSQLHandler::Task>(
167            new BookmarkModelSQLHandler::Task()),
168        row->url(), row->title()));
169  }
170  return true;
171}
172
173}  // namespace history.
174