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

Side by Side Diff: chrome/browser/history/download_database.cc

Issue 17397003: Add the referrer url to the downloads table in the History database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r207869 Created 7 years, 6 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
« no previous file with comments | « chrome/browser/history/download_database.h ('k') | chrome/browser/history/history_database.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/download_database.h" 5 #include "chrome/browser/history/download_database.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 19 matching lines...) Expand all
30 namespace { 30 namespace {
31 31
32 // Reason for dropping a particular record. 32 // Reason for dropping a particular record.
33 enum DroppedReason { 33 enum DroppedReason {
34 DROPPED_REASON_BAD_STATE = 0, 34 DROPPED_REASON_BAD_STATE = 0,
35 DROPPED_REASON_BAD_DANGER_TYPE = 1, 35 DROPPED_REASON_BAD_DANGER_TYPE = 1,
36 DROPPED_REASON_MAX 36 DROPPED_REASON_MAX
37 }; 37 };
38 38
39 static const char kSchema[] = 39 static const char kSchema[] =
40 "CREATE TABLE downloads (" 40 "CREATE TABLE downloads ("
41 "id INTEGER PRIMARY KEY," // Primary key. 41 "id INTEGER PRIMARY KEY," // Primary key.
42 "current_path LONGVARCHAR NOT NULL," // Current disk location of the download 42 "current_path LONGVARCHAR NOT NULL," // Current disk location
43 "target_path LONGVARCHAR NOT NULL," // Final disk location of the download 43 "target_path LONGVARCHAR NOT NULL," // Final disk location
44 "start_time INTEGER NOT NULL," // When the download was started. 44 "start_time INTEGER NOT NULL," // When the download was started.
45 "received_bytes INTEGER NOT NULL," // Total size downloaded. 45 "received_bytes INTEGER NOT NULL," // Total size downloaded.
46 "total_bytes INTEGER NOT NULL," // Total size of the download. 46 "total_bytes INTEGER NOT NULL," // Total size of the download.
47 "state INTEGER NOT NULL," // 1=complete, 4=interrupted 47 "state INTEGER NOT NULL," // 1=complete, 4=interrupted
48 "danger_type INTEGER NOT NULL, " // Not dangerous, danger type, validated. 48 "danger_type INTEGER NOT NULL, " // Not dangerous, danger type, validated.
49 "interrupt_reason INTEGER NOT NULL," // Reason the download was interrupted. 49 "interrupt_reason INTEGER NOT NULL,"
50 "end_time INTEGER NOT NULL," // When the download completed. 50 "end_time INTEGER NOT NULL," // When the download completed.
51 "opened INTEGER NOT NULL)"; // 1 if it has ever been opened else 0 51 "opened INTEGER NOT NULL," // 1 if it has ever been opened else 0
52 "referrer VARCHAR NOT NULL)"; // HTTP Referrer
52 53
53 static const char kUrlChainSchema[] = 54 static const char kUrlChainSchema[] =
54 "CREATE TABLE downloads_url_chains (" 55 "CREATE TABLE downloads_url_chains ("
55 "id INTEGER NOT NULL," // downloads.id. 56 "id INTEGER NOT NULL," // downloads.id.
56 "chain_index INTEGER NOT NULL," // Index of url in chain 57 "chain_index INTEGER NOT NULL," // Index of url in chain
57 // 0 is initial target, 58 // 0 is initial target,
58 // MAX is target after redirects. 59 // MAX is target after redirects.
59 "url LONGVARCHAR NOT NULL, " // URL. 60 "url LONGVARCHAR NOT NULL, " // URL.
60 "PRIMARY KEY (id, chain_index) )"; 61 "PRIMARY KEY (id, chain_index) )";
61 62
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 if (!GetDB().Execute(kSchema)) 228 if (!GetDB().Execute(kSchema))
228 return false; 229 return false;
229 230
230 // Populate it. As we do so, we transform the time values from time_t 231 // Populate it. As we do so, we transform the time values from time_t
231 // (seconds since 1/1/1970 UTC), to our internal measure (microseconds 232 // (seconds since 1/1/1970 UTC), to our internal measure (microseconds
232 // since the Windows Epoch). Note that this is dependent on the 233 // since the Windows Epoch). Note that this is dependent on the
233 // internal representation of base::Time and needs to change if that changes. 234 // internal representation of base::Time and needs to change if that changes.
234 sql::Statement statement_populate(GetDB().GetUniqueStatement( 235 sql::Statement statement_populate(GetDB().GetUniqueStatement(
235 "INSERT INTO downloads " 236 "INSERT INTO downloads "
236 "( id, current_path, target_path, start_time, received_bytes, total_bytes, " 237 "( id, current_path, target_path, start_time, received_bytes, total_bytes, "
237 " state, danger_type, interrupt_reason, end_time, opened ) " 238 " state, danger_type, interrupt_reason, end_time, opened, referrer ) "
238 "SELECT id, full_path, full_path, " 239 "SELECT id, full_path, full_path, "
239 " CASE start_time WHEN 0 THEN 0 ELSE " 240 " CASE start_time WHEN 0 THEN 0 ELSE "
240 " (start_time + 11644473600) * 1000000 END, " 241 " (start_time + 11644473600) * 1000000 END, "
241 " received_bytes, total_bytes, " 242 " received_bytes, total_bytes, "
242 " state, ?, ?, " 243 " state, ?, ?, "
243 " CASE end_time WHEN 0 THEN 0 ELSE " 244 " CASE end_time WHEN 0 THEN 0 ELSE "
244 " (end_time + 11644473600) * 1000000 END, " 245 " (end_time + 11644473600) * 1000000 END, "
245 " opened " 246 " opened, \"\" "
246 "FROM downloads_tmp")); 247 "FROM downloads_tmp"));
247 statement_populate.BindInt(0, content::DOWNLOAD_INTERRUPT_REASON_NONE); 248 statement_populate.BindInt(0, content::DOWNLOAD_INTERRUPT_REASON_NONE);
248 statement_populate.BindInt(1, kDangerTypeNotDangerous); 249 statement_populate.BindInt(1, kDangerTypeNotDangerous);
249 if (!statement_populate.Run()) 250 if (!statement_populate.Run())
250 return false; 251 return false;
251 252
252 // Create new chain table and populate it. 253 // Create new chain table and populate it.
253 if (!GetDB().Execute(kUrlChainSchema)) 254 if (!GetDB().Execute(kUrlChainSchema))
254 return false; 255 return false;
255 256
256 if (!GetDB().Execute("INSERT INTO downloads_url_chains " 257 if (!GetDB().Execute("INSERT INTO downloads_url_chains "
257 " ( id, chain_index, url) " 258 " ( id, chain_index, url) "
258 " SELECT id, 0, url from downloads_tmp")) 259 " SELECT id, 0, url from downloads_tmp"))
259 return false; 260 return false;
260 261
261 // Get rid of temporary table. 262 // Get rid of temporary table.
262 if (!GetDB().Execute("DROP TABLE downloads_tmp")) 263 if (!GetDB().Execute("DROP TABLE downloads_tmp"))
263 return false; 264 return false;
264 265
265 return true; 266 return true;
266 } 267 }
267 268
269 bool DownloadDatabase::MigrateReferrer() {
270 return EnsureColumnExists("referrer", "VARCHAR NOT NULL DEFAULT \"\"");
271 }
272
268 bool DownloadDatabase::InitDownloadTable() { 273 bool DownloadDatabase::InitDownloadTable() {
269 GetMetaTable().GetValue(kNextDownloadId, &next_id_); 274 GetMetaTable().GetValue(kNextDownloadId, &next_id_);
270 if (GetDB().DoesTableExist("downloads")) { 275 if (GetDB().DoesTableExist("downloads")) {
271 return EnsureColumnExists("end_time", "INTEGER NOT NULL DEFAULT 0") && 276 return EnsureColumnExists("end_time", "INTEGER NOT NULL DEFAULT 0") &&
272 EnsureColumnExists("opened", "INTEGER NOT NULL DEFAULT 0"); 277 EnsureColumnExists("opened", "INTEGER NOT NULL DEFAULT 0");
273 } else { 278 } else {
274 // If the "downloads" table doesn't exist, the downloads_url_chain 279 // If the "downloads" table doesn't exist, the downloads_url_chain
275 // table better not. 280 // table better not.
276 return (!GetDB().DoesTableExist("downloads_url_chain") && 281 return (!GetDB().DoesTableExist("downloads_url_chain") &&
277 GetDB().Execute(kSchema) && GetDB().Execute(kUrlChainSchema)); 282 GetDB().Execute(kSchema) && GetDB().Execute(kUrlChainSchema));
(...skipping 10 matching lines...) Expand all
288 293
289 results->clear(); 294 results->clear();
290 if (next_db_handle_ < 1) 295 if (next_db_handle_ < 1)
291 next_db_handle_ = 1; 296 next_db_handle_ = 1;
292 std::set<int64> db_handles; 297 std::set<int64> db_handles;
293 298
294 std::map<DownloadID, DownloadRow*> info_map; 299 std::map<DownloadID, DownloadRow*> info_map;
295 300
296 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, 301 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE,
297 "SELECT id, current_path, target_path, start_time, received_bytes, " 302 "SELECT id, current_path, target_path, start_time, received_bytes, "
298 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " 303 "total_bytes, state, danger_type, interrupt_reason, end_time, opened, "
299 "FROM downloads " 304 "referrer "
300 "ORDER BY start_time")); 305 "FROM downloads ORDER BY start_time"));
301 306
302 while (statement_main.Step()) { 307 while (statement_main.Step()) {
303 scoped_ptr<DownloadRow> info(new DownloadRow()); 308 scoped_ptr<DownloadRow> info(new DownloadRow());
304 int column = 0; 309 int column = 0;
305 310
306 int db_handle = statement_main.ColumnInt64(column++); 311 int db_handle = statement_main.ColumnInt64(column++);
307 info->db_handle = db_handle; 312 info->db_handle = db_handle;
308 info->current_path = ColumnFilePath(statement_main, column++); 313 info->current_path = ColumnFilePath(statement_main, column++);
309 info->target_path = ColumnFilePath(statement_main, column++); 314 info->target_path = ColumnFilePath(statement_main, column++);
310 info->start_time = base::Time::FromInternalValue( 315 info->start_time = base::Time::FromInternalValue(
311 statement_main.ColumnInt64(column++)); 316 statement_main.ColumnInt64(column++));
312 info->received_bytes = statement_main.ColumnInt64(column++); 317 info->received_bytes = statement_main.ColumnInt64(column++);
313 info->total_bytes = statement_main.ColumnInt64(column++); 318 info->total_bytes = statement_main.ColumnInt64(column++);
314 int state = statement_main.ColumnInt(column++); 319 int state = statement_main.ColumnInt(column++);
315 info->state = IntToState(state); 320 info->state = IntToState(state);
316 if (info->state == DownloadItem::MAX_DOWNLOAD_STATE) 321 if (info->state == DownloadItem::MAX_DOWNLOAD_STATE)
317 UMA_HISTOGRAM_COUNTS("Download.DatabaseInvalidState", state); 322 UMA_HISTOGRAM_COUNTS("Download.DatabaseInvalidState", state);
318 info->danger_type = IntToDangerType(statement_main.ColumnInt(column++)); 323 info->danger_type = IntToDangerType(statement_main.ColumnInt(column++));
319 info->interrupt_reason = static_cast<content::DownloadInterruptReason>( 324 info->interrupt_reason = static_cast<content::DownloadInterruptReason>(
320 statement_main.ColumnInt(column++)); 325 statement_main.ColumnInt(column++));
321 info->end_time = base::Time::FromInternalValue( 326 info->end_time = base::Time::FromInternalValue(
322 statement_main.ColumnInt64(column++)); 327 statement_main.ColumnInt64(column++));
323 info->opened = statement_main.ColumnInt(column++) != 0; 328 info->opened = statement_main.ColumnInt(column++) != 0;
329 info->referrer_url = GURL(statement_main.ColumnString(column++));
324 if (info->db_handle >= next_db_handle_) 330 if (info->db_handle >= next_db_handle_)
325 next_db_handle_ = info->db_handle + 1; 331 next_db_handle_ = info->db_handle + 1;
326 if (!db_handles.insert(info->db_handle).second) { 332 if (!db_handles.insert(info->db_handle).second) {
327 // info->db_handle was already in db_handles. The database is corrupt. 333 // info->db_handle was already in db_handles. The database is corrupt.
328 base::debug::Alias(&info->db_handle); 334 base::debug::Alias(&info->db_handle);
329 DCHECK(false); 335 DCHECK(false);
330 } 336 }
331 337
332 // If the record is corrupted, note that and drop it. 338 // If the record is corrupted, note that and drop it.
333 if (info->state == DownloadItem::MAX_DOWNLOAD_STATE || 339 if (info->state == DownloadItem::MAX_DOWNLOAD_STATE ||
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 return kUninitializedHandle; 481 return kUninitializedHandle;
476 482
477 int db_handle = next_db_handle_++; 483 int db_handle = next_db_handle_++;
478 484
479 { 485 {
480 sql::Statement statement_insert(GetDB().GetCachedStatement( 486 sql::Statement statement_insert(GetDB().GetCachedStatement(
481 SQL_FROM_HERE, 487 SQL_FROM_HERE,
482 "INSERT INTO downloads " 488 "INSERT INTO downloads "
483 "(id, current_path, target_path, start_time, " 489 "(id, current_path, target_path, start_time, "
484 " received_bytes, total_bytes, state, danger_type, interrupt_reason, " 490 " received_bytes, total_bytes, state, danger_type, interrupt_reason, "
485 " end_time, opened) " 491 " end_time, opened, referrer) "
486 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 492 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
487 493
488 int column = 0; 494 int column = 0;
489 statement_insert.BindInt64(column++, db_handle); 495 statement_insert.BindInt64(column++, db_handle);
490 BindFilePath(statement_insert, info.current_path, column++); 496 BindFilePath(statement_insert, info.current_path, column++);
491 BindFilePath(statement_insert, info.target_path, column++); 497 BindFilePath(statement_insert, info.target_path, column++);
492 statement_insert.BindInt64(column++, info.start_time.ToInternalValue()); 498 statement_insert.BindInt64(column++, info.start_time.ToInternalValue());
493 statement_insert.BindInt64(column++, info.received_bytes); 499 statement_insert.BindInt64(column++, info.received_bytes);
494 statement_insert.BindInt64(column++, info.total_bytes); 500 statement_insert.BindInt64(column++, info.total_bytes);
495 statement_insert.BindInt(column++, state); 501 statement_insert.BindInt(column++, state);
496 statement_insert.BindInt(column++, danger_type); 502 statement_insert.BindInt(column++, danger_type);
497 statement_insert.BindInt(column++, info.interrupt_reason); 503 statement_insert.BindInt(column++, info.interrupt_reason);
498 statement_insert.BindInt64(column++, info.end_time.ToInternalValue()); 504 statement_insert.BindInt64(column++, info.end_time.ToInternalValue());
499 statement_insert.BindInt(column++, info.opened ? 1 : 0); 505 statement_insert.BindInt(column++, info.opened ? 1 : 0);
506 statement_insert.BindString(column++, info.referrer_url.spec());
500 if (!statement_insert.Run()) { 507 if (!statement_insert.Run()) {
501 // GetErrorCode() returns a bitmask where the lower byte is a more general 508 // GetErrorCode() returns a bitmask where the lower byte is a more general
502 // code and the upper byte is a more specific code. In order to save 509 // code and the upper byte is a more specific code. In order to save
503 // memory, take the general code, of which there are fewer than 50. See 510 // memory, take the general code, of which there are fewer than 50. See
504 // also sql/connection.cc 511 // also sql/connection.cc
505 // http://www.sqlite.org/c3ref/c_abort_rollback.html 512 // http://www.sqlite.org/c3ref/c_abort_rollback.html
506 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainInsertError", 513 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainInsertError",
507 GetDB().GetErrorCode() & 0xff, 50); 514 GetDB().GetErrorCode() & 0xff, 50);
508 return kUninitializedHandle; 515 return kUninitializedHandle;
509 } 516 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 int DownloadDatabase::CountDownloads() { 582 int DownloadDatabase::CountDownloads() {
576 EnsureInProgressEntriesCleanedUp(); 583 EnsureInProgressEntriesCleanedUp();
577 584
578 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 585 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
579 "SELECT count(*) from downloads")); 586 "SELECT count(*) from downloads"));
580 statement.Step(); 587 statement.Step();
581 return statement.ColumnInt(0); 588 return statement.ColumnInt(0);
582 } 589 }
583 590
584 } // namespace history 591 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/download_database.h ('k') | chrome/browser/history/history_database.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698