OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |