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

Side by Side Diff: components/history/core/browser/download_database.cc

Issue 1781983002: [Downloads] Introduce GUIDs for downloads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 9 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
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 "components/history/core/browser/download_database.h" 5 #include "components/history/core/browser/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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 bool DownloadDatabase::MigrateDownloadedByExtension() { 179 bool DownloadDatabase::MigrateDownloadedByExtension() {
180 return EnsureColumnExists("by_ext_id", "VARCHAR NOT NULL DEFAULT \"\"") && 180 return EnsureColumnExists("by_ext_id", "VARCHAR NOT NULL DEFAULT \"\"") &&
181 EnsureColumnExists("by_ext_name", "VARCHAR NOT NULL DEFAULT \"\""); 181 EnsureColumnExists("by_ext_name", "VARCHAR NOT NULL DEFAULT \"\"");
182 } 182 }
183 183
184 bool DownloadDatabase::MigrateDownloadValidators() { 184 bool DownloadDatabase::MigrateDownloadValidators() {
185 return EnsureColumnExists("etag", "VARCHAR NOT NULL DEFAULT \"\"") && 185 return EnsureColumnExists("etag", "VARCHAR NOT NULL DEFAULT \"\"") &&
186 EnsureColumnExists("last_modified", "VARCHAR NOT NULL DEFAULT \"\""); 186 EnsureColumnExists("last_modified", "VARCHAR NOT NULL DEFAULT \"\"");
187 } 187 }
188 188
189 bool DownloadDatabase::MigrateHashHttpMethodAndGenerateGuids() {
190 if (!EnsureColumnExists("guid", "VARCHAR NOT NULL DEFAULT ''") ||
191 !EnsureColumnExists("hash", "BLOB NOT NULL DEFAULT X''") ||
192 !EnsureColumnExists("http_method", "VARCHAR NOT NULL DEFAULT ''"))
193 return false;
194
195 // Generate GUIDs for each download. The GUID is generated thusly:
196 //
197 // XXXXXXXX-RRRR-RRRR-RRRR-RRRRRRRRRRRR
198 // \__ __/ \___________ ____________/
199 // \/ \/
200 // | Random hex digits
201 // |
202 // Hex representation of 32-bit download ID.
203 //
204 // The 96 random bits provide entropy while the 32-bits from the download ID
205 // ensure that the generated identifiers will at least be unique amongst the
206 // download rows in the unlikely event there's a collision in the 96 entropy
207 // bits.
208 //
209 // This GUID generation scheme is only used for migrated download rows and
210 // assumes that the likelihood of a collision with a GUID generated via
211 // base::GenerateGUID() will be vanishingly small.
212 const char kMigrateGuidsQuery[] =
213 "UPDATE downloads SET guid = printf"
214 "(\"%08X-%s-%s-%s-%s\", id, hex(randomblob(2)), hex(randomblob(2)),"
215 " hex(randomblob(2)), hex(randomblob(6)))";
216 return GetDB().Execute(kMigrateGuidsQuery);
217 }
218
189 bool DownloadDatabase::InitDownloadTable() { 219 bool DownloadDatabase::InitDownloadTable() {
190 const char kSchema[] = 220 const char kSchema[] =
191 "CREATE TABLE downloads (" 221 "CREATE TABLE downloads ("
192 "id INTEGER PRIMARY KEY," // Primary key. 222 "id INTEGER PRIMARY KEY," // Primary key.
223 "guid VARCHAR NOT NULL," // GUID.
193 "current_path LONGVARCHAR NOT NULL," // Current disk location 224 "current_path LONGVARCHAR NOT NULL," // Current disk location
194 "target_path LONGVARCHAR NOT NULL," // Final disk location 225 "target_path LONGVARCHAR NOT NULL," // Final disk location
195 "start_time INTEGER NOT NULL," // When the download was started. 226 "start_time INTEGER NOT NULL," // When the download was started.
196 "received_bytes INTEGER NOT NULL," // Total size downloaded. 227 "received_bytes INTEGER NOT NULL," // Total size downloaded.
197 "total_bytes INTEGER NOT NULL," // Total size of the download. 228 "total_bytes INTEGER NOT NULL," // Total size of the download.
198 "state INTEGER NOT NULL," // 1=complete, 4=interrupted 229 "state INTEGER NOT NULL," // 1=complete, 4=interrupted
199 "danger_type INTEGER NOT NULL," // Danger type, validated. 230 "danger_type INTEGER NOT NULL," // Danger type, validated.
200 "interrupt_reason INTEGER NOT NULL," // DownloadInterruptReason 231 "interrupt_reason INTEGER NOT NULL," // DownloadInterruptReason
232 "hash BLOB NOT NULL," // Raw SHA-256 hash of contents.
201 "end_time INTEGER NOT NULL," // When the download completed. 233 "end_time INTEGER NOT NULL," // When the download completed.
202 "opened INTEGER NOT NULL," // 1 if it has ever been opened 234 "opened INTEGER NOT NULL," // 1 if it has ever been opened
203 // else 0 235 // else 0
204 "referrer VARCHAR NOT NULL," // HTTP Referrer 236 "referrer VARCHAR NOT NULL," // HTTP Referrer
237 "http_method VARCHAR NOT NULL," // HTTP method.
205 "by_ext_id VARCHAR NOT NULL," // ID of extension that started the 238 "by_ext_id VARCHAR NOT NULL," // ID of extension that started the
206 // download 239 // download
207 "by_ext_name VARCHAR NOT NULL," // name of extension 240 "by_ext_name VARCHAR NOT NULL," // name of extension
208 "etag VARCHAR NOT NULL," // ETag 241 "etag VARCHAR NOT NULL," // ETag
209 "last_modified VARCHAR NOT NULL," // Last-Modified header 242 "last_modified VARCHAR NOT NULL," // Last-Modified header
210 "mime_type VARCHAR(255) NOT NULL," // MIME type. 243 "mime_type VARCHAR(255) NOT NULL," // MIME type.
211 "original_mime_type VARCHAR(255) NOT NULL)"; // Original MIME type. 244 "original_mime_type VARCHAR(255) NOT NULL)"; // Original MIME type.
212 245
213 const char kUrlChainSchema[] = 246 const char kUrlChainSchema[] =
214 "CREATE TABLE downloads_url_chains (" 247 "CREATE TABLE downloads_url_chains ("
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 return 1 + static_cast<uint32_t>( 283 return 1 + static_cast<uint32_t>(
251 std::max(static_cast<int64_t>(kInvalidDownloadId), 284 std::max(static_cast<int64_t>(kInvalidDownloadId),
252 select_max_id.ColumnInt64(0))); 285 select_max_id.ColumnInt64(0)));
253 } 286 }
254 287
255 bool DownloadDatabase::DropDownloadTable() { 288 bool DownloadDatabase::DropDownloadTable() {
256 return GetDB().Execute("DROP TABLE downloads"); 289 return GetDB().Execute("DROP TABLE downloads");
257 } 290 }
258 291
259 void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) { 292 void DownloadDatabase::QueryDownloads(std::vector<DownloadRow>* results) {
293 SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.QueryDownloadDuration");
260 EnsureInProgressEntriesCleanedUp(); 294 EnsureInProgressEntriesCleanedUp();
261 295
262 results->clear(); 296 results->clear();
263 std::set<uint32_t> ids; 297 std::set<uint32_t> ids;
264 298
265 std::map<uint32_t, DownloadRow*> info_map; 299 std::map<uint32_t, DownloadRow*> info_map;
266 300
267 sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE, 301 sql::Statement statement_main(GetDB().GetCachedStatement(
268 "SELECT id, current_path, target_path, " 302 SQL_FROM_HERE,
269 "mime_type, original_mime_type, " 303 "SELECT id, guid, current_path, target_path, mime_type, "
270 "start_time, received_bytes, " 304 "original_mime_type, start_time, received_bytes, total_bytes, state, "
271 "total_bytes, state, danger_type, interrupt_reason, end_time, opened, " 305 "danger_type, interrupt_reason, hash, end_time, opened, referrer, "
272 "referrer, by_ext_id, by_ext_name, etag, last_modified " 306 "http_method, by_ext_id, by_ext_name, etag, last_modified "
273 "FROM downloads ORDER BY start_time")); 307 "FROM downloads ORDER BY start_time"));
274 308
275 while (statement_main.Step()) { 309 while (statement_main.Step()) {
276 scoped_ptr<DownloadRow> info(new DownloadRow()); 310 scoped_ptr<DownloadRow> info(new DownloadRow());
277 int column = 0; 311 int column = 0;
278 312
279 // SQLITE does not have unsigned integers, so explicitly handle negative 313 // SQLITE does not have unsigned integers, so explicitly handle negative
280 // |id|s instead of casting them to very large uint32s, which would break 314 // |id|s instead of casting them to very large uint32s, which would break
281 // the max(id) logic in GetNextDownloadId(). 315 // the max(id) logic in GetNextDownloadId().
282 int64_t signed_id = statement_main.ColumnInt64(column++); 316 int64_t signed_id = statement_main.ColumnInt64(column++);
283 info->id = IntToDownloadId(signed_id); 317 info->id = IntToDownloadId(signed_id);
318 info->guid = statement_main.ColumnString(column++);
284 info->current_path = ColumnFilePath(statement_main, column++); 319 info->current_path = ColumnFilePath(statement_main, column++);
285 info->target_path = ColumnFilePath(statement_main, column++); 320 info->target_path = ColumnFilePath(statement_main, column++);
286 info->mime_type = statement_main.ColumnString(column++); 321 info->mime_type = statement_main.ColumnString(column++);
287 info->original_mime_type = statement_main.ColumnString(column++); 322 info->original_mime_type = statement_main.ColumnString(column++);
288 info->start_time = 323 info->start_time =
289 base::Time::FromInternalValue(statement_main.ColumnInt64(column++)); 324 base::Time::FromInternalValue(statement_main.ColumnInt64(column++));
290 info->received_bytes = statement_main.ColumnInt64(column++); 325 info->received_bytes = statement_main.ColumnInt64(column++);
291 info->total_bytes = statement_main.ColumnInt64(column++); 326 info->total_bytes = statement_main.ColumnInt64(column++);
292 int state = statement_main.ColumnInt(column++); 327 int state = statement_main.ColumnInt(column++);
293 info->state = IntToDownloadState(state); 328 info->state = IntToDownloadState(state);
294 if (info->state == DownloadState::INVALID) 329 if (info->state == DownloadState::INVALID)
295 UMA_HISTOGRAM_COUNTS("Download.DatabaseInvalidState", state); 330 UMA_HISTOGRAM_COUNTS("Download.DatabaseInvalidState", state);
296 info->danger_type = 331 info->danger_type =
297 IntToDownloadDangerType(statement_main.ColumnInt(column++)); 332 IntToDownloadDangerType(statement_main.ColumnInt(column++));
298 info->interrupt_reason = 333 info->interrupt_reason =
299 IntToDownloadInterruptReason(statement_main.ColumnInt(column++)); 334 IntToDownloadInterruptReason(statement_main.ColumnInt(column++));
335 statement_main.ColumnBlobAsString(column++, &info->hash);
300 info->end_time = 336 info->end_time =
301 base::Time::FromInternalValue(statement_main.ColumnInt64(column++)); 337 base::Time::FromInternalValue(statement_main.ColumnInt64(column++));
302 info->opened = statement_main.ColumnInt(column++) != 0; 338 info->opened = statement_main.ColumnInt(column++) != 0;
303 info->referrer_url = GURL(statement_main.ColumnString(column++)); 339 info->referrer_url = GURL(statement_main.ColumnString(column++));
340 info->http_method = statement_main.ColumnString(column++);
304 info->by_ext_id = statement_main.ColumnString(column++); 341 info->by_ext_id = statement_main.ColumnString(column++);
305 info->by_ext_name = statement_main.ColumnString(column++); 342 info->by_ext_name = statement_main.ColumnString(column++);
306 info->etag = statement_main.ColumnString(column++); 343 info->etag = statement_main.ColumnString(column++);
307 info->last_modified = statement_main.ColumnString(column++); 344 info->last_modified = statement_main.ColumnString(column++);
308 345
309 // If the record is corrupted, note that and drop it. 346 // If the record is corrupted, note that and drop it.
310 // http://crbug.com/251269 347 // http://crbug.com/251269
311 DroppedReason dropped_reason = DROPPED_REASON_MAX; 348 DroppedReason dropped_reason = DROPPED_REASON_MAX;
312 if (signed_id <= static_cast<int64_t>(kInvalidDownloadId)) { 349 if (signed_id <= static_cast<int64_t>(kInvalidDownloadId)) {
313 // SQLITE doesn't have unsigned integers. 350 // SQLITE doesn't have unsigned integers.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } else { 420 } else {
384 // Copy the contents of the stored info. 421 // Copy the contents of the stored info.
385 results->push_back(*row); 422 results->push_back(*row);
386 } 423 }
387 delete row; 424 delete row;
388 it->second = NULL; 425 it->second = NULL;
389 } 426 }
390 } 427 }
391 428
392 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) { 429 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
430 // UpdateDownload() is called fairly frequently.
431 SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.UpdateDownloadDuration");
393 EnsureInProgressEntriesCleanedUp(); 432 EnsureInProgressEntriesCleanedUp();
394 433
395 DCHECK_NE(kInvalidDownloadId, data.id); 434 DCHECK_NE(kInvalidDownloadId, data.id);
396 if (data.state == DownloadState::INVALID) { 435 if (data.state == DownloadState::INVALID) {
397 NOTREACHED(); 436 NOTREACHED();
398 return false; 437 return false;
399 } 438 }
400 if (data.danger_type == DownloadDangerType::INVALID) { 439 if (data.danger_type == DownloadDangerType::INVALID) {
401 NOTREACHED(); 440 NOTREACHED();
402 return false; 441 return false;
403 } 442 }
404 443
405 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 444 sql::Statement statement(GetDB().GetCachedStatement(
445 SQL_FROM_HERE,
406 "UPDATE downloads " 446 "UPDATE downloads "
407 "SET current_path=?, target_path=?, " 447 "SET current_path=?, target_path=?, "
408 "mime_type=?, original_mime_type=?, " 448 "mime_type=?, original_mime_type=?, "
409 "received_bytes=?, state=?, " 449 "received_bytes=?, state=?, "
410 "danger_type=?, interrupt_reason=?, end_time=?, total_bytes=?, " 450 "danger_type=?, interrupt_reason=?, hash=?, end_time=?, total_bytes=?, "
411 "opened=?, by_ext_id=?, by_ext_name=?, etag=?, last_modified=? " 451 "opened=?, by_ext_id=?, by_ext_name=?, etag=?, last_modified=? "
412 "WHERE id=?")); 452 "WHERE id=?"));
413 int column = 0; 453 int column = 0;
414 BindFilePath(statement, data.current_path, column++); 454 BindFilePath(statement, data.current_path, column++);
415 BindFilePath(statement, data.target_path, column++); 455 BindFilePath(statement, data.target_path, column++);
416 statement.BindString(column++, data.mime_type); 456 statement.BindString(column++, data.mime_type);
417 statement.BindString(column++, data.original_mime_type); 457 statement.BindString(column++, data.original_mime_type);
418 statement.BindInt64(column++, data.received_bytes); 458 statement.BindInt64(column++, data.received_bytes);
419 statement.BindInt(column++, DownloadStateToInt(data.state)); 459 statement.BindInt(column++, DownloadStateToInt(data.state));
420 statement.BindInt(column++, DownloadDangerTypeToInt(data.danger_type)); 460 statement.BindInt(column++, DownloadDangerTypeToInt(data.danger_type));
421 statement.BindInt(column++, 461 statement.BindInt(column++,
422 DownloadInterruptReasonToInt(data.interrupt_reason)); 462 DownloadInterruptReasonToInt(data.interrupt_reason));
463 statement.BindBlob(column++, data.hash.data(), data.hash.size());
423 statement.BindInt64(column++, data.end_time.ToInternalValue()); 464 statement.BindInt64(column++, data.end_time.ToInternalValue());
424 statement.BindInt64(column++, data.total_bytes); 465 statement.BindInt64(column++, data.total_bytes);
425 statement.BindInt(column++, (data.opened ? 1 : 0)); 466 statement.BindInt(column++, (data.opened ? 1 : 0));
426 statement.BindString(column++, data.by_ext_id); 467 statement.BindString(column++, data.by_ext_id);
427 statement.BindString(column++, data.by_ext_name); 468 statement.BindString(column++, data.by_ext_name);
428 statement.BindString(column++, data.etag); 469 statement.BindString(column++, data.etag);
429 statement.BindString(column++, data.last_modified); 470 statement.BindString(column++, data.last_modified);
430 statement.BindInt(column++, DownloadIdToInt(data.id)); 471 statement.BindInt(column++, DownloadIdToInt(data.id));
431 472
432 return statement.Run(); 473 return statement.Run();
433 } 474 }
434 475
435 void DownloadDatabase::EnsureInProgressEntriesCleanedUp() { 476 void DownloadDatabase::EnsureInProgressEntriesCleanedUp() {
436 if (in_progress_entry_cleanup_completed_) 477 if (in_progress_entry_cleanup_completed_)
437 return; 478 return;
438 479
439 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 480 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
440 "UPDATE downloads SET state=?, interrupt_reason=? WHERE state=?")); 481 "UPDATE downloads SET state=?, interrupt_reason=? WHERE state=?"));
441 statement.BindInt(0, DownloadStateToInt(DownloadState::INTERRUPTED)); 482 statement.BindInt(0, DownloadStateToInt(DownloadState::INTERRUPTED));
442 statement.BindInt( 483 statement.BindInt(
443 1, DownloadInterruptReasonToInt(download_interrupt_reason_crash_)); 484 1, DownloadInterruptReasonToInt(download_interrupt_reason_crash_));
444 statement.BindInt(2, DownloadStateToInt(DownloadState::IN_PROGRESS)); 485 statement.BindInt(2, DownloadStateToInt(DownloadState::IN_PROGRESS));
445 486
446 statement.Run(); 487 statement.Run();
447 in_progress_entry_cleanup_completed_ = true; 488 in_progress_entry_cleanup_completed_ = true;
448 } 489 }
449 490
450 bool DownloadDatabase::CreateDownload(const DownloadRow& info) { 491 bool DownloadDatabase::CreateDownload(const DownloadRow& info) {
451 DCHECK_NE(kInvalidDownloadId, info.id); 492 DCHECK_NE(kInvalidDownloadId, info.id);
493 DCHECK(!info.guid.empty());
494 SCOPED_UMA_HISTOGRAM_TIMER("Download.Database.CreateDownloadDuration");
452 EnsureInProgressEntriesCleanedUp(); 495 EnsureInProgressEntriesCleanedUp();
453 496
454 if (info.url_chain.empty()) 497 if (info.url_chain.empty())
455 return false; 498 return false;
456 499
457 if (info.state == DownloadState::INVALID) 500 if (info.state == DownloadState::INVALID)
458 return false; 501 return false;
459 502
460 if (info.danger_type == DownloadDangerType::INVALID) 503 if (info.danger_type == DownloadDangerType::INVALID)
461 return false; 504 return false;
462 505
463 { 506 {
464 sql::Statement statement_insert(GetDB().GetCachedStatement( 507 sql::Statement statement_insert(GetDB().GetCachedStatement(
465 SQL_FROM_HERE, 508 SQL_FROM_HERE,
466 "INSERT INTO downloads " 509 "INSERT INTO downloads "
467 "(id, current_path, target_path, " 510 "(id, guid, current_path, target_path, mime_type, original_mime_type, "
468 " mime_type, original_mime_type, " 511 " start_time, received_bytes, total_bytes, state, danger_type, "
469 " start_time, " 512 " interrupt_reason, hash, end_time, opened, referrer, http_method, "
470 " received_bytes, total_bytes, state, danger_type, interrupt_reason, " 513 " by_ext_id, by_ext_name, etag, last_modified) "
471 " end_time, opened, referrer, by_ext_id, by_ext_name, etag, " 514 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
472 " last_modified) " 515 " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
473 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 516 " ?)"));
474 517
475 int column = 0; 518 int column = 0;
476 statement_insert.BindInt(column++, DownloadIdToInt(info.id)); 519 statement_insert.BindInt(column++, DownloadIdToInt(info.id));
520 statement_insert.BindString(column++, info.guid);
477 BindFilePath(statement_insert, info.current_path, column++); 521 BindFilePath(statement_insert, info.current_path, column++);
478 BindFilePath(statement_insert, info.target_path, column++); 522 BindFilePath(statement_insert, info.target_path, column++);
479 statement_insert.BindString(column++, info.mime_type); 523 statement_insert.BindString(column++, info.mime_type);
480 statement_insert.BindString(column++, info.original_mime_type); 524 statement_insert.BindString(column++, info.original_mime_type);
481 statement_insert.BindInt64(column++, info.start_time.ToInternalValue()); 525 statement_insert.BindInt64(column++, info.start_time.ToInternalValue());
482 statement_insert.BindInt64(column++, info.received_bytes); 526 statement_insert.BindInt64(column++, info.received_bytes);
483 statement_insert.BindInt64(column++, info.total_bytes); 527 statement_insert.BindInt64(column++, info.total_bytes);
484 statement_insert.BindInt(column++, DownloadStateToInt(info.state)); 528 statement_insert.BindInt(column++, DownloadStateToInt(info.state));
485 statement_insert.BindInt(column++, 529 statement_insert.BindInt(column++,
486 DownloadDangerTypeToInt(info.danger_type)); 530 DownloadDangerTypeToInt(info.danger_type));
487 statement_insert.BindInt( 531 statement_insert.BindInt(
488 column++, DownloadInterruptReasonToInt(info.interrupt_reason)); 532 column++, DownloadInterruptReasonToInt(info.interrupt_reason));
533 statement_insert.BindBlob(column++, info.hash.data(), info.hash.size());
489 statement_insert.BindInt64(column++, info.end_time.ToInternalValue()); 534 statement_insert.BindInt64(column++, info.end_time.ToInternalValue());
490 statement_insert.BindInt(column++, info.opened ? 1 : 0); 535 statement_insert.BindInt(column++, info.opened ? 1 : 0);
491 statement_insert.BindString(column++, info.referrer_url.spec()); 536 statement_insert.BindString(column++, info.referrer_url.spec());
537 statement_insert.BindString(column++, info.http_method);
492 statement_insert.BindString(column++, info.by_ext_id); 538 statement_insert.BindString(column++, info.by_ext_id);
493 statement_insert.BindString(column++, info.by_ext_name); 539 statement_insert.BindString(column++, info.by_ext_name);
494 statement_insert.BindString(column++, info.etag); 540 statement_insert.BindString(column++, info.etag);
495 statement_insert.BindString(column++, info.last_modified); 541 statement_insert.BindString(column++, info.last_modified);
496 if (!statement_insert.Run()) { 542 if (!statement_insert.Run()) {
497 // GetErrorCode() returns a bitmask where the lower byte is a more general 543 // GetErrorCode() returns a bitmask where the lower byte is a more general
498 // code and the upper byte is a more specific code. In order to save 544 // code and the upper byte is a more specific code. In order to save
499 // memory, take the general code, of which there are fewer than 50. See 545 // memory, take the general code, of which there are fewer than 50. See
500 // also sql/connection.cc 546 // also sql/connection.cc
501 // http://www.sqlite.org/c3ref/c_abort_rollback.html 547 // http://www.sqlite.org/c3ref/c_abort_rollback.html
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 size_t DownloadDatabase::CountDownloads() { 614 size_t DownloadDatabase::CountDownloads() {
569 EnsureInProgressEntriesCleanedUp(); 615 EnsureInProgressEntriesCleanedUp();
570 616
571 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 617 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
572 "SELECT count(*) from downloads")); 618 "SELECT count(*) from downloads"));
573 statement.Step(); 619 statement.Step();
574 return statement.ColumnInt(0); 620 return statement.ColumnInt(0);
575 } 621 }
576 622
577 } // namespace history 623 } // namespace history
OLDNEW
« no previous file with comments | « components/history/core/browser/download_database.h ('k') | components/history/core/browser/download_row.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698