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

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

Issue 13044019: Clean up entries left by crashes in the DownloadDB. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/history/download_database.h ('k') | chrome/browser/history/history_backend.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/history/download_database.h" 5 #include "chrome/browser/history/download_database.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/history/download_database.h ('k') | chrome/browser/history/history_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698