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