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