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

Unified Diff: components/history/core/browser/download_database.cc

Issue 1781983002: [Downloads] Introduce GUIDs for downloads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/history/core/browser/download_database.h ('k') | components/history/core/browser/download_row.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/history/core/browser/download_database.cc
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc
index 42710296ae1ed9cb578c71407332812de15a9b2e..93b707c9fe22f76c0bfbac30ce721b4710e40289 100644
--- a/components/history/core/browser/download_database.cc
+++ b/components/history/core/browser/download_database.cc
@@ -186,10 +186,41 @@ bool DownloadDatabase::MigrateDownloadValidators() {
EnsureColumnExists("last_modified", "VARCHAR NOT NULL DEFAULT \"\"");
}
+bool DownloadDatabase::MigrateHashHttpMethodAndGenerateGuids() {
+ if (!EnsureColumnExists("guid", "VARCHAR NOT NULL DEFAULT ''") ||
+ !EnsureColumnExists("hash", "BLOB NOT NULL DEFAULT X''") ||
+ !EnsureColumnExists("http_method", "VARCHAR NOT NULL DEFAULT ''"))
+ return false;
+
+ // Generate GUIDs for each download. The GUID is generated thusly:
+ //
+ // XXXXXXXX-RRRR-RRRR-RRRR-RRRRRRRRRRRR
+ // \__ __/ \___________ ____________/
+ // \/ \/
+ // | Random hex digits
+ // |
+ // Hex representation of 32-bit download ID.
+ //
+ // The 96 random bits provide entropy while the 32-bits from the download ID
+ // ensure that the generated identifiers will at least be unique amongst the
+ // download rows in the unlikely event there's a collision in the 96 entropy
+ // bits.
+ //
+ // This GUID generation scheme is only used for migrated download rows and
+ // assumes that the likelihood of a collision with a GUID generated via
+ // base::GenerateGUID() will be vanishingly small.
+ const char kMigrateGuidsQuery[] =
+ "UPDATE downloads SET guid = printf"
+ "(\"%08X-%s-%s-%s-%s\", id, hex(randomblob(2)), hex(randomblob(2)),"
+ " hex(randomblob(2)), hex(randomblob(6)))";
+ return GetDB().Execute(kMigrateGuidsQuery);
+}
+
bool DownloadDatabase::InitDownloadTable() {
const char kSchema[] =
"CREATE TABLE downloads ("
"id INTEGER PRIMARY KEY," // Primary key.
+ "guid VARCHAR NOT NULL," // GUID.
"current_path LONGVARCHAR NOT NULL," // Current disk location
"target_path LONGVARCHAR NOT NULL," // Final disk location
"start_time INTEGER NOT NULL," // When the download was started.
@@ -198,10 +229,12 @@ bool DownloadDatabase::InitDownloadTable() {
"state INTEGER NOT NULL," // 1=complete, 4=interrupted
"danger_type INTEGER NOT NULL," // Danger type, validated.
"interrupt_reason INTEGER NOT NULL," // DownloadInterruptReason
+ "hash BLOB NOT NULL," // Raw SHA-256 hash of contents.
"end_time INTEGER NOT NULL," // When the download completed.
"opened INTEGER NOT NULL," // 1 if it has ever been opened
// else 0
"referrer VARCHAR NOT NULL," // HTTP Referrer
+ "http_method VARCHAR NOT NULL," // HTTP method.
"by_ext_id VARCHAR NOT NULL," // ID of extension that started the
// download
"by_ext_name VARCHAR NOT NULL," // name of extension
@@ -257,6 +290,7 @@ bool DownloadDatabase::DropDownloadTable() {
}
void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
+ SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.QueryDownloadDuration");
EnsureInProgressEntriesCleanedUp();
results->clear();
@@ -264,12 +298,12 @@ void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
std::map<uint32_t, DownloadRow*> info_map;
- sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE,
- "SELECT id, current_path, target_path, "
- "mime_type, original_mime_type, "
- "start_time, received_bytes, "
- "total_bytes, state, danger_type, interrupt_reason, end_time, opened, "
- "referrer, by_ext_id, by_ext_name, etag, last_modified "
+ sql::Statement statement_main(GetDB().GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT id, guid, current_path, target_path, mime_type, "
+ "original_mime_type, start_time, received_bytes, total_bytes, state, "
+ "danger_type, interrupt_reason, hash, end_time, opened, referrer, "
+ "http_method, by_ext_id, by_ext_name, etag, last_modified "
"FROM downloads ORDER BY start_time"));
while (statement_main.Step()) {
@@ -281,6 +315,7 @@ void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
// the max(id) logic in GetNextDownloadId().
int64_t signed_id = statement_main.ColumnInt64(column++);
info->id = IntToDownloadId(signed_id);
+ info->guid = statement_main.ColumnString(column++);
info->current_path = ColumnFilePath(statement_main, column++);
info->target_path = ColumnFilePath(statement_main, column++);
info->mime_type = statement_main.ColumnString(column++);
@@ -297,10 +332,12 @@ void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
IntToDownloadDangerType(statement_main.ColumnInt(column++));
info->interrupt_reason =
IntToDownloadInterruptReason(statement_main.ColumnInt(column++));
+ statement_main.ColumnBlobAsString(column++, &info->hash);
info->end_time =
base::Time::FromInternalValue(statement_main.ColumnInt64(column++));
info->opened = statement_main.ColumnInt(column++) != 0;
info->referrer_url = GURL(statement_main.ColumnString(column++));
+ info->http_method = statement_main.ColumnString(column++);
info->by_ext_id = statement_main.ColumnString(column++);
info->by_ext_name = statement_main.ColumnString(column++);
info->etag = statement_main.ColumnString(column++);
@@ -390,6 +427,8 @@ void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
}
bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
+ // UpdateDownload() is called fairly frequently.
+ SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.UpdateDownloadDuration");
EnsureInProgressEntriesCleanedUp();
DCHECK_NE(kInvalidDownloadId, data.id);
@@ -402,12 +441,13 @@ bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
return false;
}
- sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ sql::Statement statement(GetDB().GetCachedStatement(
+ SQL_FROM_HERE,
"UPDATE downloads "
"SET current_path=?, target_path=?, "
"mime_type=?, original_mime_type=?, "
"received_bytes=?, state=?, "
- "danger_type=?, interrupt_reason=?, end_time=?, total_bytes=?, "
+ "danger_type=?, interrupt_reason=?, hash=?, end_time=?, total_bytes=?, "
"opened=?, by_ext_id=?, by_ext_name=?, etag=?, last_modified=? "
"WHERE id=?"));
int column = 0;
@@ -420,6 +460,7 @@ bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
statement.BindInt(column++, DownloadDangerTypeToInt(data.danger_type));
statement.BindInt(column++,
DownloadInterruptReasonToInt(data.interrupt_reason));
+ statement.BindBlob(column++, data.hash.data(), data.hash.size());
statement.BindInt64(column++, data.end_time.ToInternalValue());
statement.BindInt64(column++, data.total_bytes);
statement.BindInt(column++, (data.opened ? 1 : 0));
@@ -449,6 +490,8 @@ void DownloadDatabase::EnsureInProgressEntriesCleanedUp() {
bool DownloadDatabase::CreateDownload(const DownloadRow& info) {
DCHECK_NE(kInvalidDownloadId, info.id);
+ DCHECK(!info.guid.empty());
+ SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.CreateDownloadDuration");
EnsureInProgressEntriesCleanedUp();
if (info.url_chain.empty())
@@ -464,16 +507,17 @@ bool DownloadDatabase::CreateDownload(const DownloadRow& info) {
sql::Statement statement_insert(GetDB().GetCachedStatement(
SQL_FROM_HERE,
"INSERT INTO downloads "
- "(id, current_path, target_path, "
- " mime_type, original_mime_type, "
- " start_time, "
- " received_bytes, total_bytes, state, danger_type, interrupt_reason, "
- " end_time, opened, referrer, by_ext_id, by_ext_name, etag, "
- " last_modified) "
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
+ "(id, guid, current_path, target_path, mime_type, original_mime_type, "
+ " start_time, received_bytes, total_bytes, state, danger_type, "
+ " interrupt_reason, hash, end_time, opened, referrer, http_method, "
+ " by_ext_id, by_ext_name, etag, last_modified) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
+ " ?)"));
int column = 0;
statement_insert.BindInt(column++, DownloadIdToInt(info.id));
+ statement_insert.BindString(column++, info.guid);
BindFilePath(statement_insert, info.current_path, column++);
BindFilePath(statement_insert, info.target_path, column++);
statement_insert.BindString(column++, info.mime_type);
@@ -486,9 +530,11 @@ bool DownloadDatabase::CreateDownload(const DownloadRow& info) {
DownloadDangerTypeToInt(info.danger_type));
statement_insert.BindInt(
column++, DownloadInterruptReasonToInt(info.interrupt_reason));
+ statement_insert.BindBlob(column++, info.hash.data(), info.hash.size());
statement_insert.BindInt64(column++, info.end_time.ToInternalValue());
statement_insert.BindInt(column++, info.opened ? 1 : 0);
statement_insert.BindString(column++, info.referrer_url.spec());
+ statement_insert.BindString(column++, info.http_method);
statement_insert.BindString(column++, info.by_ext_id);
statement_insert.BindString(column++, info.by_ext_name);
statement_insert.BindString(column++, info.etag);
« no previous file with comments | « components/history/core/browser/download_database.h ('k') | components/history/core/browser/download_row.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698