OLD | NEW |
| (Empty) |
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_IN_MEMORY_URL_CACHE_DATABASE_H_ | |
6 #define CHROME_BROWSER_HISTORY_IN_MEMORY_URL_CACHE_DATABASE_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/callback_forward.h" | |
12 #include "base/gtest_prod_util.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/threading/sequenced_worker_pool.h" | |
15 #include "chrome/browser/history/in_memory_url_index_types.h" | |
16 #include "sql/connection.h" | |
17 #include "sql/init_status.h" | |
18 #include "sql/meta_table.h" | |
19 | |
20 class FilePath; | |
21 | |
22 namespace sql { | |
23 class Statement; | |
24 } | |
25 | |
26 namespace history { | |
27 | |
28 class InMemoryURLIndex; | |
29 class URLIndexPrivateData; | |
30 | |
31 // Supports caching and restoring of the private data of the InMemoryURLIndex. | |
32 // This class has intimate knowledge of InMemoryURLIndex's URLIndexPrivateData | |
33 // class and directly pokes data therein during cache restoration. The only | |
34 // client of this class is URLIndexPrivateData. | |
35 // | |
36 // Tables in this database: | |
37 // word - Indexed words with IDs (from word_map_ and word_list_). | |
38 // char_words - Indexed characters with IDs of words containing the | |
39 // character (from char_word_map_). | |
40 // word_history - Word IDs with the IDs of history items containing the | |
41 // word (from word_id_history_map_). | |
42 // url - URLs and page titles along with visit and other metrics | |
43 // (from the history_info_map_ and word_starts_map_). | |
44 // url_word_starts - History IDs with the starting position of each word | |
45 // found in its URL. | |
46 // title_word_starts - History IDs with the starting position of each word | |
47 // found in its page title. | |
48 // | |
49 // NOTE: The history IDs in this database for URLs are identical to those in the | |
50 // main history database. | |
51 class InMemoryURLCacheDatabase | |
52 : public base::RefCountedThreadSafe<InMemoryURLCacheDatabase> { | |
53 public: | |
54 InMemoryURLCacheDatabase(); | |
55 | |
56 // Initializes the database connection. This must return true before any other | |
57 // functions on this class are called. |file_path| gives the path to where | |
58 // the cache database is located. |sequence_token| is used to coordinate all | |
59 // access to the cache database. This is normally called on the DB thread but | |
60 // may also be called in the sequenced worker pool for certain unit tests. | |
61 bool Init(const FilePath& file_path, | |
62 const base::SequencedWorkerPool::SequenceToken& sequence_token); | |
63 | |
64 // Shuts down the database connection. Posts a sequenced task that performs | |
65 // the matching ShutDownTask function below. | |
66 void Shutdown(); | |
67 | |
68 // Restore the private InMemoryURLIndex |data| from the database. Returns true | |
69 // if there was data to restore and the restore was successful. It is | |
70 // considered an error and false is returned if _any_ of the restored data | |
71 // structures in the private data, except |available_words_|, are empty after | |
72 // restoration. Technically, the case where _all_ data structures are empty | |
73 // after a restore is an error only when the user's history has _not_ been | |
74 // cleared. In the case where history _has_ been cleared and the data | |
75 // structures are legitimately empty we still return a false as the cost of | |
76 // attempting to rebuild the private data from an empty history database is | |
77 // negligible. | |
78 bool RestorePrivateData(URLIndexPrivateData* data); | |
79 | |
80 // Reset the database by dropping and recreating all database tables. Return | |
81 // true if successful. Note that a failure does not close the database. | |
82 virtual bool Reset(); | |
83 | |
84 // Adds information for a new |row| to the various database tables. These | |
85 // functions post a sequenced task that performs the matching '[name]Task' | |
86 // functions below. The client should wrap these functions in a transaction | |
87 // by the client by calling BeginTransaction(), whatever combination of these | |
88 // function as appropriate, and finally CommitTransaction(). The | |
89 // CommitTransaction() will notify the client if any failure occurs. | |
90 void AddHistoryToURLs(HistoryID history_id, const URLRow& row); | |
91 void AddHistoryToWordHistory(WordID word_id, HistoryID history_id); | |
92 void AddWordToWords(WordID word_id, const string16& uni_word); | |
93 void AddWordToCharWords(char16 uni_char, WordID word_id); | |
94 void AddRowWordStarts(HistoryID history_id, | |
95 const RowWordStarts& row_word_starts); | |
96 | |
97 // Deletes row information from the various database tables. These functions | |
98 // post a sequenced task that performs the matching '[name]Task' functions | |
99 // below. | |
100 void RemoveHistoryIDFromURLs(HistoryID history_id); | |
101 void RemoveHistoryIDFromWordHistory(HistoryID history_id); | |
102 void RemoveWordFromWords(WordID word_id); | |
103 void RemoveWordStarts(HistoryID history_id); | |
104 | |
105 // Wraps transactions on the database. We support nested transactions and only | |
106 // commit when the outermost one is committed (sqlite doesn't support true | |
107 // nested transactions). These functions post a sequenced task that performs | |
108 // the matching '[name]Task' functions below. | |
109 void BeginTransaction(); | |
110 void CommitTransaction(); | |
111 | |
112 // Completely replaces all data in the cache database with a fresh image. | |
113 // Returns true upon success. Must not be called on the main thread and and | |
114 // the caller should ensure that no other cache database update operations | |
115 // take place while this method is being performed. Returns true if the | |
116 // refresh was successful. | |
117 virtual bool Refresh(const URLIndexPrivateData& index_data); | |
118 | |
119 private: | |
120 friend class base::RefCountedThreadSafe<InMemoryURLCacheDatabase>; | |
121 friend class InMemoryURLIndexCacheTest; | |
122 friend class InMemoryURLIndexTest; | |
123 friend class InterposingCacheDatabase; | |
124 FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, CacheAddRemove); | |
125 | |
126 virtual ~InMemoryURLCacheDatabase(); | |
127 | |
128 // Initializes the database and returns true if successful. | |
129 bool InitDatabase(); | |
130 | |
131 // Posts the given |task| for sequential execution using a pool task | |
132 // coordinated by |sequence_token_|. | |
133 void PostSequencedDBTask(const tracked_objects::Location& from_here, | |
134 const base::Closure& task); | |
135 | |
136 // Closes the database. | |
137 void ShutdownTask(); | |
138 | |
139 // Makes sure the version is up-to-date, updating if necessary. Notify the | |
140 // user if the database is newer than expected. | |
141 sql::InitStatus EnsureCurrentVersion(); | |
142 | |
143 // Starts a database transaction. | |
144 void BeginTransactionTask(); | |
145 | |
146 // Commits the database transaction if no update operations failed after | |
147 // BeginTransactionTask() was called, otherwise rolls back the transaction. | |
148 // Sends a NOTIFICATION_IN_MEMORY_URL_CACHE_DATABASE_FAILURE notification | |
149 // if the transaction failed. | |
150 void CommitTransactionTask(); | |
151 | |
152 // Returns true if all tables exist. | |
153 bool VerifyTables(); | |
154 | |
155 // Creates the various tables and indexes returning true if successful. | |
156 bool CreateTables(); | |
157 | |
158 // Notifies observers that a failure occurred during a database update | |
159 // operation. | |
160 void NotifyDatabaseFailure(); | |
161 | |
162 // Executes |statement|, sets |update_error_| if the statement did not | |
163 // run successfully, and returns true if the statement was run successfully. | |
164 bool RunStatement(sql::Statement* statement); | |
165 | |
166 // Adds information about a new row to the various database tables. | |
167 void AddHistoryToURLsTask(HistoryID history_id, const URLRow& row); | |
168 void AddHistoryToWordHistoryTask(WordID word_id, HistoryID history_id); | |
169 // Note: AddWordToWordsTask is virtual so that it can be overridden by | |
170 // unit tests to simulate database failures. | |
171 virtual void AddWordToWordsTask(WordID word_id, const string16& uni_word); | |
172 void AddWordToCharWordsTask(char16 uni_char, WordID word_id); | |
173 void AddRowWordStartsTask(HistoryID history_id, | |
174 const RowWordStarts& row_word_starts); | |
175 | |
176 // Deletes row information from the various database tables. Returns true if | |
177 // successful. | |
178 void RemoveHistoryIDFromURLsTask(HistoryID history_id); | |
179 void RemoveHistoryIDFromWordHistoryTask(HistoryID history_id); | |
180 void RemoveWordFromWordsTask(WordID word_id); | |
181 void RemoveWordStartsTask(HistoryID history_id); | |
182 | |
183 // Completely replaces all data in the cache with a fresh image. Returns true | |
184 // if successful. | |
185 bool RefreshWords(const URLIndexPrivateData& index_data); | |
186 bool RefreshCharWords(const URLIndexPrivateData& index_data); | |
187 bool RefreshWordHistory(const URLIndexPrivateData& index_data); | |
188 bool RefreshURLs(const URLIndexPrivateData& index_data); | |
189 bool RefreshWordStarts(const URLIndexPrivateData& index_data); | |
190 | |
191 // Restores individual sections of the private data for the InMemoryURLIndex. | |
192 // Returns true if there was data to restore and the restore was successful. | |
193 bool RestoreWords(URLIndexPrivateData* index_data); | |
194 bool RestoreCharWords(URLIndexPrivateData* index_data); | |
195 bool RestoreWordHistory(URLIndexPrivateData* index_data); | |
196 bool RestoreURLs(URLIndexPrivateData* index_data); | |
197 bool RestoreWordStarts(URLIndexPrivateData* index_data); | |
198 | |
199 // Returns the database connection. | |
200 sql::Connection* get_db_for_testing() { return &db_; } | |
201 | |
202 // Sequence token for coordinating database tasks. | |
203 base::SequencedWorkerPool::SequenceToken sequence_token_; | |
204 | |
205 // The database. | |
206 sql::Connection db_; | |
207 sql::MetaTable meta_table_; | |
208 int update_error_; | |
209 | |
210 // Set to true once the shutdown process has begun. | |
211 bool shutdown_; | |
212 | |
213 DISALLOW_COPY_AND_ASSIGN(InMemoryURLCacheDatabase); | |
214 }; | |
215 | |
216 } // namespace history | |
217 | |
218 #endif // CHROME_BROWSER_HISTORY_IN_MEMORY_URL_CACHE_DATABASE_H_ | |
OLD | NEW |