| 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 | 22 // Change the version number and possibly the compatibility version of |
| 35 // personal_data_manager.cc. | 23 // |meta_table_|. |
| 36 template<typename T> | 24 void ChangeVersion(sql::MetaTable* meta_table, |
| 37 T* address_of(T& v) { | 25 int version_num, |
| 38 return &v; | 26 bool update_compatible_version_num) { |
| 27 meta_table->SetVersionNumber(version_num); |
| 28 if (update_compatible_version_num) { |
| 29 meta_table->SetCompatibleVersionNumber( |
| 30 std::min(version_num, kCompatibleVersionNumber)); |
| 31 } |
| 39 } | 32 } |
| 40 | 33 |
| 41 } // anonymous namespace | 34 // Outputs the failed version number as a warning and always returns |
| 35 // |sql::INIT_FAILURE|. |
| 36 sql::InitStatus FailedMigrationTo(int version_num) { |
| 37 LOG(WARNING) << "Unable to update web database to version " |
| 38 << version_num << "."; |
| 39 NOTREACHED(); |
| 40 return sql::INIT_FAILURE; |
| 41 } |
| 42 |
| 43 } // namespace |
| 42 | 44 |
| 43 WebDatabase::WebDatabase() {} | 45 WebDatabase::WebDatabase() {} |
| 44 | 46 |
| 45 WebDatabase::~WebDatabase() {} | 47 WebDatabase::~WebDatabase() {} |
| 46 | 48 |
| 47 void WebDatabase::BeginTransaction() { | 49 void WebDatabase::BeginTransaction() { |
| 48 db_.BeginTransaction(); | 50 db_.BeginTransaction(); |
| 49 } | 51 } |
| 50 | 52 |
| 51 void WebDatabase::CommitTransaction() { | 53 void WebDatabase::CommitTransaction() { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 // There should not be a released product that makes a database too old to | 153 // 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 | 154 // 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, | 155 // better solution to handle it (i.e., pop up a dialog to tell the user, |
| 154 // erase all their prefs and start over, etc.). | 156 // erase all their prefs and start over, etc.). |
| 155 LOG(WARNING) << "Web database version " << current_version << | 157 LOG(WARNING) << "Web database version " << current_version << |
| 156 " is too old to handle."; | 158 " is too old to handle."; |
| 157 NOTREACHED(); | 159 NOTREACHED(); |
| 158 return sql::INIT_FAILURE; | 160 return sql::INIT_FAILURE; |
| 159 | 161 |
| 160 case 20: | 162 case 20: |
| 161 // Add the autogenerate_keyword column. | 163 if (!keyword_table_->MigrateToVersion21AutoGenerateKeywordColumn()) |
| 162 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN autogenerate_keyword " | 164 return FailedMigrationTo(21); |
| 163 "INTEGER DEFAULT 0")) { | 165 |
| 164 LOG(WARNING) << "Unable to update web database to version 21."; | 166 ChangeVersion(&meta_table_, 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 | 167 // FALL THROUGH |
| 172 | 168 |
| 173 case 21: | 169 case 21: |
| 174 if (!autofill_table_->ClearAutofillEmptyValueElements()) { | 170 if (!autofill_table_->ClearAutofillEmptyValueElements()) |
| 175 LOG(WARNING) << "Failed to clean-up autofill DB."; | 171 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 | 172 |
| 173 ChangeVersion(&meta_table_, 22, false); |
| 182 // FALL THROUGH | 174 // FALL THROUGH |
| 183 | 175 |
| 184 case 22: | 176 case 22: |
| 185 // Add the card_number_encrypted column if credit card table was not | 177 if (!autofill_table_->MigrateToVersion23AddCardNumberEncryptedColumn()) |
| 186 // created in this build (otherwise the column already exists). | 178 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 | 179 |
| 224 if (!db_.DoesColumnExist("credit_cards", "verification_code_encrypted")) { | 180 ChangeVersion(&meta_table_, 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 | 181 // FALL THROUGH |
| 235 | 182 |
| 236 case 23: { | 183 case 23: |
| 237 // One-time cleanup for Chromium bug 38364. In the presence of | 184 if (!autofill_table_->MigrateToVersion24CleanupOversizedStringFields()) |
| 238 // multi-byte UTF-8 characters, that bug could cause Autofill strings | 185 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 | 186 |
| 246 const std::string credit_cards_is_too_big = | 187 ChangeVersion(&meta_table_, 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 | 188 // FALL THROUGH |
| 305 } | |
| 306 | 189 |
| 307 case 24: | 190 case 24: |
| 308 // Add the logo_id column if keyword table was not created in this build. | 191 if (!keyword_table_->MigrateToVersion25AddLogoIDColumn()) |
| 309 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN logo_id " | 192 return FailedMigrationTo(25); |
| 310 "INTEGER DEFAULT 0")) { | 193 |
| 311 LOG(WARNING) << "Unable to update web database to version 25."; | 194 ChangeVersion(&meta_table_, 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 | 195 // FALL THROUGH |
| 319 | 196 |
| 320 case 25: | 197 case 25: |
| 321 // Add the created_by_policy column. | 198 if (!keyword_table_->MigrateToVersion26AddCreatedByPolicyColumn()) |
| 322 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN created_by_policy " | 199 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 | 200 |
| 329 meta_table_.SetVersionNumber(26); | 201 ChangeVersion(&meta_table_, 26, true); |
| 330 meta_table_.SetCompatibleVersionNumber( | |
| 331 std::min(26, kCompatibleVersionNumber)); | |
| 332 // FALL THROUGH | 202 // FALL THROUGH |
| 333 | 203 |
| 334 case 26: { | 204 case 26: |
| 335 // Only migrate from legacy credit card tables where specific columns | 205 if (!autofill_table_->MigrateToVersion27UpdateLegacyCreditCards()) |
| 336 // exist. | 206 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 | 207 |
| 355 std::map<int, int> cc_billing_map; | 208 ChangeVersion(&meta_table_, 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 | 209 // FALL THROUGH |
| 447 } | |
| 448 | 210 |
| 449 case 27: | 211 case 27: |
| 450 // Add supports_instant to keywords. | 212 if (!keyword_table_->MigrateToVersion28SupportsInstantColumn()) |
| 451 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN supports_instant " | 213 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 | 214 |
| 215 ChangeVersion(&meta_table_, 28, true); |
| 461 // FALL THROUGH | 216 // FALL THROUGH |
| 462 | 217 |
| 463 case 28: | 218 case 28: |
| 464 // Keywords loses the column supports_instant and gets instant_url. | 219 if (!keyword_table_->MigrateToVersion29InstantUrlToSupportsInstant()) |
| 465 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN instant_url " | 220 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 | 221 |
| 494 if (!db_.Execute( | 222 ChangeVersion(&meta_table_, 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 | 223 // FALL THROUGH |
| 524 | 224 |
| 525 case 29: | 225 case 29: |
| 526 // Add date_modified to autofill_profiles. | 226 if (!autofill_table_->MigrateToVersion30AddDateModifed()) |
| 527 if (!db_.DoesColumnExist("autofill_profiles", "date_modified")) { | 227 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 | 228 |
| 535 sql::Statement s(db_.GetUniqueStatement( | 229 ChangeVersion(&meta_table_, 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 | 230 // FALL THROUGH |
| 584 | 231 |
| 585 case 30: | 232 case 30: |
| 586 // Add |guid| column to |autofill_profiles| table. | 233 if (!autofill_table_->MigrateToVersion31AddGUIDToCreditCardsAndProfiles()) |
| 587 // Note that we need to check for the guid column's existence due to the | 234 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 | 235 |
| 598 // Set all the |guid| fields to valid values. | 236 ChangeVersion(&meta_table_, 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 | 237 // FALL THROUGH |
| 678 | 238 |
| 679 case 31: | 239 case 31: |
| 680 if (db_.DoesColumnExist("autofill_profiles", "unique_id")) { | 240 if (!autofill_table_->MigrateToVersion32UpdateProfilesAndCreditCards()) |
| 681 if (!db_.Execute("CREATE TABLE autofill_profiles_temp ( " | 241 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 | 242 |
| 703 if (!db_.Execute( | 243 ChangeVersion(&meta_table_, 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 | 244 // FALL THROUGH |
| 771 | 245 |
| 772 case 32: | 246 case 32: |
| 773 // Test the existence of the |first_name| column as an indication that | 247 if (!autofill_table_->MigrateToVersion33ProfilesBasedOnFirstName()) |
| 774 // we need a migration. It is possible that the new |autofill_profiles| | 248 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 | 249 |
| 795 { | 250 ChangeVersion(&meta_table_, 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 | 251 // FALL THROUGH |
| 911 | 252 |
| 912 case 33: | 253 case 33: |
| 913 // Test the existence of the |country_code| column as an indication that | 254 if (!autofill_table_->MigrateToVersion34ProfilesBasedOnCountryCode()) |
| 914 // we need a migration. It is possible that the new |autofill_profiles| | 255 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 | 256 |
| 925 // Set all the |country_code| fields to match existing |country| values. | 257 ChangeVersion(&meta_table_, 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 | 258 // FALL THROUGH |
| 965 | 259 |
| 966 case 34: | 260 case 34: |
| 967 // Correct all country codes with value "UK" to be "GB". This data | 261 if (!autofill_table_->MigrateToVersion35GreatBritainCountryCodes()) |
| 968 // was mistakenly introduced in build 686.0. This migration is to clean | 262 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 | 263 |
| 975 if (!s.Run()) { | 264 ChangeVersion(&meta_table_, 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 | 265 // FALL THROUGH |
| 987 | 266 |
| 988 case 35: | 267 case 35: |
| 989 // Merge and cull older profiles where possible. | 268 if (!autofill_table_->MigrateToVersion36MergeAndCullOlderProfiles()) |
| 990 { | 269 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 | 270 |
| 999 // Accumulate the good profiles. | 271 ChangeVersion(&meta_table_, 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 | 272 // FALL THROUGH |
| 1082 | 273 |
| 1083 // Add successive versions here. Each should set the version number and | 274 // Add successive versions here. Each should set the version number and |
| 1084 // compatible version number as appropriate, then fall through to the next | 275 // compatible version number as appropriate, then fall through to the next |
| 1085 // case. | 276 // case. |
| 1086 | 277 |
| 1087 case kCurrentVersionNumber: | 278 case kCurrentVersionNumber: |
| 1088 // No migration needed. | 279 // No migration needed. |
| 1089 return sql::INIT_OK; | 280 return sql::INIT_OK; |
| 1090 } | 281 } |
| 1091 } | 282 } |
| OLD | NEW |