1// Copyright 2014 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 "components/search_engines/keyword_web_data_service.h"
6
7#include "base/bind.h"
8#include "components/search_engines/keyword_table.h"
9#include "components/search_engines/template_url_data.h"
10#include "components/webdata/common/web_data_results.h"
11#include "components/webdata/common/web_database_service.h"
12
13using base::Bind;
14
15WDKeywordsResult::WDKeywordsResult()
16  : default_search_provider_id(0),
17    builtin_keyword_version(0) {
18}
19
20WDKeywordsResult::~WDKeywordsResult() {}
21
22KeywordWebDataService::BatchModeScoper::BatchModeScoper(
23    KeywordWebDataService* service)
24    : service_(service) {
25  if (service_)
26    service_->AdjustBatchModeLevel(true);
27}
28
29KeywordWebDataService::BatchModeScoper::~BatchModeScoper() {
30  if (service_)
31    service_->AdjustBatchModeLevel(false);
32}
33
34KeywordWebDataService::KeywordWebDataService(
35    scoped_refptr<WebDatabaseService> wdbs,
36    scoped_refptr<base::MessageLoopProxy> ui_thread,
37    const ProfileErrorCallback& callback)
38    : WebDataServiceBase(wdbs, callback, ui_thread),
39      batch_mode_level_(0) {
40}
41
42void KeywordWebDataService::AddKeyword(const TemplateURLData& data) {
43  if (batch_mode_level_) {
44    queued_keyword_operations_.push_back(
45        KeywordTable::Operation(KeywordTable::ADD, data));
46  } else {
47    AdjustBatchModeLevel(true);
48    AddKeyword(data);
49    AdjustBatchModeLevel(false);
50  }
51}
52
53void KeywordWebDataService::RemoveKeyword(TemplateURLID id) {
54  if (batch_mode_level_) {
55    TemplateURLData data;
56    data.id = id;
57    queued_keyword_operations_.push_back(
58        KeywordTable::Operation(KeywordTable::REMOVE, data));
59  } else {
60    AdjustBatchModeLevel(true);
61    RemoveKeyword(id);
62    AdjustBatchModeLevel(false);
63  }
64}
65
66void KeywordWebDataService::UpdateKeyword(const TemplateURLData& data) {
67  if (batch_mode_level_) {
68    queued_keyword_operations_.push_back(
69        KeywordTable::Operation(KeywordTable::UPDATE, data));
70  } else {
71    AdjustBatchModeLevel(true);
72    UpdateKeyword(data);
73    AdjustBatchModeLevel(false);
74  }
75}
76
77WebDataServiceBase::Handle KeywordWebDataService::GetKeywords(
78    WebDataServiceConsumer* consumer) {
79  return wdbs_->ScheduleDBTaskWithResult(
80      FROM_HERE, Bind(&KeywordWebDataService::GetKeywordsImpl, this), consumer);
81}
82
83void KeywordWebDataService::SetDefaultSearchProviderID(TemplateURLID id) {
84  wdbs_->ScheduleDBTask(
85      FROM_HERE,
86      Bind(&KeywordWebDataService::SetDefaultSearchProviderIDImpl, this, id));
87}
88
89void KeywordWebDataService::SetBuiltinKeywordVersion(int version) {
90  wdbs_->ScheduleDBTask(
91      FROM_HERE,
92      Bind(&KeywordWebDataService::SetBuiltinKeywordVersionImpl,
93           this, version));
94}
95
96KeywordWebDataService::~KeywordWebDataService() {
97  DCHECK(!batch_mode_level_);
98}
99
100void KeywordWebDataService::AdjustBatchModeLevel(bool entering_batch_mode) {
101  if (entering_batch_mode) {
102    ++batch_mode_level_;
103  } else {
104    DCHECK(batch_mode_level_);
105    --batch_mode_level_;
106    if (!batch_mode_level_ && !queued_keyword_operations_.empty()) {
107      wdbs_->ScheduleDBTask(
108          FROM_HERE,
109          Bind(&KeywordWebDataService::PerformKeywordOperationsImpl, this,
110               queued_keyword_operations_));
111      queued_keyword_operations_.clear();
112    }
113  }
114}
115
116WebDatabase::State KeywordWebDataService::PerformKeywordOperationsImpl(
117    const KeywordTable::Operations& operations,
118    WebDatabase* db) {
119  return KeywordTable::FromWebDatabase(db)->PerformOperations(operations) ?
120      WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
121}
122
123scoped_ptr<WDTypedResult> KeywordWebDataService::GetKeywordsImpl(
124    WebDatabase* db) {
125  scoped_ptr<WDTypedResult> result_ptr;
126  WDKeywordsResult result;
127  if (KeywordTable::FromWebDatabase(db)->GetKeywords(&result.keywords)) {
128    result.default_search_provider_id =
129        KeywordTable::FromWebDatabase(db)->GetDefaultSearchProviderID();
130    result.builtin_keyword_version =
131        KeywordTable::FromWebDatabase(db)->GetBuiltinKeywordVersion();
132    result_ptr.reset(new WDResult<WDKeywordsResult>(KEYWORDS_RESULT, result));
133  }
134  return result_ptr.Pass();
135}
136
137WebDatabase::State KeywordWebDataService::SetDefaultSearchProviderIDImpl(
138    TemplateURLID id,
139    WebDatabase* db) {
140  return KeywordTable::FromWebDatabase(db)->SetDefaultSearchProviderID(id) ?
141      WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
142}
143
144WebDatabase::State KeywordWebDataService::SetBuiltinKeywordVersionImpl(
145    int version,
146    WebDatabase* db) {
147  return KeywordTable::FromWebDatabase(db)->SetBuiltinKeywordVersion(version) ?
148      WebDatabase::COMMIT_NEEDED : WebDatabase::COMMIT_NOT_NEEDED;
149}
150