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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 statement.BindInt(3, transition); | 294 statement.BindInt(3, transition); |
295 statement.BindInt64(4, | 295 statement.BindInt64(4, |
296 max_results ? max_results : std::numeric_limits<int64>::max()); | 296 max_results ? max_results : std::numeric_limits<int64>::max()); |
297 | 297 |
298 return FillVisitVector(statement, visits); | 298 return FillVisitVector(statement, visits); |
299 } | 299 } |
300 | 300 |
301 void VisitDatabase::GetVisibleVisitsInRange(base::Time begin_time, | 301 void VisitDatabase::GetVisibleVisitsInRange(base::Time begin_time, |
302 base::Time end_time, | 302 base::Time end_time, |
303 int max_count, | 303 int max_count, |
304 VisitVector* visits) { | 304 VisitVector* visits, |
| 305 bool unique) { |
305 visits->clear(); | 306 visits->clear(); |
306 // The visit_time values can be duplicated in a redirect chain, so we sort | 307 // The visit_time values can be duplicated in a redirect chain, so we sort |
307 // by id too, to ensure a consistent ordering just in case. | 308 // by id too, to ensure a consistent ordering just in case. |
308 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 309 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
309 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " | 310 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " |
310 "WHERE visit_time >= ? AND visit_time < ? " | 311 "WHERE visit_time >= ? AND visit_time < ? " |
311 "AND (transition & ?) != 0 " // CHAIN_END | 312 "AND (transition & ?) != 0 " // CHAIN_END |
312 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or | 313 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or |
313 // KEYWORD_GENERATED | 314 // KEYWORD_GENERATED |
314 "ORDER BY visit_time DESC, id DESC")); | 315 "ORDER BY visit_time DESC, id DESC")); |
315 | 316 |
316 // Note that we use min/max values for querying unlimited ranges of time using | 317 // Note that we use min/max values for querying unlimited ranges of time using |
317 // the same statement. Since the time has an index, this will be about the | 318 // the same statement. Since the time has an index, this will be about the |
318 // same amount of work as just doing a query for everything with no qualifier. | 319 // same amount of work as just doing a query for everything with no qualifier. |
319 int64 end = end_time.ToInternalValue(); | 320 int64 end = end_time.ToInternalValue(); |
320 statement.BindInt64(0, begin_time.ToInternalValue()); | 321 statement.BindInt64(0, begin_time.ToInternalValue()); |
321 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); | 322 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); |
322 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); | 323 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); |
323 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); | 324 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); |
324 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); | 325 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); |
325 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); | 326 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); |
326 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); | 327 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); |
327 | 328 |
328 std::set<URLID> found_urls; | 329 std::set<URLID> found_urls; |
329 while (statement.Step()) { | 330 while (statement.Step()) { |
330 VisitRow visit; | 331 VisitRow visit; |
331 FillVisitRow(statement, &visit); | 332 FillVisitRow(statement, &visit); |
332 // Make sure the URL this visit corresponds to is unique. | 333 if (unique) { |
333 if (found_urls.find(visit.url_id) != found_urls.end()) | 334 // Make sure the URL this visit corresponds to is unique. |
334 continue; | 335 if (found_urls.find(visit.url_id) != found_urls.end()) |
335 found_urls.insert(visit.url_id); | 336 continue; |
| 337 found_urls.insert(visit.url_id); |
| 338 } |
336 visits->push_back(visit); | 339 visits->push_back(visit); |
337 | 340 |
338 if (max_count > 0 && static_cast<int>(visits->size()) >= max_count) | 341 if (max_count > 0 && static_cast<int>(visits->size()) >= max_count) |
339 break; | 342 break; |
340 } | 343 } |
341 } | 344 } |
342 | 345 |
343 void VisitDatabase::GetVisibleVisitsDuringTimes(const VisitFilter& time_filter, | 346 void VisitDatabase::GetVisibleVisitsDuringTimes(const VisitFilter& time_filter, |
344 int max_results, | 347 int max_results, |
345 VisitVector* visits) { | 348 VisitVector* visits) { |
346 visits->clear(); | 349 visits->clear(); |
347 if (max_results) | 350 if (max_results) |
348 visits->reserve(max_results); | 351 visits->reserve(max_results); |
349 for (VisitFilter::TimeVector::const_iterator it = time_filter.times().begin(); | 352 for (VisitFilter::TimeVector::const_iterator it = time_filter.times().begin(); |
350 it != time_filter.times().end(); ++it) { | 353 it != time_filter.times().end(); ++it) { |
351 VisitVector v; | 354 VisitVector v; |
352 GetVisibleVisitsInRange(it->first, it->second, max_results, &v); | 355 GetVisibleVisitsInRange(it->first, it->second, max_results, &v, false); |
353 size_t take_only = 0; | 356 size_t take_only = 0; |
354 if (max_results && | 357 if (max_results && |
355 static_cast<int>(visits->size() + v.size()) > max_results) { | 358 static_cast<int>(visits->size() + v.size()) > max_results) { |
356 take_only = max_results - visits->size(); | 359 take_only = max_results - visits->size(); |
357 } | 360 } |
358 | 361 |
359 visits->insert(visits->end(), | 362 visits->insert(visits->end(), |
360 v.begin(), take_only ? v.begin() + take_only : v.end()); | 363 v.begin(), take_only ? v.begin() + take_only : v.end()); |
361 if (max_results && static_cast<int>(visits->size()) == max_results) | 364 if (max_results && static_cast<int>(visits->size()) == max_results) |
362 return; | 365 return; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 while (statement.Step()) { | 578 while (statement.Step()) { |
576 BriefVisitInfo info; | 579 BriefVisitInfo info; |
577 info.url_id = statement.ColumnInt64(0); | 580 info.url_id = statement.ColumnInt64(0); |
578 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); | 581 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); |
579 info.transition = content::PageTransitionFromInt(statement.ColumnInt(2)); | 582 info.transition = content::PageTransitionFromInt(statement.ColumnInt(2)); |
580 result_vector->push_back(info); | 583 result_vector->push_back(info); |
581 } | 584 } |
582 } | 585 } |
583 | 586 |
584 } // namespace history | 587 } // namespace history |
OLD | NEW |