Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / predictors / autocomplete_action_predictor_table.cc
blob73ed0c77be45579bb0e6f6e7261bf0870edd0aec
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.
5 #include "chrome/browser/predictors/autocomplete_action_predictor_table.h"
7 #include "base/guid.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "sql/statement.h"
15 namespace {
17 // TODO(shishir): Rename the table for consistency.
18 const char kAutocompletePredictorTableName[] = "network_action_predictor";
20 // The maximum length allowed for strings in the database.
21 const size_t kMaxDataLength = 2048;
23 void BindRowToStatement(
24 const predictors::AutocompleteActionPredictorTable::Row& row,
25 sql::Statement* statement) {
26 DCHECK(base::IsValidGUID(row.id));
27 statement->BindString(0, row.id);
28 statement->BindString16(1, row.user_text.substr(0, kMaxDataLength));
29 statement->BindString(2, row.url.spec().substr(0, kMaxDataLength));
30 statement->BindInt(3, row.number_of_hits);
31 statement->BindInt(4, row.number_of_misses);
34 bool StepAndInitializeRow(
35 sql::Statement* statement,
36 predictors::AutocompleteActionPredictorTable::Row* row) {
37 if (!statement->Step())
38 return false;
40 row->id = statement->ColumnString(0);
41 row->user_text = statement->ColumnString16(1);
42 row->url = GURL(statement->ColumnString(2));
43 row->number_of_hits = statement->ColumnInt(3);
44 row->number_of_misses = statement->ColumnInt(4);
45 return true;
48 } // namespace
50 namespace predictors {
52 AutocompleteActionPredictorTable::Row::Row()
53 : number_of_hits(0),
54 number_of_misses(0) {
57 AutocompleteActionPredictorTable::Row::Row(const Row::Id& id,
58 const base::string16& user_text,
59 const GURL& url,
60 int number_of_hits,
61 int number_of_misses)
62 : id(id),
63 user_text(user_text),
64 url(url),
65 number_of_hits(number_of_hits),
66 number_of_misses(number_of_misses) {
69 AutocompleteActionPredictorTable::Row::Row(const Row& row)
70 : id(row.id),
71 user_text(row.user_text),
72 url(row.url),
73 number_of_hits(row.number_of_hits),
74 number_of_misses(row.number_of_misses) {
78 void AutocompleteActionPredictorTable::GetRow(const Row::Id& id, Row* row) {
79 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
80 if (CantAccessDatabase())
81 return;
83 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
84 base::StringPrintf("SELECT * FROM %s WHERE id=?",
85 kAutocompletePredictorTableName).c_str()));
86 statement.BindString(0, id);
88 bool success = StepAndInitializeRow(&statement, row);
89 DCHECK(success) << "Failed to get row " << id << " from "
90 << kAutocompletePredictorTableName;
93 void AutocompleteActionPredictorTable::GetAllRows(Rows* row_buffer) {
94 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
95 if (CantAccessDatabase())
96 return;
98 row_buffer->clear();
100 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
101 base::StringPrintf(
102 "SELECT * FROM %s", kAutocompletePredictorTableName).c_str()));
103 if (!statement.is_valid())
104 return;
106 Row row;
107 while (StepAndInitializeRow(&statement, &row))
108 row_buffer->push_back(row);
111 void AutocompleteActionPredictorTable::AddRow(
112 const AutocompleteActionPredictorTable::Row& row) {
113 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
114 if (CantAccessDatabase())
115 return;
117 AddAndUpdateRows(Rows(1, row), Rows());
120 void AutocompleteActionPredictorTable::UpdateRow(
121 const AutocompleteActionPredictorTable::Row& row) {
122 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
123 if (CantAccessDatabase())
124 return;
126 AddAndUpdateRows(Rows(), Rows(1, row));
129 void AutocompleteActionPredictorTable::AddAndUpdateRows(
130 const Rows& rows_to_add,
131 const Rows& rows_to_update) {
132 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
133 if (CantAccessDatabase())
134 return;
136 if (!DB()->BeginTransaction())
137 return;
138 for (Rows::const_iterator it = rows_to_add.begin();
139 it != rows_to_add.end(); ++it) {
140 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
141 base::StringPrintf(
142 "INSERT INTO %s "
143 "(id, user_text, url, number_of_hits, number_of_misses) "
144 "VALUES (?,?,?,?,?)", kAutocompletePredictorTableName).c_str()));
145 if (!statement.is_valid()) {
146 DB()->RollbackTransaction();
147 return;
150 BindRowToStatement(*it, &statement);
151 if (!statement.Run()) {
152 DB()->RollbackTransaction();
153 return;
156 for (Rows::const_iterator it = rows_to_update.begin();
157 it != rows_to_update.end(); ++it) {
158 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
159 base::StringPrintf(
160 "UPDATE %s "
161 "SET id=?, user_text=?, url=?, number_of_hits=?, number_of_misses=?"
162 " WHERE id=?1", kAutocompletePredictorTableName).c_str()));
163 if (!statement.is_valid()) {
164 DB()->RollbackTransaction();
165 return;
168 BindRowToStatement(*it, &statement);
169 if (!statement.Run()) {
170 DB()->RollbackTransaction();
171 return;
173 DCHECK_GT(DB()->GetLastChangeCount(), 0);
175 DB()->CommitTransaction();
178 void AutocompleteActionPredictorTable::DeleteRows(
179 const std::vector<Row::Id>& id_list) {
180 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
181 if (CantAccessDatabase())
182 return;
184 if (!DB()->BeginTransaction())
185 return;
186 for (std::vector<Row::Id>::const_iterator it = id_list.begin();
187 it != id_list.end(); ++it) {
188 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
189 base::StringPrintf(
190 "DELETE FROM %s WHERE id=?",
191 kAutocompletePredictorTableName).c_str()));
192 if (!statement.is_valid()) {
193 DB()->RollbackTransaction();
194 return;
197 statement.BindString(0, *it);
198 if (!statement.Run()) {
199 DB()->RollbackTransaction();
200 return;
203 DB()->CommitTransaction();
206 void AutocompleteActionPredictorTable::DeleteAllRows() {
207 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
208 if (CantAccessDatabase())
209 return;
211 sql::Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
212 base::StringPrintf("DELETE FROM %s",
213 kAutocompletePredictorTableName).c_str()));
214 if (!statement.is_valid())
215 return;
217 statement.Run();
220 AutocompleteActionPredictorTable::AutocompleteActionPredictorTable()
221 : PredictorTableBase() {
224 AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() {
227 void AutocompleteActionPredictorTable::CreateTableIfNonExistent() {
228 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
229 if (CantAccessDatabase())
230 return;
232 if (DB()->DoesTableExist(kAutocompletePredictorTableName))
233 return;
235 bool success = DB()->Execute(base::StringPrintf(
236 "CREATE TABLE %s ( "
237 "id TEXT PRIMARY KEY, "
238 "user_text TEXT, "
239 "url TEXT, "
240 "number_of_hits INTEGER, "
241 "number_of_misses INTEGER)", kAutocompletePredictorTableName).c_str());
242 if (!success)
243 ResetDB();
246 void AutocompleteActionPredictorTable::LogDatabaseStats() {
247 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
248 if (CantAccessDatabase())
249 return;
251 sql::Statement count_statement(DB()->GetUniqueStatement(
252 base::StringPrintf("SELECT count(id) FROM %s",
253 kAutocompletePredictorTableName).c_str()));
254 if (!count_statement.is_valid() || !count_statement.Step())
255 return;
256 UMA_HISTOGRAM_COUNTS("AutocompleteActionPredictor.DatabaseRowCount",
257 count_statement.ColumnInt(0));
260 } // namespace predictors