Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |