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 // Returns true if the history backend should erase the full text search 142 // and archived history files as part of version 16 -> 17 migration. The 143 // time format changed in this revision, and these files would be much slower 144 // to migrate. Since the data is less important, they should be deleted. 145 // 146 // This flag will be valid after Init() is called. It will always be false 147 // when running on Windows. 148 bool needs_version_17_migration() const { 149 return needs_version_17_migration_; 150 } 151 152 // Visit table functions ---------------------------------------------------- 153 154 // Update the segment id of a visit. Return true on success. 155 bool SetSegmentID(VisitID visit_id, SegmentID segment_id); 156 157 // Query the segment ID for the provided visit. Return 0 on failure or if the 158 // visit id wasn't found. 159 SegmentID GetSegmentID(VisitID visit_id); 160 161 // Retrieves/Updates early expiration threshold, which specifies the earliest 162 // known point in history that may possibly to contain visits suitable for 163 // early expiration (AUTO_SUBFRAMES). 164 virtual base::Time GetEarlyExpirationThreshold(); 165 virtual void UpdateEarlyExpirationThreshold(base::Time threshold); 166 167 private: 168 #if defined(OS_ANDROID) 169 // AndroidProviderBackend uses the |db_|. 170 friend class AndroidProviderBackend; 171 FRIEND_TEST_ALL_PREFIXES(AndroidURLsMigrationTest, MigrateToVersion22); 172 #endif 173 friend class ::HistoryQuickProviderTest; 174 friend class InMemoryURLIndexTest; 175 176 // Overridden from URLDatabase: 177 virtual sql::Connection& GetDB() OVERRIDE; 178 179 // Migration ----------------------------------------------------------------- 180 181 // Makes sure the version is up-to-date, updating if necessary. If the 182 // database is too old to migrate, the user will be notified. Returns 183 // sql::INIT_OK iff the DB is up-to-date and ready for use. 184 // 185 // This assumes it is called from the init function inside a transaction. It 186 // may commit the transaction and start a new one if migration requires it. 187 sql::InitStatus EnsureCurrentVersion(); 188 189 #if !defined(OS_WIN) 190 // Converts the time epoch in the database from being 1970-based to being 191 // 1601-based which corresponds to the change in Time.internal_value_. 192 void MigrateTimeEpoch(); 193 #endif 194 195 // --------------------------------------------------------------------------- 196 197 sql::Connection::ErrorCallback error_callback_; 198 sql::Connection db_; 199 sql::MetaTable meta_table_; 200 201 base::Time cached_early_expiration_threshold_; 202 203 // See the getters above. 204 bool needs_version_17_migration_; 205 206 DISALLOW_COPY_AND_ASSIGN(HistoryDatabase); 207 }; 208 209 } // namespace history 210 211 #endif // CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_ 212