Chromium Code Reviews| 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 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 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 | 30 // static |
| 31 const int64 DownloadDatabase::kUninitializedHandle = -1; | 31 const int64 DownloadDatabase::kUninitializedHandle = -1; |
| 32 | 32 |
| 33 // These constants and the transformation functions below are used to allow | |
| 34 // DownloadItem::DownloadState and DownloadDangerType to change without | |
| 35 // breaking the database schema. | |
| 36 // They guarantee that the values of the |state| field in the database are one | |
| 37 // of the values returned by StateToInt, and that the values of the |state| | |
| 38 // field of the DownloadRows returned by QueryDownloads() are one of the values | |
| 39 // returned by IntToState(). | |
| 40 const int DownloadDatabase::kStateInvalid = -1; | |
| 41 const int DownloadDatabase::kStateInProgress = 0; | |
| 42 const int DownloadDatabase::kStateComplete = 1; | |
| 43 const int DownloadDatabase::kStateCancelled = 2; | |
| 44 const int DownloadDatabase::kStateBug140687 = 3; | |
| 45 const int DownloadDatabase::kStateInterrupted = 4; | |
| 46 | |
| 47 const int DownloadDatabase::kDangerTypeInvalid = -1; | |
| 48 const int DownloadDatabase::kDangerTypeNotDangerous = 0; | |
| 49 const int DownloadDatabase::kDangerTypeDangerousFile = 1; | |
| 50 const int DownloadDatabase::kDangerTypeDangerousUrl = 2; | |
| 51 const int DownloadDatabase::kDangerTypeDangerousContent = 3; | |
| 52 const int DownloadDatabase::kDangerTypeMaybeDangerousContent = 4; | |
| 53 const int DownloadDatabase::kDangerTypeUncommonContent = 5; | |
| 54 const int DownloadDatabase::kDangerTypeUserValidated = 6; | |
| 55 const int DownloadDatabase::kDangerTypeDangerousHost = 7; | |
| 56 | |
| 33 namespace { | 57 namespace { |
| 34 | 58 |
| 35 // Reason for dropping a particular record. | 59 // Reason for dropping a particular record. |
| 36 enum DroppedReason { | 60 enum DroppedReason { |
| 37 DROPPED_REASON_BAD_STATE = 0, | 61 DROPPED_REASON_BAD_STATE = 0, |
| 38 DROPPED_REASON_BAD_DANGER_TYPE = 1, | 62 DROPPED_REASON_BAD_DANGER_TYPE = 1, |
| 39 DROPPED_REASON_MAX | 63 DROPPED_REASON_MAX |
| 40 }; | 64 }; |
| 41 | 65 |
| 42 static const char kSchema[] = | 66 static const char kSchema[] = |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 55 | 79 |
| 56 static const char kUrlChainSchema[] = | 80 static const char kUrlChainSchema[] = |
| 57 "CREATE TABLE downloads_url_chains (" | 81 "CREATE TABLE downloads_url_chains (" |
| 58 "id INTEGER NOT NULL," // downloads.id. | 82 "id INTEGER NOT NULL," // downloads.id. |
| 59 "chain_index INTEGER NOT NULL," // Index of url in chain | 83 "chain_index INTEGER NOT NULL," // Index of url in chain |
| 60 // 0 is initial target, | 84 // 0 is initial target, |
| 61 // MAX is target after redirects. | 85 // MAX is target after redirects. |
| 62 "url LONGVARCHAR NOT NULL, " // URL. | 86 "url LONGVARCHAR NOT NULL, " // URL. |
| 63 "PRIMARY KEY (id, chain_index) )"; | 87 "PRIMARY KEY (id, chain_index) )"; |
| 64 | 88 |
| 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) { | 89 int StateToInt(DownloadItem::DownloadState state) { |
| 90 switch (state) { | 90 switch (state) { |
| 91 case DownloadItem::IN_PROGRESS: return kStateInProgress; | 91 case DownloadItem::IN_PROGRESS: return DownloadDatabase::kStateInProgress; |
| 92 case DownloadItem::COMPLETE: return kStateComplete; | 92 case DownloadItem::COMPLETE: return DownloadDatabase::kStateComplete; |
| 93 case DownloadItem::CANCELLED: return kStateCancelled; | 93 case DownloadItem::CANCELLED: return DownloadDatabase::kStateCancelled; |
| 94 case DownloadItem::INTERRUPTED: return kStateInterrupted; | 94 case DownloadItem::INTERRUPTED: return DownloadDatabase::kStateInterrupted; |
| 95 case DownloadItem::MAX_DOWNLOAD_STATE: | 95 case DownloadItem::MAX_DOWNLOAD_STATE: |
| 96 NOTREACHED(); | 96 NOTREACHED(); |
| 97 return kStateInvalid; | 97 return DownloadDatabase::kStateInvalid; |
| 98 } | 98 } |
| 99 NOTREACHED(); | 99 NOTREACHED(); |
| 100 return kStateInvalid; | 100 return DownloadDatabase::kStateInvalid; |
| 101 } | 101 } |
| 102 | 102 |
| 103 DownloadItem::DownloadState IntToState(int state) { | 103 DownloadItem::DownloadState IntToState(int state) { |
| 104 switch (state) { | 104 switch (state) { |
| 105 case kStateInProgress: return DownloadItem::IN_PROGRESS; | 105 case DownloadDatabase::kStateInProgress: return DownloadItem::IN_PROGRESS; |
| 106 case kStateComplete: return DownloadItem::COMPLETE; | 106 case DownloadDatabase::kStateComplete: return DownloadItem::COMPLETE; |
| 107 case kStateCancelled: return DownloadItem::CANCELLED; | 107 case DownloadDatabase::kStateCancelled: return DownloadItem::CANCELLED; |
| 108 // We should not need kStateBug140687 here because MigrateDownloadsState() | 108 // We should not need kStateBug140687 here because MigrateDownloadsState() |
| 109 // is called in HistoryDatabase::Init(). | 109 // is called in HistoryDatabase::Init(). |
| 110 case kStateInterrupted: return DownloadItem::INTERRUPTED; | 110 case DownloadDatabase::kStateInterrupted: return DownloadItem::INTERRUPTED; |
| 111 default: return DownloadItem::MAX_DOWNLOAD_STATE; | 111 default: return DownloadItem::MAX_DOWNLOAD_STATE; |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 int DangerTypeToInt(content::DownloadDangerType danger_type) { | 115 int DangerTypeToInt(content::DownloadDangerType danger_type) { |
| 116 switch (danger_type) { | 116 switch (danger_type) { |
| 117 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: | 117 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: |
| 118 return kDangerTypeNotDangerous; | 118 return DownloadDatabase::kDangerTypeNotDangerous; |
| 119 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 119 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
| 120 return kDangerTypeDangerousFile; | 120 return DownloadDatabase::kDangerTypeDangerousFile; |
| 121 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 121 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
| 122 return kDangerTypeDangerousUrl; | 122 return DownloadDatabase::kDangerTypeDangerousUrl; |
| 123 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: | 123 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: |
| 124 return kDangerTypeDangerousContent; | 124 return DownloadDatabase::kDangerTypeDangerousContent; |
| 125 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: | 125 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: |
| 126 return kDangerTypeMaybeDangerousContent; | 126 return DownloadDatabase::kDangerTypeMaybeDangerousContent; |
| 127 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: | 127 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: |
| 128 return kDangerTypeUncommonContent; | 128 return DownloadDatabase::kDangerTypeUncommonContent; |
| 129 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: | 129 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: |
| 130 return kDangerTypeUserValidated; | 130 return DownloadDatabase::kDangerTypeUserValidated; |
| 131 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: | 131 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: |
| 132 return kDangerTypeDangerousHost; | 132 return DownloadDatabase::kDangerTypeDangerousHost; |
| 133 case content::DOWNLOAD_DANGER_TYPE_MAX: | 133 case content::DOWNLOAD_DANGER_TYPE_MAX: |
| 134 NOTREACHED(); | 134 NOTREACHED(); |
| 135 return kDangerTypeInvalid; | 135 return DownloadDatabase::kDangerTypeInvalid; |
| 136 } | 136 } |
| 137 NOTREACHED(); | 137 NOTREACHED(); |
| 138 return kDangerTypeInvalid; | 138 return DownloadDatabase::kDangerTypeInvalid; |
| 139 } | 139 } |
| 140 | 140 |
| 141 content::DownloadDangerType IntToDangerType(int danger_type) { | 141 content::DownloadDangerType IntToDangerType(int danger_type) { |
| 142 switch (danger_type) { | 142 switch (danger_type) { |
| 143 case kDangerTypeNotDangerous: | 143 case DownloadDatabase::kDangerTypeNotDangerous: |
| 144 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; | 144 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; |
| 145 case kDangerTypeDangerousFile: | 145 case DownloadDatabase::kDangerTypeDangerousFile: |
| 146 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; | 146 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; |
| 147 case kDangerTypeDangerousUrl: | 147 case DownloadDatabase::kDangerTypeDangerousUrl: |
| 148 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; | 148 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; |
| 149 case kDangerTypeDangerousContent: | 149 case DownloadDatabase::kDangerTypeDangerousContent: |
| 150 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT; | 150 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT; |
| 151 case kDangerTypeMaybeDangerousContent: | 151 case DownloadDatabase::kDangerTypeMaybeDangerousContent: |
| 152 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT; | 152 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT; |
| 153 case kDangerTypeUncommonContent: | 153 case DownloadDatabase::kDangerTypeUncommonContent: |
| 154 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT; | 154 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT; |
| 155 case kDangerTypeUserValidated: | 155 case DownloadDatabase::kDangerTypeUserValidated: |
| 156 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED; | 156 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED; |
| 157 case kDangerTypeDangerousHost: | 157 case DownloadDatabase::kDangerTypeDangerousHost: |
| 158 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST; | 158 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST; |
| 159 default: | 159 default: |
| 160 return content::DOWNLOAD_DANGER_TYPE_MAX; | 160 return content::DOWNLOAD_DANGER_TYPE_MAX; |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 #if defined(OS_POSIX) | 164 #if defined(OS_POSIX) |
| 165 | 165 |
| 166 // Binds/reads the given file path to the given column of the given statement. | 166 // Binds/reads the given file path to the given column of the given statement. |
| 167 void BindFilePath(sql::Statement& statement, const base::FilePath& path, | 167 void BindFilePath(sql::Statement& statement, const base::FilePath& path, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 188 // Key in the meta_table containing the next id to use for a new download in | 188 // Key in the meta_table containing the next id to use for a new download in |
| 189 // this profile. | 189 // this profile. |
| 190 static const char kNextDownloadId[] = "next_download_id"; | 190 static const char kNextDownloadId[] = "next_download_id"; |
| 191 | 191 |
| 192 } // namespace | 192 } // namespace |
| 193 | 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 if (!in_progress_entry_cleanup_completed_) | |
| 288 CleanUpInProgressEntries(); | |
| 289 | |
| 286 results->clear(); | 290 results->clear(); |
| 287 if (next_db_handle_ < 1) | 291 if (next_db_handle_ < 1) |
| 288 next_db_handle_ = 1; | 292 next_db_handle_ = 1; |
| 289 std::set<int64> db_handles; | 293 std::set<int64> db_handles; |
| 290 | 294 |
| 291 std::map<DownloadID, DownloadRow*> info_map; | 295 std::map<DownloadID, DownloadRow*> info_map; |
| 292 | 296 |
| 293 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, | 297 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 294 "SELECT id, current_path, target_path, start_time, received_bytes, " | 298 "SELECT id, current_path, target_path, start_time, received_bytes, " |
| 295 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " | 299 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 for (std::map<DownloadID, DownloadRow*>::iterator | 391 for (std::map<DownloadID, DownloadRow*>::iterator |
| 388 it = info_map.begin(); it != info_map.end(); ++it) { | 392 it = info_map.begin(); it != info_map.end(); ++it) { |
| 389 // Copy the contents of the stored info. | 393 // Copy the contents of the stored info. |
| 390 results->push_back(*it->second); | 394 results->push_back(*it->second); |
| 391 delete it->second; | 395 delete it->second; |
| 392 it->second = NULL; | 396 it->second = NULL; |
| 393 } | 397 } |
| 394 } | 398 } |
| 395 | 399 |
| 396 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { | 400 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { |
| 401 if (!in_progress_entry_cleanup_completed_) | |
| 402 CleanUpInProgressEntries(); | |
| 403 | |
| 397 DCHECK(data.db_handle > 0); | 404 DCHECK(data.db_handle > 0); |
| 398 int state = StateToInt(data.state); | 405 int state = StateToInt(data.state); |
| 399 if (state == kStateInvalid) { | 406 if (state == kStateInvalid) { |
| 400 NOTREACHED(); | 407 NOTREACHED(); |
| 401 return false; | 408 return false; |
| 402 } | 409 } |
| 403 int danger_type = DangerTypeToInt(data.danger_type); | 410 int danger_type = DangerTypeToInt(data.danger_type); |
| 404 if (danger_type == kDangerTypeInvalid) { | 411 if (danger_type == kDangerTypeInvalid) { |
| 405 NOTREACHED(); | 412 NOTREACHED(); |
| 406 return false; | 413 return false; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 419 statement.BindInt(column++, danger_type); | 426 statement.BindInt(column++, danger_type); |
| 420 statement.BindInt(column++, static_cast<int>(data.interrupt_reason)); | 427 statement.BindInt(column++, static_cast<int>(data.interrupt_reason)); |
| 421 statement.BindInt64(column++, data.end_time.ToInternalValue()); | 428 statement.BindInt64(column++, data.end_time.ToInternalValue()); |
| 422 statement.BindInt(column++, data.total_bytes); | 429 statement.BindInt(column++, data.total_bytes); |
| 423 statement.BindInt(column++, (data.opened ? 1 : 0)); | 430 statement.BindInt(column++, (data.opened ? 1 : 0)); |
| 424 statement.BindInt64(column++, data.db_handle); | 431 statement.BindInt64(column++, data.db_handle); |
| 425 | 432 |
| 426 return statement.Run(); | 433 return statement.Run(); |
| 427 } | 434 } |
| 428 | 435 |
| 429 bool DownloadDatabase::CleanUpInProgressEntries() { | 436 void DownloadDatabase::CleanUpInProgressEntries() { |
|
brettw
2013/04/01 23:52:51
I sort of prefer the scheme where the function is
Randy Smith (Not in Mondays)
2013/04/02 18:58:52
Done.
| |
| 430 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 437 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 431 "UPDATE downloads SET state=? WHERE state=?")); | 438 "UPDATE downloads SET state=?, interrupt_reason=? WHERE state=?")); |
| 432 statement.BindInt(0, kStateCancelled); | 439 statement.BindInt(0, kStateInterrupted); |
| 433 statement.BindInt(1, kStateInProgress); | 440 statement.BindInt(1, content::DOWNLOAD_INTERRUPT_REASON_CRASH); |
| 441 statement.BindInt(2, kStateInProgress); | |
| 434 | 442 |
| 435 return statement.Run(); | 443 statement.Run(); |
| 444 in_progress_entry_cleanup_completed_ = true; | |
| 436 } | 445 } |
| 437 | 446 |
| 438 int64 DownloadDatabase::CreateDownload( | 447 int64 DownloadDatabase::CreateDownload( |
| 439 const DownloadRow& info) { | 448 const DownloadRow& info) { |
| 449 if (!in_progress_entry_cleanup_completed_) | |
| 450 CleanUpInProgressEntries(); | |
| 451 | |
| 440 if (next_db_handle_ == 0) { | 452 if (next_db_handle_ == 0) { |
| 441 // This is unlikely. All current known tests and users already call | 453 // This is unlikely. All current known tests and users already call |
| 442 // QueryDownloads() before CreateDownload(). | 454 // QueryDownloads() before CreateDownload(). |
| 443 std::vector<DownloadRow> results; | 455 std::vector<DownloadRow> results; |
| 444 QueryDownloads(&results); | 456 QueryDownloads(&results); |
| 445 CHECK_NE(0, next_db_handle_); | 457 CHECK_NE(0, next_db_handle_); |
| 446 } | 458 } |
| 447 | 459 |
| 448 int state = StateToInt(info.state); | 460 int state = StateToInt(info.state); |
| 449 if (state == kStateInvalid) | 461 if (state == kStateInvalid) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 statement_insert_chain.Reset(true); | 510 statement_insert_chain.Reset(true); |
| 499 } | 511 } |
| 500 | 512 |
| 501 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} | 513 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} |
| 502 GetMetaTable().SetValue(kNextDownloadId, ++next_id_); | 514 GetMetaTable().SetValue(kNextDownloadId, ++next_id_); |
| 503 | 515 |
| 504 return db_handle; | 516 return db_handle; |
| 505 } | 517 } |
| 506 | 518 |
| 507 void DownloadDatabase::RemoveDownload(int64 handle) { | 519 void DownloadDatabase::RemoveDownload(int64 handle) { |
| 520 if (!in_progress_entry_cleanup_completed_) | |
| 521 CleanUpInProgressEntries(); | |
| 522 | |
| 508 sql::Statement downloads_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 523 sql::Statement downloads_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 509 "DELETE FROM downloads WHERE id=?")); | 524 "DELETE FROM downloads WHERE id=?")); |
| 510 downloads_statement.BindInt64(0, handle); | 525 downloads_statement.BindInt64(0, handle); |
| 511 downloads_statement.Run(); | 526 downloads_statement.Run(); |
| 512 | 527 |
| 513 sql::Statement urlchain_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 528 sql::Statement urlchain_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 514 "DELETE FROM downloads_url_chains WHERE id=?")); | 529 "DELETE FROM downloads_url_chains WHERE id=?")); |
| 515 urlchain_statement.BindInt64(0, handle); | 530 urlchain_statement.BindInt64(0, handle); |
| 516 urlchain_statement.Run(); | 531 urlchain_statement.Run(); |
| 517 } | 532 } |
| 518 | 533 |
| 519 int DownloadDatabase::CountDownloads() { | 534 int DownloadDatabase::CountDownloads() { |
| 535 if (!in_progress_entry_cleanup_completed_) | |
| 536 CleanUpInProgressEntries(); | |
| 537 | |
| 520 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 538 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 521 "SELECT count(*) from downloads")); | 539 "SELECT count(*) from downloads")); |
| 522 statement.Step(); | 540 statement.Step(); |
| 523 return statement.ColumnInt(0); | 541 return statement.ColumnInt(0); |
| 524 } | 542 } |
| 525 | 543 |
| 526 } // namespace history | 544 } // namespace history |
| OLD | NEW |