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

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: Fixed error from last rebase 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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 return false; 372 return false;
373 373
374 return true; 374 return true;
375 } 375 }
376 376
377 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData( 377 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData(
378 const std::string& extension_id, 378 const std::string& extension_id,
379 const Action::ActionType type, 379 const Action::ActionType type,
380 const std::string& api_name, 380 const std::string& api_name,
381 const std::string& page_url, 381 const std::string& page_url,
382 const std::string& arg_url) { 382 const std::string& arg_url,
383 const int days_ago) {
383 // Ensure data is flushed to the database first so that we query over all 384 // Ensure data is flushed to the database first so that we query over all
384 // data. 385 // data.
385 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); 386 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
386 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); 387 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
387 388
388 sql::Connection* db = GetDatabaseConnection(); 389 sql::Connection* db = GetDatabaseConnection();
389 if (!db) 390 if (!db)
390 return actions.Pass(); 391 return actions.Pass();
391 392
392 // Build up the query based on which parameters were specified. 393 // Build up the query based on which parameters were specified.
393 std::string where_str = ""; 394 std::string where_str = "";
394 std::string where_next = ""; 395 std::string where_next = "";
395 if (!extension_id.empty()) { 396 if (!extension_id.empty()) {
396 where_str += "extension_id=?"; 397 where_str += "extension_id=?";
397 where_next = " AND "; 398 where_next = " AND ";
398 } 399 }
399 if (!api_name.empty()) { 400 if (!api_name.empty()) {
400 where_str += where_next + "api_name=?"; 401 where_str += where_next + "api_name=?";
401 where_next = " AND "; 402 where_next = " AND ";
402 } 403 }
403 if (type != Action::ACTION_ANY) { 404 if (type != Action::ACTION_ANY) {
404 where_str += where_next + "action_type=?"; 405 where_str += where_next + "action_type=?";
405 where_next = " AND "; 406 where_next = " AND ";
406 } 407 }
407 if (!page_url.empty()) { 408 if (!page_url.empty()) {
408 where_str += where_next + "page_url LIKE ?"; 409 where_str += where_next + "page_url LIKE ?";
409 where_next = " AND "; 410 where_next = " AND ";
410 } 411 }
411 if (!arg_url.empty()) 412 if (!arg_url.empty()) {
412 where_str += where_next + "arg_url LIKE ?"; 413 where_str += where_next + "arg_url LIKE ?";
414 where_next = " AND ";
415 }
416 if (days_ago >= 0)
417 where_str += where_next + "time BETWEEN ? AND ?";
418
413 std::string query_str = base::StringPrintf( 419 std::string query_str = base::StringPrintf(
414 "SELECT extension_id,time, action_type, api_name, args, page_url," 420 "SELECT extension_id,time, action_type, api_name, args, page_url,"
415 "page_title, arg_url, other, count FROM %s %s %s ORDER BY time DESC " 421 "page_title, arg_url, other, count FROM %s %s %s ORDER BY count DESC,"
416 "LIMIT 300", 422 " time DESC LIMIT 300",
417 kReadViewName, 423 kReadViewName,
418 where_str.empty() ? "" : "WHERE", 424 where_str.empty() ? "" : "WHERE",
419 where_str.c_str()); 425 where_str.c_str());
420 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); 426 sql::Statement query(db->GetUniqueStatement(query_str.c_str()));
421 int i = -1; 427 int i = -1;
422 if (!extension_id.empty()) 428 if (!extension_id.empty())
423 query.BindString(++i, extension_id); 429 query.BindString(++i, extension_id);
424 if (!api_name.empty()) 430 if (!api_name.empty())
425 query.BindString(++i, api_name); 431 query.BindString(++i, api_name);
426 if (type != Action::ACTION_ANY) 432 if (type != Action::ACTION_ANY)
427 query.BindInt(++i, static_cast<int>(type)); 433 query.BindInt(++i, static_cast<int>(type));
428 if (!page_url.empty()) 434 if (!page_url.empty())
429 query.BindString(++i, page_url + "%"); 435 query.BindString(++i, page_url + "%");
430 if (!arg_url.empty()) 436 if (!arg_url.empty())
431 query.BindString(++i, arg_url + "%"); 437 query.BindString(++i, arg_url + "%");
438 if (days_ago >= 0) {
439 int64 early_bound;
440 int64 late_bound;
441 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
442 query.BindInt64(++i, early_bound);
443 query.BindInt64(++i, late_bound);
444 }
432 445
433 // Execute the query and get results. 446 // Execute the query and get results.
434 while (query.is_valid() && query.Step()) { 447 while (query.is_valid() && query.Step()) {
435 scoped_refptr<Action> action = 448 scoped_refptr<Action> action =
436 new Action(query.ColumnString(0), 449 new Action(query.ColumnString(0),
437 base::Time::FromInternalValue(query.ColumnInt64(1)), 450 base::Time::FromInternalValue(query.ColumnInt64(1)),
438 static_cast<Action::ActionType>(query.ColumnInt(2)), 451 static_cast<Action::ActionType>(query.ColumnInt(2)),
439 query.ColumnString(3)); 452 query.ColumnString(3));
440 453
441 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { 454 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) {
(...skipping 17 matching lines...) Expand all
459 static_cast<DictionaryValue*>(parsed_value.release()))); 472 static_cast<DictionaryValue*>(parsed_value.release())));
460 } 473 }
461 } 474 }
462 action->set_count(query.ColumnInt(9)); 475 action->set_count(query.ColumnInt(9));
463 actions->push_back(action); 476 actions->push_back(action);
464 } 477 }
465 478
466 return actions.Pass(); 479 return actions.Pass();
467 } 480 }
468 481
469 scoped_ptr<Action::ActionVector> CountingPolicy::DoReadData(
470 const std::string& extension_id,
471 const int days_ago) {
472 // Ensure data is flushed to the database first so that we query over all
473 // data.
474 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
475
476 DCHECK_GE(days_ago, 0);
477 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
478
479 sql::Connection* db = GetDatabaseConnection();
480 if (!db) {
481 return actions.Pass();
482 }
483
484 int64 early_bound;
485 int64 late_bound;
486 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
487 std::string query_str = base::StringPrintf(
488 "SELECT time, action_type, api_name, args, page_url, page_title, "
489 "arg_url, other, count "
490 "FROM %s WHERE extension_id=? AND time>? AND time<=? "
491 "ORDER BY time DESC",
492 kReadViewName);
493 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE,
494 query_str.c_str()));
495 query.BindString(0, extension_id);
496 query.BindInt64(1, early_bound);
497 query.BindInt64(2, late_bound);
498
499 while (query.is_valid() && query.Step()) {
500 scoped_refptr<Action> action =
501 new Action(extension_id,
502 base::Time::FromInternalValue(query.ColumnInt64(0)),
503 static_cast<Action::ActionType>(query.ColumnInt(1)),
504 query.ColumnString(2));
505
506 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) {
507 scoped_ptr<Value> parsed_value(
508 base::JSONReader::Read(query.ColumnString(3)));
509 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) {
510 action->set_args(
511 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release())));
512 } else {
513 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3)
514 << "'";
515 }
516 }
517
518 action->ParsePageUrl(query.ColumnString(4));
519 action->set_page_title(query.ColumnString(5));
520 action->ParseArgUrl(query.ColumnString(6));
521
522 if (query.ColumnType(7) != sql::COLUMN_TYPE_NULL) {
523 scoped_ptr<Value> parsed_value(
524 base::JSONReader::Read(query.ColumnString(7)));
525 if (parsed_value && parsed_value->IsType(Value::TYPE_DICTIONARY)) {
526 action->set_other(make_scoped_ptr(
527 static_cast<DictionaryValue*>(parsed_value.release())));
528 } else {
529 LOG(WARNING) << "Unable to parse other: '" << query.ColumnString(7)
530 << "'";
531 }
532 }
533
534 action->set_count(query.ColumnInt(8));
535
536 actions->push_back(action);
537 }
538
539 return actions.Pass();
540 }
541
542 void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { 482 void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) {
543 sql::Connection* db = GetDatabaseConnection(); 483 sql::Connection* db = GetDatabaseConnection();
544 if (!db) { 484 if (!db) {
545 LOG(ERROR) << "Unable to connect to database"; 485 LOG(ERROR) << "Unable to connect to database";
546 return; 486 return;
547 } 487 }
548 488
549 // Flush data first so the URL clearing affects queued-up data as well. 489 // Flush data first so the URL clearing affects queued-up data as well.
550 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); 490 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
551 491
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 } 589 }
650 statement.Clear(); 590 statement.Clear();
651 statement.Assign(db->GetCachedStatement(sql::StatementID(SQL_FROM_HERE), 591 statement.Assign(db->GetCachedStatement(sql::StatementID(SQL_FROM_HERE),
652 "VACUUM")); 592 "VACUUM"));
653 if (!statement.Run()) { 593 if (!statement.Run()) {
654 LOG(ERROR) << "Vacuuming the database failed: " 594 LOG(ERROR) << "Vacuuming the database failed: "
655 << statement.GetSQLStatement(); 595 << statement.GetSQLStatement();
656 } 596 }
657 } 597 }
658 598
659 void CountingPolicy::ReadData(
660 const std::string& extension_id,
661 const int day,
662 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& callback) {
663 BrowserThread::PostTaskAndReplyWithResult(
664 BrowserThread::DB,
665 FROM_HERE,
666 base::Bind(&CountingPolicy::DoReadData,
667 base::Unretained(this),
668 extension_id,
669 day),
670 callback);
671 }
672
673 void CountingPolicy::ReadFilteredData( 599 void CountingPolicy::ReadFilteredData(
674 const std::string& extension_id, 600 const std::string& extension_id,
675 const Action::ActionType type, 601 const Action::ActionType type,
676 const std::string& api_name, 602 const std::string& api_name,
677 const std::string& page_url, 603 const std::string& page_url,
678 const std::string& arg_url, 604 const std::string& arg_url,
605 const int days_ago,
679 const base::Callback 606 const base::Callback
680 <void(scoped_ptr<Action::ActionVector>)>& callback) { 607 <void(scoped_ptr<Action::ActionVector>)>& callback) {
681 BrowserThread::PostTaskAndReplyWithResult( 608 BrowserThread::PostTaskAndReplyWithResult(
682 BrowserThread::DB, 609 BrowserThread::DB,
683 FROM_HERE, 610 FROM_HERE,
684 base::Bind(&CountingPolicy::DoReadFilteredData, 611 base::Bind(&CountingPolicy::DoReadFilteredData,
685 base::Unretained(this), 612 base::Unretained(this),
686 extension_id, 613 extension_id,
687 type, 614 type,
688 api_name, 615 api_name,
689 page_url, 616 page_url,
690 arg_url), 617 arg_url,
618 days_ago),
691 callback); 619 callback);
692 } 620 }
693 621
694 void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { 622 void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) {
695 ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls); 623 ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls);
696 } 624 }
697 625
698 void CountingPolicy::DeleteDatabase() { 626 void CountingPolicy::DeleteDatabase() {
699 ScheduleAndForget(this, &CountingPolicy::DoDeleteDatabase); 627 ScheduleAndForget(this, &CountingPolicy::DoDeleteDatabase);
700 } 628 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 return true; 668 return true;
741 } 669 }
742 670
743 void CountingPolicy::Close() { 671 void CountingPolicy::Close() {
744 // The policy object should have never been created if there's no DB thread. 672 // The policy object should have never been created if there's no DB thread.
745 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); 673 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB));
746 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); 674 ScheduleAndForget(activity_database(), &ActivityDatabase::Close);
747 } 675 }
748 676
749 } // namespace extensions 677 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698