OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/webdata/web_database.h" | 5 #include "chrome/browser/webdata/web_database.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "chrome/browser/webdata/autofill_table.h" | 9 #include "chrome/browser/webdata/autofill_table.h" |
10 #include "chrome/browser/webdata/keyword_table.h" | 10 #include "chrome/browser/webdata/keyword_table.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 void WebDatabase::BeginTransaction() { | 56 void WebDatabase::BeginTransaction() { |
57 db_.BeginTransaction(); | 57 db_.BeginTransaction(); |
58 } | 58 } |
59 | 59 |
60 void WebDatabase::CommitTransaction() { | 60 void WebDatabase::CommitTransaction() { |
61 db_.CommitTransaction(); | 61 db_.CommitTransaction(); |
62 } | 62 } |
63 | 63 |
64 AutofillTable* WebDatabase::GetAutofillTable() { | 64 AutofillTable* WebDatabase::GetAutofillTable() { |
65 return autofill_table_.get(); | 65 return autofill_table_; |
66 } | 66 } |
67 | 67 |
68 KeywordTable* WebDatabase::GetKeywordTable() { | 68 KeywordTable* WebDatabase::GetKeywordTable() { |
69 return keyword_table_.get(); | 69 return keyword_table_; |
70 } | 70 } |
71 | 71 |
72 LoginsTable* WebDatabase::GetLoginsTable() { | 72 LoginsTable* WebDatabase::GetLoginsTable() { |
73 return logins_table_.get(); | 73 return logins_table_; |
74 } | 74 } |
75 | 75 |
76 TokenServiceTable* WebDatabase::GetTokenServiceTable() { | 76 TokenServiceTable* WebDatabase::GetTokenServiceTable() { |
77 return token_service_table_.get(); | 77 return token_service_table_; |
78 } | 78 } |
79 | 79 |
80 WebAppsTable* WebDatabase::GetWebAppsTable() { | 80 WebAppsTable* WebDatabase::GetWebAppsTable() { |
81 return web_apps_table_.get(); | 81 return web_apps_table_; |
82 } | 82 } |
83 | 83 |
84 sql::Connection* WebDatabase::GetSQLConnection() { | 84 sql::Connection* WebDatabase::GetSQLConnection() { |
85 return &db_; | 85 return &db_; |
86 } | 86 } |
87 | 87 |
88 sql::InitStatus WebDatabase::Init(const base::FilePath& db_name, | 88 sql::InitStatus WebDatabase::Init(const base::FilePath& db_name, |
89 const std::string& app_locale) { | 89 const std::string& app_locale) { |
90 // When running in unit tests, there is already a NotificationService object. | 90 // When running in unit tests, there is already a NotificationService object. |
91 // Since only one can exist at a time per thread, check first. | 91 // Since only one can exist at a time per thread, check first. |
(...skipping 24 matching lines...) Expand all Loading... |
116 return sql::INIT_FAILURE; | 116 return sql::INIT_FAILURE; |
117 | 117 |
118 // Version check. | 118 // Version check. |
119 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) | 119 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) |
120 return sql::INIT_FAILURE; | 120 return sql::INIT_FAILURE; |
121 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 121 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
122 LOG(WARNING) << "Web database is too new."; | 122 LOG(WARNING) << "Web database is too new."; |
123 return sql::INIT_TOO_NEW; | 123 return sql::INIT_TOO_NEW; |
124 } | 124 } |
125 | 125 |
| 126 // TODO(joi): Table creation should move out of this class; switch |
| 127 // to a two-phase init to accomplish this. |
| 128 |
126 // Create the tables. | 129 // Create the tables. |
127 autofill_table_.reset(new AutofillTable(&db_, &meta_table_)); | 130 autofill_table_ = new AutofillTable(&db_, &meta_table_); |
128 keyword_table_.reset(new KeywordTable(&db_, &meta_table_)); | 131 tables_.push_back(autofill_table_); |
| 132 |
| 133 keyword_table_ = new KeywordTable(&db_, &meta_table_); |
| 134 tables_.push_back(keyword_table_); |
| 135 |
129 // TODO(mdm): We only really need the LoginsTable on Windows for IE7 password | 136 // TODO(mdm): We only really need the LoginsTable on Windows for IE7 password |
130 // access, but for now, we still create it on all platforms since it deletes | 137 // access, but for now, we still create it on all platforms since it deletes |
131 // the old logins table. We can remove this after a while, e.g. in M22 or so. | 138 // the old logins table. We can remove this after a while, e.g. in M22 or so. |
132 logins_table_.reset(new LoginsTable(&db_, &meta_table_)); | 139 logins_table_ = new LoginsTable(&db_, &meta_table_); |
133 token_service_table_.reset(new TokenServiceTable(&db_, &meta_table_)); | 140 tables_.push_back(logins_table_); |
134 web_apps_table_.reset(new WebAppsTable(&db_, &meta_table_)); | 141 |
135 web_intents_table_.reset(new WebIntentsTable(&db_, &meta_table_)); | 142 token_service_table_ = new TokenServiceTable(&db_, &meta_table_); |
| 143 tables_.push_back(token_service_table_); |
| 144 |
| 145 web_apps_table_ = new WebAppsTable(&db_, &meta_table_); |
| 146 tables_.push_back(web_apps_table_); |
| 147 |
| 148 web_intents_table_ = new WebIntentsTable(&db_, &meta_table_); |
| 149 tables_.push_back(web_intents_table_); |
136 | 150 |
137 // Initialize the tables. | 151 // Initialize the tables. |
138 if (!keyword_table_->Init() || !autofill_table_->Init() || | 152 for (ScopedVector<WebDatabaseTable>::iterator it = tables_.begin(); |
139 !logins_table_->Init() || !web_apps_table_->Init() || | 153 it != tables_.end(); |
140 !token_service_table_->Init() || !web_intents_table_->Init()) { | 154 ++it) { |
141 LOG(WARNING) << "Unable to initialize the web database."; | 155 if (!(*it)->Init()) { |
142 return sql::INIT_FAILURE; | 156 LOG(WARNING) << "Unable to initialize the web database."; |
| 157 return sql::INIT_FAILURE; |
| 158 } |
143 } | 159 } |
144 | 160 |
145 // If the file on disk is an older database version, bring it up to date. | 161 // If the file on disk is an older database version, bring it up to date. |
146 // If the migration fails we return an error to caller and do not commit | 162 // If the migration fails we return an error to caller and do not commit |
147 // the migration. | 163 // the migration. |
148 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(app_locale); | 164 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(app_locale); |
149 if (migration_status != sql::INIT_OK) | 165 if (migration_status != sql::INIT_OK) |
150 return migration_status; | 166 return migration_status; |
151 | 167 |
152 return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; | 168 return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; |
153 } | 169 } |
154 | 170 |
155 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded( | 171 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded( |
156 const std::string& app_locale) { | 172 const std::string& app_locale) { |
157 // Some malware used to lower the version number, causing migration to | 173 // Some malware used to lower the version number, causing migration to |
158 // fail. Ensure the version number is at least as high as the compatible | 174 // fail. Ensure the version number is at least as high as the compatible |
159 // version number. | 175 // version number. |
160 int current_version = std::max(meta_table_.GetVersionNumber(), | 176 int current_version = std::max(meta_table_.GetVersionNumber(), |
161 meta_table_.GetCompatibleVersionNumber()); | 177 meta_table_.GetCompatibleVersionNumber()); |
162 if (current_version > meta_table_.GetVersionNumber()) | 178 if (current_version > meta_table_.GetVersionNumber()) |
163 ChangeVersion(&meta_table_, current_version, false); | 179 ChangeVersion(&meta_table_, current_version, false); |
164 | 180 |
165 // Migrate if necessary. | 181 if (current_version < 20) { |
166 switch (current_version) { | |
167 // Versions 1 - 19 are unhandled. Version numbers greater than | 182 // Versions 1 - 19 are unhandled. Version numbers greater than |
168 // kCurrentVersionNumber should have already been weeded out by the caller. | 183 // kCurrentVersionNumber should have already been weeded out by the caller. |
169 default: | 184 // |
170 // When the version is too old, we return failure error code. The schema | 185 // When the version is too old, we return failure error code. The schema |
171 // is too out of date to migrate. | 186 // is too out of date to migrate. |
172 // There should not be a released product that makes a database too old to | 187 // |
173 // migrate. If we do encounter such a legacy database, we will need a | 188 // There should not be a released product that makes a database too old to |
174 // better solution to handle it (i.e., pop up a dialog to tell the user, | 189 // migrate. If we do encounter such a legacy database, we will need a |
175 // erase all their prefs and start over, etc.). | 190 // better solution to handle it (i.e., pop up a dialog to tell the user, |
176 LOG(WARNING) << "Web database version " << current_version << | 191 // erase all their prefs and start over, etc.). |
177 " is too old to handle."; | 192 LOG(WARNING) << "Web database version " << current_version << |
178 NOTREACHED(); | 193 " is too old to handle."; |
179 return sql::INIT_FAILURE; | 194 NOTREACHED(); |
| 195 return sql::INIT_FAILURE; |
| 196 } |
180 | 197 |
181 case 20: | 198 for (int next_version = current_version + 1; |
182 if (!keyword_table_->MigrateToVersion21AutoGenerateKeywordColumn()) | 199 next_version <= kCurrentVersionNumber; |
183 return FailedMigrationTo(21); | 200 ++next_version) { |
| 201 // Give each table a chance to migrate to this version. |
| 202 for (ScopedVector<WebDatabaseTable>::iterator it = tables_.begin(); |
| 203 it != tables_.end(); |
| 204 ++it) { |
| 205 // Any of the tables may set this to true, but by default it is false. |
| 206 bool update_compatible_version = false; |
| 207 if (!(*it)->MigrateToVersion(next_version, |
| 208 app_locale, |
| 209 &update_compatible_version)) { |
| 210 return FailedMigrationTo(next_version); |
| 211 } |
184 | 212 |
185 ChangeVersion(&meta_table_, 21, true); | 213 ChangeVersion(&meta_table_, next_version, update_compatible_version); |
186 // FALL THROUGH | 214 } |
187 | |
188 case 21: | |
189 if (!autofill_table_->ClearAutofillEmptyValueElements()) | |
190 return FailedMigrationTo(22); | |
191 | |
192 ChangeVersion(&meta_table_, 22, false); | |
193 // FALL THROUGH | |
194 | |
195 case 22: | |
196 if (!autofill_table_->MigrateToVersion23AddCardNumberEncryptedColumn()) | |
197 return FailedMigrationTo(23); | |
198 | |
199 ChangeVersion(&meta_table_, 23, false); | |
200 // FALL THROUGH | |
201 | |
202 case 23: | |
203 if (!autofill_table_->MigrateToVersion24CleanupOversizedStringFields()) | |
204 return FailedMigrationTo(24); | |
205 | |
206 ChangeVersion(&meta_table_, 24, false); | |
207 // FALL THROUGH | |
208 | |
209 case 24: | |
210 if (!keyword_table_->MigrateToVersion25AddLogoIDColumn()) | |
211 return FailedMigrationTo(25); | |
212 | |
213 ChangeVersion(&meta_table_, 25, true); | |
214 // FALL THROUGH | |
215 | |
216 case 25: | |
217 if (!keyword_table_->MigrateToVersion26AddCreatedByPolicyColumn()) | |
218 return FailedMigrationTo(26); | |
219 | |
220 ChangeVersion(&meta_table_, 26, true); | |
221 // FALL THROUGH | |
222 | |
223 case 26: | |
224 if (!autofill_table_->MigrateToVersion27UpdateLegacyCreditCards()) | |
225 return FailedMigrationTo(27); | |
226 | |
227 ChangeVersion(&meta_table_, 27, true); | |
228 // FALL THROUGH | |
229 | |
230 case 27: | |
231 if (!keyword_table_->MigrateToVersion28SupportsInstantColumn()) | |
232 return FailedMigrationTo(28); | |
233 | |
234 ChangeVersion(&meta_table_, 28, true); | |
235 // FALL THROUGH | |
236 | |
237 case 28: | |
238 if (!keyword_table_->MigrateToVersion29InstantURLToSupportsInstant()) | |
239 return FailedMigrationTo(29); | |
240 | |
241 ChangeVersion(&meta_table_, 29, true); | |
242 // FALL THROUGH | |
243 | |
244 case 29: | |
245 if (!autofill_table_->MigrateToVersion30AddDateModifed()) | |
246 return FailedMigrationTo(30); | |
247 | |
248 ChangeVersion(&meta_table_, 30, true); | |
249 // FALL THROUGH | |
250 | |
251 case 30: | |
252 if (!autofill_table_->MigrateToVersion31AddGUIDToCreditCardsAndProfiles()) | |
253 return FailedMigrationTo(31); | |
254 | |
255 ChangeVersion(&meta_table_, 31, true); | |
256 // FALL THROUGH | |
257 | |
258 case 31: | |
259 if (!autofill_table_->MigrateToVersion32UpdateProfilesAndCreditCards()) | |
260 return FailedMigrationTo(32); | |
261 | |
262 ChangeVersion(&meta_table_, 32, true); | |
263 // FALL THROUGH | |
264 | |
265 case 32: | |
266 if (!autofill_table_->MigrateToVersion33ProfilesBasedOnFirstName()) | |
267 return FailedMigrationTo(33); | |
268 | |
269 ChangeVersion(&meta_table_, 33, true); | |
270 // FALL THROUGH | |
271 | |
272 case 33: | |
273 if (!autofill_table_->MigrateToVersion34ProfilesBasedOnCountryCode( | |
274 app_locale)) | |
275 return FailedMigrationTo(34); | |
276 | |
277 ChangeVersion(&meta_table_, 34, true); | |
278 // FALL THROUGH | |
279 | |
280 case 34: | |
281 if (!autofill_table_->MigrateToVersion35GreatBritainCountryCodes()) | |
282 return FailedMigrationTo(35); | |
283 | |
284 ChangeVersion(&meta_table_, 35, true); | |
285 // FALL THROUGH | |
286 | |
287 // Combine migrations 35 and 36. This is due to enhancements to the merge | |
288 // step when migrating profiles. The original migration from 35 to 36 did | |
289 // not merge profiles with identical addresses, but the migration from 36 to | |
290 // 37 does. The step from 35 to 36 should only happen on the Chrome 12 dev | |
291 // channel. Chrome 12 beta and release users will jump from 35 to 37 | |
292 // directly getting the full benefits of the multi-valued merge as well as | |
293 // the culling of bad data. | |
294 case 35: | |
295 case 36: | |
296 if (!autofill_table_->MigrateToVersion37MergeAndCullOlderProfiles()) | |
297 return FailedMigrationTo(37); | |
298 | |
299 ChangeVersion(&meta_table_, 37, true); | |
300 // FALL THROUGH | |
301 | |
302 case 37: | |
303 if (!keyword_table_->MigrateToVersion38AddLastModifiedColumn()) | |
304 return FailedMigrationTo(38); | |
305 | |
306 ChangeVersion(&meta_table_, 38, true); | |
307 // FALL THROUGH | |
308 | |
309 case 38: | |
310 if (!keyword_table_->MigrateToVersion39AddSyncGUIDColumn()) | |
311 return FailedMigrationTo(39); | |
312 | |
313 ChangeVersion(&meta_table_, 39, true); | |
314 // FALL THROUGH | |
315 | |
316 // Subsequent search engine backup migrations are merged into a single one. | |
317 case 39: | |
318 case 40: | |
319 case 41: | |
320 case 42: | |
321 case 43: | |
322 if (!keyword_table_->MigrateToVersion44AddDefaultSearchProviderBackup()) | |
323 return FailedMigrationTo(44); | |
324 | |
325 ChangeVersion(&meta_table_, 44, true); | |
326 // FALL THROUGH | |
327 | |
328 case 44: | |
329 if (!keyword_table_-> | |
330 MigrateToVersion45RemoveLogoIDAndAutogenerateColumns()) | |
331 return FailedMigrationTo(45); | |
332 | |
333 ChangeVersion(&meta_table_, 45, true); | |
334 // FALL THROUGH | |
335 | |
336 case 45: | |
337 if (!web_intents_table_->MigrateToVersion46AddSchemeColumn()) | |
338 return FailedMigrationTo(46); | |
339 | |
340 ChangeVersion(&meta_table_, 46, true); | |
341 // FALL THROUGH | |
342 | |
343 case 46: | |
344 if (!keyword_table_->MigrateToVersion47AddAlternateURLsColumn()) | |
345 return FailedMigrationTo(47); | |
346 | |
347 ChangeVersion(&meta_table_, 47, true); | |
348 // FALL THROUGH | |
349 | |
350 case 47: | |
351 if (!keyword_table_->MigrateToVersion48RemoveKeywordsBackup()) | |
352 return FailedMigrationTo(48); | |
353 | |
354 ChangeVersion(&meta_table_, 48, true); | |
355 // FALL THROUGH | |
356 | |
357 case 48: | |
358 if (!keyword_table_-> | |
359 MigrateToVersion49AddSearchTermsReplacementKeyColumn()) | |
360 return FailedMigrationTo(49); | |
361 | |
362 ChangeVersion(&meta_table_, 49, true); | |
363 // FALL THROUGH | |
364 | |
365 // Add successive versions here. Each should set the version number and | |
366 // compatible version number as appropriate, then fall through to the next | |
367 // case. | |
368 | |
369 case kCurrentVersionNumber: | |
370 // No migration needed. | |
371 return sql::INIT_OK; | |
372 } | 215 } |
| 216 return sql::INIT_OK; |
373 } | 217 } |
OLD | NEW |