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 25namespace base { 26class FilePath; 27} 28 29class HistoryQuickProviderTest; 30 31namespace 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. 40class 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