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

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

Issue 21646004: Compressed activity log database storage (Closed) Base URL: http://git.chromium.org/chromium/src.git@refactor-cleanups
Patch Set: Factor out dropping of obsolete tables and use in all policies Created 7 years, 4 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
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 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" 5 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 15 matching lines...) Expand all
26 using base::Callback; 26 using base::Callback;
27 using base::FilePath; 27 using base::FilePath;
28 using base::Time; 28 using base::Time;
29 using base::Unretained; 29 using base::Unretained;
30 using content::BrowserThread; 30 using content::BrowserThread;
31 31
32 namespace constants = activity_log_constants; 32 namespace constants = activity_log_constants;
33 33
34 namespace { 34 namespace {
35 35
36 // Key strings for passing parameters to the ProcessAction member function.
37 const char kKeyReason[] = "fsuip.reason";
38 const char kKeyDomainAction[] = "fsuip.domact";
39 const char kKeyURLTitle[] = "fsuip.urltitle";
40 const char kKeyDetailsString[] = "fsuip.details";
41
42 // Obsolete database tables: these should be dropped from the database if
43 // found.
44 const char* kObsoleteTables[] = {"activitylog_apis", "activitylog_blocked",
45 "activitylog_urls"};
46
47 std::string Serialize(const base::Value* value) { 36 std::string Serialize(const base::Value* value) {
48 std::string value_as_text; 37 std::string value_as_text;
49 if (!value) { 38 if (!value) {
50 value_as_text = "null"; 39 value_as_text = "null";
51 } else { 40 } else {
52 JSONStringValueSerializer serializer(&value_as_text); 41 JSONStringValueSerializer serializer(&value_as_text);
53 serializer.SerializeAndOmitBinaryValues(*value); 42 serializer.SerializeAndOmitBinaryValues(*value);
54 } 43 }
55 return value_as_text; 44 return value_as_text;
56 } 45 }
57 46
58 } // namespace 47 } // namespace
59 48
60 namespace extensions { 49 namespace extensions {
61 50
62 const char* FullStreamUIPolicy::kTableName = "activitylog_full"; 51 const char* FullStreamUIPolicy::kTableName = "activitylog_full";
63 const char* FullStreamUIPolicy::kTableContentFields[] = { 52 const char* FullStreamUIPolicy::kTableContentFields[] = {
64 "extension_id", "time", "action_type", "api_name", "args", "page_url", 53 "extension_id", "time", "action_type", "api_name", "args", "page_url",
65 "page_title", "arg_url", "other" 54 "page_title", "arg_url", "other"
66 }; 55 };
67 const char* FullStreamUIPolicy::kTableFieldTypes[] = { 56 const char* FullStreamUIPolicy::kTableFieldTypes[] = {
68 "LONGVARCHAR NOT NULL", "INTEGER", "INTEGER", "LONGVARCHAR", "LONGVARCHAR", 57 "LONGVARCHAR NOT NULL", "INTEGER", "INTEGER", "LONGVARCHAR", "LONGVARCHAR",
69 "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR" 58 "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
70 }; 59 };
71 const int FullStreamUIPolicy::kTableFieldCount = arraysize(kTableContentFields); 60 const int FullStreamUIPolicy::kTableFieldCount =
61 arraysize(FullStreamUIPolicy::kTableContentFields);
72 62
73 FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile) 63 FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile)
74 : ActivityLogDatabasePolicy( 64 : ActivityLogDatabasePolicy(
75 profile, 65 profile,
76 FilePath(chrome::kExtensionActivityLogFilename)) {} 66 FilePath(chrome::kExtensionActivityLogFilename)) {}
77 67
78 FullStreamUIPolicy::~FullStreamUIPolicy() {} 68 FullStreamUIPolicy::~FullStreamUIPolicy() {}
79 69
80 bool FullStreamUIPolicy::InitDatabase(sql::Connection* db) { 70 bool FullStreamUIPolicy::InitDatabase(sql::Connection* db) {
81 // Drop old database tables. 71 if (!Util::DropObsoleteTables(db))
82 for (size_t i = 0; i < arraysize(kObsoleteTables); i++) { 72 return false;
83 const char* table_name = kObsoleteTables[i];
84 if (db->DoesTableExist(table_name)) {
85 std::string drop_statement =
86 base::StringPrintf("DROP TABLE %s", table_name);
87 if (!db->Execute(drop_statement.c_str())) {
88 return false;
89 }
90 }
91 }
92 73
93 // Create the unified activity log entry table. 74 // Create the unified activity log entry table.
94 return ActivityDatabase::InitializeTable(db, 75 return ActivityDatabase::InitializeTable(db,
95 kTableName, 76 kTableName,
96 kTableContentFields, 77 kTableContentFields,
97 kTableFieldTypes, 78 kTableFieldTypes,
98 arraysize(kTableContentFields)); 79 arraysize(kTableContentFields));
99 } 80 }
100 81
101 bool FullStreamUIPolicy::FlushDatabase(sql::Connection* db) { 82 bool FullStreamUIPolicy::FlushDatabase(sql::Connection* db) {
102 if (queued_actions_.empty()) 83 if (queued_actions_.empty())
103 return true; 84 return true;
104 85
105 sql::Transaction transaction(db); 86 sql::Transaction transaction(db);
106 if (!transaction.Begin()) 87 if (!transaction.Begin())
107 return false; 88 return false;
108 89
109 std::string sql_str = 90 std::string sql_str =
110 "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) + 91 "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
111 " (extension_id, time, action_type, api_name, args, " 92 " (extension_id, time, action_type, api_name, args, "
112 "page_url, page_title, arg_url, other) VALUES (?,?,?,?,?,?,?,?,?)"; 93 "page_url, page_title, arg_url, other) VALUES (?,?,?,?,?,?,?,?,?)";
113 sql::Statement statement(db->GetCachedStatement( 94 sql::Statement statement(db->GetCachedStatement(
114 sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); 95 sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
115 96
116 url_canon::Replacements<char> url_sanitizer;
117 if (!CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kEnableExtensionActivityLogTesting)) {
119 url_sanitizer.ClearQuery();
120 url_sanitizer.ClearRef();
121 }
122
123 Action::ActionVector::size_type i; 97 Action::ActionVector::size_type i;
124 for (i = 0; i != queued_actions_.size(); ++i) { 98 for (i = 0; i != queued_actions_.size(); ++i) {
125 const Action& action = *queued_actions_[i]; 99 const Action& action = *queued_actions_[i];
126 statement.Reset(true); 100 statement.Reset(true);
127 statement.BindString(0, action.extension_id()); 101 statement.BindString(0, action.extension_id());
128 statement.BindInt64(1, action.time().ToInternalValue()); 102 statement.BindInt64(1, action.time().ToInternalValue());
129 statement.BindInt(2, static_cast<int>(action.action_type())); 103 statement.BindInt(2, static_cast<int>(action.action_type()));
130 statement.BindString(3, action.api_name()); 104 statement.BindString(3, action.api_name());
131 if (action.args()) { 105 if (action.args()) {
132 statement.BindString(4, Serialize(action.args())); 106 statement.BindString(4, Serialize(action.args()));
133 } 107 }
134 if (action.page_url().is_valid()) { 108 if (action.page_url().is_valid()) {
135 if (action.page_incognito()) { 109 if (action.page_incognito()) {
136 statement.BindString(5, constants::kIncognitoUrl); 110 statement.BindString(5, constants::kIncognitoUrl);
137 } else { 111 } else {
138 statement.BindString( 112 statement.BindString(5, action.page_url().spec());
139 5, action.page_url().ReplaceComponents(url_sanitizer).spec());
140 } 113 }
141 } 114 }
142 if (!action.page_title().empty() && !action.page_incognito()) { 115 if (!action.page_title().empty() && !action.page_incognito()) {
143 statement.BindString(6, action.page_title()); 116 statement.BindString(6, action.page_title());
144 } 117 }
145 if (action.arg_url().is_valid()) { 118 if (action.arg_url().is_valid()) {
146 if (action.arg_incognito()) { 119 if (action.arg_incognito()) {
147 statement.BindString(7, constants::kIncognitoUrl); 120 statement.BindString(7, constants::kIncognitoUrl);
felt 2013/08/07 01:09:42 Probably should have caught this before. Why are w
mvrable 2013/08/07 17:01:19 Looks like I forgot to update this code. The inte
felt 2013/08/08 02:08:50 Hmm. It seems like doing "<incognito>url" is overl
148 } else { 121 } else {
149 statement.BindString( 122 statement.BindString(7, action.arg_url().spec());
150 7, action.arg_url().ReplaceComponents(url_sanitizer).spec());
151 } 123 }
152 } 124 }
153 if (action.other()) { 125 if (action.other()) {
154 statement.BindString(8, Serialize(action.other())); 126 statement.BindString(8, Serialize(action.other()));
155 } 127 }
156 128
157 if (!statement.Run()) { 129 if (!statement.Run()) {
158 LOG(ERROR) << "Activity log database I/O failed: " << sql_str; 130 LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
159 return false; 131 return false;
160 } 132 }
161 } 133 }
162 134
163 if (!transaction.Commit()) 135 if (!transaction.Commit())
164 return false; 136 return false;
165 137
166 queued_actions_.clear(); 138 queued_actions_.clear();
167 return true; 139 return true;
168 } 140 }
169 141
170 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadData( 142 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadData(
171 const std::string& extension_id, 143 const std::string& extension_id,
172 const int days_ago) { 144 const int days_ago) {
145 // Ensure data is flushed to the database first so that we query over all
146 // data.
147 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
148
173 DCHECK_GE(days_ago, 0); 149 DCHECK_GE(days_ago, 0);
174 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); 150 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
175 151
176 sql::Connection* db = GetDatabaseConnection(); 152 sql::Connection* db = GetDatabaseConnection();
177 if (!db) { 153 if (!db) {
178 return actions.Pass(); 154 return actions.Pass();
179 } 155 }
180 156
181 // Compute the time bounds for that day. 157 int64 early_bound;
182 base::Time morning_midnight = Now().LocalMidnight(); 158 int64 late_bound;
183 int64 early_bound = 0; 159 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
184 int64 late_bound = 0;
185 if (days_ago == 0) {
186 early_bound = morning_midnight.ToInternalValue();
187 late_bound = base::Time::Max().ToInternalValue();
188 } else {
189 base::Time early_time = morning_midnight -
190 base::TimeDelta::FromDays(days_ago);
191 base::Time late_time = morning_midnight -
192 base::TimeDelta::FromDays(days_ago-1);
193 early_bound = early_time.ToInternalValue();
194 late_bound = late_time.ToInternalValue();
195 }
196 std::string query_str = base::StringPrintf( 160 std::string query_str = base::StringPrintf(
197 "SELECT time, action_type, api_name, args, page_url, page_title, " 161 "SELECT time, action_type, api_name, args, page_url, page_title, "
198 "arg_url, other " 162 "arg_url, other "
199 "FROM %s WHERE extension_id=? AND time>? AND time<=? " 163 "FROM %s WHERE extension_id=? AND time>? AND time<=? "
200 "ORDER BY time DESC", 164 "ORDER BY time DESC",
201 kTableName); 165 kTableName);
202 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE, 166 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE,
203 query_str.c_str())); 167 query_str.c_str()));
204 query.BindString(0, extension_id); 168 query.BindString(0, extension_id);
205 query.BindInt64(1, early_bound); 169 query.BindInt64(1, early_bound);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 BrowserThread::PostTaskAndReplyWithResult( 234 BrowserThread::PostTaskAndReplyWithResult(
271 BrowserThread::DB, 235 BrowserThread::DB,
272 FROM_HERE, 236 FROM_HERE,
273 base::Bind(&FullStreamUIPolicy::DoReadData, 237 base::Bind(&FullStreamUIPolicy::DoReadData,
274 base::Unretained(this), 238 base::Unretained(this),
275 extension_id, 239 extension_id,
276 day), 240 day),
277 callback); 241 callback);
278 } 242 }
279 243
280 std::string FullStreamUIPolicy::GetKey(ActivityLogPolicy::KeyType key_ty) const
felt 2013/08/07 01:09:42 where did this go?
mvrable 2013/08/07 17:01:19 This code isn't being used any longer. The consta
felt 2013/08/08 02:08:50 Ahhh OK, right, I couldn't find them in this CL be
281 {
282 switch (key_ty) {
283 case PARAM_KEY_REASON:
284 return std::string(kKeyReason);
285 case PARAM_KEY_DOM_ACTION:
286 return std::string(kKeyDomainAction);
287 case PARAM_KEY_URL_TITLE:
288 return std::string(kKeyURLTitle);
289 case PARAM_KEY_DETAILS_STRING:
290 return std::string(kKeyDetailsString);
291 default:
292 return std::string();
293 }
294 }
295
296 scoped_refptr<Action> FullStreamUIPolicy::ProcessArguments( 244 scoped_refptr<Action> FullStreamUIPolicy::ProcessArguments(
297 scoped_refptr<Action> action) const { 245 scoped_refptr<Action> action) const {
298 return action; 246 return action;
299 } 247 }
300 248
301 void FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) { 249 void FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) {
302 // TODO(mvrable): Right now this argument stripping updates the Action object 250 // TODO(mvrable): Right now this argument stripping updates the Action object
303 // in place, which isn't good if there are other users of the object. When 251 // in place, which isn't good if there are other users of the object. When
304 // database writing is moved to policy class, the modifications should be 252 // database writing is moved to policy class, the modifications should be
305 // made locally. 253 // made locally.
306 action = ProcessArguments(action); 254 action = ProcessArguments(action);
307 ScheduleAndForget(this, &FullStreamUIPolicy::QueueAction, action); 255 ScheduleAndForget(this, &FullStreamUIPolicy::QueueAction, action);
308 } 256 }
309 257
310 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) { 258 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) {
311 if (activity_database()->is_db_valid()) { 259 if (activity_database()->is_db_valid()) {
312 queued_actions_.push_back(action); 260 queued_actions_.push_back(action);
313 activity_database()->NotifyAction(); 261 activity_database()->AdviseFlush(queued_actions_.size());
314 } 262 }
315 } 263 }
316 264
317 } // namespace extensions 265 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698