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 |