| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/history/visit_database.h" | 5 #include "chrome/browser/history/visit_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 bool VisitDatabase::InitVisitTable() { | 28 bool VisitDatabase::InitVisitTable() { |
| 29 if (!GetDB().DoesTableExist("visits")) { | 29 if (!GetDB().DoesTableExist("visits")) { |
| 30 if (!GetDB().Execute("CREATE TABLE visits(" | 30 if (!GetDB().Execute("CREATE TABLE visits(" |
| 31 "id INTEGER PRIMARY KEY," | 31 "id INTEGER PRIMARY KEY," |
| 32 "url INTEGER NOT NULL," // key of the URL this corresponds to | 32 "url INTEGER NOT NULL," // key of the URL this corresponds to |
| 33 "visit_time INTEGER NOT NULL," | 33 "visit_time INTEGER NOT NULL," |
| 34 "from_visit INTEGER," | 34 "from_visit INTEGER," |
| 35 "transition INTEGER DEFAULT 0 NOT NULL," | 35 "transition INTEGER DEFAULT 0 NOT NULL," |
| 36 "segment_id INTEGER," | 36 "segment_id INTEGER," |
| 37 // Some old DBs may have an "is_indexed" field here, but this is no | 37 // True when we have indexed data for this visit. |
| 38 // longer used and should NOT be read or written from any longer. | 38 "is_indexed BOOLEAN," |
| 39 "visit_duration INTEGER DEFAULT 0 NOT NULL)")) | 39 "visit_duration INTEGER DEFAULT 0 NOT NULL)")) |
| 40 return false; | 40 return false; |
| 41 } else if (!GetDB().DoesColumnExist("visits", "is_indexed")) { |
| 42 // Old versions don't have the is_indexed column, we can just add that and |
| 43 // not worry about different database revisions, since old ones will |
| 44 // continue to work. |
| 45 // |
| 46 // TODO(brettw) this should be removed once we think everybody has been |
| 47 // updated (added early Mar 2008). |
| 48 if (!GetDB().Execute("ALTER TABLE visits ADD COLUMN is_indexed BOOLEAN")) |
| 49 return false; |
| 41 } | 50 } |
| 42 | 51 |
| 43 // Visit source table contains the source information for all the visits. To | 52 // Visit source table contains the source information for all the visits. To |
| 44 // save space, we do not record those user browsed visits which would be the | 53 // save space, we do not record those user browsed visits which would be the |
| 45 // majority in this table. Only other sources are recorded. | 54 // majority in this table. Only other sources are recorded. |
| 46 // Due to the tight relationship between visit_source and visits table, they | 55 // Due to the tight relationship between visit_source and visits table, they |
| 47 // should be created and dropped at the same time. | 56 // should be created and dropped at the same time. |
| 48 if (!GetDB().DoesTableExist("visit_source")) { | 57 if (!GetDB().DoesTableExist("visit_source")) { |
| 49 if (!GetDB().Execute("CREATE TABLE visit_source(" | 58 if (!GetDB().Execute("CREATE TABLE visit_source(" |
| 50 "id INTEGER PRIMARY KEY,source INTEGER NOT NULL)")) | 59 "id INTEGER PRIMARY KEY,source INTEGER NOT NULL)")) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 91 |
| 83 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. | 92 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. |
| 84 // static | 93 // static |
| 85 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { | 94 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { |
| 86 visit->visit_id = statement.ColumnInt64(0); | 95 visit->visit_id = statement.ColumnInt64(0); |
| 87 visit->url_id = statement.ColumnInt64(1); | 96 visit->url_id = statement.ColumnInt64(1); |
| 88 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); | 97 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); |
| 89 visit->referring_visit = statement.ColumnInt64(3); | 98 visit->referring_visit = statement.ColumnInt64(3); |
| 90 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4)); | 99 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4)); |
| 91 visit->segment_id = statement.ColumnInt64(5); | 100 visit->segment_id = statement.ColumnInt64(5); |
| 101 visit->is_indexed = !!statement.ColumnInt(6); |
| 92 visit->visit_duration = | 102 visit->visit_duration = |
| 93 base::TimeDelta::FromInternalValue(statement.ColumnInt64(6)); | 103 base::TimeDelta::FromInternalValue(statement.ColumnInt64(7)); |
| 94 } | 104 } |
| 95 | 105 |
| 96 // static | 106 // static |
| 97 bool VisitDatabase::FillVisitVector(sql::Statement& statement, | 107 bool VisitDatabase::FillVisitVector(sql::Statement& statement, |
| 98 VisitVector* visits) { | 108 VisitVector* visits) { |
| 99 if (!statement.is_valid()) | 109 if (!statement.is_valid()) |
| 100 return false; | 110 return false; |
| 101 | 111 |
| 102 while (statement.Step()) { | 112 while (statement.Step()) { |
| 103 history::VisitRow visit; | 113 history::VisitRow visit; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 if (static_cast<int>(visits->size()) >= options.EffectiveMaxCount()) | 147 if (static_cast<int>(visits->size()) >= options.EffectiveMaxCount()) |
| 138 return true; | 148 return true; |
| 139 visits->push_back(visit); | 149 visits->push_back(visit); |
| 140 } | 150 } |
| 141 return false; | 151 return false; |
| 142 } | 152 } |
| 143 | 153 |
| 144 VisitID VisitDatabase::AddVisit(VisitRow* visit, VisitSource source) { | 154 VisitID VisitDatabase::AddVisit(VisitRow* visit, VisitSource source) { |
| 145 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 155 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 146 "INSERT INTO visits " | 156 "INSERT INTO visits " |
| 147 "(url, visit_time, from_visit, transition, segment_id, " | 157 "(url, visit_time, from_visit, transition, segment_id, is_indexed, " |
| 148 "visit_duration) VALUES (?,?,?,?,?,?)")); | 158 "visit_duration) VALUES (?,?,?,?,?,?,?)")); |
| 149 statement.BindInt64(0, visit->url_id); | 159 statement.BindInt64(0, visit->url_id); |
| 150 statement.BindInt64(1, visit->visit_time.ToInternalValue()); | 160 statement.BindInt64(1, visit->visit_time.ToInternalValue()); |
| 151 statement.BindInt64(2, visit->referring_visit); | 161 statement.BindInt64(2, visit->referring_visit); |
| 152 statement.BindInt64(3, visit->transition); | 162 statement.BindInt64(3, visit->transition); |
| 153 statement.BindInt64(4, visit->segment_id); | 163 statement.BindInt64(4, visit->segment_id); |
| 154 statement.BindInt64(5, visit->visit_duration.ToInternalValue()); | 164 statement.BindInt64(5, visit->is_indexed); |
| 165 statement.BindInt64(6, visit->visit_duration.ToInternalValue()); |
| 155 | 166 |
| 156 if (!statement.Run()) { | 167 if (!statement.Run()) { |
| 157 VLOG(0) << "Failed to execute visit insert statement: " | 168 VLOG(0) << "Failed to execute visit insert statement: " |
| 158 << "url_id = " << visit->url_id; | 169 << "url_id = " << visit->url_id; |
| 159 return 0; | 170 return 0; |
| 160 } | 171 } |
| 161 | 172 |
| 162 visit->visit_id = GetDB().GetLastInsertRowId(); | 173 visit->visit_id = GetDB().GetLastInsertRowId(); |
| 163 | 174 |
| 164 if (source != SOURCE_BROWSED) { | 175 if (source != SOURCE_BROWSED) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 } | 234 } |
| 224 | 235 |
| 225 bool VisitDatabase::UpdateVisitRow(const VisitRow& visit) { | 236 bool VisitDatabase::UpdateVisitRow(const VisitRow& visit) { |
| 226 // Don't store inconsistent data to the database. | 237 // Don't store inconsistent data to the database. |
| 227 DCHECK_NE(visit.visit_id, visit.referring_visit); | 238 DCHECK_NE(visit.visit_id, visit.referring_visit); |
| 228 if (visit.visit_id == visit.referring_visit) | 239 if (visit.visit_id == visit.referring_visit) |
| 229 return false; | 240 return false; |
| 230 | 241 |
| 231 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 242 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 232 "UPDATE visits SET " | 243 "UPDATE visits SET " |
| 233 "url=?,visit_time=?,from_visit=?,transition=?,segment_id=?," | 244 "url=?,visit_time=?,from_visit=?,transition=?,segment_id=?,is_indexed=?," |
| 234 "visit_duration=? WHERE id=?")); | 245 "visit_duration=? WHERE id=?")); |
| 235 statement.BindInt64(0, visit.url_id); | 246 statement.BindInt64(0, visit.url_id); |
| 236 statement.BindInt64(1, visit.visit_time.ToInternalValue()); | 247 statement.BindInt64(1, visit.visit_time.ToInternalValue()); |
| 237 statement.BindInt64(2, visit.referring_visit); | 248 statement.BindInt64(2, visit.referring_visit); |
| 238 statement.BindInt64(3, visit.transition); | 249 statement.BindInt64(3, visit.transition); |
| 239 statement.BindInt64(4, visit.segment_id); | 250 statement.BindInt64(4, visit.segment_id); |
| 240 statement.BindInt64(5, visit.visit_duration.ToInternalValue()); | 251 statement.BindInt64(5, visit.is_indexed); |
| 241 statement.BindInt64(6, visit.visit_id); | 252 statement.BindInt64(6, visit.visit_duration.ToInternalValue()); |
| 253 statement.BindInt64(7, visit.visit_id); |
| 242 | 254 |
| 243 return statement.Run(); | 255 return statement.Run(); |
| 244 } | 256 } |
| 245 | 257 |
| 246 bool VisitDatabase::GetVisitsForURL(URLID url_id, VisitVector* visits) { | 258 bool VisitDatabase::GetVisitsForURL(URLID url_id, VisitVector* visits) { |
| 247 visits->clear(); | 259 visits->clear(); |
| 248 | 260 |
| 249 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 261 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 250 "SELECT" HISTORY_VISIT_ROW_FIELDS | 262 "SELECT" HISTORY_VISIT_ROW_FIELDS |
| 251 "FROM visits " | 263 "FROM visits " |
| 252 "WHERE url=? " | 264 "WHERE url=? " |
| 253 "ORDER BY visit_time ASC")); | 265 "ORDER BY visit_time ASC")); |
| 254 statement.BindInt64(0, url_id); | 266 statement.BindInt64(0, url_id); |
| 255 return FillVisitVector(statement, visits); | 267 return FillVisitVector(statement, visits); |
| 256 } | 268 } |
| 257 | 269 |
| 270 bool VisitDatabase::GetIndexedVisitsForURL(URLID url_id, VisitVector* visits) { |
| 271 visits->clear(); |
| 272 |
| 273 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 274 "SELECT" HISTORY_VISIT_ROW_FIELDS |
| 275 "FROM visits " |
| 276 "WHERE url=? AND is_indexed=1")); |
| 277 statement.BindInt64(0, url_id); |
| 278 return FillVisitVector(statement, visits); |
| 279 } |
| 280 |
| 258 bool VisitDatabase::GetVisitsForURLWithOptions(URLID url_id, | 281 bool VisitDatabase::GetVisitsForURLWithOptions(URLID url_id, |
| 259 const QueryOptions& options, | 282 const QueryOptions& options, |
| 260 VisitVector* visits) { | 283 VisitVector* visits) { |
| 261 visits->clear(); | 284 visits->clear(); |
| 262 | 285 |
| 263 if (options.REMOVE_ALL_DUPLICATES) { | 286 if (options.REMOVE_ALL_DUPLICATES) { |
| 264 VisitRow visit_row; | 287 VisitRow visit_row; |
| 265 VisitID visit_id = GetMostRecentVisitForURL(url_id, &visit_row); | 288 VisitID visit_id = GetMostRecentVisitForURL(url_id, &visit_row); |
| 266 if (visit_id && options.EffectiveMaxCount() != 0) { | 289 if (visit_id && options.EffectiveMaxCount() != 0) { |
| 267 visits->push_back(visit_row); | 290 visits->push_back(visit_row); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 while (statement.Step()) { | 639 while (statement.Step()) { |
| 617 BriefVisitInfo info; | 640 BriefVisitInfo info; |
| 618 info.url_id = statement.ColumnInt64(0); | 641 info.url_id = statement.ColumnInt64(0); |
| 619 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); | 642 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); |
| 620 info.transition = content::PageTransitionFromInt(statement.ColumnInt(2)); | 643 info.transition = content::PageTransitionFromInt(statement.ColumnInt(2)); |
| 621 result_vector->push_back(info); | 644 result_vector->push_back(info); |
| 622 } | 645 } |
| 623 } | 646 } |
| 624 | 647 |
| 625 } // namespace history | 648 } // namespace history |
| OLD | NEW |