Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: chrome/browser/history/thumbnail_database.cc

Issue 50493012: [sql] Recover Favicons v5 databases, with more recovery automation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase and cleanup Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/history/thumbnail_database_unittest.cc » ('j') | sql/recovery.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/history/thumbnail_database.h" 5 #include "chrome/browser/history/thumbnail_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 // want once-only handling? Sqlite.Error.Thumbnail shows 268 // want once-only handling? Sqlite.Error.Thumbnail shows
269 // CORRUPT and READONLY as almost 95% of all reports on these 269 // CORRUPT and READONLY as almost 95% of all reports on these
270 // channels, so probably easier to just harvest from the field. 270 // channels, so probably easier to just harvest from the field.
271 if (rand < kReportsPerMillion) { 271 if (rand < kReportsPerMillion) {
272 reported = true; 272 reported = true;
273 ReportError(db, extended_error); 273 ReportError(db, extended_error);
274 } 274 }
275 } 275 }
276 } 276 }
277 277
278 // Create v5 schema for recovery code.
279 bool InitSchemaV5(sql::Connection* db) {
280 // This schema was derived from the strings used when v5 was in
281 // force. The [favicons] index and the [icon_mapping] items were
282 // copied from the current strings, after verifying that the
283 // resulting schema exactly matches the schema created by the
284 // original versions of those strings. This allows the linker to
285 // share the strings if they match, while preferring correctness of
286 // the current versions change.
287
288 const char kFaviconsV5[] =
289 "CREATE TABLE favicons("
pkotwicz 2013/11/04 02:38:31 Nit: It would be nice if we were consistent in usi
Scott Hess - ex-Googler 2013/11/04 21:41:44 As a general rule, I would prefer if we never ever
290 "id INTEGER PRIMARY KEY,"
291 "url LONGVARCHAR NOT NULL,"
292 "last_updated INTEGER DEFAULT 0,"
293 "image_data BLOB,"
294 "icon_type INTEGER DEFAULT 1,"
295 "sizes LONGVARCHAR"
296 ")";
297 const char kFaviconsIndexV5[] =
298 "CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)";
299 if (!db->Execute(kFaviconsV5) || !db->Execute(kFaviconsIndexV5))
300 return false;
301
302 const char kIconMappingV5[] =
303 "CREATE TABLE IF NOT EXISTS icon_mapping"
304 "("
305 "id INTEGER PRIMARY KEY,"
306 "page_url LONGVARCHAR NOT NULL,"
307 "icon_id INTEGER"
308 ")";
309 const char kIconMappingUrlIndexV5[] =
310 "CREATE INDEX IF NOT EXISTS icon_mapping_page_url_idx"
311 " ON icon_mapping(page_url)";
312 const char kIconMappingIdIndexV5[] =
313 "CREATE INDEX IF NOT EXISTS icon_mapping_icon_id_idx"
314 " ON icon_mapping(icon_id)";
315 if (!db->Execute(kIconMappingV5) ||
316 !db->Execute(kIconMappingUrlIndexV5) ||
317 !db->Execute(kIconMappingIdIndexV5)) {
318 return false;
319 }
320
321 return true;
322 }
323
324 // TODO(shess): Consider InitSchemaV7(). InitSchemaV5() is worthwhile
325 // because there appear to be 10s of thousands of marooned v5
326 // databases in the wild. Once recovery reaches stable, the number of
327 // corrupt-but-recoverable databases should drop, possibly to the
328 // point where it is not worthwhile to maintain previous-version
329 // recovery code.
330 // TODO(shess): Alternately, think on a way to more cleanly represent
331 // versioned schema going forward.
278 bool InitTables(sql::Connection* db) { 332 bool InitTables(sql::Connection* db) {
279 const char kIconMappingSql[] = 333 const char kIconMappingSql[] =
280 "CREATE TABLE IF NOT EXISTS icon_mapping" 334 "CREATE TABLE IF NOT EXISTS icon_mapping"
281 "(" 335 "("
282 "id INTEGER PRIMARY KEY," 336 "id INTEGER PRIMARY KEY,"
283 "page_url LONGVARCHAR NOT NULL," 337 "page_url LONGVARCHAR NOT NULL,"
284 "icon_id INTEGER" 338 "icon_id INTEGER"
285 ")"; 339 ")";
286 if (!db->Execute(kIconMappingSql)) 340 if (!db->Execute(kIconMappingSql))
287 return false; 341 return false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 "favicon_bitmaps(icon_id)"; 389 "favicon_bitmaps(icon_id)";
336 if (!db->Execute(kFaviconBitmapsIndexSql)) 390 if (!db->Execute(kFaviconBitmapsIndexSql))
337 return false; 391 return false;
338 392
339 return true; 393 return true;
340 } 394 }
341 395
342 enum RecoveryEventType { 396 enum RecoveryEventType {
343 RECOVERY_EVENT_RECOVERED = 0, 397 RECOVERY_EVENT_RECOVERED = 0,
344 RECOVERY_EVENT_FAILED_SCOPER, 398 RECOVERY_EVENT_FAILED_SCOPER,
345 RECOVERY_EVENT_FAILED_META_VERSION_ERROR, 399 RECOVERY_EVENT_FAILED_META_VERSION_ERROR, // obsolete
346 RECOVERY_EVENT_FAILED_META_VERSION_NONE, 400 RECOVERY_EVENT_FAILED_META_VERSION_NONE, // obsolete
347 RECOVERY_EVENT_FAILED_META_WRONG_VERSION6, // obsolete 401 RECOVERY_EVENT_FAILED_META_WRONG_VERSION6, // obsolete
348 RECOVERY_EVENT_FAILED_META_WRONG_VERSION5, 402 RECOVERY_EVENT_FAILED_META_WRONG_VERSION5, // obsolete
349 RECOVERY_EVENT_FAILED_META_WRONG_VERSION, 403 RECOVERY_EVENT_FAILED_META_WRONG_VERSION,
350 RECOVERY_EVENT_FAILED_RECOVER_META, 404 RECOVERY_EVENT_FAILED_RECOVER_META, // obsolete
351 RECOVERY_EVENT_FAILED_META_INSERT, // obsolete 405 RECOVERY_EVENT_FAILED_META_INSERT, // obsolete
352 RECOVERY_EVENT_FAILED_INIT, 406 RECOVERY_EVENT_FAILED_INIT,
353 RECOVERY_EVENT_FAILED_RECOVER_FAVICONS, 407 RECOVERY_EVENT_FAILED_RECOVER_FAVICONS, // obsolete
354 RECOVERY_EVENT_FAILED_FAVICONS_INSERT, 408 RECOVERY_EVENT_FAILED_FAVICONS_INSERT, // obsolete
355 RECOVERY_EVENT_FAILED_RECOVER_FAVICON_BITMAPS, 409 RECOVERY_EVENT_FAILED_RECOVER_FAVICON_BITMAPS, // obsolete
356 RECOVERY_EVENT_FAILED_FAVICON_BITMAPS_INSERT, 410 RECOVERY_EVENT_FAILED_FAVICON_BITMAPS_INSERT, // obsolete
357 RECOVERY_EVENT_FAILED_RECOVER_ICON_MAPPING, 411 RECOVERY_EVENT_FAILED_RECOVER_ICON_MAPPING, // obsolete
358 RECOVERY_EVENT_FAILED_ICON_MAPPING_INSERT, 412 RECOVERY_EVENT_FAILED_ICON_MAPPING_INSERT, // obsolete
359 RECOVERY_EVENT_RECOVERED_VERSION6, 413 RECOVERY_EVENT_RECOVERED_VERSION6,
360 RECOVERY_EVENT_FAILED_META_INIT, 414 RECOVERY_EVENT_FAILED_META_INIT,
415 RECOVERY_EVENT_FAILED_META_VERSION,
416 RECOVERY_EVENT_DEPRECATED,
417 RECOVERY_EVENT_FAILED_V5_INITSCHEMA,
418 RECOVERY_EVENT_FAILED_V5_AUTORECOVER_FAVICONS,
419 RECOVERY_EVENT_FAILED_V5_AUTORECOVER_ICON_MAPPING,
420 RECOVERY_EVENT_RECOVERED_VERSION5,
421 RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICONS,
422 RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICON_BITMAPS,
423 RECOVERY_EVENT_FAILED_AUTORECOVER_ICON_MAPPING,
361 424
362 // Always keep this at the end. 425 // Always keep this at the end.
363 RECOVERY_EVENT_MAX, 426 RECOVERY_EVENT_MAX,
364 }; 427 };
365 428
366 void RecordRecoveryEvent(RecoveryEventType recovery_event) { 429 void RecordRecoveryEvent(RecoveryEventType recovery_event) {
367 UMA_HISTOGRAM_ENUMERATION("History.FaviconsRecovery", 430 UMA_HISTOGRAM_ENUMERATION("History.FaviconsRecovery",
368 recovery_event, RECOVERY_EVENT_MAX); 431 recovery_event, RECOVERY_EVENT_MAX);
369 } 432 }
370 433
(...skipping 20 matching lines...) Expand all
391 // 454 //
392 // Possible responses are unclear. If the failure relates to a 455 // Possible responses are unclear. If the failure relates to a
393 // problem somehow specific to the temporary file used to back the 456 // problem somehow specific to the temporary file used to back the
394 // database, then an in-memory database could possibly be used. 457 // database, then an in-memory database could possibly be used.
395 // This could potentially allow recovering the main database, and 458 // This could potentially allow recovering the main database, and
396 // might be simple to implement w/in Begin(). 459 // might be simple to implement w/in Begin().
397 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_SCOPER); 460 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_SCOPER);
398 return; 461 return;
399 } 462 }
400 463
401 // Setup the meta recovery table, and check that the version number 464 // Setup the meta recovery table and fetch the version number from
402 // is covered by the recovery code. 465 // the corrupt database.
403 // TODO(shess): sql::Recovery should provide a helper to handle meta. 466 int version = 0;
404 int version = 0; // For reporting which version was recovered. 467 if (!recovery->SetupMeta() || !recovery->GetMetaVersionNumber(&version)) {
405 { 468 // TODO(shess): Prior histograms indicate all failures are in
406 const char kRecoverySql[] = 469 // creating the recover virtual table for corrupt.meta. The table
407 "CREATE VIRTUAL TABLE temp.recover_meta USING recover" 470 // may not exist, or the database may be too far gone. Either
408 "(" 471 // way, unclear how to resolve.
409 "corrupt.meta," 472 sql::Recovery::Rollback(recovery.Pass());
410 "key TEXT NOT NULL," 473 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_VERSION);
411 "value TEXT" // Really? Never int? 474 return;
412 ")"; 475 }
413 if (!recovery->db()->Execute(kRecoverySql)) {
414 // TODO(shess): Failure to create the recover_meta table could
415 // mean that the main database is too corrupt to access, or that
416 // the meta table doesn't exist.
417 sql::Recovery::Rollback(recovery.Pass());
418 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_RECOVER_META);
419 return;
420 }
421 476
422 { 477 // Recover v5 database to v5 schema. Next pass through Init() will
423 const char kRecoveryVersionSql[] = 478 // migrate to v7.
424 "SELECT value FROM recover_meta WHERE key = 'version'"; 479 if (version == 5) {
425 sql::Statement recovery_version(
426 recovery->db()->GetUniqueStatement(kRecoveryVersionSql));
427 if (!recovery_version.Step()) {
428 if (!recovery_version.Succeeded()) {
429 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_VERSION_ERROR);
430 // TODO(shess): An error while processing the statement is
431 // probably not recoverable.
432 } else {
433 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_VERSION_NONE);
434 // TODO(shess): If a positive version lock cannot be achieved,
435 // the database could still be recovered by optimistically
436 // attempting to copy things. In the limit, the schema found
437 // could be inspected. Less clear is whether optimistic
438 // recovery really makes sense.
439 }
440 recovery_version.Clear();
441 sql::Recovery::Rollback(recovery.Pass());
442 return;
443 }
444 version = recovery_version.ColumnInt(0);
445
446 // Recovery code is generally schema-dependent. Version 7 and
447 // version 6 are very similar, so can be handled together.
448 // Track version 5, to see whether it's worth writing recovery
449 // code for.
450 if (version != 7 && version != 6) {
451 if (version == 5) {
452 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_WRONG_VERSION5);
453 } else {
454 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_WRONG_VERSION);
455 }
456 recovery_version.Clear();
457 sql::Recovery::Rollback(recovery.Pass());
458 return;
459 }
460 }
461
462 // Either version 6 or version 7 recovers to current.
463 sql::MetaTable recover_meta_table; 480 sql::MetaTable recover_meta_table;
464 if (!recover_meta_table.Init(recovery->db(), kCurrentVersionNumber, 481 if (!recover_meta_table.Init(recovery->db(), version, version)) {
465 kCompatibleVersionNumber)) {
466 sql::Recovery::Rollback(recovery.Pass()); 482 sql::Recovery::Rollback(recovery.Pass());
467 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_INIT); 483 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_INIT);
468 return; 484 return;
469 } 485 }
486
487 // TODO(shess): These tests are separate for histogram purposes,
488 // but once things look stable it can be tightened up.
489 if (!InitSchemaV5(recovery->db())) {
490 sql::Recovery::Rollback(recovery.Pass());
491 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_V5_INITSCHEMA);
492 return;
493 }
494
495 if (!recovery->AutoRecoverTable("favicons", 0)) {
496 sql::Recovery::Rollback(recovery.Pass());
497 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_V5_AUTORECOVER_FAVICONS);
498 return;
499 }
500
501 if (!recovery->AutoRecoverTable("icon_mapping", 0)) {
502 sql::Recovery::Rollback(recovery.Pass());
503 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_V5_AUTORECOVER_ICON_MAPPING);
504 return;
505 }
506
507 ignore_result(sql::Recovery::Recovered(recovery.Pass()));
508 RecordRecoveryEvent(RECOVERY_EVENT_RECOVERED_VERSION5);
509 return;
510 }
511
512 // This code may be able to fetch versions that the regular
513 // deprecation path cannot.
514 if (version <= kDeprecatedVersionNumber) {
515 sql::Recovery::Unrecoverable(recovery.Pass());
516 RecordRecoveryEvent(RECOVERY_EVENT_DEPRECATED);
517 return;
518 }
519
520 // TODO(shess): Earlier versions have been handled or deprecated,
521 // later versions should be impossible. Unrecoverable() seems
522 // reasonable.
523 if (version != 6 && version != 7) {
524 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_WRONG_VERSION);
525 sql::Recovery::Rollback(recovery.Pass());
526 return;
527 }
528
529 // Both v6 and v7 recover to current schema version.
530 sql::MetaTable recover_meta_table;
531 if (!recover_meta_table.Init(recovery->db(), kCurrentVersionNumber,
532 kCompatibleVersionNumber)) {
533 sql::Recovery::Rollback(recovery.Pass());
534 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_META_INIT);
535 return;
470 } 536 }
471 537
472 // Create a fresh version of the database. The recovery code uses 538 // Create a fresh version of the database. The recovery code uses
473 // conflict-resolution to handle duplicates, so the indices are 539 // conflict-resolution to handle duplicates, so the indices are
474 // necessary. 540 // necessary.
475 if (!InitTables(recovery->db()) || !InitIndices(recovery->db())) { 541 if (!InitTables(recovery->db()) || !InitIndices(recovery->db())) {
476 // TODO(shess): Unable to create the new schema in the new 542 // TODO(shess): Unable to create the new schema in the new
477 // database. The new database should be a temporary file, so 543 // database. The new database should be a temporary file, so
478 // being unable to work with it is pretty unclear. 544 // being unable to work with it is pretty unclear.
479 // 545 //
480 // What are the potential responses, even? The recovery database 546 // What are the potential responses, even? The recovery database
481 // could be opened as in-memory. If the temp database had a 547 // could be opened as in-memory. If the temp database had a
482 // filesystem problem and the temp filesystem differs from the 548 // filesystem problem and the temp filesystem differs from the
483 // main database, then that could fix it. 549 // main database, then that could fix it.
484 sql::Recovery::Rollback(recovery.Pass()); 550 sql::Recovery::Rollback(recovery.Pass());
485 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_INIT); 551 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_INIT);
486 return; 552 return;
487 } 553 }
488 554
489 // Setup favicons table. 555 // [favicons] differs because v6 had an unused [sizes] column which
490 { 556 // was removed in v7.
491 // Version 6 had the |sizes| column, version 7 removed it. The 557 if (!recovery->AutoRecoverTable("favicons", 1)) {
492 // recover virtual table treats more columns than expected as an 558 sql::Recovery::Rollback(recovery.Pass());
493 // error, but if _fewer_ columns are present, they can be treated 559 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICONS);
494 // as NULL. SQLite requires this because ALTER TABLE adds columns 560 return;
495 // to the schema, but not to the actual table storage.
496 const char kRecoverySql[] =
497 "CREATE VIRTUAL TABLE temp.recover_favicons USING recover"
498 "("
499 "corrupt.favicons,"
500 "id ROWID,"
501 "url TEXT NOT NULL,"
502 "icon_type INTEGER,"
503 "sizes TEXT"
504 ")";
505 if (!recovery->db()->Execute(kRecoverySql)) {
506 // TODO(shess): Failure to create the recovery table probably
507 // means unrecoverable.
508 sql::Recovery::Rollback(recovery.Pass());
509 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_RECOVER_FAVICONS);
510 return;
511 }
512
513 // TODO(shess): Check if the DEFAULT 1 will just cover the
514 // COALESCE(). Either way, the new code has a literal 1 rather
515 // than a NULL, right?
516 const char kCopySql[] =
517 "INSERT OR REPLACE INTO main.favicons "
518 "SELECT id, url, COALESCE(icon_type, 1) FROM recover_favicons";
519 if (!recovery->db()->Execute(kCopySql)) {
520 // TODO(shess): The recover_favicons table should mask problems
521 // with the source file, so this implies failure to write to the
522 // recovery database.
523 sql::Recovery::Rollback(recovery.Pass());
524 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_FAVICONS_INSERT);
525 return;
526 }
527 } 561 }
528 562 if (!recovery->AutoRecoverTable("favicon_bitmaps", 0)) {
529 // Setup favicons_bitmaps table. 563 sql::Recovery::Rollback(recovery.Pass());
530 { 564 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_FAVICON_BITMAPS);
531 const char kRecoverySql[] = 565 return;
532 "CREATE VIRTUAL TABLE temp.recover_favicons_bitmaps USING recover"
533 "("
534 "corrupt.favicon_bitmaps,"
535 "id ROWID,"
536 "icon_id INTEGER STRICT NOT NULL,"
537 "last_updated INTEGER,"
538 "image_data BLOB,"
539 "width INTEGER,"
540 "height INTEGER"
541 ")";
542 if (!recovery->db()->Execute(kRecoverySql)) {
543 // TODO(shess): Failure to create the recovery table probably
544 // means unrecoverable.
545 sql::Recovery::Rollback(recovery.Pass());
546 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_RECOVER_FAVICON_BITMAPS);
547 return;
548 }
549
550 const char kCopySql[] =
551 "INSERT OR REPLACE INTO main.favicon_bitmaps "
552 "SELECT id, icon_id, COALESCE(last_updated, 0), image_data, "
553 " COALESCE(width, 0), COALESCE(height, 0) "
554 "FROM recover_favicons_bitmaps";
555 if (!recovery->db()->Execute(kCopySql)) {
556 // TODO(shess): The recover_faviconbitmaps table should mask
557 // problems with the source file, so this implies failure to
558 // write to the recovery database.
559 sql::Recovery::Rollback(recovery.Pass());
560 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_FAVICON_BITMAPS_INSERT);
561 return;
562 }
563 } 566 }
564 567 if (!recovery->AutoRecoverTable("icon_mapping", 0)) {
565 // Setup icon_mapping table. 568 sql::Recovery::Rollback(recovery.Pass());
566 { 569 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_AUTORECOVER_ICON_MAPPING);
567 const char kRecoverySql[] = 570 return;
568 "CREATE VIRTUAL TABLE temp.recover_icon_mapping USING recover"
569 "("
570 "corrupt.icon_mapping,"
571 "id ROWID,"
572 "page_url TEXT STRICT NOT NULL,"
573 "icon_id INTEGER STRICT"
574 ")";
575 if (!recovery->db()->Execute(kRecoverySql)) {
576 // TODO(shess): Failure to create the recovery table probably
577 // means unrecoverable.
578 sql::Recovery::Rollback(recovery.Pass());
579 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_RECOVER_ICON_MAPPING);
580 return;
581 }
582
583 const char kCopySql[] =
584 "INSERT OR REPLACE INTO main.icon_mapping "
585 "SELECT id, page_url, icon_id FROM recover_icon_mapping";
586 if (!recovery->db()->Execute(kCopySql)) {
587 // TODO(shess): The recover_icon_mapping table should mask
588 // problems with the source file, so this implies failure to
589 // write to the recovery database.
590 sql::Recovery::Rollback(recovery.Pass());
591 RecordRecoveryEvent(RECOVERY_EVENT_FAILED_ICON_MAPPING_INSERT);
592 return;
593 }
594 } 571 }
595 572
596 // TODO(shess): Is it possible/likely to have broken foreign-key 573 // TODO(shess): Is it possible/likely to have broken foreign-key
597 // issues with the tables? 574 // issues with the tables?
598 // - icon_mapping.icon_id maps to no favicons.id 575 // - icon_mapping.icon_id maps to no favicons.id
599 // - favicon_bitmaps.icon_id maps to no favicons.id 576 // - favicon_bitmaps.icon_id maps to no favicons.id
600 // - favicons.id is referenced by no icon_mapping.icon_id 577 // - favicons.id is referenced by no icon_mapping.icon_id
601 // - favicons.id is referenced by no favicon_bitmaps.icon_id 578 // - favicons.id is referenced by no favicon_bitmaps.icon_id
602 // This step is possibly not worth the effort necessary to develop 579 // This step is possibly not worth the effort necessary to develop
603 // and sequence the statements, as it is basically a form of garbage 580 // and sequence the statements, as it is basically a form of garbage
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 ignore_result(db_.Execute("DROP TABLE IF EXISTS temp_icon_mapping")); 1247 ignore_result(db_.Execute("DROP TABLE IF EXISTS temp_icon_mapping"));
1271 1248
1272 // Create the tables. 1249 // Create the tables.
1273 if (!meta_table_.Init(&db_, kCurrentVersionNumber, 1250 if (!meta_table_.Init(&db_, kCurrentVersionNumber,
1274 kCompatibleVersionNumber) || 1251 kCompatibleVersionNumber) ||
1275 !InitTables(&db_) || 1252 !InitTables(&db_) ||
1276 !InitIndices(&db_)) { 1253 !InitIndices(&db_)) {
1277 return sql::INIT_FAILURE; 1254 return sql::INIT_FAILURE;
1278 } 1255 }
1279 1256
1280 // Version check. We should not encounter a database too old for us to handle 1257 // Version check. We should not encounter a database too old for us to handle
pkotwicz 2013/11/04 02:38:31 Unrelated: Shouldn't this comment be "too new for
Scott Hess - ex-Googler 2013/11/04 21:41:44 I think this means that the too-new case fails (wi
1281 // in the wild, so we try to continue in that case. 1258 // in the wild, so we try to continue in that case.
1282 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 1259 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
1283 LOG(WARNING) << "Thumbnail database is too new."; 1260 LOG(WARNING) << "Thumbnail database is too new.";
1284 return sql::INIT_TOO_NEW; 1261 return sql::INIT_TOO_NEW;
1285 } 1262 }
1286 1263
1287 int cur_version = meta_table_.GetVersionNumber(); 1264 int cur_version = meta_table_.GetVersionNumber();
1288 1265
1289 if (!db_.DoesColumnExist("favicons", "icon_type")) { 1266 if (!db_.DoesColumnExist("favicons", "icon_type")) {
1290 LOG(ERROR) << "Raze because of missing favicon.icon_type"; 1267 LOG(ERROR) << "Raze because of missing favicon.icon_type";
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 meta_table_.SetVersionNumber(7); 1369 meta_table_.SetVersionNumber(7);
1393 meta_table_.SetCompatibleVersionNumber(std::min(7, kCompatibleVersionNumber)); 1370 meta_table_.SetCompatibleVersionNumber(std::min(7, kCompatibleVersionNumber));
1394 return true; 1371 return true;
1395 } 1372 }
1396 1373
1397 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { 1374 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() {
1398 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); 1375 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons");
1399 } 1376 }
1400 1377
1401 } // namespace history 1378 } // namespace history
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/history/thumbnail_database_unittest.cc » ('j') | sql/recovery.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698