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

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

Issue 13044019: Clean up entries left by crashes in the DownloadDB. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync'd to r192579 Created 7 years, 8 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_backend.h » ('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
11 #include "base/debug/alias.h" 11 #include "base/debug/alias.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/stringprintf.h" 16 #include "base/stringprintf.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "chrome/browser/history/download_row.h" 20 #include "chrome/browser/history/download_row.h"
21 #include "chrome/browser/history/history_types.h" 21 #include "chrome/browser/history/history_types.h"
22 #include "content/public/browser/download_interrupt_reasons.h" 22 #include "content/public/browser/download_interrupt_reasons.h"
23 #include "content/public/browser/download_item.h" 23 #include "content/public/browser/download_item.h"
24 #include "sql/statement.h" 24 #include "sql/statement.h"
25 25
26 using content::DownloadItem; 26 using content::DownloadItem;
27 27
28 namespace history { 28 namespace history {
29 29
30 // static
31 const int64 DownloadDatabase::kUninitializedHandle = -1;
32
33 namespace { 30 namespace {
34 31
35 // Reason for dropping a particular record. 32 // Reason for dropping a particular record.
36 enum DroppedReason { 33 enum DroppedReason {
37 DROPPED_REASON_BAD_STATE = 0, 34 DROPPED_REASON_BAD_STATE = 0,
38 DROPPED_REASON_BAD_DANGER_TYPE = 1, 35 DROPPED_REASON_BAD_DANGER_TYPE = 1,
39 DROPPED_REASON_MAX 36 DROPPED_REASON_MAX
40 }; 37 };
41 38
42 static const char kSchema[] = 39 static const char kSchema[] =
(...skipping 12 matching lines...) Expand all
55 52
56 static const char kUrlChainSchema[] = 53 static const char kUrlChainSchema[] =
57 "CREATE TABLE downloads_url_chains (" 54 "CREATE TABLE downloads_url_chains ("
58 "id INTEGER NOT NULL," // downloads.id. 55 "id INTEGER NOT NULL," // downloads.id.
59 "chain_index INTEGER NOT NULL," // Index of url in chain 56 "chain_index INTEGER NOT NULL," // Index of url in chain
60 // 0 is initial target, 57 // 0 is initial target,
61 // MAX is target after redirects. 58 // MAX is target after redirects.
62 "url LONGVARCHAR NOT NULL, " // URL. 59 "url LONGVARCHAR NOT NULL, " // URL.
63 "PRIMARY KEY (id, chain_index) )"; 60 "PRIMARY KEY (id, chain_index) )";
64 61
65 // These constants and next two functions are used to allow
66 // DownloadItem::DownloadState and DownloadDangerType to change without
67 // breaking the database schema.
68 // They guarantee that the values of the |state| field in the database are one
69 // of the values returned by StateToInt, and that the values of the |state|
70 // field of the DownloadRows returned by QueryDownloads() are one of the values
71 // returned by IntToState().
72 static const int kStateInvalid = -1;
73 static const int kStateInProgress = 0;
74 static const int kStateComplete = 1;
75 static const int kStateCancelled = 2;
76 static const int kStateBug140687 = 3;
77 static const int kStateInterrupted = 4;
78
79 static const int kDangerTypeInvalid = -1;
80 static const int kDangerTypeNotDangerous = 0;
81 static const int kDangerTypeDangerousFile = 1;
82 static const int kDangerTypeDangerousUrl = 2;
83 static const int kDangerTypeDangerousContent = 3;
84 static const int kDangerTypeMaybeDangerousContent = 4;
85 static const int kDangerTypeUncommonContent = 5;
86 static const int kDangerTypeUserValidated = 6;
87 static const int kDangerTypeDangerousHost = 7;
88
89 int StateToInt(DownloadItem::DownloadState state) {
90 switch (state) {
91 case DownloadItem::IN_PROGRESS: return kStateInProgress;
92 case DownloadItem::COMPLETE: return kStateComplete;
93 case DownloadItem::CANCELLED: return kStateCancelled;
94 case DownloadItem::INTERRUPTED: return kStateInterrupted;
95 case DownloadItem::MAX_DOWNLOAD_STATE:
96 NOTREACHED();
97 return kStateInvalid;
98 }
99 NOTREACHED();
100 return kStateInvalid;
101 }
102
103 DownloadItem::DownloadState IntToState(int state) {
104 switch (state) {
105 case kStateInProgress: return DownloadItem::IN_PROGRESS;
106 case kStateComplete: return DownloadItem::COMPLETE;
107 case kStateCancelled: return DownloadItem::CANCELLED;
108 // We should not need kStateBug140687 here because MigrateDownloadsState()
109 // is called in HistoryDatabase::Init().
110 case kStateInterrupted: return DownloadItem::INTERRUPTED;
111 default: return DownloadItem::MAX_DOWNLOAD_STATE;
112 }
113 }
114
115 int DangerTypeToInt(content::DownloadDangerType danger_type) {
116 switch (danger_type) {
117 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
118 return kDangerTypeNotDangerous;
119 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
120 return kDangerTypeDangerousFile;
121 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
122 return kDangerTypeDangerousUrl;
123 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
124 return kDangerTypeDangerousContent;
125 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
126 return kDangerTypeMaybeDangerousContent;
127 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
128 return kDangerTypeUncommonContent;
129 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
130 return kDangerTypeUserValidated;
131 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
132 return kDangerTypeDangerousHost;
133 case content::DOWNLOAD_DANGER_TYPE_MAX:
134 NOTREACHED();
135 return kDangerTypeInvalid;
136 }
137 NOTREACHED();
138 return kDangerTypeInvalid;
139 }
140
141 content::DownloadDangerType IntToDangerType(int danger_type) {
142 switch (danger_type) {
143 case kDangerTypeNotDangerous:
144 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
145 case kDangerTypeDangerousFile:
146 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
147 case kDangerTypeDangerousUrl:
148 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
149 case kDangerTypeDangerousContent:
150 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
151 case kDangerTypeMaybeDangerousContent:
152 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
153 case kDangerTypeUncommonContent:
154 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT;
155 case kDangerTypeUserValidated:
156 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED;
157 case kDangerTypeDangerousHost:
158 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST;
159 default:
160 return content::DOWNLOAD_DANGER_TYPE_MAX;
161 }
162 }
163
164 #if defined(OS_POSIX) 62 #if defined(OS_POSIX)
165 63
166 // Binds/reads the given file path to the given column of the given statement. 64 // Binds/reads the given file path to the given column of the given statement.
167 void BindFilePath(sql::Statement& statement, const base::FilePath& path, 65 void BindFilePath(sql::Statement& statement, const base::FilePath& path,
168 int col) { 66 int col) {
169 statement.BindString(col, path.value()); 67 statement.BindString(col, path.value());
170 } 68 }
171 base::FilePath ColumnFilePath(sql::Statement& statement, int col) { 69 base::FilePath ColumnFilePath(sql::Statement& statement, int col) {
172 return base::FilePath(statement.ColumnString(col)); 70 return base::FilePath(statement.ColumnString(col));
173 } 71 }
(...skipping 10 matching lines...) Expand all
184 } 82 }
185 83
186 #endif 84 #endif
187 85
188 // Key in the meta_table containing the next id to use for a new download in 86 // Key in the meta_table containing the next id to use for a new download in
189 // this profile. 87 // this profile.
190 static const char kNextDownloadId[] = "next_download_id"; 88 static const char kNextDownloadId[] = "next_download_id";
191 89
192 } // namespace 90 } // namespace
193 91
92 // static
93 const int64 DownloadDatabase::kUninitializedHandle = -1;
94
95 // These constants and the transformation functions below are used to allow
96 // DownloadItem::DownloadState and DownloadDangerType to change without
97 // breaking the database schema.
98 // They guarantee that the values of the |state| field in the database are one
99 // of the values returned by StateToInt, and that the values of the |state|
100 // field of the DownloadRows returned by QueryDownloads() are one of the values
101 // returned by IntToState().
102 const int DownloadDatabase::kStateInvalid = -1;
103 const int DownloadDatabase::kStateInProgress = 0;
104 const int DownloadDatabase::kStateComplete = 1;
105 const int DownloadDatabase::kStateCancelled = 2;
106 const int DownloadDatabase::kStateBug140687 = 3;
107 const int DownloadDatabase::kStateInterrupted = 4;
108
109 const int DownloadDatabase::kDangerTypeInvalid = -1;
110 const int DownloadDatabase::kDangerTypeNotDangerous = 0;
111 const int DownloadDatabase::kDangerTypeDangerousFile = 1;
112 const int DownloadDatabase::kDangerTypeDangerousUrl = 2;
113 const int DownloadDatabase::kDangerTypeDangerousContent = 3;
114 const int DownloadDatabase::kDangerTypeMaybeDangerousContent = 4;
115 const int DownloadDatabase::kDangerTypeUncommonContent = 5;
116 const int DownloadDatabase::kDangerTypeUserValidated = 6;
117 const int DownloadDatabase::kDangerTypeDangerousHost = 7;
118
119 int DownloadDatabase::StateToInt(DownloadItem::DownloadState state) {
120 switch (state) {
121 case DownloadItem::IN_PROGRESS: return DownloadDatabase::kStateInProgress;
122 case DownloadItem::COMPLETE: return DownloadDatabase::kStateComplete;
123 case DownloadItem::CANCELLED: return DownloadDatabase::kStateCancelled;
124 case DownloadItem::INTERRUPTED: return DownloadDatabase::kStateInterrupted;
125 case DownloadItem::MAX_DOWNLOAD_STATE:
126 NOTREACHED();
127 return DownloadDatabase::kStateInvalid;
128 }
129 NOTREACHED();
130 return DownloadDatabase::kStateInvalid;
131 }
132
133 DownloadItem::DownloadState DownloadDatabase::IntToState(int state) {
134 switch (state) {
135 case DownloadDatabase::kStateInProgress: return DownloadItem::IN_PROGRESS;
136 case DownloadDatabase::kStateComplete: return DownloadItem::COMPLETE;
137 case DownloadDatabase::kStateCancelled: return DownloadItem::CANCELLED;
138 // We should not need kStateBug140687 here because MigrateDownloadsState()
139 // is called in HistoryDatabase::Init().
140 case DownloadDatabase::kStateInterrupted: return DownloadItem::INTERRUPTED;
141 default: return DownloadItem::MAX_DOWNLOAD_STATE;
142 }
143 }
144
145 int DownloadDatabase::DangerTypeToInt(content::DownloadDangerType danger_type) {
146 switch (danger_type) {
147 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
148 return DownloadDatabase::kDangerTypeNotDangerous;
149 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
150 return DownloadDatabase::kDangerTypeDangerousFile;
151 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
152 return DownloadDatabase::kDangerTypeDangerousUrl;
153 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
154 return DownloadDatabase::kDangerTypeDangerousContent;
155 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
156 return DownloadDatabase::kDangerTypeMaybeDangerousContent;
157 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
158 return DownloadDatabase::kDangerTypeUncommonContent;
159 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
160 return DownloadDatabase::kDangerTypeUserValidated;
161 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
162 return DownloadDatabase::kDangerTypeDangerousHost;
163 case content::DOWNLOAD_DANGER_TYPE_MAX:
164 NOTREACHED();
165 return DownloadDatabase::kDangerTypeInvalid;
166 }
167 NOTREACHED();
168 return DownloadDatabase::kDangerTypeInvalid;
169 }
170
171 content::DownloadDangerType DownloadDatabase::IntToDangerType(int danger_type) {
172 switch (danger_type) {
173 case DownloadDatabase::kDangerTypeNotDangerous:
174 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
175 case DownloadDatabase::kDangerTypeDangerousFile:
176 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
177 case DownloadDatabase::kDangerTypeDangerousUrl:
178 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
179 case DownloadDatabase::kDangerTypeDangerousContent:
180 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
181 case DownloadDatabase::kDangerTypeMaybeDangerousContent:
182 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
183 case DownloadDatabase::kDangerTypeUncommonContent:
184 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT;
185 case DownloadDatabase::kDangerTypeUserValidated:
186 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED;
187 case DownloadDatabase::kDangerTypeDangerousHost:
188 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST;
189 default:
190 return content::DOWNLOAD_DANGER_TYPE_MAX;
191 }
192 }
193
194 DownloadDatabase::DownloadDatabase() 194 DownloadDatabase::DownloadDatabase()
195 : owning_thread_set_(false), 195 : owning_thread_set_(false),
196 owning_thread_(0), 196 owning_thread_(0),
197 next_id_(0), 197 next_id_(0),
198 next_db_handle_(0) { 198 next_db_handle_(0),
199 in_progress_entry_cleanup_completed_(false) {
199 } 200 }
200 201
201 DownloadDatabase::~DownloadDatabase() { 202 DownloadDatabase::~DownloadDatabase() {
202 } 203 }
203 204
204 bool DownloadDatabase::EnsureColumnExists( 205 bool DownloadDatabase::EnsureColumnExists(
205 const std::string& name, const std::string& type) { 206 const std::string& name, const std::string& type) {
206 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type; 207 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type;
207 return GetDB().DoesColumnExist("downloads", name.c_str()) || 208 return GetDB().DoesColumnExist("downloads", name.c_str()) ||
208 GetDB().Execute(add_col.c_str()); 209 GetDB().Execute(add_col.c_str());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 GetDB().Execute(kSchema) && GetDB().Execute(kUrlChainSchema)); 277 GetDB().Execute(kSchema) && GetDB().Execute(kUrlChainSchema));
277 } 278 }
278 } 279 }
279 280
280 bool DownloadDatabase::DropDownloadTable() { 281 bool DownloadDatabase::DropDownloadTable() {
281 return GetDB().Execute("DROP TABLE downloads"); 282 return GetDB().Execute("DROP TABLE downloads");
282 } 283 }
283 284
284 void DownloadDatabase::QueryDownloads( 285 void DownloadDatabase::QueryDownloads(
285 std::vector<DownloadRow>* results) { 286 std::vector<DownloadRow>* results) {
287 EnsureInProgressEntriesCleanedUp();
288
286 results->clear(); 289 results->clear();
287 if (next_db_handle_ < 1) 290 if (next_db_handle_ < 1)
288 next_db_handle_ = 1; 291 next_db_handle_ = 1;
289 std::set<int64> db_handles; 292 std::set<int64> db_handles;
290 293
291 std::map<DownloadID, DownloadRow*> info_map; 294 std::map<DownloadID, DownloadRow*> info_map;
292 295
293 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, 296 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE,
294 "SELECT id, current_path, target_path, start_time, received_bytes, " 297 "SELECT id, current_path, target_path, start_time, received_bytes, "
295 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " 298 "total_bytes, state, danger_type, interrupt_reason, end_time, opened "
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } else { 397 } else {
395 // Copy the contents of the stored info. 398 // Copy the contents of the stored info.
396 results->push_back(*row); 399 results->push_back(*row);
397 } 400 }
398 delete row; 401 delete row;
399 it->second = NULL; 402 it->second = NULL;
400 } 403 }
401 } 404 }
402 405
403 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { 406 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
407 EnsureInProgressEntriesCleanedUp();
408
404 DCHECK(data.db_handle > 0); 409 DCHECK(data.db_handle > 0);
405 int state = StateToInt(data.state); 410 int state = StateToInt(data.state);
406 if (state == kStateInvalid) { 411 if (state == kStateInvalid) {
407 NOTREACHED(); 412 NOTREACHED();
408 return false; 413 return false;
409 } 414 }
410 int danger_type = DangerTypeToInt(data.danger_type); 415 int danger_type = DangerTypeToInt(data.danger_type);
411 if (danger_type == kDangerTypeInvalid) { 416 if (danger_type == kDangerTypeInvalid) {
412 NOTREACHED(); 417 NOTREACHED();
413 return false; 418 return false;
(...skipping 12 matching lines...) Expand all
426 statement.BindInt(column++, danger_type); 431 statement.BindInt(column++, danger_type);
427 statement.BindInt(column++, static_cast<int>(data.interrupt_reason)); 432 statement.BindInt(column++, static_cast<int>(data.interrupt_reason));
428 statement.BindInt64(column++, data.end_time.ToInternalValue()); 433 statement.BindInt64(column++, data.end_time.ToInternalValue());
429 statement.BindInt(column++, data.total_bytes); 434 statement.BindInt(column++, data.total_bytes);
430 statement.BindInt(column++, (data.opened ? 1 : 0)); 435 statement.BindInt(column++, (data.opened ? 1 : 0));
431 statement.BindInt64(column++, data.db_handle); 436 statement.BindInt64(column++, data.db_handle);
432 437
433 return statement.Run(); 438 return statement.Run();
434 } 439 }
435 440
436 bool DownloadDatabase::CleanUpInProgressEntries() { 441 void DownloadDatabase::EnsureInProgressEntriesCleanedUp() {
442 if (in_progress_entry_cleanup_completed_)
443 return;
444
437 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 445 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
438 "UPDATE downloads SET state=? WHERE state=?")); 446 "UPDATE downloads SET state=?, interrupt_reason=? WHERE state=?"));
439 statement.BindInt(0, kStateCancelled); 447 statement.BindInt(0, kStateInterrupted);
440 statement.BindInt(1, kStateInProgress); 448 statement.BindInt(1, content::DOWNLOAD_INTERRUPT_REASON_CRASH);
449 statement.BindInt(2, kStateInProgress);
441 450
442 return statement.Run(); 451 statement.Run();
452 in_progress_entry_cleanup_completed_ = true;
443 } 453 }
444 454
445 int64 DownloadDatabase::CreateDownload(const DownloadRow& info) { 455 int64 DownloadDatabase::CreateDownload(const DownloadRow& info) {
456 EnsureInProgressEntriesCleanedUp();
457
446 if (next_db_handle_ == 0) { 458 if (next_db_handle_ == 0) {
447 // This is unlikely. All current known tests and users already call 459 // This is unlikely. All current known tests and users already call
448 // QueryDownloads() before CreateDownload(). 460 // QueryDownloads() before CreateDownload().
449 std::vector<DownloadRow> results; 461 std::vector<DownloadRow> results;
450 QueryDownloads(&results); 462 QueryDownloads(&results);
451 CHECK_NE(0, next_db_handle_); 463 CHECK_NE(0, next_db_handle_);
452 } 464 }
453 465
454 if (info.url_chain.empty()) 466 if (info.url_chain.empty())
455 return kUninitializedHandle; 467 return kUninitializedHandle;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 542 }
531 statement_insert_chain.Reset(true); 543 statement_insert_chain.Reset(true);
532 } 544 }
533 545
534 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} 546 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;}
535 GetMetaTable().SetValue(kNextDownloadId, ++next_id_); 547 GetMetaTable().SetValue(kNextDownloadId, ++next_id_);
536 return db_handle; 548 return db_handle;
537 } 549 }
538 550
539 void DownloadDatabase::RemoveDownload(int64 handle) { 551 void DownloadDatabase::RemoveDownload(int64 handle) {
552 EnsureInProgressEntriesCleanedUp();
553
540 sql::Statement downloads_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 554 sql::Statement downloads_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
541 "DELETE FROM downloads WHERE id=?")); 555 "DELETE FROM downloads WHERE id=?"));
542 downloads_statement.BindInt64(0, handle); 556 downloads_statement.BindInt64(0, handle);
543 if (!downloads_statement.Run()) { 557 if (!downloads_statement.Run()) {
544 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainDeleteError", 558 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainDeleteError",
545 GetDB().GetErrorCode() & 0xff, 50); 559 GetDB().GetErrorCode() & 0xff, 50);
546 return; 560 return;
547 } 561 }
548 RemoveDownloadURLs(handle); 562 RemoveDownloadURLs(handle);
549 } 563 }
550 564
551 void DownloadDatabase::RemoveDownloadURLs(int64 handle) { 565 void DownloadDatabase::RemoveDownloadURLs(int64 handle) {
552 sql::Statement urlchain_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 566 sql::Statement urlchain_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
553 "DELETE FROM downloads_url_chains WHERE id=?")); 567 "DELETE FROM downloads_url_chains WHERE id=?"));
554 urlchain_statement.BindInt64(0, handle); 568 urlchain_statement.BindInt64(0, handle);
555 if (!urlchain_statement.Run()) { 569 if (!urlchain_statement.Run()) {
556 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseURLChainDeleteError", 570 UMA_HISTOGRAM_ENUMERATION("Download.DatabaseURLChainDeleteError",
557 GetDB().GetErrorCode() & 0xff, 50); 571 GetDB().GetErrorCode() & 0xff, 50);
558 } 572 }
559 } 573 }
560 574
561 int DownloadDatabase::CountDownloads() { 575 int DownloadDatabase::CountDownloads() {
576 EnsureInProgressEntriesCleanedUp();
577
562 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 578 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
563 "SELECT count(*) from downloads")); 579 "SELECT count(*) from downloads"));
564 statement.Step(); 580 statement.Step();
565 return statement.ColumnInt(0); 581 return statement.ColumnInt(0);
566 } 582 }
567 583
568 } // namespace history 584 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/download_database.h ('k') | chrome/browser/history/history_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698