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/history_database.h" | 5 #include "components/history/core/browser/history_database.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <set> | 10 #include <set> |
(...skipping 24 matching lines...) Expand all Loading... |
35 namespace { | 35 namespace { |
36 | 36 |
37 // Current version number. We write databases at the "current" version number, | 37 // Current version number. We write databases at the "current" version number, |
38 // but any previous version that can read the "compatible" one can make do with | 38 // but any previous version that can read the "compatible" one can make do with |
39 // our database without *too* many bad effects. | 39 // our database without *too* many bad effects. |
40 const int kCurrentVersionNumber = 36; | 40 const int kCurrentVersionNumber = 36; |
41 const int kCompatibleVersionNumber = 16; | 41 const int kCompatibleVersionNumber = 16; |
42 const char kEarlyExpirationThresholdKey[] = "early_expiration_threshold"; | 42 const char kEarlyExpirationThresholdKey[] = "early_expiration_threshold"; |
43 const int kMaxHostsInMemory = 10000; | 43 const int kMaxHostsInMemory = 10000; |
44 | 44 |
| 45 // Logs a migration failure to UMA and logging. The return value will be |
| 46 // what to return from ::Init (to simplify the call sites). Migration failures |
| 47 // are almost always fatal since the database can be in an inconsistent state. |
| 48 sql::InitStatus LogMigrationFailure(int from_version) { |
| 49 UMA_HISTOGRAM_SPARSE_SLOWLY("History.MigrateFailureFromVersion", |
| 50 from_version); |
| 51 LOG(ERROR) << "History failed to migrate from version " << from_version |
| 52 << ". History will be disabled."; |
| 53 return sql::INIT_FAILURE; |
| 54 } |
| 55 |
| 56 // Reasons for initialization to fail. These are logged to UMA. It corresponds |
| 57 // to the HistoryInitStep enum in enums.xml. |
| 58 // |
| 59 // DO NOT CHANGE THE VALUES. Leave holes if anything is removed and add only |
| 60 // to the end. |
| 61 enum class InitStep { |
| 62 OPEN = 0, |
| 63 TRANSACTION_BEGIN = 1, |
| 64 META_TABLE_INIT = 2, |
| 65 CREATE_TABLES = 3, |
| 66 VERSION = 4, |
| 67 COMMIT = 5, |
| 68 }; |
| 69 |
| 70 sql::InitStatus LogInitFailure(InitStep what) { |
| 71 UMA_HISTOGRAM_SPARSE_SLOWLY("History.InitializationFailureStep", |
| 72 static_cast<int>(what)); |
| 73 return sql::INIT_FAILURE; |
| 74 } |
| 75 |
45 } // namespace | 76 } // namespace |
46 | 77 |
47 HistoryDatabase::HistoryDatabase( | 78 HistoryDatabase::HistoryDatabase( |
48 DownloadInterruptReason download_interrupt_reason_none, | 79 DownloadInterruptReason download_interrupt_reason_none, |
49 DownloadInterruptReason download_interrupt_reason_crash) | 80 DownloadInterruptReason download_interrupt_reason_crash) |
50 : DownloadDatabase(download_interrupt_reason_none, | 81 : DownloadDatabase(download_interrupt_reason_none, |
51 download_interrupt_reason_crash) { | 82 download_interrupt_reason_crash) { |
52 } | 83 } |
53 | 84 |
54 HistoryDatabase::~HistoryDatabase() { | 85 HistoryDatabase::~HistoryDatabase() { |
(...skipping 12 matching lines...) Expand all Loading... |
67 // value, tells us how much memory the cache will use maximum. | 98 // value, tells us how much memory the cache will use maximum. |
68 // 1000 * 4kB = 4MB | 99 // 1000 * 4kB = 4MB |
69 // TODO(brettw) scale this value to the amount of available memory. | 100 // TODO(brettw) scale this value to the amount of available memory. |
70 db_.set_cache_size(1000); | 101 db_.set_cache_size(1000); |
71 | 102 |
72 // Note that we don't set exclusive locking here. That's done by | 103 // Note that we don't set exclusive locking here. That's done by |
73 // BeginExclusiveMode below which is called later (we have to be in shared | 104 // BeginExclusiveMode below which is called later (we have to be in shared |
74 // mode to start out for the in-memory backend to read the data). | 105 // mode to start out for the in-memory backend to read the data). |
75 | 106 |
76 if (!db_.Open(history_name)) | 107 if (!db_.Open(history_name)) |
77 return sql::INIT_FAILURE; | 108 return LogInitFailure(InitStep::OPEN); |
78 | 109 |
79 // Wrap the rest of init in a tranaction. This will prevent the database from | 110 // Wrap the rest of init in a tranaction. This will prevent the database from |
80 // getting corrupted if we crash in the middle of initialization or migration. | 111 // getting corrupted if we crash in the middle of initialization or migration. |
81 sql::Transaction committer(&db_); | 112 sql::Transaction committer(&db_); |
82 if (!committer.Begin()) | 113 if (!committer.Begin()) |
83 return sql::INIT_FAILURE; | 114 return LogInitFailure(InitStep::TRANSACTION_BEGIN); |
84 | 115 |
85 #if defined(OS_MACOSX) && !defined(OS_IOS) | 116 #if defined(OS_MACOSX) && !defined(OS_IOS) |
86 // Exclude the history file from backups. | 117 // Exclude the history file from backups. |
87 base::mac::SetFileBackupExclusion(history_name); | 118 base::mac::SetFileBackupExclusion(history_name); |
88 #endif | 119 #endif |
89 | 120 |
90 // Prime the cache. | 121 // Prime the cache. |
91 db_.Preload(); | 122 db_.Preload(); |
92 | 123 |
93 // Create the tables and indices. | 124 // Create the tables and indices. |
94 // NOTE: If you add something here, also add it to | 125 // NOTE: If you add something here, also add it to |
95 // RecreateAllButStarAndURLTables. | 126 // RecreateAllButStarAndURLTables. |
96 if (!meta_table_.Init(&db_, GetCurrentVersion(), kCompatibleVersionNumber)) | 127 if (!meta_table_.Init(&db_, GetCurrentVersion(), kCompatibleVersionNumber)) |
97 return sql::INIT_FAILURE; | 128 return LogInitFailure(InitStep::META_TABLE_INIT); |
98 if (!CreateURLTable(false) || !InitVisitTable() || | 129 if (!CreateURLTable(false) || !InitVisitTable() || |
99 !InitKeywordSearchTermsTable() || !InitDownloadTable() || | 130 !InitKeywordSearchTermsTable() || !InitDownloadTable() || |
100 !InitSegmentTables() || !InitSyncTable()) | 131 !InitSegmentTables() || !InitSyncTable()) |
101 return sql::INIT_FAILURE; | 132 return LogInitFailure(InitStep::CREATE_TABLES); |
102 CreateMainURLIndex(); | 133 CreateMainURLIndex(); |
103 CreateKeywordSearchTermsIndices(); | 134 CreateKeywordSearchTermsIndices(); |
104 | 135 |
105 // TODO(benjhayden) Remove at some point. | 136 // TODO(benjhayden) Remove at some point. |
106 meta_table_.DeleteKey("next_download_id"); | 137 meta_table_.DeleteKey("next_download_id"); |
107 | 138 |
108 // Version check. | 139 // Version check. |
109 sql::InitStatus version_status = EnsureCurrentVersion(); | 140 sql::InitStatus version_status = EnsureCurrentVersion(); |
110 if (version_status != sql::INIT_OK) | 141 if (version_status != sql::INIT_OK) { |
| 142 LogInitFailure(InitStep::VERSION); |
111 return version_status; | 143 return version_status; |
| 144 } |
112 | 145 |
113 return committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; | 146 if (!committer.Commit()) |
| 147 return LogInitFailure(InitStep::COMMIT); |
| 148 return sql::INIT_OK; |
114 } | 149 } |
115 | 150 |
116 void HistoryDatabase::ComputeDatabaseMetrics( | 151 void HistoryDatabase::ComputeDatabaseMetrics( |
117 const base::FilePath& history_name) { | 152 const base::FilePath& history_name) { |
118 base::TimeTicks start_time = base::TimeTicks::Now(); | 153 base::TimeTicks start_time = base::TimeTicks::Now(); |
119 int64_t file_size = 0; | 154 int64_t file_size = 0; |
120 if (!base::GetFileSize(history_name, &file_size)) | 155 if (!base::GetFileSize(history_name, &file_size)) |
121 return; | 156 return; |
122 int file_mb = static_cast<int>(file_size / (1024 * 1024)); | 157 int file_mb = static_cast<int>(file_size / (1024 * 1024)); |
123 UMA_HISTOGRAM_MEMORY_MB("History.DatabaseFileMB", file_mb); | 158 UMA_HISTOGRAM_MEMORY_MB("History.DatabaseFileMB", file_mb); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 411 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
377 LOG(WARNING) << "History database is too new."; | 412 LOG(WARNING) << "History database is too new."; |
378 return sql::INIT_TOO_NEW; | 413 return sql::INIT_TOO_NEW; |
379 } | 414 } |
380 | 415 |
381 int cur_version = meta_table_.GetVersionNumber(); | 416 int cur_version = meta_table_.GetVersionNumber(); |
382 | 417 |
383 // Put migration code here | 418 // Put migration code here |
384 | 419 |
385 if (cur_version == 15) { | 420 if (cur_version == 15) { |
386 if (!db_.Execute("DROP TABLE starred") || !DropStarredIDFromURLs()) { | 421 if (!db_.Execute("DROP TABLE starred") || !DropStarredIDFromURLs()) |
387 LOG(WARNING) << "Unable to update history database to version 16."; | 422 return LogMigrationFailure(15); |
388 return sql::INIT_FAILURE; | |
389 } | |
390 ++cur_version; | 423 ++cur_version; |
391 meta_table_.SetVersionNumber(cur_version); | 424 meta_table_.SetVersionNumber(cur_version); |
392 meta_table_.SetCompatibleVersionNumber( | 425 meta_table_.SetCompatibleVersionNumber( |
393 std::min(cur_version, kCompatibleVersionNumber)); | 426 std::min(cur_version, kCompatibleVersionNumber)); |
394 } | 427 } |
395 | 428 |
396 if (cur_version == 16) { | 429 if (cur_version == 16) { |
397 #if !defined(OS_WIN) | 430 #if !defined(OS_WIN) |
398 // In this version we bring the time format on Mac & Linux in sync with the | 431 // In this version we bring the time format on Mac & Linux in sync with the |
399 // Windows version so that profiles can be moved between computers. | 432 // Windows version so that profiles can be moved between computers. |
(...skipping 23 matching lines...) Expand all Loading... |
423 | 456 |
424 if (cur_version == 19) { | 457 if (cur_version == 19) { |
425 cur_version++; | 458 cur_version++; |
426 meta_table_.SetVersionNumber(cur_version); | 459 meta_table_.SetVersionNumber(cur_version); |
427 // This was the thumbnail migration. Obsolete. | 460 // This was the thumbnail migration. Obsolete. |
428 } | 461 } |
429 | 462 |
430 if (cur_version == 20) { | 463 if (cur_version == 20) { |
431 // This is the version prior to adding the visit_duration field in visits | 464 // This is the version prior to adding the visit_duration field in visits |
432 // database. We need to migrate the database. | 465 // database. We need to migrate the database. |
433 if (!MigrateVisitsWithoutDuration()) { | 466 if (!MigrateVisitsWithoutDuration()) |
434 LOG(WARNING) << "Unable to update history database to version 21."; | 467 return LogMigrationFailure(20); |
435 return sql::INIT_FAILURE; | |
436 } | |
437 ++cur_version; | 468 ++cur_version; |
438 meta_table_.SetVersionNumber(cur_version); | 469 meta_table_.SetVersionNumber(cur_version); |
439 } | 470 } |
440 | 471 |
441 if (cur_version == 21) { | 472 if (cur_version == 21) { |
442 // The android_urls table's data schemal was changed in version 21. | 473 // The android_urls table's data schemal was changed in version 21. |
443 #if defined(OS_ANDROID) | 474 #if defined(OS_ANDROID) |
444 if (!MigrateToVersion22()) { | 475 if (!MigrateToVersion22()) |
445 LOG(WARNING) << "Unable to migrate the android_urls table to version 22"; | 476 return LogMigrationFailure(21); |
446 } | |
447 #endif | 477 #endif |
448 ++cur_version; | 478 ++cur_version; |
449 meta_table_.SetVersionNumber(cur_version); | 479 meta_table_.SetVersionNumber(cur_version); |
450 } | 480 } |
451 | 481 |
452 if (cur_version == 22) { | 482 if (cur_version == 22) { |
453 if (!MigrateDownloadsState()) { | 483 if (!MigrateDownloadsState()) |
454 LOG(WARNING) << "Unable to fix invalid downloads state values"; | 484 return LogMigrationFailure(22); |
455 // Invalid state values may cause crashes. | |
456 return sql::INIT_FAILURE; | |
457 } | |
458 cur_version++; | 485 cur_version++; |
459 meta_table_.SetVersionNumber(cur_version); | 486 meta_table_.SetVersionNumber(cur_version); |
460 } | 487 } |
461 | 488 |
462 if (cur_version == 23) { | 489 if (cur_version == 23) { |
463 if (!MigrateDownloadsReasonPathsAndDangerType()) { | 490 if (!MigrateDownloadsReasonPathsAndDangerType()) |
464 LOG(WARNING) << "Unable to upgrade download interrupt reason and paths"; | 491 return LogMigrationFailure(23); |
465 // Invalid state values may cause crashes. | |
466 return sql::INIT_FAILURE; | |
467 } | |
468 cur_version++; | 492 cur_version++; |
469 meta_table_.SetVersionNumber(cur_version); | 493 meta_table_.SetVersionNumber(cur_version); |
470 } | 494 } |
471 | 495 |
472 if (cur_version == 24) { | 496 if (cur_version == 24) { |
473 if (!MigratePresentationIndex()) { | 497 if (!MigratePresentationIndex()) |
474 LOG(WARNING) << "Unable to migrate history to version 25"; | 498 return LogMigrationFailure(24); |
475 return sql::INIT_FAILURE; | |
476 } | |
477 cur_version++; | 499 cur_version++; |
478 meta_table_.SetVersionNumber(cur_version); | 500 meta_table_.SetVersionNumber(cur_version); |
479 } | 501 } |
480 | 502 |
481 if (cur_version == 25) { | 503 if (cur_version == 25) { |
482 if (!MigrateReferrer()) { | 504 if (!MigrateReferrer()) |
483 LOG(WARNING) << "Unable to migrate history to version 26"; | 505 return LogMigrationFailure(25); |
484 return sql::INIT_FAILURE; | |
485 } | |
486 cur_version++; | 506 cur_version++; |
487 meta_table_.SetVersionNumber(cur_version); | 507 meta_table_.SetVersionNumber(cur_version); |
488 } | 508 } |
489 | 509 |
490 if (cur_version == 26) { | 510 if (cur_version == 26) { |
491 if (!MigrateDownloadedByExtension()) { | 511 if (!MigrateDownloadedByExtension()) |
492 LOG(WARNING) << "Unable to migrate history to version 27"; | 512 return LogMigrationFailure(26); |
493 return sql::INIT_FAILURE; | |
494 } | |
495 cur_version++; | 513 cur_version++; |
496 meta_table_.SetVersionNumber(cur_version); | 514 meta_table_.SetVersionNumber(cur_version); |
497 } | 515 } |
498 | 516 |
499 if (cur_version == 27) { | 517 if (cur_version == 27) { |
500 if (!MigrateDownloadValidators()) { | 518 if (!MigrateDownloadValidators()) |
501 LOG(WARNING) << "Unable to migrate history to version 28"; | 519 return LogMigrationFailure(27); |
502 return sql::INIT_FAILURE; | |
503 } | |
504 cur_version++; | 520 cur_version++; |
505 meta_table_.SetVersionNumber(cur_version); | 521 meta_table_.SetVersionNumber(cur_version); |
506 } | 522 } |
507 | 523 |
508 if (cur_version == 28) { | 524 if (cur_version == 28) { |
509 if (!MigrateMimeType()) { | 525 if (!MigrateMimeType()) |
510 LOG(WARNING) << "Unable to migrate history to version 29"; | 526 return LogMigrationFailure(28); |
511 return sql::INIT_FAILURE; | |
512 } | |
513 cur_version++; | 527 cur_version++; |
514 meta_table_.SetVersionNumber(cur_version); | 528 meta_table_.SetVersionNumber(cur_version); |
515 } | 529 } |
516 | 530 |
517 if (cur_version == 29) { | 531 if (cur_version == 29) { |
518 if (!MigrateHashHttpMethodAndGenerateGuids()) { | 532 if (!MigrateHashHttpMethodAndGenerateGuids()) |
519 LOG(WARNING) << "Unable to migrate history to version 30"; | 533 return LogMigrationFailure(29); |
520 return sql::INIT_FAILURE; | |
521 } | |
522 cur_version++; | 534 cur_version++; |
523 meta_table_.SetVersionNumber(cur_version); | 535 meta_table_.SetVersionNumber(cur_version); |
524 } | 536 } |
525 | 537 |
526 if (cur_version == 30) { | 538 if (cur_version == 30) { |
527 if (!MigrateDownloadTabUrl()) { | 539 if (!MigrateDownloadTabUrl()) |
528 LOG(WARNING) << "Unable to migrate history to version 31"; | 540 return LogMigrationFailure(30); |
529 return sql::INIT_FAILURE; | |
530 } | |
531 cur_version++; | 541 cur_version++; |
532 meta_table_.SetVersionNumber(cur_version); | 542 meta_table_.SetVersionNumber(cur_version); |
533 } | 543 } |
534 | 544 |
535 if (cur_version == 31) { | 545 if (cur_version == 31) { |
536 if (!MigrateDownloadSiteInstanceUrl()) { | 546 if (!MigrateDownloadSiteInstanceUrl()) |
537 LOG(WARNING) << "Unable to migrate history to version 32"; | 547 return LogMigrationFailure(31); |
538 return sql::INIT_FAILURE; | |
539 } | |
540 cur_version++; | 548 cur_version++; |
541 meta_table_.SetVersionNumber(cur_version); | 549 meta_table_.SetVersionNumber(cur_version); |
542 } | 550 } |
543 | 551 |
544 if (cur_version == 32) { | 552 if (cur_version == 32) { |
545 // New download slices table is introduced, no migration needed. | 553 // New download slices table is introduced, no migration needed. |
546 cur_version++; | 554 cur_version++; |
547 meta_table_.SetVersionNumber(cur_version); | 555 meta_table_.SetVersionNumber(cur_version); |
548 } | 556 } |
549 | 557 |
550 if (cur_version == 33) { | 558 if (cur_version == 33) { |
551 if (!MigrateDownloadLastAccessTime()) { | 559 if (!MigrateDownloadLastAccessTime()) |
552 LOG(WARNING) << "Unable to migrate to version 34"; | 560 return LogMigrationFailure(33); |
553 return sql::INIT_FAILURE; | |
554 } | |
555 cur_version++; | 561 cur_version++; |
556 meta_table_.SetVersionNumber(cur_version); | 562 meta_table_.SetVersionNumber(cur_version); |
557 } | 563 } |
558 | 564 |
559 if (cur_version == 34) { | 565 if (cur_version == 34) { |
| 566 /* |
| 567 This code is commented out because we suspect the additional disk storage |
| 568 requirements of duplicating the URL table to update the schema cause |
| 569 some devices to run out of storage. Errors during initialization are |
| 570 very disruptive to the user experience. |
| 571 |
| 572 TODO(https://crbug.com/736136) figure out how to update users to use |
| 573 AUTOINCREMENT. |
| 574 |
560 // AUTOINCREMENT is added to urls table PRIMARY KEY(id), need to recreate a | 575 // AUTOINCREMENT is added to urls table PRIMARY KEY(id), need to recreate a |
561 // new table and copy all contents over. favicon_id is removed from urls | 576 // new table and copy all contents over. favicon_id is removed from urls |
562 // table since we never use it. Also typed_url_sync_metadata and | 577 // table since we never use it. Also typed_url_sync_metadata and |
563 // autofill_model_type_state tables are introduced, no migration needed for | 578 // autofill_model_type_state tables are introduced, no migration needed for |
564 // those two tables. | 579 // those two tables. |
565 if (!RecreateURLTableWithAllContents()) { | 580 if (!RecreateURLTableWithAllContents()) |
566 LOG(WARNING) << "Unable to update history database to version 35."; | 581 return LogMigrationFailure(34); |
567 return sql::INIT_FAILURE; | 582 */ |
568 } | |
569 cur_version++; | 583 cur_version++; |
570 meta_table_.SetVersionNumber(cur_version); | 584 meta_table_.SetVersionNumber(cur_version); |
571 } | 585 } |
572 | 586 |
573 if (cur_version == 35) { | 587 if (cur_version == 35) { |
574 if (!MigrateDownloadTransient()) { | 588 if (!MigrateDownloadTransient()) |
575 LOG(WARNING) << "Unable to migrate to version 36"; | 589 return LogMigrationFailure(35); |
576 return sql::INIT_FAILURE; | |
577 } | |
578 cur_version++; | 590 cur_version++; |
579 meta_table_.SetVersionNumber(cur_version); | 591 meta_table_.SetVersionNumber(cur_version); |
580 } | 592 } |
581 | 593 |
| 594 // ========================= ^^ new migration code goes here ^^ |
| 595 // ADDING NEW MIGRATION CODE |
| 596 // ========================= |
| 597 // |
| 598 // Add new migration code above here. It's important to use as little space |
| 599 // as possible during migration. Many phones are very near their storage |
| 600 // limit, so anything that recreates or duplicates large history tables can |
| 601 // easily push them over that limit. |
| 602 // |
| 603 // When failures happen during initialization, history is not loaded. This |
| 604 // causes all components related to the history database file to fail |
| 605 // completely, including autocomplete and downloads. Devices near their |
| 606 // storage limit are likely to fail doing some update later, but those |
| 607 // operations will then just be skipped which is not nearly as disruptive. |
| 608 // See https://crbug.com/734194. |
| 609 |
582 // When the version is too old, we just try to continue anyway, there should | 610 // When the version is too old, we just try to continue anyway, there should |
583 // not be a released product that makes a database too old for us to handle. | 611 // not be a released product that makes a database too old for us to handle. |
584 LOG_IF(WARNING, cur_version < GetCurrentVersion()) << | 612 LOG_IF(WARNING, cur_version < GetCurrentVersion()) << |
585 "History database version " << cur_version << " is too old to handle."; | 613 "History database version " << cur_version << " is too old to handle."; |
586 | 614 |
587 return sql::INIT_OK; | 615 return sql::INIT_OK; |
588 } | 616 } |
589 | 617 |
590 #if !defined(OS_WIN) | 618 #if !defined(OS_WIN) |
591 void HistoryDatabase::MigrateTimeEpoch() { | 619 void HistoryDatabase::MigrateTimeEpoch() { |
592 // Update all the times in the URLs and visits table in the main database. | 620 // Update all the times in the URLs and visits table in the main database. |
593 ignore_result(db_.Execute( | 621 ignore_result(db_.Execute( |
594 "UPDATE urls " | 622 "UPDATE urls " |
595 "SET last_visit_time = last_visit_time + 11644473600000000 " | 623 "SET last_visit_time = last_visit_time + 11644473600000000 " |
596 "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);")); | 624 "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);")); |
597 ignore_result(db_.Execute( | 625 ignore_result(db_.Execute( |
598 "UPDATE visits " | 626 "UPDATE visits " |
599 "SET visit_time = visit_time + 11644473600000000 " | 627 "SET visit_time = visit_time + 11644473600000000 " |
600 "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);")); | 628 "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);")); |
601 ignore_result(db_.Execute( | 629 ignore_result(db_.Execute( |
602 "UPDATE segment_usage " | 630 "UPDATE segment_usage " |
603 "SET time_slot = time_slot + 11644473600000000 " | 631 "SET time_slot = time_slot + 11644473600000000 " |
604 "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);")); | 632 "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);")); |
605 } | 633 } |
606 #endif | 634 #endif |
607 | 635 |
608 } // namespace history | 636 } // namespace history |
OLD | NEW |