OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include <limits> | |
9 #include <set> | |
10 #include <string> | |
11 | 8 |
12 #include "app/sql/statement.h" | 9 #include "app/sql/statement.h" |
13 #include "app/sql/transaction.h" | 10 #include "app/sql/transaction.h" |
14 #include "base/string_number_conversions.h" | |
15 #include "chrome/browser/autofill/autofill_country.h" | |
16 #include "chrome/browser/autofill/autofill_profile.h" | |
17 #include "chrome/browser/autofill/autofill_type.h" | |
18 #include "chrome/browser/autofill/personal_data_manager.h" | |
19 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 11 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
20 #include "chrome/browser/webdata/autofill_util.h" | |
21 #include "chrome/common/guid.h" | |
22 #include "content/common/notification_service.h" | 12 #include "content/common/notification_service.h" |
23 | 13 |
24 using base::Time; | |
25 | |
26 namespace { | 14 namespace { |
27 | 15 |
28 // Current version number. Note: when changing the current version number, | 16 // Current version number. Note: when changing the current version number, |
29 // corresponding changes must happen in the unit tests, and new migration test | 17 // corresponding changes must happen in the unit tests, and new migration test |
30 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. | 18 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. |
31 const int kCurrentVersionNumber = 36; | 19 const int kCurrentVersionNumber = 36; |
32 const int kCompatibleVersionNumber = 36; | 20 const int kCompatibleVersionNumber = 36; |
33 | 21 |
34 // TODO(dhollowa): Find a common place for this. It is duplicated in | |
35 // personal_data_manager.cc. | |
36 template<typename T> | |
37 T* address_of(T& v) { | |
38 return &v; | |
39 } | |
40 | |
41 } // anonymous namespace | 22 } // anonymous namespace |
42 | 23 |
43 WebDatabase::WebDatabase() {} | 24 WebDatabase::WebDatabase() {} |
44 | 25 |
45 WebDatabase::~WebDatabase() {} | 26 WebDatabase::~WebDatabase() {} |
46 | 27 |
47 void WebDatabase::BeginTransaction() { | 28 void WebDatabase::BeginTransaction() { |
48 db_.BeginTransaction(); | 29 db_.BeginTransaction(); |
49 } | 30 } |
50 | 31 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 // If the file on disk is an older database version, bring it up to date. | 113 // If the file on disk is an older database version, bring it up to date. |
133 // If the migration fails we return an error to caller and do not commit | 114 // If the migration fails we return an error to caller and do not commit |
134 // the migration. | 115 // the migration. |
135 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(); | 116 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded(); |
136 if (migration_status != sql::INIT_OK) | 117 if (migration_status != sql::INIT_OK) |
137 return migration_status; | 118 return migration_status; |
138 | 119 |
139 return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; | 120 return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; |
140 } | 121 } |
141 | 122 |
| 123 void WebDatabase::ChangeVersion(int version_num, |
| 124 bool update_compatible_version_num) { |
| 125 meta_table_.SetVersionNumber(version_num); |
| 126 if (update_compatible_version_num) { |
| 127 meta_table_.SetCompatibleVersionNumber( |
| 128 std::min(version_num, kCompatibleVersionNumber)); |
| 129 } |
| 130 } |
| 131 |
| 132 sql::InitStatus WebDatabase::FailedMigrationTo(int version_num) { |
| 133 LOG(WARNING) << "Unable to update web database to version " |
| 134 << version_num << "."; |
| 135 NOTREACHED(); |
| 136 return sql::INIT_FAILURE; |
| 137 } |
| 138 |
142 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded() { | 139 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded() { |
143 // Migrate if necessary. | 140 // Migrate if necessary. |
144 int current_version = meta_table_.GetVersionNumber(); | 141 int current_version = meta_table_.GetVersionNumber(); |
145 switch (current_version) { | 142 switch (current_version) { |
146 // Versions 1 - 19 are unhandled. Version numbers greater than | 143 // Versions 1 - 19 are unhandled. Version numbers greater than |
147 // kCurrentVersionNumber should have already been weeded out by the caller. | 144 // kCurrentVersionNumber should have already been weeded out by the caller. |
148 default: | 145 default: |
149 // When the version is too old, we return failure error code. The schema | 146 // When the version is too old, we return failure error code. The schema |
150 // is too out of date to migrate. | 147 // is too out of date to migrate. |
151 // There should not be a released product that makes a database too old to | 148 // There should not be a released product that makes a database too old to |
152 // migrate. If we do encounter such a legacy database, we will need a | 149 // migrate. If we do encounter such a legacy database, we will need a |
153 // better solution to handle it (i.e., pop up a dialog to tell the user, | 150 // better solution to handle it (i.e., pop up a dialog to tell the user, |
154 // erase all their prefs and start over, etc.). | 151 // erase all their prefs and start over, etc.). |
155 LOG(WARNING) << "Web database version " << current_version << | 152 LOG(WARNING) << "Web database version " << current_version << |
156 " is too old to handle."; | 153 " is too old to handle."; |
157 NOTREACHED(); | 154 NOTREACHED(); |
158 return sql::INIT_FAILURE; | 155 return sql::INIT_FAILURE; |
159 | 156 |
160 case 20: | 157 case 20: |
161 // Add the autogenerate_keyword column. | 158 if (!keyword_table_->AddAutoGenerateKeywordColumnForVersion21()) |
162 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN autogenerate_keyword " | 159 return FailedMigrationTo(21); |
163 "INTEGER DEFAULT 0")) { | 160 |
164 LOG(WARNING) << "Unable to update web database to version 21."; | 161 ChangeVersion(21, true); |
165 NOTREACHED(); | |
166 return sql::INIT_FAILURE; | |
167 } | |
168 meta_table_.SetVersionNumber(21); | |
169 meta_table_.SetCompatibleVersionNumber( | |
170 std::min(21, kCompatibleVersionNumber)); | |
171 // FALL THROUGH | 162 // FALL THROUGH |
172 | 163 |
173 case 21: | 164 case 21: |
174 if (!autofill_table_->ClearAutofillEmptyValueElements()) { | 165 if (!autofill_table_->ClearAutofillEmptyValueElements()) |
175 LOG(WARNING) << "Failed to clean-up autofill DB."; | 166 return FailedMigrationTo(22); |
176 NOTREACHED(); | |
177 return sql::INIT_FAILURE; | |
178 } | |
179 meta_table_.SetVersionNumber(22); | |
180 // No change in the compatibility version number. | |
181 | 167 |
| 168 ChangeVersion(22, false); |
182 // FALL THROUGH | 169 // FALL THROUGH |
183 | 170 |
184 case 22: | 171 case 22: |
185 // Add the card_number_encrypted column if credit card table was not | 172 if (!autofill_table_->AddCardNumberEncryptedColumnForVersion23()) |
186 // created in this build (otherwise the column already exists). | 173 return FailedMigrationTo(23); |
187 // WARNING: Do not change the order of the execution of the SQL | |
188 // statements in this case! Profile corruption and data migration | |
189 // issues WILL OCCUR. (see http://crbug.com/10913) | |
190 // | |
191 // The problem is that if a user has a profile which was created before | |
192 // r37036, when the credit_cards table was added, and then failed to | |
193 // update this profile between the credit card addition and the addition | |
194 // of the "encrypted" columns (44963), the next data migration will put | |
195 // the user's profile in an incoherent state: The user will update from | |
196 // a data profile set to be earlier than 22, and therefore pass through | |
197 // this update case. But because the user did not have a credit_cards | |
198 // table before starting Chrome, it will have just been initialized | |
199 // above, and so already have these columns -- and thus this data | |
200 // update step will have failed. | |
201 // | |
202 // The false assumption in this case is that at this step in the | |
203 // migration, the user has a credit card table, and that this | |
204 // table does not include encrypted columns! | |
205 // Because this case does not roll back the complete set of SQL | |
206 // transactions properly in case of failure (that is, it does not | |
207 // roll back the table initialization done above), the incoherent | |
208 // profile will now see itself as being at version 22 -- but include a | |
209 // fully initialized credit_cards table. Every time Chrome runs, it | |
210 // will try to update the web database and fail at this step, unless | |
211 // we allow for the faulty assumption described above by checking for | |
212 // the existence of the columns only AFTER we've executed the commands | |
213 // to add them. | |
214 if (!db_.DoesColumnExist("credit_cards", "card_number_encrypted")) { | |
215 if (!db_.Execute("ALTER TABLE credit_cards ADD COLUMN " | |
216 "card_number_encrypted BLOB DEFAULT NULL")) { | |
217 LOG(WARNING) << "Could not add card_number_encrypted to " | |
218 "credit_cards table."; | |
219 NOTREACHED(); | |
220 return sql::INIT_FAILURE; | |
221 } | |
222 } | |
223 | 174 |
224 if (!db_.DoesColumnExist("credit_cards", "verification_code_encrypted")) { | 175 ChangeVersion(23, false); |
225 if (!db_.Execute("ALTER TABLE credit_cards ADD COLUMN " | |
226 "verification_code_encrypted BLOB DEFAULT NULL")) { | |
227 LOG(WARNING) << "Could not add verification_code_encrypted to " | |
228 "credit_cards table."; | |
229 NOTREACHED(); | |
230 return sql::INIT_FAILURE; | |
231 } | |
232 } | |
233 meta_table_.SetVersionNumber(23); | |
234 // FALL THROUGH | 176 // FALL THROUGH |
235 | 177 |
236 case 23: { | 178 case 23: |
237 // One-time cleanup for Chromium bug 38364. In the presence of | 179 if (!autofill_table_->CleanupOversizedStringFieldsForVersion24()) |
238 // multi-byte UTF-8 characters, that bug could cause Autofill strings | 180 return FailedMigrationTo(24); |
239 // to grow larger and more corrupt with each save. The cleanup removes | |
240 // any row with a string field larger than a reasonable size. The string | |
241 // fields examined here are precisely the ones that were subject to | |
242 // corruption by the original bug. | |
243 const std::string autofill_is_too_big = | |
244 "max(length(name), length(value)) > 500"; | |
245 | 181 |
246 const std::string credit_cards_is_too_big = | 182 ChangeVersion(24, false); |
247 "max(length(label), length(name_on_card), length(type), " | |
248 " length(expiration_month), length(expiration_year), " | |
249 " length(billing_address), length(shipping_address) " | |
250 ") > 500"; | |
251 | |
252 const std::string autofill_profiles_is_too_big = | |
253 "max(length(label), length(first_name), " | |
254 " length(middle_name), length(last_name), length(email), " | |
255 " length(company_name), length(address_line_1), " | |
256 " length(address_line_2), length(city), length(state), " | |
257 " length(zipcode), length(country), length(phone), " | |
258 " length(fax)) > 500"; | |
259 | |
260 std::string query = "DELETE FROM autofill_dates WHERE pair_id IN (" | |
261 "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")"; | |
262 if (!db_.Execute(query.c_str())) { | |
263 LOG(WARNING) << "Unable to update web database to version 24."; | |
264 NOTREACHED(); | |
265 return sql::INIT_FAILURE; | |
266 } | |
267 query = "DELETE FROM autofill WHERE " + autofill_is_too_big; | |
268 if (!db_.Execute(query.c_str())) { | |
269 LOG(WARNING) << "Unable to update web database to version 24."; | |
270 NOTREACHED(); | |
271 return sql::INIT_FAILURE; | |
272 } | |
273 // Only delete from legacy credit card tables where specific columns | |
274 // exist. | |
275 if (db_.DoesColumnExist("credit_cards", "label") && | |
276 db_.DoesColumnExist("credit_cards", "name_on_card") && | |
277 db_.DoesColumnExist("credit_cards", "type") && | |
278 db_.DoesColumnExist("credit_cards", "expiration_month") && | |
279 db_.DoesColumnExist("credit_cards", "expiration_year") && | |
280 db_.DoesColumnExist("credit_cards", "billing_address") && | |
281 db_.DoesColumnExist("credit_cards", "shipping_address") && | |
282 db_.DoesColumnExist("autofill_profiles", "label")) { | |
283 query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big + | |
284 ") OR label IN (SELECT label FROM autofill_profiles WHERE " + | |
285 autofill_profiles_is_too_big + ")"; | |
286 if (!db_.Execute(query.c_str())) { | |
287 LOG(WARNING) << "Unable to update web database to version 24."; | |
288 NOTREACHED(); | |
289 return sql::INIT_FAILURE; | |
290 } | |
291 } | |
292 if (db_.DoesColumnExist("autofill_profiles", "label")) { | |
293 query = "DELETE FROM autofill_profiles WHERE " + | |
294 autofill_profiles_is_too_big; | |
295 if (!db_.Execute(query.c_str())) { | |
296 LOG(WARNING) << "Unable to update web database to version 24."; | |
297 NOTREACHED(); | |
298 return sql::INIT_FAILURE; | |
299 } | |
300 } | |
301 | |
302 meta_table_.SetVersionNumber(24); | |
303 | |
304 // FALL THROUGH | 183 // FALL THROUGH |
305 } | |
306 | 184 |
307 case 24: | 185 case 24: |
308 // Add the logo_id column if keyword table was not created in this build. | 186 if (!keyword_table_->AddLogoIDColumnForVersionVersion25()) |
309 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN logo_id " | 187 return FailedMigrationTo(25); |
310 "INTEGER DEFAULT 0")) { | 188 |
311 LOG(WARNING) << "Unable to update web database to version 25."; | 189 ChangeVersion(25, true); |
312 NOTREACHED(); | |
313 return sql::INIT_FAILURE; | |
314 } | |
315 meta_table_.SetVersionNumber(25); | |
316 meta_table_.SetCompatibleVersionNumber( | |
317 std::min(25, kCompatibleVersionNumber)); | |
318 // FALL THROUGH | 190 // FALL THROUGH |
319 | 191 |
320 case 25: | 192 case 25: |
321 // Add the created_by_policy column. | 193 if (!keyword_table_->AddCreatedByPolicyColumnForVersion26()) |
322 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN created_by_policy " | 194 return FailedMigrationTo(26); |
323 "INTEGER DEFAULT 0")) { | |
324 LOG(WARNING) << "Unable to update web database to version 26."; | |
325 NOTREACHED(); | |
326 return sql::INIT_FAILURE; | |
327 } | |
328 | 195 |
329 meta_table_.SetVersionNumber(26); | 196 ChangeVersion(26, true); |
330 meta_table_.SetCompatibleVersionNumber( | |
331 std::min(26, kCompatibleVersionNumber)); | |
332 // FALL THROUGH | 197 // FALL THROUGH |
333 | 198 |
334 case 26: { | 199 case 26: |
335 // Only migrate from legacy credit card tables where specific columns | 200 if (!autofill_table_->UpdateLegacyCreditCardsForVersion27()) |
336 // exist. | 201 return FailedMigrationTo(27); |
337 if (db_.DoesColumnExist("credit_cards", "unique_id") && | |
338 db_.DoesColumnExist("credit_cards", "billing_address") && | |
339 db_.DoesColumnExist("autofill_profiles", "unique_id")) { | |
340 // Change the credit_cards.billing_address column from a string to an | |
341 // int. The stored string is the label of an address, so we have to | |
342 // select the unique ID of this address using the label as a foreign | |
343 // key into the |autofill_profiles| table. | |
344 std::string stmt = | |
345 "SELECT credit_cards.unique_id, autofill_profiles.unique_id " | |
346 "FROM autofill_profiles, credit_cards " | |
347 "WHERE credit_cards.billing_address = autofill_profiles.label"; | |
348 sql::Statement s(db_.GetUniqueStatement(stmt.c_str())); | |
349 if (!s) { | |
350 LOG(WARNING) << "Statement prepare failed"; | |
351 NOTREACHED(); | |
352 return sql::INIT_FAILURE; | |
353 } | |
354 | 202 |
355 std::map<int, int> cc_billing_map; | 203 ChangeVersion(27, true); |
356 while (s.Step()) | |
357 cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1); | |
358 | |
359 // Windows already stores the IDs as strings in |billing_address|. Try | |
360 // to convert those. | |
361 if (cc_billing_map.empty()) { | |
362 std::string stmt = | |
363 "SELECT unique_id,billing_address FROM credit_cards"; | |
364 sql::Statement s(db_.GetUniqueStatement(stmt.c_str())); | |
365 if (!s) { | |
366 LOG(WARNING) << "Statement prepare failed"; | |
367 NOTREACHED(); | |
368 return sql::INIT_FAILURE; | |
369 } | |
370 | |
371 while (s.Step()) { | |
372 int id = 0; | |
373 if (base::StringToInt(s.ColumnString(1), &id)) | |
374 cc_billing_map[s.ColumnInt(0)] = id; | |
375 } | |
376 } | |
377 | |
378 if (!db_.Execute("CREATE TABLE credit_cards_temp ( " | |
379 "label VARCHAR, " | |
380 "unique_id INTEGER PRIMARY KEY, " | |
381 "name_on_card VARCHAR, " | |
382 "type VARCHAR, " | |
383 "card_number VARCHAR, " | |
384 "expiration_month INTEGER, " | |
385 "expiration_year INTEGER, " | |
386 "verification_code VARCHAR, " | |
387 "billing_address INTEGER, " | |
388 "shipping_address VARCHAR, " | |
389 "card_number_encrypted BLOB, " | |
390 "verification_code_encrypted BLOB)")) { | |
391 LOG(WARNING) << "Unable to update web database to version 27."; | |
392 NOTREACHED(); | |
393 return sql::INIT_FAILURE; | |
394 } | |
395 | |
396 if (!db_.Execute( | |
397 "INSERT INTO credit_cards_temp " | |
398 "SELECT label,unique_id,name_on_card,type,card_number," | |
399 "expiration_month,expiration_year,verification_code,0," | |
400 "shipping_address,card_number_encrypted," | |
401 "verification_code_encrypted FROM credit_cards")) { | |
402 LOG(WARNING) << "Unable to update web database to version 27."; | |
403 NOTREACHED(); | |
404 return sql::INIT_FAILURE; | |
405 } | |
406 | |
407 if (!db_.Execute("DROP TABLE credit_cards")) { | |
408 LOG(WARNING) << "Unable to update web database to version 27."; | |
409 NOTREACHED(); | |
410 return sql::INIT_FAILURE; | |
411 } | |
412 | |
413 if (!db_.Execute( | |
414 "ALTER TABLE credit_cards_temp RENAME TO credit_cards")) { | |
415 LOG(WARNING) << "Unable to update web database to version 27."; | |
416 NOTREACHED(); | |
417 return sql::INIT_FAILURE; | |
418 } | |
419 | |
420 for (std::map<int, int>::const_iterator iter = cc_billing_map.begin(); | |
421 iter != cc_billing_map.end(); ++iter) { | |
422 sql::Statement s(db_.GetCachedStatement( | |
423 SQL_FROM_HERE, | |
424 "UPDATE credit_cards SET billing_address=? WHERE unique_id=?")); | |
425 if (!s) { | |
426 LOG(WARNING) << "Statement prepare failed"; | |
427 NOTREACHED(); | |
428 return sql::INIT_FAILURE; | |
429 } | |
430 | |
431 s.BindInt(0, (*iter).second); | |
432 s.BindInt(1, (*iter).first); | |
433 | |
434 if (!s.Run()) { | |
435 LOG(WARNING) << "Unable to update web database to version 27."; | |
436 NOTREACHED(); | |
437 return sql::INIT_FAILURE; | |
438 } | |
439 } | |
440 } | |
441 | |
442 meta_table_.SetVersionNumber(27); | |
443 meta_table_.SetCompatibleVersionNumber( | |
444 std::min(27, kCompatibleVersionNumber)); | |
445 | |
446 // FALL THROUGH | 204 // FALL THROUGH |
447 } | |
448 | 205 |
449 case 27: | 206 case 27: |
450 // Add supports_instant to keywords. | 207 if (!keyword_table_->AddSupportsInstantColumnForVersion28()) |
451 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN supports_instant " | 208 return FailedMigrationTo(28); |
452 "INTEGER DEFAULT 0")) { | |
453 LOG(WARNING) << "Unable to update web database to version 28."; | |
454 NOTREACHED(); | |
455 return sql::INIT_FAILURE; | |
456 } | |
457 meta_table_.SetVersionNumber(28); | |
458 meta_table_.SetCompatibleVersionNumber( | |
459 std::min(28, kCompatibleVersionNumber)); | |
460 | 209 |
| 210 ChangeVersion(28, true); |
461 // FALL THROUGH | 211 // FALL THROUGH |
462 | 212 |
463 case 28: | 213 case 28: |
464 // Keywords loses the column supports_instant and gets instant_url. | 214 if (!keyword_table_->ChangeInstantUrlToSupportsInstantForVersion29()) |
465 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN instant_url " | 215 return FailedMigrationTo(29); |
466 "VARCHAR")) { | |
467 LOG(WARNING) << "Unable to update web database to version 29."; | |
468 NOTREACHED(); | |
469 return sql::INIT_FAILURE; | |
470 } | |
471 if (!db_.Execute("CREATE TABLE keywords_temp (" | |
472 "id INTEGER PRIMARY KEY," | |
473 "short_name VARCHAR NOT NULL," | |
474 "keyword VARCHAR NOT NULL," | |
475 "favicon_url VARCHAR NOT NULL," | |
476 "url VARCHAR NOT NULL," | |
477 "show_in_default_list INTEGER," | |
478 "safe_for_autoreplace INTEGER," | |
479 "originating_url VARCHAR," | |
480 "date_created INTEGER DEFAULT 0," | |
481 "usage_count INTEGER DEFAULT 0," | |
482 "input_encodings VARCHAR," | |
483 "suggest_url VARCHAR," | |
484 "prepopulate_id INTEGER DEFAULT 0," | |
485 "autogenerate_keyword INTEGER DEFAULT 0," | |
486 "logo_id INTEGER DEFAULT 0," | |
487 "created_by_policy INTEGER DEFAULT 0," | |
488 "instant_url VARCHAR)")) { | |
489 LOG(WARNING) << "Unable to update web database to version 29."; | |
490 NOTREACHED(); | |
491 return sql::INIT_FAILURE; | |
492 } | |
493 | 216 |
494 if (!db_.Execute( | 217 ChangeVersion(29, true); |
495 "INSERT INTO keywords_temp " | |
496 "SELECT id, short_name, keyword, favicon_url, url, " | |
497 "show_in_default_list, safe_for_autoreplace, originating_url, " | |
498 "date_created, usage_count, input_encodings, suggest_url, " | |
499 "prepopulate_id, autogenerate_keyword, logo_id, created_by_policy, " | |
500 "instant_url FROM keywords")) { | |
501 LOG(WARNING) << "Unable to update web database to version 29."; | |
502 NOTREACHED(); | |
503 return sql::INIT_FAILURE; | |
504 } | |
505 | |
506 if (!db_.Execute("DROP TABLE keywords")) { | |
507 LOG(WARNING) << "Unable to update web database to version 29."; | |
508 NOTREACHED(); | |
509 return sql::INIT_FAILURE; | |
510 } | |
511 | |
512 if (!db_.Execute( | |
513 "ALTER TABLE keywords_temp RENAME TO keywords")) { | |
514 LOG(WARNING) << "Unable to update web database to version 29."; | |
515 NOTREACHED(); | |
516 return sql::INIT_FAILURE; | |
517 } | |
518 | |
519 meta_table_.SetVersionNumber(29); | |
520 meta_table_.SetCompatibleVersionNumber( | |
521 std::min(29, kCompatibleVersionNumber)); | |
522 | |
523 // FALL THROUGH | 218 // FALL THROUGH |
524 | 219 |
525 case 29: | 220 case 29: |
526 // Add date_modified to autofill_profiles. | 221 if (!autofill_table_->AddDateModifedForVersion30()) |
527 if (!db_.DoesColumnExist("autofill_profiles", "date_modified")) { | 222 return FailedMigrationTo(30); |
528 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
529 "date_modified INTEGER NON NULL DEFAULT 0")) { | |
530 LOG(WARNING) << "Unable to update web database to version 30"; | |
531 NOTREACHED(); | |
532 return sql::INIT_FAILURE; | |
533 } | |
534 | 223 |
535 sql::Statement s(db_.GetUniqueStatement( | 224 ChangeVersion(30, true); |
536 "UPDATE autofill_profiles SET date_modified=?")); | |
537 if (!s) { | |
538 LOG(WARNING) << "Unable to update web database to version 30."; | |
539 NOTREACHED(); | |
540 return sql::INIT_FAILURE; | |
541 } | |
542 | |
543 s.BindInt64(0, Time::Now().ToTimeT()); | |
544 | |
545 if (!s.Run()) { | |
546 LOG(WARNING) << "Unable to update web database to version 30."; | |
547 NOTREACHED(); | |
548 return sql::INIT_FAILURE; | |
549 } | |
550 | |
551 } | |
552 | |
553 // Add date_modified to credit_cards. | |
554 if (!db_.DoesColumnExist("credit_cards", "date_modified")) { | |
555 if (!db_.Execute("ALTER TABLE credit_cards ADD COLUMN " | |
556 "date_modified INTEGER NON NULL DEFAULT 0")) { | |
557 LOG(WARNING) << "Unable to update web database to version 30"; | |
558 NOTREACHED(); | |
559 return sql::INIT_FAILURE; | |
560 } | |
561 | |
562 sql::Statement s(db_.GetUniqueStatement( | |
563 "UPDATE credit_cards SET date_modified=?")); | |
564 if (!s) { | |
565 LOG(WARNING) << "Unable to update web database to version 30."; | |
566 NOTREACHED(); | |
567 return sql::INIT_FAILURE; | |
568 } | |
569 | |
570 s.BindInt64(0, Time::Now().ToTimeT()); | |
571 | |
572 if (!s.Run()) { | |
573 LOG(WARNING) << "Unable to update web database to version 30."; | |
574 NOTREACHED(); | |
575 return sql::INIT_FAILURE; | |
576 } | |
577 } | |
578 | |
579 meta_table_.SetVersionNumber(30); | |
580 meta_table_.SetCompatibleVersionNumber( | |
581 std::min(30, kCompatibleVersionNumber)); | |
582 | |
583 // FALL THROUGH | 225 // FALL THROUGH |
584 | 226 |
585 case 30: | 227 case 30: |
586 // Add |guid| column to |autofill_profiles| table. | 228 if (!autofill_table_->AddGUIDToCreditCardsAndProfilesForVersion31()) |
587 // Note that we need to check for the guid column's existence due to the | 229 return FailedMigrationTo(31); |
588 // fact that for a version 22 database the |autofill_profiles| table | |
589 // gets created fresh with |InitAutofillProfilesTable|. | |
590 if (!db_.DoesColumnExist("autofill_profiles", "guid")) { | |
591 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
592 "guid VARCHAR NOT NULL DEFAULT \"\"")) { | |
593 LOG(WARNING) << "Unable to update web database to version 30."; | |
594 NOTREACHED(); | |
595 return sql::INIT_FAILURE; | |
596 } | |
597 | 230 |
598 // Set all the |guid| fields to valid values. | 231 ChangeVersion(31, true); |
599 { | |
600 sql::Statement s(db_.GetUniqueStatement("SELECT unique_id " | |
601 "FROM autofill_profiles")); | |
602 | |
603 if (!s) { | |
604 LOG(WARNING) << "Unable to update web database to version 30."; | |
605 NOTREACHED(); | |
606 return sql::INIT_FAILURE; | |
607 } | |
608 | |
609 while (s.Step()) { | |
610 sql::Statement update_s( | |
611 db_.GetUniqueStatement("UPDATE autofill_profiles " | |
612 "SET guid=? WHERE unique_id=?")); | |
613 if (!update_s) { | |
614 LOG(WARNING) << "Unable to update web database to version 30."; | |
615 NOTREACHED(); | |
616 return sql::INIT_FAILURE; | |
617 } | |
618 update_s.BindString(0, guid::GenerateGUID()); | |
619 update_s.BindInt(1, s.ColumnInt(0)); | |
620 | |
621 if (!update_s.Run()) { | |
622 LOG(WARNING) << "Unable to update web database to version 30."; | |
623 NOTREACHED(); | |
624 return sql::INIT_FAILURE; | |
625 } | |
626 } | |
627 } | |
628 } | |
629 | |
630 // Add |guid| column to |credit_cards| table. | |
631 // Note that we need to check for the guid column's existence due to the | |
632 // fact that for a version 22 database the |autofill_profiles| table | |
633 // gets created fresh with |InitAutofillProfilesTable|. | |
634 if (!db_.DoesColumnExist("credit_cards", "guid")) { | |
635 if (!db_.Execute("ALTER TABLE credit_cards ADD COLUMN " | |
636 "guid VARCHAR NOT NULL DEFAULT \"\"")) { | |
637 LOG(WARNING) << "Unable to update web database to version 30."; | |
638 NOTREACHED(); | |
639 return sql::INIT_FAILURE; | |
640 } | |
641 | |
642 // Set all the |guid| fields to valid values. | |
643 { | |
644 sql::Statement s(db_.GetUniqueStatement("SELECT unique_id " | |
645 "FROM credit_cards")); | |
646 if (!s) { | |
647 LOG(WARNING) << "Unable to update web database to version 30."; | |
648 NOTREACHED(); | |
649 return sql::INIT_FAILURE; | |
650 } | |
651 | |
652 while (s.Step()) { | |
653 sql::Statement update_s( | |
654 db_.GetUniqueStatement("UPDATE credit_cards " | |
655 "set guid=? WHERE unique_id=?")); | |
656 if (!update_s) { | |
657 LOG(WARNING) << "Unable to update web database to version 30."; | |
658 NOTREACHED(); | |
659 return sql::INIT_FAILURE; | |
660 } | |
661 update_s.BindString(0, guid::GenerateGUID()); | |
662 update_s.BindInt(1, s.ColumnInt(0)); | |
663 | |
664 if (!update_s.Run()) { | |
665 LOG(WARNING) << "Unable to update web database to version 30."; | |
666 NOTREACHED(); | |
667 return sql::INIT_FAILURE; | |
668 } | |
669 } | |
670 } | |
671 } | |
672 | |
673 meta_table_.SetVersionNumber(31); | |
674 meta_table_.SetCompatibleVersionNumber( | |
675 std::min(31, kCompatibleVersionNumber)); | |
676 | |
677 // FALL THROUGH | 232 // FALL THROUGH |
678 | 233 |
679 case 31: | 234 case 31: |
680 if (db_.DoesColumnExist("autofill_profiles", "unique_id")) { | 235 if (!autofill_table_->UpdateProfilesAndCreditCardsForVersion32()) |
681 if (!db_.Execute("CREATE TABLE autofill_profiles_temp ( " | 236 return FailedMigrationTo(32); |
682 "guid VARCHAR PRIMARY KEY, " | |
683 "label VARCHAR, " | |
684 "first_name VARCHAR, " | |
685 "middle_name VARCHAR, " | |
686 "last_name VARCHAR, " | |
687 "email VARCHAR, " | |
688 "company_name VARCHAR, " | |
689 "address_line_1 VARCHAR, " | |
690 "address_line_2 VARCHAR, " | |
691 "city VARCHAR, " | |
692 "state VARCHAR, " | |
693 "zipcode VARCHAR, " | |
694 "country VARCHAR, " | |
695 "phone VARCHAR, " | |
696 "fax VARCHAR, " | |
697 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
698 LOG(WARNING) << "Unable to update web database to version 32."; | |
699 NOTREACHED(); | |
700 return sql::INIT_FAILURE; | |
701 } | |
702 | 237 |
703 if (!db_.Execute( | 238 ChangeVersion(32, true); |
704 "INSERT INTO autofill_profiles_temp " | |
705 "SELECT guid, label, first_name, middle_name, last_name, email, " | |
706 "company_name, address_line_1, address_line_2, city, state, " | |
707 "zipcode, country, phone, fax, date_modified " | |
708 "FROM autofill_profiles")) { | |
709 LOG(WARNING) << "Unable to update web database to version 32."; | |
710 NOTREACHED(); | |
711 return sql::INIT_FAILURE; | |
712 } | |
713 | |
714 if (!db_.Execute("DROP TABLE autofill_profiles")) { | |
715 LOG(WARNING) << "Unable to update web database to version 32."; | |
716 NOTREACHED(); | |
717 return sql::INIT_FAILURE; | |
718 } | |
719 | |
720 if (!db_.Execute( | |
721 "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { | |
722 LOG(WARNING) << "Unable to update web database to version 32."; | |
723 NOTREACHED(); | |
724 return sql::INIT_FAILURE; | |
725 } | |
726 } | |
727 | |
728 if (db_.DoesColumnExist("credit_cards", "unique_id")) { | |
729 if (!db_.Execute("CREATE TABLE credit_cards_temp ( " | |
730 "guid VARCHAR PRIMARY KEY, " | |
731 "label VARCHAR, " | |
732 "name_on_card VARCHAR, " | |
733 "expiration_month INTEGER, " | |
734 "expiration_year INTEGER, " | |
735 "card_number_encrypted BLOB, " | |
736 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
737 LOG(WARNING) << "Unable to update web database to version 32."; | |
738 NOTREACHED(); | |
739 return sql::INIT_FAILURE; | |
740 } | |
741 | |
742 if (!db_.Execute( | |
743 "INSERT INTO credit_cards_temp " | |
744 "SELECT guid, label, name_on_card, expiration_month, " | |
745 "expiration_year, card_number_encrypted, date_modified " | |
746 "FROM credit_cards")) { | |
747 LOG(WARNING) << "Unable to update web database to version 32."; | |
748 NOTREACHED(); | |
749 return sql::INIT_FAILURE; | |
750 } | |
751 | |
752 if (!db_.Execute("DROP TABLE credit_cards")) { | |
753 LOG(WARNING) << "Unable to update web database to version 32."; | |
754 NOTREACHED(); | |
755 return sql::INIT_FAILURE; | |
756 } | |
757 | |
758 if (!db_.Execute( | |
759 "ALTER TABLE credit_cards_temp RENAME TO credit_cards")) { | |
760 LOG(WARNING) << "Unable to update web database to version 32."; | |
761 NOTREACHED(); | |
762 return sql::INIT_FAILURE; | |
763 } | |
764 } | |
765 | |
766 meta_table_.SetVersionNumber(32); | |
767 meta_table_.SetCompatibleVersionNumber( | |
768 std::min(32, kCompatibleVersionNumber)); | |
769 | |
770 // FALL THROUGH | 239 // FALL THROUGH |
771 | 240 |
772 case 32: | 241 case 32: |
773 // Test the existence of the |first_name| column as an indication that | 242 if (!autofill_table_->UpdateProfilesBasedOnFirstNameForVersion33()) |
774 // we need a migration. It is possible that the new |autofill_profiles| | 243 return FailedMigrationTo(33); |
775 // schema is in place because the table was newly created when migrating | |
776 // from a pre-version-22 database. | |
777 if (db_.DoesColumnExist("autofill_profiles", "first_name")) { | |
778 // Create autofill_profiles_temp table that will receive the data. | |
779 if (!db_.DoesTableExist("autofill_profiles_temp")) { | |
780 if (!db_.Execute("CREATE TABLE autofill_profiles_temp ( " | |
781 "guid VARCHAR PRIMARY KEY, " | |
782 "company_name VARCHAR, " | |
783 "address_line_1 VARCHAR, " | |
784 "address_line_2 VARCHAR, " | |
785 "city VARCHAR, " | |
786 "state VARCHAR, " | |
787 "zipcode VARCHAR, " | |
788 "country VARCHAR, " | |
789 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
790 NOTREACHED(); | |
791 return sql::INIT_FAILURE; | |
792 } | |
793 } | |
794 | 244 |
795 { | 245 ChangeVersion(33, true); |
796 sql::Statement s(db_.GetUniqueStatement( | |
797 "SELECT guid, first_name, middle_name, last_name, email, " | |
798 "company_name, address_line_1, address_line_2, city, state, " | |
799 "zipcode, country, phone, fax, date_modified " | |
800 "FROM autofill_profiles")); | |
801 while (s.Step()) { | |
802 AutofillProfile profile; | |
803 profile.set_guid(s.ColumnString(0)); | |
804 DCHECK(guid::IsValidGUID(profile.guid())); | |
805 | |
806 profile.SetInfo(NAME_FIRST, s.ColumnString16(1)); | |
807 profile.SetInfo(NAME_MIDDLE, s.ColumnString16(2)); | |
808 profile.SetInfo(NAME_LAST, s.ColumnString16(3)); | |
809 profile.SetInfo(EMAIL_ADDRESS, s.ColumnString16(4)); | |
810 profile.SetInfo(COMPANY_NAME, s.ColumnString16(5)); | |
811 profile.SetInfo(ADDRESS_HOME_LINE1, s.ColumnString16(6)); | |
812 profile.SetInfo(ADDRESS_HOME_LINE2, s.ColumnString16(7)); | |
813 profile.SetInfo(ADDRESS_HOME_CITY, s.ColumnString16(8)); | |
814 profile.SetInfo(ADDRESS_HOME_STATE, s.ColumnString16(9)); | |
815 profile.SetInfo(ADDRESS_HOME_ZIP, s.ColumnString16(10)); | |
816 profile.SetInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(11)); | |
817 profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(12)); | |
818 profile.SetInfo(PHONE_FAX_WHOLE_NUMBER, s.ColumnString16(13)); | |
819 int64 date_modified = s.ColumnInt64(14); | |
820 | |
821 sql::Statement s_insert(db_.GetUniqueStatement( | |
822 "INSERT INTO autofill_profiles_temp" | |
823 "(guid, company_name, address_line_1, address_line_2, city," | |
824 " state, zipcode, country, date_modified)" | |
825 "VALUES (?,?,?,?,?,?,?,?,?)")); | |
826 if (!s) { | |
827 LOG(WARNING) << "Unable to update web database to version 33."; | |
828 NOTREACHED(); | |
829 return sql::INIT_FAILURE; | |
830 } | |
831 s_insert.BindString(0, profile.guid()); | |
832 s_insert.BindString16(1, profile.GetInfo(COMPANY_NAME)); | |
833 s_insert.BindString16(2, profile.GetInfo(ADDRESS_HOME_LINE1)); | |
834 s_insert.BindString16(3, profile.GetInfo(ADDRESS_HOME_LINE2)); | |
835 s_insert.BindString16(4, profile.GetInfo(ADDRESS_HOME_CITY)); | |
836 s_insert.BindString16(5, profile.GetInfo(ADDRESS_HOME_STATE)); | |
837 s_insert.BindString16(6, profile.GetInfo(ADDRESS_HOME_ZIP)); | |
838 s_insert.BindString16(7, profile.GetInfo(ADDRESS_HOME_COUNTRY)); | |
839 s_insert.BindInt64(8, date_modified); | |
840 | |
841 if (!s_insert.Run()) { | |
842 NOTREACHED(); | |
843 return sql::INIT_FAILURE; | |
844 } | |
845 | |
846 // Add the other bits: names, emails, and phone/fax. | |
847 if (!autofill_util::AddAutofillProfilePieces(profile, &db_)) { | |
848 NOTREACHED(); | |
849 return sql::INIT_FAILURE; | |
850 } | |
851 } | |
852 } | |
853 | |
854 if (!db_.Execute("DROP TABLE autofill_profiles")) { | |
855 LOG(WARNING) << "Unable to update web database to version 33."; | |
856 NOTREACHED(); | |
857 return sql::INIT_FAILURE; | |
858 } | |
859 | |
860 if (!db_.Execute( | |
861 "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { | |
862 LOG(WARNING) << "Unable to update web database to version 33."; | |
863 NOTREACHED(); | |
864 return sql::INIT_FAILURE; | |
865 } | |
866 } | |
867 | |
868 // Remove the labels column from the credit_cards table. | |
869 if (db_.DoesColumnExist("credit_cards", "label")) { | |
870 if (!db_.Execute("CREATE TABLE credit_cards_temp ( " | |
871 "guid VARCHAR PRIMARY KEY, " | |
872 "name_on_card VARCHAR, " | |
873 "expiration_month INTEGER, " | |
874 "expiration_year INTEGER, " | |
875 "card_number_encrypted BLOB, " | |
876 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | |
877 LOG(WARNING) << "Unable to update web database to version 33."; | |
878 NOTREACHED(); | |
879 return sql::INIT_FAILURE; | |
880 } | |
881 | |
882 if (!db_.Execute( | |
883 "INSERT INTO credit_cards_temp " | |
884 "SELECT guid, name_on_card, expiration_month, " | |
885 "expiration_year, card_number_encrypted, date_modified " | |
886 "FROM credit_cards")) { | |
887 LOG(WARNING) << "Unable to update web database to version 33."; | |
888 NOTREACHED(); | |
889 return sql::INIT_FAILURE; | |
890 } | |
891 | |
892 if (!db_.Execute("DROP TABLE credit_cards")) { | |
893 LOG(WARNING) << "Unable to update web database to version 33."; | |
894 NOTREACHED(); | |
895 return sql::INIT_FAILURE; | |
896 } | |
897 | |
898 if (!db_.Execute( | |
899 "ALTER TABLE credit_cards_temp RENAME TO credit_cards")) { | |
900 LOG(WARNING) << "Unable to update web database to version 33."; | |
901 NOTREACHED(); | |
902 return sql::INIT_FAILURE; | |
903 } | |
904 } | |
905 | |
906 meta_table_.SetVersionNumber(33); | |
907 meta_table_.SetCompatibleVersionNumber( | |
908 std::min(33, kCompatibleVersionNumber)); | |
909 | |
910 // FALL THROUGH | 246 // FALL THROUGH |
911 | 247 |
912 case 33: | 248 case 33: |
913 // Test the existence of the |country_code| column as an indication that | 249 if (!autofill_table_->UpdatesProfilesBasedOnCountryCodeForVersion34()) |
914 // we need a migration. It is possible that the new |autofill_profiles| | 250 return FailedMigrationTo(34); |
915 // schema is in place because the table was newly created when migrating | |
916 // from a pre-version-22 database. | |
917 if (!db_.DoesColumnExist("autofill_profiles", "country_code")) { | |
918 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " | |
919 "country_code VARCHAR")) { | |
920 LOG(WARNING) << "Unable to update web database to version 33."; | |
921 NOTREACHED(); | |
922 return sql::INIT_FAILURE; | |
923 } | |
924 | 251 |
925 // Set all the |country_code| fields to match existing |country| values. | 252 ChangeVersion(34, true); |
926 { | |
927 sql::Statement s(db_.GetUniqueStatement("SELECT guid, country " | |
928 "FROM autofill_profiles")); | |
929 | |
930 if (!s) { | |
931 LOG(WARNING) << "Unable to update web database to version 33."; | |
932 NOTREACHED(); | |
933 return sql::INIT_FAILURE; | |
934 } | |
935 | |
936 while (s.Step()) { | |
937 sql::Statement update_s( | |
938 db_.GetUniqueStatement("UPDATE autofill_profiles " | |
939 "SET country_code=? WHERE guid=?")); | |
940 if (!update_s) { | |
941 LOG(WARNING) << "Unable to update web database to version 33."; | |
942 NOTREACHED(); | |
943 return sql::INIT_FAILURE; | |
944 } | |
945 string16 country = s.ColumnString16(1); | |
946 std::string app_locale = AutofillCountry::ApplicationLocale(); | |
947 update_s.BindString(0, AutofillCountry::GetCountryCode(country, | |
948 app_locale)); | |
949 update_s.BindString(1, s.ColumnString(0)); | |
950 | |
951 if (!update_s.Run()) { | |
952 LOG(WARNING) << "Unable to update web database to version 33."; | |
953 NOTREACHED(); | |
954 return sql::INIT_FAILURE; | |
955 } | |
956 } | |
957 } | |
958 } | |
959 | |
960 meta_table_.SetVersionNumber(34); | |
961 meta_table_.SetCompatibleVersionNumber( | |
962 std::min(34, kCompatibleVersionNumber)); | |
963 | |
964 // FALL THROUGH | 253 // FALL THROUGH |
965 | 254 |
966 case 34: | 255 case 34: |
967 // Correct all country codes with value "UK" to be "GB". This data | 256 if (!autofill_table_->CorrectGreatBritainCountryCodesForVersion35()) |
968 // was mistakenly introduced in build 686.0. This migration is to clean | 257 return FailedMigrationTo(35); |
969 // it up. See http://crbug.com/74511 for details. | |
970 { | |
971 sql::Statement s(db_.GetUniqueStatement( | |
972 "UPDATE autofill_profiles SET country_code=\"GB\" " | |
973 "WHERE country_code=\"UK\"")); | |
974 | 258 |
975 if (!s.Run()) { | 259 ChangeVersion(35, true); |
976 LOG(WARNING) << "Unable to update web database to version 35."; | |
977 NOTREACHED(); | |
978 return sql::INIT_FAILURE; | |
979 } | |
980 } | |
981 | |
982 meta_table_.SetVersionNumber(35); | |
983 meta_table_.SetCompatibleVersionNumber( | |
984 std::min(35, kCompatibleVersionNumber)); | |
985 | |
986 // FALL THROUGH | 260 // FALL THROUGH |
987 | 261 |
988 case 35: | 262 case 35: |
989 // Merge and cull older profiles where possible. | 263 if (!autofill_table_->MergeAndCullOlderProfilesForVersion36()) |
990 { | 264 return FailedMigrationTo(36); |
991 sql::Statement s(db_.GetUniqueStatement( | |
992 "SELECT guid, date_modified " | |
993 "FROM autofill_profiles")); | |
994 if (!s) { | |
995 NOTREACHED() << "Statement prepare failed"; | |
996 return sql::INIT_FAILURE; | |
997 } | |
998 | 265 |
999 // Accumulate the good profiles. | 266 ChangeVersion(36, true); |
1000 std::vector<AutofillProfile> accumulated_profiles; | |
1001 std::vector<AutofillProfile*> accumulated_profiles_p; | |
1002 std::map<std::string, int64> modification_map; | |
1003 while (s.Step()) { | |
1004 std::string guid = s.ColumnString(0); | |
1005 int64 date_modified = s.ColumnInt64(1); | |
1006 modification_map.insert( | |
1007 std::pair<std::string, int64>(guid, date_modified)); | |
1008 AutofillProfile* profile = NULL; | |
1009 if (!autofill_table_->GetAutofillProfile(guid, &profile)) { | |
1010 NOTREACHED() << "Bad read of profile."; | |
1011 return sql::INIT_FAILURE; | |
1012 } | |
1013 scoped_ptr<AutofillProfile> p(profile); | |
1014 | |
1015 if (PersonalDataManager::IsValidLearnableProfile(*p)) { | |
1016 std::vector<AutofillProfile> merged_profiles; | |
1017 bool merged = PersonalDataManager::MergeProfile( | |
1018 *p, accumulated_profiles_p, &merged_profiles); | |
1019 | |
1020 std::swap(accumulated_profiles, merged_profiles); | |
1021 | |
1022 accumulated_profiles_p.clear(); | |
1023 accumulated_profiles_p.resize(accumulated_profiles.size()); | |
1024 std::transform(accumulated_profiles.begin(), | |
1025 accumulated_profiles.end(), | |
1026 accumulated_profiles_p.begin(), | |
1027 address_of<AutofillProfile>); | |
1028 | |
1029 // If the profile got merged trash the original. | |
1030 if (merged) | |
1031 autofill_table_->AddAutofillGUIDToTrash(p->guid()); | |
1032 } else { | |
1033 // An invalid profile, so trash it. | |
1034 autofill_table_->AddAutofillGUIDToTrash(p->guid()); | |
1035 } | |
1036 } | |
1037 | |
1038 // Drop the current profiles. | |
1039 if (!autofill_table_->ClearAutofillProfiles()) { | |
1040 LOG(WARNING) << "Unable to update web database to version 36."; | |
1041 NOTREACHED(); | |
1042 return sql::INIT_FAILURE; | |
1043 } | |
1044 | |
1045 // Add the newly merged profiles back in. | |
1046 for (std::vector<AutofillProfile>::const_iterator | |
1047 iter = accumulated_profiles.begin(); | |
1048 iter != accumulated_profiles.end(); | |
1049 ++iter) { | |
1050 if (!autofill_table_->AddAutofillProfile(*iter)) { | |
1051 LOG(WARNING) << "Unable to update web database to version 36."; | |
1052 NOTREACHED(); | |
1053 return sql::INIT_FAILURE; | |
1054 } | |
1055 | |
1056 // Fix up the original modification date. | |
1057 std::map<std::string, int64>::const_iterator date_item = | |
1058 modification_map.find(iter->guid()); | |
1059 if (date_item == modification_map.end()) { | |
1060 LOG(WARNING) << "Unable to update web database to version 36."; | |
1061 NOTREACHED(); | |
1062 return sql::INIT_FAILURE; | |
1063 } | |
1064 sql::Statement s_date(db_.GetUniqueStatement( | |
1065 "UPDATE autofill_profiles SET date_modified=? " | |
1066 "WHERE guid=?")); | |
1067 s_date.BindInt64(0, date_item->second); | |
1068 s_date.BindString(1, iter->guid()); | |
1069 if (!s_date.Run()) { | |
1070 LOG(WARNING) << "Unable to update web database to version 36."; | |
1071 NOTREACHED(); | |
1072 return sql::INIT_FAILURE; | |
1073 } | |
1074 } | |
1075 } | |
1076 | |
1077 meta_table_.SetVersionNumber(36); | |
1078 meta_table_.SetCompatibleVersionNumber( | |
1079 std::min(36, kCompatibleVersionNumber)); | |
1080 | |
1081 // FALL THROUGH | 267 // FALL THROUGH |
1082 | 268 |
1083 // Add successive versions here. Each should set the version number and | 269 // Add successive versions here. Each should set the version number and |
1084 // compatible version number as appropriate, then fall through to the next | 270 // compatible version number as appropriate, then fall through to the next |
1085 // case. | 271 // case. |
1086 | 272 |
1087 case kCurrentVersionNumber: | 273 case kCurrentVersionNumber: |
1088 // No migration needed. | 274 // No migration needed. |
1089 return sql::INIT_OK; | 275 return sql::INIT_OK; |
1090 } | 276 } |
1091 } | 277 } |
OLD | NEW |