Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: chrome/browser/extensions/activity_log/counting_policy.cc

Issue 23980002: Activity Log: allow searching by day (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 // A policy for storing activity log data to a database that performs 5 // A policy for storing activity log data to a database that performs
6 // aggregation to reduce the size of the database. The database layout is 6 // aggregation to reduce the size of the database. The database layout is
7 // nearly the same as FullStreamUIPolicy, which stores a complete log, with a 7 // nearly the same as FullStreamUIPolicy, which stores a complete log, with a
8 // few changes: 8 // few changes:
9 // - a "count" column is added to track how many log records were merged 9 // - a "count" column is added to track how many log records were merged
10 // together into this row 10 // together into this row
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return false; 402 return false;
403 403
404 return true; 404 return true;
405 } 405 }
406 406
407 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData( 407 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData(
408 const std::string& extension_id, 408 const std::string& extension_id,
409 const Action::ActionType type, 409 const Action::ActionType type,
410 const std::string& api_name, 410 const std::string& api_name,
411 const std::string& page_url, 411 const std::string& page_url,
412 const std::string& arg_url) { 412 const std::string& arg_url,
413 const int days_ago) {
413 // Ensure data is flushed to the database first so that we query over all 414 // Ensure data is flushed to the database first so that we query over all
414 // data. 415 // data.
415 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); 416 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
416 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); 417 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
417 418
418 sql::Connection* db = GetDatabaseConnection(); 419 sql::Connection* db = GetDatabaseConnection();
419 if (!db) 420 if (!db)
420 return actions.Pass(); 421 return actions.Pass();
421 422
422 // Build up the query based on which parameters were specified. 423 // Build up the query based on which parameters were specified.
423 std::string where_str = ""; 424 std::string where_str = "";
424 std::string where_next = ""; 425 std::string where_next = "";
425 if (!extension_id.empty()) { 426 if (!extension_id.empty()) {
426 where_str += "extension_id=?"; 427 where_str += "extension_id=?";
427 where_next = " AND "; 428 where_next = " AND ";
428 } 429 }
429 if (!api_name.empty()) { 430 if (!api_name.empty()) {
430 where_str += where_next + "api_name=?"; 431 where_str += where_next + "api_name=?";
431 where_next = " AND "; 432 where_next = " AND ";
432 } 433 }
433 if (type != Action::ACTION_ANY) { 434 if (type != Action::ACTION_ANY) {
434 where_str += where_next + "action_type=?"; 435 where_str += where_next + "action_type=?";
435 where_next = " AND "; 436 where_next = " AND ";
436 } 437 }
437 if (!page_url.empty()) { 438 if (!page_url.empty()) {
438 where_str += where_next + "page_url LIKE ?"; 439 where_str += where_next + "page_url LIKE ?";
439 where_next = " AND "; 440 where_next = " AND ";
440 } 441 }
441 if (!arg_url.empty()) 442 if (!arg_url.empty()) {
442 where_str += where_next + "arg_url LIKE ?"; 443 where_str += where_next + "arg_url LIKE ?";
444 where_next = " AND ";
445 }
446 if (days_ago >= 0)
447 where_str += where_next + "time BETWEEN ? AND ?";
448
443 std::string query_str = base::StringPrintf( 449 std::string query_str = base::StringPrintf(
444 "SELECT extension_id,time, action_type, api_name, args, page_url," 450 "SELECT extension_id,time, action_type, api_name, args, page_url,"
445 "page_title, arg_url, other, count FROM %s WHERE %s ORDER BY time DESC", 451 "page_title, arg_url, other, count FROM %s WHERE %s ORDER BY time DESC",
446 kReadViewName, 452 kReadViewName,
447 where_str.c_str()); 453 where_str.c_str());
448 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); 454 sql::Statement query(db->GetUniqueStatement(query_str.c_str()));
449 int i = -1; 455 int i = -1;
450 if (!extension_id.empty()) 456 if (!extension_id.empty())
451 query.BindString(++i, extension_id); 457 query.BindString(++i, extension_id);
452 if (!api_name.empty()) 458 if (!api_name.empty())
453 query.BindString(++i, api_name); 459 query.BindString(++i, api_name);
454 if (type != Action::ACTION_ANY) 460 if (type != Action::ACTION_ANY)
455 query.BindInt(++i, static_cast<int>(type)); 461 query.BindInt(++i, static_cast<int>(type));
456 if (!page_url.empty()) 462 if (!page_url.empty())
457 query.BindString(++i, page_url + "%"); 463 query.BindString(++i, page_url + "%");
458 if (!arg_url.empty()) 464 if (!arg_url.empty())
459 query.BindString(++i, arg_url + "%"); 465 query.BindString(++i, arg_url + "%");
466 if (days_ago >= 0) {
467 int64 early_bound;
468 int64 late_bound;
469 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
470 query.BindInt64(++i, early_bound);
471 query.BindInt64(++i, late_bound);
472 }
460 473
461 // Execute the query and get results. 474 // Execute the query and get results.
462 while (query.is_valid() && query.Step()) { 475 while (query.is_valid() && query.Step()) {
463 scoped_refptr<CountedAction> action = 476 scoped_refptr<CountedAction> action =
464 new CountedAction(query.ColumnString(0), 477 new CountedAction(query.ColumnString(0),
465 base::Time::FromInternalValue(query.ColumnInt64(1)), 478 base::Time::FromInternalValue(query.ColumnInt64(1)),
466 static_cast<Action::ActionType>(query.ColumnInt(2)), 479 static_cast<Action::ActionType>(query.ColumnInt(2)),
467 query.ColumnString(3)); 480 query.ColumnString(3));
468 481
469 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { 482 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) {
(...skipping 17 matching lines...) Expand all
487 static_cast<DictionaryValue*>(parsed_value.release()))); 500 static_cast<DictionaryValue*>(parsed_value.release())));
488 } 501 }
489 } 502 }
490 action->set_count(query.ColumnInt(9)); 503 action->set_count(query.ColumnInt(9));
491 actions->push_back(action); 504 actions->push_back(action);
492 } 505 }
493 506
494 return actions.Pass(); 507 return actions.Pass();
495 } 508 }
496 509
497 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadData(
498 const std::string& extension_id,
499 const int days_ago) {
500 // Ensure data is flushed to the database first so that we query over all
501 // data.
502 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
503
504 DCHECK_GE(days_ago, 0);
505 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
506
507 sql::Connection* db = GetDatabaseConnection();
508 if (!db) {
509 return actions.Pass();
510 }
511
512 int64 early_bound;
513 int64 late_bound;
514 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
515 std::string query_str = base::StringPrintf(
516 "SELECT time, action_type, api_name, args, page_url, page_title, "
517 "arg_url, other, count "
518 "FROM %s WHERE extension_id=? AND time>? AND time<=? "
519 "ORDER BY time DESC",
520 kReadViewName);
521 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE,
522 query_str.c_str()));
523 query.BindString(0, extension_id);
524 query.BindInt64(1, early_bound);
525 query.BindInt64(2, late_bound);
526
527 while (query.is_valid() && query.Step()) {
528 scoped_refptr<CountedAction> action =
529 new CountedAction(extension_id,
530 base::Time::FromInternalValue(query.ColumnInt64(0)),
531 static_cast<Action::ActionType>(query.ColumnInt(1)),
532 query.ColumnString(2));
533
534 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) {
535 scoped_ptr<Value> parsed_value(
536 base::JSONReader::Read(query.ColumnString(3)));
537 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) {
538 action->set_args(
539 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release())));
540 } else {
541 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3)
542 << "'";
543 }
544 }
545
546 action->ParsePageUrl(query.ColumnString(4));
547 action->set_page_title(query.ColumnString(5));
548 action->ParseArgUrl(query.ColumnString(6));
549
550 if (query.ColumnType(7) != sql::COLUMN_TYPE_NULL) {
551 scoped_ptr<Value> parsed_value(
552 base::JSONReader::Read(query.ColumnString(7)));
553 if (parsed_value && parsed_value->IsType(Value::TYPE_DICTIONARY)) {
554 action->set_other(make_scoped_ptr(
555 static_cast<DictionaryValue*>(parsed_value.release())));
556 } else {
557 LOG(WARNING) << "Unable to parse other: '" << query.ColumnString(7)
558 << "'";
559 }
560 }
561
562 action->set_count(query.ColumnInt(8));
563
564 actions->push_back(action);
565 }
566
567 return actions.Pass();
568 }
569
570 void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { 510 void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) {
571 sql::Connection* db = GetDatabaseConnection(); 511 sql::Connection* db = GetDatabaseConnection();
572 if (!db) { 512 if (!db) {
573 LOG(ERROR) << "Unable to connect to database"; 513 LOG(ERROR) << "Unable to connect to database";
574 return; 514 return;
575 } 515 }
576 516
577 // Flush data first so the URL clearing affects queued-up data as well. 517 // Flush data first so the URL clearing affects queued-up data as well.
578 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); 518 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
579 519
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 return; 572 return;
633 } 573 }
634 } 574 }
635 575
636 // Clean up unused strings from the strings and urls table to really delete 576 // Clean up unused strings from the strings and urls table to really delete
637 // the urls and page titles. Should be called even if an error occured when 577 // the urls and page titles. Should be called even if an error occured when
638 // removing a URL as there may some things to clean up. 578 // removing a URL as there may some things to clean up.
639 CleanStringTables(db); 579 CleanStringTables(db);
640 } 580 }
641 581
642 void CountingPolicy::ReadData(
643 const std::string& extension_id,
644 const int day,
645 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& callback) {
646 BrowserThread::PostTaskAndReplyWithResult(
647 BrowserThread::DB,
648 FROM_HERE,
649 base::Bind(&CountingPolicy::DoReadData,
650 base::Unretained(this),
651 extension_id,
652 day),
653 callback);
654 }
655
656 void CountingPolicy::ReadFilteredData( 582 void CountingPolicy::ReadFilteredData(
657 const std::string& extension_id, 583 const std::string& extension_id,
658 const Action::ActionType type, 584 const Action::ActionType type,
659 const std::string& api_name, 585 const std::string& api_name,
660 const std::string& page_url, 586 const std::string& page_url,
661 const std::string& arg_url, 587 const std::string& arg_url,
588 const int days_ago,
662 const base::Callback 589 const base::Callback
663 <void(scoped_ptr<Action::ActionVector>)>& callback) { 590 <void(scoped_ptr<Action::ActionVector>)>& callback) {
664 BrowserThread::PostTaskAndReplyWithResult( 591 BrowserThread::PostTaskAndReplyWithResult(
665 BrowserThread::DB, 592 BrowserThread::DB,
666 FROM_HERE, 593 FROM_HERE,
667 base::Bind(&CountingPolicy::DoReadFilteredData, 594 base::Bind(&CountingPolicy::DoReadFilteredData,
668 base::Unretained(this), 595 base::Unretained(this),
669 extension_id, 596 extension_id,
670 type, 597 type,
671 api_name, 598 api_name,
672 page_url, 599 page_url,
673 arg_url), 600 arg_url,
601 days_ago),
674 callback); 602 callback);
675 } 603 }
676 604
677 void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { 605 void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) {
678 ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls); 606 ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls);
679 } 607 }
680 608
681 void CountingPolicy::OnDatabaseFailure() { 609 void CountingPolicy::OnDatabaseFailure() {
682 queued_actions_.clear(); 610 queued_actions_.clear();
683 } 611 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 return true; 647 return true;
720 } 648 }
721 649
722 void CountingPolicy::Close() { 650 void CountingPolicy::Close() {
723 // The policy object should have never been created if there's no DB thread. 651 // The policy object should have never been created if there's no DB thread.
724 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); 652 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB));
725 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); 653 ScheduleAndForget(activity_database(), &ActivityDatabase::Close);
726 } 654 }
727 655
728 } // namespace extensions 656 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698