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/bind.h" | |
11 #include "base/debug/alias.h" | 12 #include "base/debug/alias.h" |
12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
13 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/message_loop.h" | |
14 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
15 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
16 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
17 #include "base/time.h" | 19 #include "base/time.h" |
18 #include "base/utf_string_conversions.h" | 20 #include "base/utf_string_conversions.h" |
19 #include "build/build_config.h" | 21 #include "build/build_config.h" |
20 #include "chrome/browser/history/download_row.h" | 22 #include "chrome/browser/history/download_row.h" |
21 #include "chrome/browser/history/history_types.h" | 23 #include "chrome/browser/history/history_types.h" |
22 #include "content/public/browser/download_interrupt_reasons.h" | 24 #include "content/public/browser/download_interrupt_reasons.h" |
23 #include "content/public/browser/download_item.h" | |
24 #include "sql/statement.h" | 25 #include "sql/statement.h" |
25 | 26 |
26 using content::DownloadItem; | 27 using content::DownloadItem; |
27 | 28 |
28 namespace history { | 29 namespace history { |
29 | 30 |
30 // static | 31 // static |
31 const int64 DownloadDatabase::kUninitializedHandle = -1; | 32 const int64 DownloadDatabase::kUninitializedHandle = -1; |
32 | 33 |
34 // These constants and the transformation functions below are used to allow | |
35 // DownloadItem::DownloadState and DownloadDangerType to change without | |
36 // breaking the database schema. | |
37 // They guarantee that the values of the |state| field in the database are one | |
38 // of the values returned by StateToInt, and that the values of the |state| | |
39 // field of the DownloadRows returned by QueryDownloads() are one of the values | |
40 // returned by IntToState(). | |
41 const int DownloadDatabase::kStateInvalid = -1; | |
42 const int DownloadDatabase::kStateInProgress = 0; | |
43 const int DownloadDatabase::kStateComplete = 1; | |
44 const int DownloadDatabase::kStateCancelled = 2; | |
45 const int DownloadDatabase::kStateBug140687 = 3; | |
46 const int DownloadDatabase::kStateInterrupted = 4; | |
47 | |
48 const int DownloadDatabase::kDangerTypeInvalid = -1; | |
49 const int DownloadDatabase::kDangerTypeNotDangerous = 0; | |
50 const int DownloadDatabase::kDangerTypeDangerousFile = 1; | |
51 const int DownloadDatabase::kDangerTypeDangerousUrl = 2; | |
52 const int DownloadDatabase::kDangerTypeDangerousContent = 3; | |
53 const int DownloadDatabase::kDangerTypeMaybeDangerousContent = 4; | |
54 const int DownloadDatabase::kDangerTypeUncommonContent = 5; | |
55 const int DownloadDatabase::kDangerTypeUserValidated = 6; | |
56 const int DownloadDatabase::kDangerTypeDangerousHost = 7; | |
57 | |
33 namespace { | 58 namespace { |
34 | 59 |
35 // Reason for dropping a particular record. | 60 // Reason for dropping a particular record. |
36 enum DroppedReason { | 61 enum DroppedReason { |
37 DROPPED_REASON_BAD_STATE = 0, | 62 DROPPED_REASON_BAD_STATE = 0, |
38 DROPPED_REASON_BAD_DANGER_TYPE = 1, | 63 DROPPED_REASON_BAD_DANGER_TYPE = 1, |
39 DROPPED_REASON_MAX | 64 DROPPED_REASON_MAX |
40 }; | 65 }; |
41 | 66 |
42 static const char kSchema[] = | 67 static const char kSchema[] = |
(...skipping 12 matching lines...) Expand all Loading... | |
55 | 80 |
56 static const char kUrlChainSchema[] = | 81 static const char kUrlChainSchema[] = |
57 "CREATE TABLE downloads_url_chains (" | 82 "CREATE TABLE downloads_url_chains (" |
58 "id INTEGER NOT NULL," // downloads.id. | 83 "id INTEGER NOT NULL," // downloads.id. |
59 "chain_index INTEGER NOT NULL," // Index of url in chain | 84 "chain_index INTEGER NOT NULL," // Index of url in chain |
60 // 0 is initial target, | 85 // 0 is initial target, |
61 // MAX is target after redirects. | 86 // MAX is target after redirects. |
62 "url LONGVARCHAR NOT NULL, " // URL. | 87 "url LONGVARCHAR NOT NULL, " // URL. |
63 "PRIMARY KEY (id, chain_index) )"; | 88 "PRIMARY KEY (id, chain_index) )"; |
64 | 89 |
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 int StateToInt(DownloadItem::DownloadState state) { |
90 switch (state) { | 91 switch (state) { |
91 case DownloadItem::IN_PROGRESS: return kStateInProgress; | 92 case DownloadItem::IN_PROGRESS: return DownloadDatabase::kStateInProgress; |
92 case DownloadItem::COMPLETE: return kStateComplete; | 93 case DownloadItem::COMPLETE: return DownloadDatabase::kStateComplete; |
93 case DownloadItem::CANCELLED: return kStateCancelled; | 94 case DownloadItem::CANCELLED: return DownloadDatabase::kStateCancelled; |
94 case DownloadItem::INTERRUPTED: return kStateInterrupted; | 95 case DownloadItem::INTERRUPTED: return DownloadDatabase::kStateInterrupted; |
95 case DownloadItem::MAX_DOWNLOAD_STATE: | 96 case DownloadItem::MAX_DOWNLOAD_STATE: |
96 NOTREACHED(); | 97 NOTREACHED(); |
97 return kStateInvalid; | 98 return DownloadDatabase::kStateInvalid; |
98 } | 99 } |
99 NOTREACHED(); | 100 NOTREACHED(); |
100 return kStateInvalid; | 101 return DownloadDatabase::kStateInvalid; |
101 } | 102 } |
102 | 103 |
103 DownloadItem::DownloadState IntToState(int state) { | 104 DownloadItem::DownloadState IntToState(int state) { |
104 switch (state) { | 105 switch (state) { |
105 case kStateInProgress: return DownloadItem::IN_PROGRESS; | 106 case DownloadDatabase::kStateInProgress: return DownloadItem::IN_PROGRESS; |
106 case kStateComplete: return DownloadItem::COMPLETE; | 107 case DownloadDatabase::kStateComplete: return DownloadItem::COMPLETE; |
107 case kStateCancelled: return DownloadItem::CANCELLED; | 108 case DownloadDatabase::kStateCancelled: return DownloadItem::CANCELLED; |
108 // We should not need kStateBug140687 here because MigrateDownloadsState() | 109 // We should not need kStateBug140687 here because MigrateDownloadsState() |
109 // is called in HistoryDatabase::Init(). | 110 // is called in HistoryDatabase::Init(). |
110 case kStateInterrupted: return DownloadItem::INTERRUPTED; | 111 case DownloadDatabase::kStateInterrupted: return DownloadItem::INTERRUPTED; |
111 default: return DownloadItem::MAX_DOWNLOAD_STATE; | 112 default: return DownloadItem::MAX_DOWNLOAD_STATE; |
112 } | 113 } |
113 } | 114 } |
114 | 115 |
115 int DangerTypeToInt(content::DownloadDangerType danger_type) { | 116 int DangerTypeToInt(content::DownloadDangerType danger_type) { |
116 switch (danger_type) { | 117 switch (danger_type) { |
117 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: | 118 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: |
118 return kDangerTypeNotDangerous; | 119 return DownloadDatabase::kDangerTypeNotDangerous; |
119 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 120 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
120 return kDangerTypeDangerousFile; | 121 return DownloadDatabase::kDangerTypeDangerousFile; |
121 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 122 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
122 return kDangerTypeDangerousUrl; | 123 return DownloadDatabase::kDangerTypeDangerousUrl; |
123 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: | 124 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: |
124 return kDangerTypeDangerousContent; | 125 return DownloadDatabase::kDangerTypeDangerousContent; |
125 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: | 126 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: |
126 return kDangerTypeMaybeDangerousContent; | 127 return DownloadDatabase::kDangerTypeMaybeDangerousContent; |
127 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: | 128 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: |
128 return kDangerTypeUncommonContent; | 129 return DownloadDatabase::kDangerTypeUncommonContent; |
129 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: | 130 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: |
130 return kDangerTypeUserValidated; | 131 return DownloadDatabase::kDangerTypeUserValidated; |
131 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: | 132 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: |
132 return kDangerTypeDangerousHost; | 133 return DownloadDatabase::kDangerTypeDangerousHost; |
133 case content::DOWNLOAD_DANGER_TYPE_MAX: | 134 case content::DOWNLOAD_DANGER_TYPE_MAX: |
134 NOTREACHED(); | 135 NOTREACHED(); |
135 return kDangerTypeInvalid; | 136 return DownloadDatabase::kDangerTypeInvalid; |
136 } | 137 } |
137 NOTREACHED(); | 138 NOTREACHED(); |
138 return kDangerTypeInvalid; | 139 return DownloadDatabase::kDangerTypeInvalid; |
139 } | 140 } |
140 | 141 |
141 content::DownloadDangerType IntToDangerType(int danger_type) { | 142 content::DownloadDangerType IntToDangerType(int danger_type) { |
142 switch (danger_type) { | 143 switch (danger_type) { |
143 case kDangerTypeNotDangerous: | 144 case DownloadDatabase::kDangerTypeNotDangerous: |
144 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; | 145 return content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; |
145 case kDangerTypeDangerousFile: | 146 case DownloadDatabase::kDangerTypeDangerousFile: |
146 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; | 147 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; |
147 case kDangerTypeDangerousUrl: | 148 case DownloadDatabase::kDangerTypeDangerousUrl: |
148 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; | 149 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; |
149 case kDangerTypeDangerousContent: | 150 case DownloadDatabase::kDangerTypeDangerousContent: |
150 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT; | 151 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT; |
151 case kDangerTypeMaybeDangerousContent: | 152 case DownloadDatabase::kDangerTypeMaybeDangerousContent: |
152 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT; | 153 return content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT; |
153 case kDangerTypeUncommonContent: | 154 case DownloadDatabase::kDangerTypeUncommonContent: |
154 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT; | 155 return content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT; |
155 case kDangerTypeUserValidated: | 156 case DownloadDatabase::kDangerTypeUserValidated: |
156 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED; | 157 return content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED; |
157 case kDangerTypeDangerousHost: | 158 case DownloadDatabase::kDangerTypeDangerousHost: |
158 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST; | 159 return content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST; |
159 default: | 160 default: |
160 return content::DOWNLOAD_DANGER_TYPE_MAX; | 161 return content::DOWNLOAD_DANGER_TYPE_MAX; |
161 } | 162 } |
162 } | 163 } |
163 | 164 |
164 #if defined(OS_POSIX) | 165 #if defined(OS_POSIX) |
165 | 166 |
166 // Binds/reads the given file path to the given column of the given statement. | 167 // Binds/reads the given file path to the given column of the given statement. |
167 void BindFilePath(sql::Statement& statement, const base::FilePath& path, | 168 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 | 189 // Key in the meta_table containing the next id to use for a new download in |
189 // this profile. | 190 // this profile. |
190 static const char kNextDownloadId[] = "next_download_id"; | 191 static const char kNextDownloadId[] = "next_download_id"; |
191 | 192 |
192 } // namespace | 193 } // namespace |
193 | 194 |
194 DownloadDatabase::DownloadDatabase() | 195 DownloadDatabase::DownloadDatabase() |
195 : owning_thread_set_(false), | 196 : owning_thread_set_(false), |
196 owning_thread_(0), | 197 owning_thread_(0), |
197 next_id_(0), | 198 next_id_(0), |
198 next_db_handle_(0) { | 199 next_db_handle_(0), |
200 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
199 } | 201 } |
200 | 202 |
201 DownloadDatabase::~DownloadDatabase() { | 203 DownloadDatabase::~DownloadDatabase() { |
202 } | 204 } |
203 | 205 |
204 bool DownloadDatabase::EnsureColumnExists( | 206 bool DownloadDatabase::EnsureColumnExists( |
205 const std::string& name, const std::string& type) { | 207 const std::string& name, const std::string& type) { |
206 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type; | 208 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type; |
207 return GetDB().DoesColumnExist("downloads", name.c_str()) || | 209 return GetDB().DoesColumnExist("downloads", name.c_str()) || |
208 GetDB().Execute(add_col.c_str()); | 210 GetDB().Execute(add_col.c_str()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 std::set<int64> db_handles; | 291 std::set<int64> db_handles; |
290 | 292 |
291 std::map<DownloadID, DownloadRow*> info_map; | 293 std::map<DownloadID, DownloadRow*> info_map; |
292 | 294 |
293 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, | 295 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, |
294 "SELECT id, current_path, target_path, start_time, received_bytes, " | 296 "SELECT id, current_path, target_path, start_time, received_bytes, " |
295 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " | 297 "total_bytes, state, danger_type, interrupt_reason, end_time, opened " |
296 "FROM downloads " | 298 "FROM downloads " |
297 "ORDER BY start_time")); | 299 "ORDER BY start_time")); |
298 | 300 |
301 bool initiate_db_cleanup(false); | |
299 while (statement_main.Step()) { | 302 while (statement_main.Step()) { |
300 scoped_ptr<DownloadRow> info(new DownloadRow()); | 303 scoped_ptr<DownloadRow> info(new DownloadRow()); |
301 int column = 0; | 304 int column = 0; |
302 | 305 |
303 int db_handle = statement_main.ColumnInt64(column++); | 306 int db_handle = statement_main.ColumnInt64(column++); |
304 info->db_handle = db_handle; | 307 info->db_handle = db_handle; |
305 info->current_path = ColumnFilePath(statement_main, column++); | 308 info->current_path = ColumnFilePath(statement_main, column++); |
306 info->target_path = ColumnFilePath(statement_main, column++); | 309 info->target_path = ColumnFilePath(statement_main, column++); |
307 info->start_time = base::Time::FromInternalValue( | 310 info->start_time = base::Time::FromInternalValue( |
308 statement_main.ColumnInt64(column++)); | 311 statement_main.ColumnInt64(column++)); |
(...skipping 27 matching lines...) Expand all Loading... | |
336 reason = DROPPED_REASON_BAD_DANGER_TYPE; | 339 reason = DROPPED_REASON_BAD_DANGER_TYPE; |
337 else | 340 else |
338 NOTREACHED(); | 341 NOTREACHED(); |
339 | 342 |
340 UMA_HISTOGRAM_ENUMERATION( | 343 UMA_HISTOGRAM_ENUMERATION( |
341 "Download.DatabaseRecordDropped", reason, DROPPED_REASON_MAX + 1); | 344 "Download.DatabaseRecordDropped", reason, DROPPED_REASON_MAX + 1); |
342 | 345 |
343 continue; | 346 continue; |
344 } | 347 } |
345 | 348 |
349 // If the record is the result of a crash during an in-progress download, | |
350 // clean that record up and arrange for a separate task to be spawned to | |
351 // clean up the database. | |
352 if (content::DownloadItem::IN_PROGRESS == info->state) { | |
353 info->state = content::DownloadItem::INTERRUPTED; | |
354 info->interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_CRASH; | |
355 initiate_db_cleanup = true; | |
356 } | |
357 | |
346 DCHECK(!ContainsKey(info_map, info->db_handle)); | 358 DCHECK(!ContainsKey(info_map, info->db_handle)); |
347 info_map[db_handle] = info.release(); | 359 info_map[db_handle] = info.release(); |
348 } | 360 } |
349 | 361 |
350 sql::Statement statement_chain(GetDB().GetCachedStatement( | 362 sql::Statement statement_chain(GetDB().GetCachedStatement( |
351 SQL_FROM_HERE, | 363 SQL_FROM_HERE, |
352 "SELECT id, chain_index, url FROM downloads_url_chains " | 364 "SELECT id, chain_index, url FROM downloads_url_chains " |
353 "ORDER BY id, chain_index")); | 365 "ORDER BY id, chain_index")); |
354 | 366 |
355 while (statement_chain.Step()) { | 367 while (statement_chain.Step()) { |
(...skipping 28 matching lines...) Expand all Loading... | |
384 url_chain->push_back(GURL(statement_chain.ColumnString(2))); | 396 url_chain->push_back(GURL(statement_chain.ColumnString(2))); |
385 } | 397 } |
386 | 398 |
387 for (std::map<DownloadID, DownloadRow*>::iterator | 399 for (std::map<DownloadID, DownloadRow*>::iterator |
388 it = info_map.begin(); it != info_map.end(); ++it) { | 400 it = info_map.begin(); it != info_map.end(); ++it) { |
389 // Copy the contents of the stored info. | 401 // Copy the contents of the stored info. |
390 results->push_back(*it->second); | 402 results->push_back(*it->second); |
391 delete it->second; | 403 delete it->second; |
392 it->second = NULL; | 404 it->second = NULL; |
393 } | 405 } |
406 | |
407 if (initiate_db_cleanup) { | |
408 // Don't delay the return of the data. | |
409 MessageLoop::current()->PostTask( | |
410 FROM_HERE, base::Bind(&DownloadDatabase::CleanUpInProgressEntries, | |
411 weak_ptr_factory_.GetWeakPtr())); | |
412 } | |
394 } | 413 } |
395 | 414 |
396 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { | 415 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { |
397 DCHECK(data.db_handle > 0); | 416 DCHECK(data.db_handle > 0); |
398 int state = StateToInt(data.state); | 417 int state = StateToInt(data.state); |
399 if (state == kStateInvalid) { | 418 if (state == kStateInvalid) { |
400 NOTREACHED(); | 419 NOTREACHED(); |
401 return false; | 420 return false; |
402 } | 421 } |
403 int danger_type = DangerTypeToInt(data.danger_type); | 422 int danger_type = DangerTypeToInt(data.danger_type); |
(...skipping 15 matching lines...) Expand all Loading... | |
419 statement.BindInt(column++, danger_type); | 438 statement.BindInt(column++, danger_type); |
420 statement.BindInt(column++, static_cast<int>(data.interrupt_reason)); | 439 statement.BindInt(column++, static_cast<int>(data.interrupt_reason)); |
421 statement.BindInt64(column++, data.end_time.ToInternalValue()); | 440 statement.BindInt64(column++, data.end_time.ToInternalValue()); |
422 statement.BindInt(column++, data.total_bytes); | 441 statement.BindInt(column++, data.total_bytes); |
423 statement.BindInt(column++, (data.opened ? 1 : 0)); | 442 statement.BindInt(column++, (data.opened ? 1 : 0)); |
424 statement.BindInt64(column++, data.db_handle); | 443 statement.BindInt64(column++, data.db_handle); |
425 | 444 |
426 return statement.Run(); | 445 return statement.Run(); |
427 } | 446 } |
428 | 447 |
429 bool DownloadDatabase::CleanUpInProgressEntries() { | 448 void DownloadDatabase::CleanUpInProgressEntries() { |
430 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 449 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
431 "UPDATE downloads SET state=? WHERE state=?")); | 450 "UPDATE downloads SET state=?, interrupt_reason=? WHERE state=?")); |
432 statement.BindInt(0, kStateCancelled); | 451 statement.BindInt(0, kStateInterrupted); |
433 statement.BindInt(1, kStateInProgress); | 452 statement.BindInt(1, content::DOWNLOAD_INTERRUPT_REASON_CRASH); |
453 statement.BindInt(2, kStateInProgress); | |
434 | 454 |
435 return statement.Run(); | 455 statement.Run(); |
benjhayden
2013/03/27 19:38:14
Do you want to call HistoryBackend::ScheduleCommit
Randy Smith (Not in Mondays)
2013/03/27 19:40:00
I can't call that from inside DownloadDatabase. A
| |
436 } | 456 } |
437 | 457 |
438 int64 DownloadDatabase::CreateDownload( | 458 int64 DownloadDatabase::CreateDownload( |
439 const DownloadRow& info) { | 459 const DownloadRow& info) { |
440 if (next_db_handle_ == 0) { | 460 if (next_db_handle_ == 0) { |
441 // This is unlikely. All current known tests and users already call | 461 // This is unlikely. All current known tests and users already call |
442 // QueryDownloads() before CreateDownload(). | 462 // QueryDownloads() before CreateDownload(). |
443 std::vector<DownloadRow> results; | 463 std::vector<DownloadRow> results; |
444 QueryDownloads(&results); | 464 QueryDownloads(&results); |
445 CHECK_NE(0, next_db_handle_); | 465 CHECK_NE(0, next_db_handle_); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 } | 537 } |
518 | 538 |
519 int DownloadDatabase::CountDownloads() { | 539 int DownloadDatabase::CountDownloads() { |
520 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 540 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
521 "SELECT count(*) from downloads")); | 541 "SELECT count(*) from downloads")); |
522 statement.Step(); | 542 statement.Step(); |
523 return statement.ColumnInt(0); | 543 return statement.ColumnInt(0); |
524 } | 544 } |
525 | 545 |
526 } // namespace history | 546 } // namespace history |
OLD | NEW |