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

Side by Side Diff: chrome/browser/net/sqlite_persistent_cookie_store.cc

Issue 9567022: Reinitialize the cookie database if the meta table gets corrupted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move things around a bit for a slightly smaller diff. Created 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc » ('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/net/sqlite_persistent_cookie_store.h" 5 #include "chrome/browser/net/sqlite_persistent_cookie_store.h"
6 6
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 private: 102 private:
103 friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>; 103 friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>;
104 104
105 // You should call Close() before destructing this object. 105 // You should call Close() before destructing this object.
106 ~Backend() { 106 ~Backend() {
107 DCHECK(!db_.get()) << "Close should have already been called."; 107 DCHECK(!db_.get()) << "Close should have already been called.";
108 DCHECK(num_pending_ == 0 && pending_.empty()); 108 DCHECK(num_pending_ == 0 && pending_.empty());
109 } 109 }
110 110
111 // Database upgrade statements.
112 bool EnsureDatabaseVersion();
113
114 class PendingOperation { 111 class PendingOperation {
115 public: 112 public:
116 typedef enum { 113 typedef enum {
117 COOKIE_ADD, 114 COOKIE_ADD,
118 COOKIE_UPDATEACCESS, 115 COOKIE_UPDATEACCESS,
119 COOKIE_DELETE, 116 COOKIE_DELETE,
120 } OperationType; 117 } OperationType;
121 118
122 PendingOperation(OperationType op, 119 PendingOperation(OperationType op,
123 const net::CookieMonster::CanonicalCookie& cc) 120 const net::CookieMonster::CanonicalCookie& cc)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 bool load_success); 155 bool load_success);
159 156
160 // Sends all metrics, including posting a ReportMetricsOnDBThread task. 157 // Sends all metrics, including posting a ReportMetricsOnDBThread task.
161 // Called after all priority and regular loading is complete. 158 // Called after all priority and regular loading is complete.
162 void ReportMetrics(); 159 void ReportMetrics();
163 160
164 // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread 161 // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread
165 // tasks). 162 // tasks).
166 void ReportMetricsOnDBThread(); 163 void ReportMetricsOnDBThread();
167 164
168 // Initialize the data base. 165 // Open the database and read enough information to allow us to respond to
169 bool InitializeDatabase(); 166 // clients.
167 bool PrepareDatabaseForAccess();
168
169 // Opens the database file and creates or migrates the schema if necessary.
170 bool OpenDatabase();
171
172 // Initializes the cookies table, returning true on success.
173 bool InitializeSchema();
174
175 // Check the database version and perform migration steps if necessary.
176 bool EnsureDatabaseVersion();
170 177
171 // Loads cookies for the next domain key from the DB, then either reschedules 178 // Loads cookies for the next domain key from the DB, then either reschedules
172 // itself or schedules the provided callback to run on the IO thread (if all 179 // itself or schedules the provided callback to run on the IO thread (if all
173 // domains are loaded). 180 // domains are loaded).
174 void ChainLoadCookies(const LoadedCallback& loaded_callback); 181 void ChainLoadCookies(const LoadedCallback& loaded_callback);
175 182
176 // Load all cookies for a set of domains/hosts 183 // Load all cookies for a set of domains/hosts
177 bool LoadCookiesForDomains(const std::set<std::string>& key); 184 bool LoadCookiesForDomains(const std::set<std::string>& key);
178 185
179 // Batch a cookie operation (add or delete) 186 // Batch a cookie operation (add or delete)
180 void BatchOperation(PendingOperation::OperationType op, 187 void BatchOperation(PendingOperation::OperationType op,
181 const net::CookieMonster::CanonicalCookie& cc); 188 const net::CookieMonster::CanonicalCookie& cc);
189
182 // Commit our pending operations to the database. 190 // Commit our pending operations to the database.
183 void Commit(); 191 void Commit();
192
184 // Close() executed on the background thread. 193 // Close() executed on the background thread.
185 void InternalBackgroundClose(); 194 void InternalBackgroundClose();
186 195
187 void DeleteSessionCookies(); 196 void DeleteSessionCookies();
188 197
189 FilePath path_; 198 FilePath path_;
190 scoped_ptr<sql::Connection> db_; 199 scoped_ptr<sql::Connection> db_;
191 sql::MetaTable meta_table_; 200 sql::MetaTable meta_table_;
192 201
193 typedef std::list<PendingOperation*> PendingOperationsList; 202 typedef std::list<PendingOperation*> PendingOperationsList;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 } 280 }
272 281
273 private: 282 private:
274 base::TimeDelta* delta_; 283 base::TimeDelta* delta_;
275 base::TimeDelta original_value_; 284 base::TimeDelta original_value_;
276 base::Time start_; 285 base::Time start_;
277 286
278 DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta); 287 DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta);
279 }; 288 };
280 289
281 // Initializes the cookies table, returning true on success.
282 bool InitTable(sql::Connection* db) {
283 if (!db->DoesTableExist("cookies")) {
284 if (!db->Execute("CREATE TABLE cookies ("
285 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,"
286 "host_key TEXT NOT NULL,"
287 "name TEXT NOT NULL,"
288 "value TEXT NOT NULL,"
289 "path TEXT NOT NULL,"
290 "expires_utc INTEGER NOT NULL,"
291 "secure INTEGER NOT NULL,"
292 "httponly INTEGER NOT NULL,"
293 "last_access_utc INTEGER NOT NULL, "
294 "has_expires INTEGER NOT NULL DEFAULT 1, "
295 "persistent INTEGER NOT NULL DEFAULT 1)"))
296 return false;
297 }
298
299 // Try to create the index every time. Older versions did not have this index,
300 // so we want those people to get it.
301 if (!db->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies"
302 " (creation_utc)"))
303 return false;
304
305 if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)"))
306 return false;
307
308 return true;
309 }
310
311 // TODO(shess): Send up a crash report containing information to help 290 // TODO(shess): Send up a crash report containing information to help
312 // debug http://crbug.com/111376 . 291 // debug http://crbug.com/111376 .
313 void DumpSchemaInfoWithoutCrashing(sql::Connection* db, 292 void DumpSchemaInfoWithoutCrashing(sql::Connection* db,
314 sql::MetaTable* meta_table, 293 sql::MetaTable* meta_table,
315 const FilePath& path) { 294 const FilePath& path) {
316 // Buffer for accumulating debugging info about the database. Place 295 // Buffer for accumulating debugging info about the database. Place
317 // more relevant information earlier, in case a large datum 296 // more relevant information earlier, in case a large datum
318 // overflows the fixed-size buffer. 297 // overflows the fixed-size buffer.
319 std::string debug_info; 298 std::string debug_info;
320 299
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 const LoadedCallback& loaded_callback, const base::Time& posted_at) { 369 const LoadedCallback& loaded_callback, const base::Time& posted_at) {
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
392 IncrementTimeDelta increment(&cookie_load_duration_); 371 IncrementTimeDelta increment(&cookie_load_duration_);
393 372
394 UMA_HISTOGRAM_CUSTOM_TIMES( 373 UMA_HISTOGRAM_CUSTOM_TIMES(
395 "Cookie.TimeLoadDBQueueWait", 374 "Cookie.TimeLoadDBQueueWait",
396 base::Time::Now() - posted_at, 375 base::Time::Now() - posted_at,
397 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 376 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
398 50); 377 50);
399 378
400 if (!InitializeDatabase()) { 379 if (!PrepareDatabaseForAccess()) {
401 BrowserThread::PostTask( 380 BrowserThread::PostTask(
402 BrowserThread::IO, FROM_HERE, 381 BrowserThread::IO, FROM_HERE,
403 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread, 382 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
404 this, loaded_callback, false)); 383 this, loaded_callback, false));
405 } else { 384 } else {
406 ChainLoadCookies(loaded_callback); 385 ChainLoadCookies(loaded_callback);
407 } 386 }
408 } 387 }
409 388
410 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( 389 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
411 const std::string& key, 390 const std::string& key,
412 const LoadedCallback& loaded_callback, 391 const LoadedCallback& loaded_callback,
413 const base::Time& posted_at) { 392 const base::Time& posted_at) {
414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
415 IncrementTimeDelta increment(&cookie_load_duration_); 394 IncrementTimeDelta increment(&cookie_load_duration_);
416 395
417 UMA_HISTOGRAM_CUSTOM_TIMES( 396 UMA_HISTOGRAM_CUSTOM_TIMES(
418 "Cookie.TimeKeyLoadDBQueueWait", 397 "Cookie.TimeKeyLoadDBQueueWait",
419 base::Time::Now() - posted_at, 398 base::Time::Now() - posted_at,
420 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 399 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
421 50); 400 50);
422 401
423 bool success = false; 402 bool success = false;
424 if (InitializeDatabase()) { 403 if (PrepareDatabaseForAccess()) {
425 std::map<std::string, std::set<std::string> >::iterator 404 std::map<std::string, std::set<std::string> >::iterator
426 it = keys_to_load_.find(key); 405 it = keys_to_load_.find(key);
427 if (it != keys_to_load_.end()) { 406 if (it != keys_to_load_.end()) {
428 success = LoadCookiesForDomains(it->second); 407 success = LoadCookiesForDomains(it->second);
429 keys_to_load_.erase(it); 408 keys_to_load_.erase(it);
430 } else { 409 } else {
431 success = true; 410 success = true;
432 } 411 }
433 } 412 }
434 413
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 479
501 std::vector<net::CookieMonster::CanonicalCookie*> cookies; 480 std::vector<net::CookieMonster::CanonicalCookie*> cookies;
502 { 481 {
503 base::AutoLock locked(lock_); 482 base::AutoLock locked(lock_);
504 cookies.swap(cookies_); 483 cookies.swap(cookies_);
505 } 484 }
506 485
507 loaded_callback.Run(cookies); 486 loaded_callback.Run(cookies);
508 } 487 }
509 488
510 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { 489 bool SQLitePersistentCookieStore::Backend::PrepareDatabaseForAccess() {
511 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
512 491
513 if (initialized_) { 492 if (initialized_) {
514 // Return false if we were previously initialized but the DB has since been 493 // Return false if we were previously initialized but the DB has since been
515 // closed. 494 // closed.
516 return db_.get() ? true : false; 495 return db_.get() ? true : false;
517 } 496 }
518 497
519 base::Time start = base::Time::Now(); 498 base::Time start = base::Time::Now();
520 499
521 const FilePath dir = path_.DirName(); 500 const FilePath dir = path_.DirName();
522 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { 501 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
523 return false; 502 return false;
524 } 503 }
525 504
526 int64 db_size = 0; 505 int64 db_size = 0;
527 if (file_util::GetFileSize(path_, &db_size)) { 506 if (file_util::GetFileSize(path_, &db_size)) {
528 base::ThreadRestrictions::ScopedAllowIO allow_io; 507 base::ThreadRestrictions::ScopedAllowIO allow_io;
529 UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 ); 508 UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 );
530 } 509 }
531 510
532 db_.reset(new sql::Connection); 511 if (!OpenDatabase())
533 if (!db_->Open(path_)) {
534 NOTREACHED() << "Unable to open cookie DB.";
535 db_.reset();
536 return false; 512 return false;
537 }
538
539 db_->set_error_delegate(GetErrorHandlerForCookieDb());
540
541 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
542 NOTREACHED() << "Unable to open cookie DB.";
543 db_.reset();
544 return false;
545 }
546 513
547 UMA_HISTOGRAM_CUSTOM_TIMES( 514 UMA_HISTOGRAM_CUSTOM_TIMES(
548 "Cookie.TimeInitializeDB", 515 "Cookie.TimeInitializeDB",
549 base::Time::Now() - start, 516 base::Time::Now() - start,
550 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 517 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
551 50); 518 50);
552 519
553 start = base::Time::Now(); 520 start = base::Time::Now();
554 521
555 // Retrieve all the domains 522 // Retrieve all the domains
(...skipping 22 matching lines...) Expand all
578 UMA_HISTOGRAM_CUSTOM_TIMES( 545 UMA_HISTOGRAM_CUSTOM_TIMES(
579 "Cookie.TimeInitializeDomainMap", 546 "Cookie.TimeInitializeDomainMap",
580 base::Time::Now() - start, 547 base::Time::Now() - start,
581 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 548 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
582 50); 549 50);
583 550
584 initialized_ = true; 551 initialized_ = true;
585 return true; 552 return true;
586 } 553 }
587 554
555 bool SQLitePersistentCookieStore::Backend::OpenDatabase() {
556 DCHECK(!db_.get());
557
558 db_.reset(new sql::Connection);
559 if (!db_->Open(path_)) {
560 NOTREACHED() << "Unable to open cookie DB.";
561 db_.reset();
562 return false;
563 }
564
565 db_->set_error_delegate(GetErrorHandlerForCookieDb());
566
567 if (!sql::MetaTable::DoesTableExist(db_.get()))
568 return InitializeSchema();
569
570 // We don't pass the current version or current compatible version because
571 // we are expecting the schema to already be populated - hence these values
572 // will be ignored. If we subsequently query for the version and get back 0
573 // we know something is wrong.
Scott Hess - ex-Googler 2012/03/08 00:48:44 I don't like making these assumptions on how MetaT
574 if (!meta_table_.Init(db_.get(), 0, 0) ||
575 meta_table_.GetVersionNumber() == 0 ||
576 meta_table_.GetCompatibleVersionNumber() == 0) {
577 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1);
578
579 meta_table_.Reset();
580 db_.reset(new sql::Connection);
581 if (!file_util::Delete(path_, false) || !db_->Open(path_)) {
582 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTableRecoveryFailed", 1);
583 NOTREACHED() << "Unable to reset the cookie DB.";
584 meta_table_.Reset();
585 db_.reset();
586 return false;
587 }
588 db_->set_error_delegate(GetErrorHandlerForCookieDb());
589
590 return InitializeSchema();
591 }
592
593 return EnsureDatabaseVersion();
594 }
595
596 bool SQLitePersistentCookieStore::Backend::InitializeSchema() {
597 DCHECK(!db_.get()->DoesTableExist("cookies"));
598 sql::Transaction transaction(db_.get());
599
600 return transaction.Begin() &&
601 meta_table_.Init(db_.get(),
602 kCurrentVersionNumber,
603 kCompatibleVersionNumber) &&
604 db_->Execute("CREATE TABLE cookies ("
605 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,"
606 "host_key TEXT NOT NULL,"
607 "name TEXT NOT NULL,"
608 "value TEXT NOT NULL,"
609 "path TEXT NOT NULL,"
610 "expires_utc INTEGER NOT NULL,"
611 "secure INTEGER NOT NULL,"
612 "httponly INTEGER NOT NULL,"
613 "last_access_utc INTEGER NOT NULL, "
614 "has_expires INTEGER NOT NULL DEFAULT 1, "
615 "persistent INTEGER NOT NULL DEFAULT 1)") &&
616 db_->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies"
617 " (creation_utc)") &&
618 db_->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)") &&
619 transaction.Commit();
Scott Hess - ex-Googler 2012/03/08 00:48:44 I don't really care for this style, versus a bunch
620 }
621
588 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( 622 void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
589 const LoadedCallback& loaded_callback) { 623 const LoadedCallback& loaded_callback) {
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
591 IncrementTimeDelta increment(&cookie_load_duration_); 625 IncrementTimeDelta increment(&cookie_load_duration_);
592 626
593 bool load_success = true; 627 bool load_success = true;
594 628
595 if (!db_.get()) { 629 if (!db_.get()) {
596 // Close() has been called on this store. 630 // Close() has been called on this store.
597 load_success = false; 631 load_success = false;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 smt.Reset(); 709 smt.Reset();
676 } 710 }
677 { 711 {
678 base::AutoLock locked(lock_); 712 base::AutoLock locked(lock_);
679 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end()); 713 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end());
680 } 714 }
681 return true; 715 return true;
682 } 716 }
683 717
684 bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() { 718 bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() {
685 // Version check.
686 if (!meta_table_.Init(
687 db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) {
688 return false;
689 }
690
691 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 719 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
692 LOG(WARNING) << "Cookie database is too new."; 720 LOG(WARNING) << "Cookie database is too new.";
693 return false; 721 return false;
694 } 722 }
695 723
696 int cur_version = meta_table_.GetVersionNumber(); 724 int cur_version = meta_table_.GetVersionNumber();
697 if (cur_version == 2) { 725 if (cur_version == 2) {
698 sql::Transaction transaction(db_.get()); 726 sql::Transaction transaction(db_.get());
699 if (!transaction.Begin()) 727 if (!transaction.Begin())
700 return false; 728 return false;
701 if (!db_->Execute("ALTER TABLE cookies ADD COLUMN last_access_utc " 729 if (!db_->Execute("ALTER TABLE cookies ADD COLUMN last_access_utc "
702 "INTEGER DEFAULT 0") || 730 "INTEGER DEFAULT 0") ||
703 !db_->Execute("UPDATE cookies SET last_access_utc = creation_utc")) { 731 !db_->Execute("UPDATE cookies SET last_access_utc = creation_utc")) {
704 LOG(WARNING) << "Unable to update cookie database to version 3."; 732 LOG(WARNING) << "Unable to update cookie database to version 3.";
705 return false; 733 return false;
706 } 734 }
707 ++cur_version; 735 ++cur_version;
708 meta_table_.SetVersionNumber(cur_version); 736 meta_table_.SetVersionNumber(cur_version);
709 meta_table_.SetCompatibleVersionNumber( 737 meta_table_.SetCompatibleVersionNumber(
710 std::min(cur_version, kCompatibleVersionNumber)); 738 std::min(cur_version, kCompatibleVersionNumber));
711 transaction.Commit(); 739 if (!transaction.Commit())
740 return false;
712 } 741 }
713 742
714 if (cur_version == 3) { 743 if (cur_version == 3) {
715 // The time epoch changed for Mac & Linux in this version to match Windows. 744 // The time epoch changed for Mac & Linux in this version to match Windows.
716 // This patch came after the main epoch change happened, so some 745 // This patch came after the main epoch change happened, so some
717 // developers have "good" times for cookies added by the more recent 746 // developers have "good" times for cookies added by the more recent
718 // versions. So we have to be careful to only update times that are under 747 // versions. So we have to be careful to only update times that are under
719 // the old system (which will appear to be from before 1970 in the new 748 // the old system (which will appear to be from before 1970 in the new
720 // system). The magic number used below is 1970 in our time units. 749 // system). The magic number used below is 1970 in our time units.
721 sql::Transaction transaction(db_.get()); 750 sql::Transaction transaction(db_.get());
(...skipping 13 matching lines...) Expand all
735 "expires_utc > 0 AND expires_utc < 11644473600000000)")); 764 "expires_utc > 0 AND expires_utc < 11644473600000000)"));
736 ignore_result(db_->Execute( 765 ignore_result(db_->Execute(
737 "UPDATE cookies " 766 "UPDATE cookies "
738 "SET last_access_utc = last_access_utc + 11644473600000000 " 767 "SET last_access_utc = last_access_utc + 11644473600000000 "
739 "WHERE rowid IN " 768 "WHERE rowid IN "
740 "(SELECT rowid FROM cookies WHERE " 769 "(SELECT rowid FROM cookies WHERE "
741 "last_access_utc > 0 AND last_access_utc < 11644473600000000)")); 770 "last_access_utc > 0 AND last_access_utc < 11644473600000000)"));
742 #endif 771 #endif
743 ++cur_version; 772 ++cur_version;
744 meta_table_.SetVersionNumber(cur_version); 773 meta_table_.SetVersionNumber(cur_version);
745 transaction.Commit(); 774 if (!transaction.Commit())
775 return false;
746 } 776 }
747 777
748 if (cur_version == 4) { 778 if (cur_version == 4) {
749 const base::TimeTicks start_time = base::TimeTicks::Now(); 779 const base::TimeTicks start_time = base::TimeTicks::Now();
750 sql::Transaction transaction(db_.get()); 780 sql::Transaction transaction(db_.get());
751 if (!transaction.Begin()) 781 if (!transaction.Begin())
752 return false; 782 return false;
783
784 // The IF NOT EXISTS are because some databases were created without
785 // these indexes. As of version 5 all tables are create with them, so let's
786 // make sure that those old DBs get them as they go through this migration.
753 if (!db_->Execute("ALTER TABLE cookies " 787 if (!db_->Execute("ALTER TABLE cookies "
754 "ADD COLUMN has_expires INTEGER DEFAULT 1") || 788 "ADD COLUMN has_expires INTEGER DEFAULT 1") ||
755 !db_->Execute("ALTER TABLE cookies " 789 !db_->Execute("ALTER TABLE cookies "
756 "ADD COLUMN persistent INTEGER DEFAULT 1")) { 790 "ADD COLUMN persistent INTEGER DEFAULT 1") ||
791 !db_->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies"
792 " (creation_utc)") ||
Scott Hess - ex-Googler 2012/03/08 00:48:44 If/when you get the conflict with my change to rem
793 !db_->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies"
794 "(host_key)")) {
757 LOG(WARNING) << "Unable to update cookie database to version 5."; 795 LOG(WARNING) << "Unable to update cookie database to version 5.";
758 return false; 796 return false;
759 } 797 }
798
760 ++cur_version; 799 ++cur_version;
761 meta_table_.SetVersionNumber(cur_version); 800 meta_table_.SetVersionNumber(cur_version);
762 meta_table_.SetCompatibleVersionNumber( 801 meta_table_.SetCompatibleVersionNumber(
763 std::min(cur_version, kCompatibleVersionNumber)); 802 std::min(cur_version, kCompatibleVersionNumber));
764 transaction.Commit(); 803 if (!transaction.Commit())
804 return false;
765 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", 805 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5",
766 base::TimeTicks::Now() - start_time); 806 base::TimeTicks::Now() - start_time);
767 } 807 }
768 808
769 // Put future migration cases here. 809 // Put future migration cases here.
770 810
771 // When the version is too old, we just try to continue anyway, there should
772 // not be a released product that makes a database too old for us to handle.
773 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
774 "Cookie database version " << cur_version << " is too old to handle.";
775
Scott Hess - ex-Googler 2012/03/08 00:48:44 If the code gets to this point without cur_version
776 return true; 811 return true;
777 } 812 }
778 813
779 void SQLitePersistentCookieStore::Backend::AddCookie( 814 void SQLitePersistentCookieStore::Backend::AddCookie(
780 const net::CookieMonster::CanonicalCookie& cc) { 815 const net::CookieMonster::CanonicalCookie& cc) {
781 BatchOperation(PendingOperation::COOKIE_ADD, cc); 816 BatchOperation(PendingOperation::COOKIE_ADD, cc);
782 } 817 }
783 818
784 void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime( 819 void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime(
785 const net::CookieMonster::CanonicalCookie& cc) { 820 const net::CookieMonster::CanonicalCookie& cc) {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 if (backend_.get()) 1041 if (backend_.get())
1007 backend_->SetClearLocalStateOnExit(clear_local_state); 1042 backend_->SetClearLocalStateOnExit(clear_local_state);
1008 } 1043 }
1009 1044
1010 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { 1045 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) {
1011 if (backend_.get()) 1046 if (backend_.get())
1012 backend_->Flush(callback); 1047 backend_->Flush(callback);
1013 else if (!callback.is_null()) 1048 else if (!callback.is_null())
1014 MessageLoop::current()->PostTask(FROM_HERE, callback); 1049 MessageLoop::current()->PostTask(FROM_HERE, callback);
1015 } 1050 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698