• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TransactionScoper(HistoryDatabase * db)54     explicit TransactionScoper(HistoryDatabase* db) : db_(db) {
55       db_->BeginTransaction();
56     }
~TransactionScoper()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.
set_error_callback(const sql::Connection::ErrorCallback & error_callback)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();
transaction_nesting()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.
needs_version_17_migration()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