Home | History | Annotate | Download | only in history
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
      6 #define CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/gtest_prod_util.h"
     11 #include "build/build_config.h"
     12 #include "chrome/browser/history/download_database.h"
     13 #include "chrome/browser/history/visit_database.h"
     14 #include "chrome/browser/history/visitsegment_database.h"
     15 #include "components/history/core/browser/url_database.h"
     16 #include "sql/connection.h"
     17 #include "sql/init_status.h"
     18 #include "sql/meta_table.h"
     19 
     20 #if defined(OS_ANDROID)
     21 #include "chrome/browser/history/android/android_cache_database.h"
     22 #include "chrome/browser/history/android/android_urls_database.h"
     23 #endif
     24 
     25 namespace base {
     26 class FilePath;
     27 }
     28 
     29 class HistoryQuickProviderTest;
     30 
     31 namespace history {
     32 
     33 // Encapsulates the SQL connection for the history database. This class holds
     34 // the database connection and has methods the history system (including full
     35 // text search) uses for writing and retrieving information.
     36 //
     37 // We try to keep most logic out of the history database; this should be seen
     38 // as the storage interface. Logic for manipulating this storage layer should
     39 // be in HistoryBackend.cc.
     40 class HistoryDatabase : public DownloadDatabase,
     41 #if defined(OS_ANDROID)
     42                         public AndroidURLsDatabase,
     43                         public AndroidCacheDatabase,
     44 #endif
     45                         public URLDatabase,
     46                         public VisitDatabase,
     47                         public VisitSegmentDatabase {
     48  public:
     49   // A simple class for scoping a history database transaction. This does not
     50   // support rollback since the history database doesn't, either.
     51   class TransactionScoper {
     52    public:
     53     explicit TransactionScoper(HistoryDatabase* db) : db_(db) {
     54       db_->BeginTransaction();
     55     }
     56     ~TransactionScoper() {
     57       db_->CommitTransaction();
     58     }
     59    private:
     60     HistoryDatabase* db_;
     61   };
     62 
     63   // Must call Init() to complete construction. Although it can be created on
     64   // any thread, it must be destructed on the history thread for proper
     65   // database cleanup.
     66   HistoryDatabase();
     67 
     68   virtual ~HistoryDatabase();
     69 
     70   // Call before Init() to set the error callback to be used for the
     71   // underlying database connection.
     72   void set_error_callback(
     73       const sql::Connection::ErrorCallback& error_callback) {
     74     error_callback_ = error_callback;
     75   }
     76 
     77   // Must call this function to complete initialization. Will return
     78   // sql::INIT_OK on success. Otherwise, no other function should be called. You
     79   // may want to call BeginExclusiveMode after this when you are ready.
     80   sql::InitStatus Init(const base::FilePath& history_name);
     81 
     82   // Computes and records various metrics for the database. Should only be
     83   // called once and only upon successful Init.
     84   void ComputeDatabaseMetrics(const base::FilePath& filename);
     85 
     86   // Call to set the mode on the database to exclusive. The default locking mode
     87   // is "normal" but we want to run in exclusive mode for slightly better
     88   // performance since we know nobody else is using the database. This is
     89   // separate from Init() since the in-memory database attaches to slurp the
     90   // data out, and this can't happen in exclusive mode.
     91   void BeginExclusiveMode();
     92 
     93   // Returns the current version that we will generate history databases with.
     94   static int GetCurrentVersion();
     95 
     96   // Transactions on the history database. Use the Transaction object above
     97   // for most work instead of these directly. We support nested transactions
     98   // and only commit when the outermost transaction is committed. This means
     99   // that it is impossible to rollback a specific transaction. We could roll
    100   // back the outermost transaction if any inner one is rolled back, but it
    101   // turns out we don't really need this type of integrity for the history
    102   // database, so we just don't support it.
    103   void BeginTransaction();
    104   void CommitTransaction();
    105   int transaction_nesting() const {  // for debugging and assertion purposes
    106     return db_.transaction_nesting();
    107   }
    108   void RollbackTransaction();
    109 
    110   // Drops all tables except the URL, and download tables, and recreates them
    111   // from scratch. This is done to rapidly clean up stuff when deleting all
    112   // history. It is faster and less likely to have problems that deleting all
    113   // rows in the tables.
    114   //
    115   // We don't delete the downloads table, since there may be in progress
    116   // downloads. We handle the download history clean up separately in:
    117   // content::DownloadManager::RemoveDownloadsFromHistoryBetween.
    118   //
    119   // Returns true on success. On failure, the caller should assume that the
    120   // database is invalid. There could have been an error recreating a table.
    121   // This should be treated the same as an init failure, and the database
    122   // should not be used any more.
    123   //
    124   // This will also recreate the supplementary URL indices, since these
    125   // indices won't be created automatically when using the temporary URL
    126   // table (what the caller does right before calling this).
    127   bool RecreateAllTablesButURL();
    128 
    129   // Vacuums the database. This will cause sqlite to defragment and collect
    130   // unused space in the file. It can be VERY SLOW.
    131   void Vacuum();
    132 
    133   // Try to trim the cache memory used by the database.  If |aggressively| is
    134   // true try to trim all unused cache, otherwise trim by half.
    135   void TrimMemory(bool aggressively);
    136 
    137   // Razes the database. Returns true if successful.
    138   bool Raze();
    139 
    140   // Visit table functions ----------------------------------------------------
    141 
    142   // Update the segment id of a visit. Return true on success.
    143   bool SetSegmentID(VisitID visit_id, SegmentID segment_id);
    144 
    145   // Query the segment ID for the provided visit. Return 0 on failure or if the
    146   // visit id wasn't found.
    147   SegmentID GetSegmentID(VisitID visit_id);
    148 
    149   // Retrieves/Updates early expiration threshold, which specifies the earliest
    150   // known point in history that may possibly to contain visits suitable for
    151   // early expiration (AUTO_SUBFRAMES).
    152   virtual base::Time GetEarlyExpirationThreshold();
    153   virtual void UpdateEarlyExpirationThreshold(base::Time threshold);
    154 
    155  private:
    156 #if defined(OS_ANDROID)
    157   // AndroidProviderBackend uses the |db_|.
    158   friend class AndroidProviderBackend;
    159   FRIEND_TEST_ALL_PREFIXES(AndroidURLsMigrationTest, MigrateToVersion22);
    160 #endif
    161   friend class ::HistoryQuickProviderTest;
    162   friend class InMemoryURLIndexTest;
    163 
    164   // Overridden from URLDatabase:
    165   virtual sql::Connection& GetDB() OVERRIDE;
    166 
    167   // Migration -----------------------------------------------------------------
    168 
    169   // Makes sure the version is up-to-date, updating if necessary. If the
    170   // database is too old to migrate, the user will be notified. Returns
    171   // sql::INIT_OK iff  the DB is up-to-date and ready for use.
    172   //
    173   // This assumes it is called from the init function inside a transaction. It
    174   // may commit the transaction and start a new one if migration requires it.
    175   sql::InitStatus EnsureCurrentVersion();
    176 
    177 #if !defined(OS_WIN)
    178   // Converts the time epoch in the database from being 1970-based to being
    179   // 1601-based which corresponds to the change in Time.internal_value_.
    180   void MigrateTimeEpoch();
    181 #endif
    182 
    183   // ---------------------------------------------------------------------------
    184 
    185   sql::Connection::ErrorCallback error_callback_;
    186   sql::Connection db_;
    187   sql::MetaTable meta_table_;
    188 
    189   base::Time cached_early_expiration_threshold_;
    190 
    191   DISALLOW_COPY_AND_ASSIGN(HistoryDatabase);
    192 };
    193 
    194 }  // namespace history
    195 
    196 #endif  // CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
    197