OLD | NEW |
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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 "DELETE FROM url_ids WHERE id NOT IN\n" | 120 "DELETE FROM url_ids WHERE id NOT IN\n" |
121 "(SELECT page_url_x FROM activitylog_compressed\n" | 121 "(SELECT page_url_x FROM activitylog_compressed\n" |
122 " WHERE page_url_x IS NOT NULL\n" | 122 " WHERE page_url_x IS NOT NULL\n" |
123 " UNION SELECT arg_url_x FROM activitylog_compressed\n" | 123 " UNION SELECT arg_url_x FROM activitylog_compressed\n" |
124 " WHERE arg_url_x IS NOT NULL)"; | 124 " WHERE arg_url_x IS NOT NULL)"; |
125 | 125 |
126 } // namespace | 126 } // namespace |
127 | 127 |
128 namespace extensions { | 128 namespace extensions { |
129 | 129 |
130 // A specialized Action subclass which is used to represent an action read from | |
131 // the database with a corresponding count. | |
132 class CountedAction : public Action { | |
133 public: | |
134 CountedAction(const std::string& extension_id, | |
135 const base::Time& time, | |
136 const ActionType action_type, | |
137 const std::string& api_name) | |
138 : Action(extension_id, time, action_type, api_name), | |
139 count_(0) { | |
140 } | |
141 | |
142 // Number of merged records for this action. | |
143 int count() const { return count_; } | |
144 void set_count(int count) { count_ = count; } | |
145 | |
146 virtual std::string PrintForDebug() const OVERRIDE; | |
147 | |
148 protected: | |
149 virtual ~CountedAction() {} | |
150 | |
151 private: | |
152 int count_; | |
153 }; | |
154 | |
155 std::string CountedAction::PrintForDebug() const { | |
156 return base::StringPrintf( | |
157 "%s COUNT=%d", Action::PrintForDebug().c_str(), count()); | |
158 } | |
159 | |
160 const char* CountingPolicy::kTableName = "activitylog_compressed"; | 130 const char* CountingPolicy::kTableName = "activitylog_compressed"; |
161 const char* CountingPolicy::kReadViewName = "activitylog_uncompressed"; | 131 const char* CountingPolicy::kReadViewName = "activitylog_uncompressed"; |
162 | 132 |
163 CountingPolicy::CountingPolicy(Profile* profile) | 133 CountingPolicy::CountingPolicy(Profile* profile) |
164 : ActivityLogDatabasePolicy( | 134 : ActivityLogDatabasePolicy( |
165 profile, | 135 profile, |
166 base::FilePath(chrome::kExtensionActivityLogFilename)), | 136 base::FilePath(chrome::kExtensionActivityLogFilename)), |
167 string_table_("string_ids"), | 137 string_table_("string_ids"), |
168 url_table_("url_ids"), | 138 url_table_("url_ids"), |
169 retention_time_(base::TimeDelta::FromHours(60)) { | 139 retention_time_(base::TimeDelta::FromHours(60)) { |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 query.BindString(++i, api_name); | 424 query.BindString(++i, api_name); |
455 if (type != Action::ACTION_ANY) | 425 if (type != Action::ACTION_ANY) |
456 query.BindInt(++i, static_cast<int>(type)); | 426 query.BindInt(++i, static_cast<int>(type)); |
457 if (!page_url.empty()) | 427 if (!page_url.empty()) |
458 query.BindString(++i, page_url + "%"); | 428 query.BindString(++i, page_url + "%"); |
459 if (!arg_url.empty()) | 429 if (!arg_url.empty()) |
460 query.BindString(++i, arg_url + "%"); | 430 query.BindString(++i, arg_url + "%"); |
461 | 431 |
462 // Execute the query and get results. | 432 // Execute the query and get results. |
463 while (query.is_valid() && query.Step()) { | 433 while (query.is_valid() && query.Step()) { |
464 scoped_refptr<CountedAction> action = | 434 scoped_refptr<Action> action = |
465 new CountedAction(query.ColumnString(0), | 435 new Action(query.ColumnString(0), |
466 base::Time::FromInternalValue(query.ColumnInt64(1)), | 436 base::Time::FromInternalValue(query.ColumnInt64(1)), |
467 static_cast<Action::ActionType>(query.ColumnInt(2)), | 437 static_cast<Action::ActionType>(query.ColumnInt(2)), |
468 query.ColumnString(3)); | 438 query.ColumnString(3)); |
469 | 439 |
470 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { | 440 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { |
471 scoped_ptr<Value> parsed_value( | 441 scoped_ptr<Value> parsed_value( |
472 base::JSONReader::Read(query.ColumnString(4))); | 442 base::JSONReader::Read(query.ColumnString(4))); |
473 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { | 443 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { |
474 action->set_args( | 444 action->set_args( |
475 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); | 445 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 "FROM %s WHERE extension_id=? AND time>? AND time<=? " | 489 "FROM %s WHERE extension_id=? AND time>? AND time<=? " |
520 "ORDER BY time DESC", | 490 "ORDER BY time DESC", |
521 kReadViewName); | 491 kReadViewName); |
522 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE, | 492 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE, |
523 query_str.c_str())); | 493 query_str.c_str())); |
524 query.BindString(0, extension_id); | 494 query.BindString(0, extension_id); |
525 query.BindInt64(1, early_bound); | 495 query.BindInt64(1, early_bound); |
526 query.BindInt64(2, late_bound); | 496 query.BindInt64(2, late_bound); |
527 | 497 |
528 while (query.is_valid() && query.Step()) { | 498 while (query.is_valid() && query.Step()) { |
529 scoped_refptr<CountedAction> action = | 499 scoped_refptr<Action> action = |
530 new CountedAction(extension_id, | 500 new Action(extension_id, |
531 base::Time::FromInternalValue(query.ColumnInt64(0)), | 501 base::Time::FromInternalValue(query.ColumnInt64(0)), |
532 static_cast<Action::ActionType>(query.ColumnInt(1)), | 502 static_cast<Action::ActionType>(query.ColumnInt(1)), |
533 query.ColumnString(2)); | 503 query.ColumnString(2)); |
534 | 504 |
535 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) { | 505 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) { |
536 scoped_ptr<Value> parsed_value( | 506 scoped_ptr<Value> parsed_value( |
537 base::JSONReader::Read(query.ColumnString(3))); | 507 base::JSONReader::Read(query.ColumnString(3))); |
538 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { | 508 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { |
539 action->set_args( | 509 action->set_args( |
540 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); | 510 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); |
541 } else { | 511 } else { |
542 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3) | 512 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3) |
543 << "'"; | 513 << "'"; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 return true; | 690 return true; |
721 } | 691 } |
722 | 692 |
723 void CountingPolicy::Close() { | 693 void CountingPolicy::Close() { |
724 // The policy object should have never been created if there's no DB thread. | 694 // The policy object should have never been created if there's no DB thread. |
725 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); | 695 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); |
726 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); | 696 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); |
727 } | 697 } |
728 | 698 |
729 } // namespace extensions | 699 } // namespace extensions |
OLD | NEW |