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: TransactionScoper(HistoryDatabase * db)46 explicit TransactionScoper(HistoryDatabase* db) : db_(db) { 47 db_->BeginTransaction(); 48 } ~TransactionScoper()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(); transaction_nesting()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. needs_version_17_migration()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