| 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 |