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 "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |