| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2013 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 | 418 |
| 419 void setOpenSucceeded() { m_openSucceeded = true; } | 419 void setOpenSucceeded() { m_openSucceeded = true; } |
| 420 | 420 |
| 421 private: | 421 private: |
| 422 Member<Database> m_database; | 422 Member<Database> m_database; |
| 423 bool m_openSucceeded; | 423 bool m_openSucceeded; |
| 424 }; | 424 }; |
| 425 | 425 |
| 426 bool Database::performOpenAndVerify(bool shouldSetVersionInNewDatabase, Database
Error& error, String& errorMessage) | 426 bool Database::performOpenAndVerify(bool shouldSetVersionInNewDatabase, Database
Error& error, String& errorMessage) |
| 427 { | 427 { |
| 428 double callStartTime = WTF::monotonicallyIncreasingTime(); |
| 428 DoneCreatingDatabaseOnExitCaller onExitCaller(this); | 429 DoneCreatingDatabaseOnExitCaller onExitCaller(this); |
| 429 ASSERT(errorMessage.isEmpty()); | 430 ASSERT(errorMessage.isEmpty()); |
| 430 ASSERT(error == DatabaseError::None); // Better not have any errors already. | 431 ASSERT(error == DatabaseError::None); // Better not have any errors already. |
| 431 // Presumed failure. We'll clear it if we succeed below. | 432 // Presumed failure. We'll clear it if we succeed below. |
| 432 error = DatabaseError::InvalidDatabaseState; | 433 error = DatabaseError::InvalidDatabaseState; |
| 433 | 434 |
| 434 const int maxSqliteBusyWaitTime = 30000; | 435 const int maxSqliteBusyWaitTime = 30000; |
| 435 | 436 |
| 436 if (!m_sqliteDatabase.open(m_filename)) { | 437 if (!m_sqliteDatabase.open(m_filename)) { |
| 437 reportOpenDatabaseResult(1, InvalidStateError, m_sqliteDatabase.lastErro
r()); | 438 reportOpenDatabaseResult(1, InvalidStateError, m_sqliteDatabase.lastErro
r(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 438 errorMessage = formatErrorMessage("unable to open database", m_sqliteDat
abase.lastError(), m_sqliteDatabase.lastErrorMsg()); | 439 errorMessage = formatErrorMessage("unable to open database", m_sqliteDat
abase.lastError(), m_sqliteDatabase.lastErrorMsg()); |
| 439 return false; | 440 return false; |
| 440 } | 441 } |
| 441 if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum()) | 442 if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum()) |
| 442 WTF_LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sql
iteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); | 443 WTF_LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sql
iteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); |
| 443 | 444 |
| 444 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 445 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 445 | 446 |
| 446 String currentVersion; | 447 String currentVersion; |
| 447 { | 448 { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 467 currentVersion = versionFromDatabase; | 468 currentVersion = versionFromDatabase; |
| 468 updateGuidVersionMap(m_guid, currentVersion); | 469 updateGuidVersionMap(m_guid, currentVersion); |
| 469 } | 470 } |
| 470 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 471 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 471 } else { | 472 } else { |
| 472 WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); | 473 WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); |
| 473 | 474 |
| 474 SQLiteTransaction transaction(m_sqliteDatabase); | 475 SQLiteTransaction transaction(m_sqliteDatabase); |
| 475 transaction.begin(); | 476 transaction.begin(); |
| 476 if (!transaction.inProgress()) { | 477 if (!transaction.inProgress()) { |
| 477 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase.
lastError()); | 478 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 478 errorMessage = formatErrorMessage("unable to open database, fail
ed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErr
orMsg()); | 479 errorMessage = formatErrorMessage("unable to open database, fail
ed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErr
orMsg()); |
| 479 m_sqliteDatabase.close(); | 480 m_sqliteDatabase.close(); |
| 480 return false; | 481 return false; |
| 481 } | 482 } |
| 482 | 483 |
| 483 String tableName(infoTableName); | 484 String tableName(infoTableName); |
| 484 if (!m_sqliteDatabase.tableExists(tableName)) { | 485 if (!m_sqliteDatabase.tableExists(tableName)) { |
| 485 m_new = true; | 486 m_new = true; |
| 486 | 487 |
| 487 if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + tableName
+ " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT N
OT NULL ON CONFLICT FAIL);")) { | 488 if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + tableName
+ " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT N
OT NULL ON CONFLICT FAIL);")) { |
| 488 reportOpenDatabaseResult(3, InvalidStateError, m_sqliteDatab
ase.lastError()); | 489 reportOpenDatabaseResult(3, InvalidStateError, m_sqliteDatab
ase.lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 489 errorMessage = formatErrorMessage("unable to open database,
failed to create 'info' table", m_sqliteDatabase.lastError(), m_sqliteDatabase.l
astErrorMsg()); | 490 errorMessage = formatErrorMessage("unable to open database,
failed to create 'info' table", m_sqliteDatabase.lastError(), m_sqliteDatabase.l
astErrorMsg()); |
| 490 transaction.rollback(); | 491 transaction.rollback(); |
| 491 m_sqliteDatabase.close(); | 492 m_sqliteDatabase.close(); |
| 492 return false; | 493 return false; |
| 493 } | 494 } |
| 494 } else if (!getVersionFromDatabase(currentVersion, false)) { | 495 } else if (!getVersionFromDatabase(currentVersion, false)) { |
| 495 reportOpenDatabaseResult(4, InvalidStateError, m_sqliteDatabase.
lastError()); | 496 reportOpenDatabaseResult(4, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 496 errorMessage = formatErrorMessage("unable to open database, fail
ed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.last
ErrorMsg()); | 497 errorMessage = formatErrorMessage("unable to open database, fail
ed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.last
ErrorMsg()); |
| 497 transaction.rollback(); | 498 transaction.rollback(); |
| 498 m_sqliteDatabase.close(); | 499 m_sqliteDatabase.close(); |
| 499 return false; | 500 return false; |
| 500 } | 501 } |
| 501 | 502 |
| 502 if (currentVersion.length()) { | 503 if (currentVersion.length()) { |
| 503 WTF_LOG(StorageAPI, "Retrieved current version %s from database
%s", currentVersion.ascii().data(), databaseDebugName().ascii().data()); | 504 WTF_LOG(StorageAPI, "Retrieved current version %s from database
%s", currentVersion.ascii().data(), databaseDebugName().ascii().data()); |
| 504 } else if (!m_new || shouldSetVersionInNewDatabase) { | 505 } else if (!m_new || shouldSetVersionInNewDatabase) { |
| 505 WTF_LOG(StorageAPI, "Setting version %s in database %s that was
just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().dat
a()); | 506 WTF_LOG(StorageAPI, "Setting version %s in database %s that was
just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().dat
a()); |
| 506 if (!setVersionInDatabase(m_expectedVersion, false)) { | 507 if (!setVersionInDatabase(m_expectedVersion, false)) { |
| 507 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab
ase.lastError()); | 508 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab
ase.lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 508 errorMessage = formatErrorMessage("unable to open database,
failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase
.lastErrorMsg()); | 509 errorMessage = formatErrorMessage("unable to open database,
failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase
.lastErrorMsg()); |
| 509 transaction.rollback(); | 510 transaction.rollback(); |
| 510 m_sqliteDatabase.close(); | 511 m_sqliteDatabase.close(); |
| 511 return false; | 512 return false; |
| 512 } | 513 } |
| 513 currentVersion = m_expectedVersion; | 514 currentVersion = m_expectedVersion; |
| 514 } | 515 } |
| 515 updateGuidVersionMap(m_guid, currentVersion); | 516 updateGuidVersionMap(m_guid, currentVersion); |
| 516 transaction.commit(); | 517 transaction.commit(); |
| 517 } | 518 } |
| 518 } | 519 } |
| 519 | 520 |
| 520 if (currentVersion.isNull()) { | 521 if (currentVersion.isNull()) { |
| 521 WTF_LOG(StorageAPI, "Database %s does not have its version set", databas
eDebugName().ascii().data()); | 522 WTF_LOG(StorageAPI, "Database %s does not have its version set", databas
eDebugName().ascii().data()); |
| 522 currentVersion = ""; | 523 currentVersion = ""; |
| 523 } | 524 } |
| 524 | 525 |
| 525 // If the expected version isn't the empty string, ensure that the current | 526 // If the expected version isn't the empty string, ensure that the current |
| 526 // database version we have matches that version. Otherwise, set an | 527 // database version we have matches that version. Otherwise, set an |
| 527 // exception. | 528 // exception. |
| 528 // If the expected version is the empty string, then we always return with | 529 // If the expected version is the empty string, then we always return with |
| 529 // whatever version of the database we have. | 530 // whatever version of the database we have. |
| 530 if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length()
&& m_expectedVersion != currentVersion) { | 531 if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length()
&& m_expectedVersion != currentVersion) { |
| 531 reportOpenDatabaseResult(6, InvalidStateError, 0); | 532 reportOpenDatabaseResult(6, InvalidStateError, 0, WTF::monotonicallyIncr
easingTime() - callStartTime); |
| 532 errorMessage = "unable to open database, version mismatch, '" + m_expect
edVersion + "' does not match the currentVersion of '" + currentVersion + "'"; | 533 errorMessage = "unable to open database, version mismatch, '" + m_expect
edVersion + "' does not match the currentVersion of '" + currentVersion + "'"; |
| 533 m_sqliteDatabase.close(); | 534 m_sqliteDatabase.close(); |
| 534 return false; | 535 return false; |
| 535 } | 536 } |
| 536 | 537 |
| 537 ASSERT(m_databaseAuthorizer); | 538 ASSERT(m_databaseAuthorizer); |
| 538 m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer.get()); | 539 m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer.get()); |
| 539 | 540 |
| 540 // See comment at the top this file regarding calling addOpenDatabase(). | 541 // See comment at the top this file regarding calling addOpenDatabase(). |
| 541 DatabaseTracker::tracker().addOpenDatabase(this); | 542 DatabaseTracker::tracker().addOpenDatabase(this); |
| 542 m_opened = true; | 543 m_opened = true; |
| 543 | 544 |
| 544 // Declare success: | 545 // Declare success: |
| 545 error = DatabaseError::None; // Clear the presumed error from above. | 546 error = DatabaseError::None; // Clear the presumed error from above. |
| 546 onExitCaller.setOpenSucceeded(); | 547 onExitCaller.setOpenSucceeded(); |
| 547 | 548 |
| 548 if (m_new && !shouldSetVersionInNewDatabase) { | 549 if (m_new && !shouldSetVersionInNewDatabase) { |
| 549 // The caller provided a creationCallback which will set the expected | 550 // The caller provided a creationCallback which will set the expected |
| 550 // version. | 551 // version. |
| 551 m_expectedVersion = ""; | 552 m_expectedVersion = ""; |
| 552 } | 553 } |
| 553 | 554 |
| 554 reportOpenDatabaseResult(0, -1, 0); // OK | 555 reportOpenDatabaseResult(0, -1, 0, WTF::monotonicallyIncreasingTime() - call
StartTime); // OK |
| 555 | 556 |
| 556 if (databaseContext()->databaseThread()) | 557 if (databaseContext()->databaseThread()) |
| 557 databaseContext()->databaseThread()->recordDatabaseOpen(this); | 558 databaseContext()->databaseThread()->recordDatabaseOpen(this); |
| 558 return true; | 559 return true; |
| 559 } | 560 } |
| 560 | 561 |
| 561 String Database::stringIdentifier() const | 562 String Database::stringIdentifier() const |
| 562 { | 563 { |
| 563 // Return a deep copy for ref counting thread safety | 564 // Return a deep copy for ref counting thread safety |
| 564 return m_name.isolatedCopy(); | 565 return m_name.isolatedCopy(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 if (totalSize <= 10 * freeSpaceSize) { | 709 if (totalSize <= 10 * freeSpaceSize) { |
| 709 int result = m_sqliteDatabase.runIncrementalVacuumCommand(); | 710 int result = m_sqliteDatabase.runIncrementalVacuumCommand(); |
| 710 reportVacuumDatabaseResult(result); | 711 reportVacuumDatabaseResult(result); |
| 711 if (result != SQLResultOk) | 712 if (result != SQLResultOk) |
| 712 logErrorMessage(formatErrorMessage("error vacuuming database", resul
t, m_sqliteDatabase.lastErrorMsg())); | 713 logErrorMessage(formatErrorMessage("error vacuuming database", resul
t, m_sqliteDatabase.lastErrorMsg())); |
| 713 } | 714 } |
| 714 } | 715 } |
| 715 | 716 |
| 716 // These are used to generate histograms of errors seen with websql. | 717 // These are used to generate histograms of errors seen with websql. |
| 717 // See about:histograms in chromium. | 718 // See about:histograms in chromium. |
| 718 void Database::reportOpenDatabaseResult(int errorSite, int webSqlErrorCode, int
sqliteErrorCode) | 719 void Database::reportOpenDatabaseResult(int errorSite, int webSqlErrorCode, int
sqliteErrorCode, double duration) |
| 719 { | 720 { |
| 720 if (Platform::current()->databaseObserver()) { | 721 if (Platform::current()->databaseObserver()) { |
| 721 Platform::current()->databaseObserver()->reportOpenDatabaseResult( | 722 Platform::current()->databaseObserver()->reportOpenDatabaseResult( |
| 722 createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), | 723 createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), |
| 723 stringIdentifier(), errorSite, webSqlErrorCode, sqliteErrorCode); | 724 stringIdentifier(), errorSite, webSqlErrorCode, sqliteErrorCode, |
| 725 duration); |
| 724 } | 726 } |
| 725 } | 727 } |
| 726 | 728 |
| 727 void Database::reportChangeVersionResult(int errorSite, int webSqlErrorCode, int
sqliteErrorCode) | 729 void Database::reportChangeVersionResult(int errorSite, int webSqlErrorCode, int
sqliteErrorCode) |
| 728 { | 730 { |
| 729 if (Platform::current()->databaseObserver()) { | 731 if (Platform::current()->databaseObserver()) { |
| 730 Platform::current()->databaseObserver()->reportChangeVersionResult( | 732 Platform::current()->databaseObserver()->reportChangeVersionResult( |
| 731 createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), | 733 createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), |
| 732 stringIdentifier(), errorSite, webSqlErrorCode, sqliteErrorCode); | 734 stringIdentifier(), errorSite, webSqlErrorCode, sqliteErrorCode); |
| 733 } | 735 } |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 SecurityOrigin* Database::securityOrigin() const | 905 SecurityOrigin* Database::securityOrigin() const |
| 904 { | 906 { |
| 905 if (executionContext()->isContextThread()) | 907 if (executionContext()->isContextThread()) |
| 906 return m_contextThreadSecurityOrigin.get(); | 908 return m_contextThreadSecurityOrigin.get(); |
| 907 if (databaseContext()->databaseThread()->isDatabaseThread()) | 909 if (databaseContext()->databaseThread()->isDatabaseThread()) |
| 908 return m_databaseThreadSecurityOrigin.get(); | 910 return m_databaseThreadSecurityOrigin.get(); |
| 909 return 0; | 911 return 0; |
| 910 } | 912 } |
| 911 | 913 |
| 912 } // namespace blink | 914 } // namespace blink |
| OLD | NEW |