| OLD | NEW | 
|    1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2009 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  |    8  | 
|    9 #include "app/sql/statement.h" |    9 #include "app/sql/statement.h" | 
|   10 #include "app/sql/transaction.h" |   10 #include "app/sql/transaction.h" | 
|   11 #include "base/basictypes.h" |   11 #include "base/basictypes.h" | 
|   12 #include "base/logging.h" |   12 #include "base/logging.h" | 
|   13 #include "base/ref_counted.h" |   13 #include "base/ref_counted.h" | 
|   14 #include "base/scoped_ptr.h" |   14 #include "base/scoped_ptr.h" | 
|   15 #include "base/string_util.h" |   15 #include "base/string_util.h" | 
|   16 #include "base/thread.h" |   16 #include "base/thread.h" | 
 |   17 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 
|   17  |   18  | 
|   18 using base::Time; |   19 using base::Time; | 
|   19  |   20  | 
|   20 // This class is designed to be shared between any calling threads and the |   21 // This class is designed to be shared between any calling threads and the | 
|   21 // database thread.  It batches operations and commits them on a timer. |   22 // database thread.  It batches operations and commits them on a timer. | 
|   22 class SQLitePersistentCookieStore::Backend |   23 class SQLitePersistentCookieStore::Backend | 
|   23     : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { |   24     : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { | 
|   24  public: |   25  public: | 
|   25   // The passed database pointer must be already-initialized. This object will |   26   // The passed database pointer must be already-initialized. This object will | 
|   26   // take ownership. |   27   // take ownership. | 
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  274 // are the same. |  275 // are the same. | 
|  275 // |  276 // | 
|  276 // Version 3 updated the database to include the last access time, so we can |  277 // Version 3 updated the database to include the last access time, so we can | 
|  277 // expire them in decreasing order of use when we've reached the maximum |  278 // expire them in decreasing order of use when we've reached the maximum | 
|  278 // number of cookies. |  279 // number of cookies. | 
|  279 static const int kCurrentVersionNumber = 4; |  280 static const int kCurrentVersionNumber = 4; | 
|  280 static const int kCompatibleVersionNumber = 3; |  281 static const int kCompatibleVersionNumber = 3; | 
|  281  |  282  | 
|  282 namespace { |  283 namespace { | 
|  283  |  284  | 
|  284 // This class handles the exceptional sqlite errors that we might encounter |  | 
|  285 // if for example the db is corrupted. Right now we just generate a UMA |  | 
|  286 // histogram for release and an assert for debug builds. |  | 
|  287 class CookieDbSqliteErrrorHandler : public sql::ErrorDelegate { |  | 
|  288  public: |  | 
|  289   virtual int OnError(int error, sql::Connection* connection, |  | 
|  290                       sql::Statement* stmt) { |  | 
|  291     NOTREACHED() << "cookie db sqlite error " << error; |  | 
|  292     RecordErrorInHistogram(error); |  | 
|  293     return error; |  | 
|  294   } |  | 
|  295  private: |  | 
|  296   static void RecordErrorInHistogram(int error) { |  | 
|  297     // The histogram values from sqlite result codes go currently from 1 to |  | 
|  298     // 26 currently but 50 gives them room to grow. |  | 
|  299     static LinearHistogram histogram("Sqlite.Cookie.Error", 1, 50, 51); |  | 
|  300     histogram.SetFlags(kUmaTargetedHistogramFlag); |  | 
|  301     histogram.Add(error); |  | 
|  302   } |  | 
|  303 }; |  | 
|  304  |  | 
|  305 // Initializes the cookies table, returning true on success. |  285 // Initializes the cookies table, returning true on success. | 
|  306 bool InitTable(sql::Connection* db) { |  286 bool InitTable(sql::Connection* db) { | 
|  307   if (!db->DoesTableExist("cookies")) { |  287   if (!db->DoesTableExist("cookies")) { | 
|  308     if (!db->Execute("CREATE TABLE cookies (" |  288     if (!db->Execute("CREATE TABLE cookies (" | 
|  309                      "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," |  289                      "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," | 
|  310                      "host_key TEXT NOT NULL," |  290                      "host_key TEXT NOT NULL," | 
|  311                      "name TEXT NOT NULL," |  291                      "name TEXT NOT NULL," | 
|  312                      "value TEXT NOT NULL," |  292                      "value TEXT NOT NULL," | 
|  313                      "path TEXT NOT NULL," |  293                      "path TEXT NOT NULL," | 
|  314                      // We only store persistent, so we know it expires |  294                      // We only store persistent, so we know it expires | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  328 }  // namespace |  308 }  // namespace | 
|  329  |  309  | 
|  330 bool SQLitePersistentCookieStore::Load( |  310 bool SQLitePersistentCookieStore::Load( | 
|  331     std::vector<net::CookieMonster::KeyedCanonicalCookie>* cookies) { |  311     std::vector<net::CookieMonster::KeyedCanonicalCookie>* cookies) { | 
|  332   scoped_ptr<sql::Connection> db(new sql::Connection); |  312   scoped_ptr<sql::Connection> db(new sql::Connection); | 
|  333   if (!db->Open(path_)) { |  313   if (!db->Open(path_)) { | 
|  334     NOTREACHED() << "Unable to open cookie DB."; |  314     NOTREACHED() << "Unable to open cookie DB."; | 
|  335     return false; |  315     return false; | 
|  336   } |  316   } | 
|  337  |  317  | 
|  338   db->set_error_delegate(new CookieDbSqliteErrrorHandler()); |  318   db->set_error_delegate(GetErrorHandlerForCookieDb()); | 
|  339  |  319  | 
|  340   if (!EnsureDatabaseVersion(db.get()) || !InitTable(db.get())) { |  320   if (!EnsureDatabaseVersion(db.get()) || !InitTable(db.get())) { | 
|  341     NOTREACHED() << "Unable to initialize cookie DB."; |  321     NOTREACHED() << "Unable to initialize cookie DB."; | 
|  342     return false; |  322     return false; | 
|  343   } |  323   } | 
|  344  |  324  | 
|  345   db->Preload(); |  325   db->Preload(); | 
|  346  |  326  | 
|  347   // Slurp all the cookies into the out-vector. |  327   // Slurp all the cookies into the out-vector. | 
|  348   sql::Statement smt(db->GetUniqueStatement( |  328   sql::Statement smt(db->GetUniqueStatement( | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  460     const net::CookieMonster::CanonicalCookie& cc) { |  440     const net::CookieMonster::CanonicalCookie& cc) { | 
|  461   if (backend_.get()) |  441   if (backend_.get()) | 
|  462     backend_->UpdateCookieAccessTime(cc); |  442     backend_->UpdateCookieAccessTime(cc); | 
|  463 } |  443 } | 
|  464  |  444  | 
|  465 void SQLitePersistentCookieStore::DeleteCookie( |  445 void SQLitePersistentCookieStore::DeleteCookie( | 
|  466     const net::CookieMonster::CanonicalCookie& cc) { |  446     const net::CookieMonster::CanonicalCookie& cc) { | 
|  467   if (backend_.get()) |  447   if (backend_.get()) | 
|  468     backend_->DeleteCookie(cc); |  448     backend_->DeleteCookie(cc); | 
|  469 } |  449 } | 
| OLD | NEW |