| 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 28 matching lines...) Expand all Loading... |
| 39 #include "modules/webdatabase/DatabaseTask.h" | 39 #include "modules/webdatabase/DatabaseTask.h" |
| 40 #include "modules/webdatabase/DatabaseThread.h" | 40 #include "modules/webdatabase/DatabaseThread.h" |
| 41 #include "modules/webdatabase/DatabaseTracker.h" | 41 #include "modules/webdatabase/DatabaseTracker.h" |
| 42 #include "modules/webdatabase/SQLError.h" | 42 #include "modules/webdatabase/SQLError.h" |
| 43 #include "modules/webdatabase/SQLTransaction.h" | 43 #include "modules/webdatabase/SQLTransaction.h" |
| 44 #include "modules/webdatabase/SQLTransactionBackend.h" | 44 #include "modules/webdatabase/SQLTransactionBackend.h" |
| 45 #include "modules/webdatabase/SQLTransactionCallback.h" | 45 #include "modules/webdatabase/SQLTransactionCallback.h" |
| 46 #include "modules/webdatabase/SQLTransactionClient.h" | 46 #include "modules/webdatabase/SQLTransactionClient.h" |
| 47 #include "modules/webdatabase/SQLTransactionCoordinator.h" | 47 #include "modules/webdatabase/SQLTransactionCoordinator.h" |
| 48 #include "modules/webdatabase/SQLTransactionErrorCallback.h" | 48 #include "modules/webdatabase/SQLTransactionErrorCallback.h" |
| 49 #include "modules/webdatabase/StorageLog.h" |
| 49 #include "modules/webdatabase/sqlite/SQLiteStatement.h" | 50 #include "modules/webdatabase/sqlite/SQLiteStatement.h" |
| 50 #include "modules/webdatabase/sqlite/SQLiteTransaction.h" | 51 #include "modules/webdatabase/sqlite/SQLiteTransaction.h" |
| 51 #include "platform/Logging.h" | |
| 52 #include "platform/heap/SafePoint.h" | 52 #include "platform/heap/SafePoint.h" |
| 53 #include "public/platform/Platform.h" | 53 #include "public/platform/Platform.h" |
| 54 #include "public/platform/WebDatabaseObserver.h" | 54 #include "public/platform/WebDatabaseObserver.h" |
| 55 #include "public/platform/WebSecurityOrigin.h" | 55 #include "public/platform/WebSecurityOrigin.h" |
| 56 #include "wtf/Atomics.h" | 56 #include "wtf/Atomics.h" |
| 57 #include "wtf/CurrentTime.h" | 57 #include "wtf/CurrentTime.h" |
| 58 #include <memory> | 58 #include <memory> |
| 59 | 59 |
| 60 // Registering "opened" databases with the DatabaseTracker | 60 // Registering "opened" databases with the DatabaseTracker |
| 61 // ======================================================= | 61 // ======================================================= |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 void Database::scheduleTransaction() | 326 void Database::scheduleTransaction() |
| 327 { | 327 { |
| 328 ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller. | 328 ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller. |
| 329 SQLTransactionBackend* transaction = nullptr; | 329 SQLTransactionBackend* transaction = nullptr; |
| 330 | 330 |
| 331 if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty()) | 331 if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty()) |
| 332 transaction = m_transactionQueue.takeFirst(); | 332 transaction = m_transactionQueue.takeFirst(); |
| 333 | 333 |
| 334 if (transaction && getDatabaseContext()->databaseThreadAvailable()) { | 334 if (transaction && getDatabaseContext()->databaseThreadAvailable()) { |
| 335 std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask:
:create(transaction); | 335 std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask:
:create(transaction); |
| 336 WTF_LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transacti
on %p\n", task.get(), task->transaction()); | 336 STORAGE_DVLOG(1) << "Scheduling DatabaseTransactionTask " << task.get()
<< " for transaction " << task->transaction(); |
| 337 m_transactionInProgress = true; | 337 m_transactionInProgress = true; |
| 338 getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); | 338 getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); |
| 339 } else { | 339 } else { |
| 340 m_transactionInProgress = false; | 340 m_transactionInProgress = false; |
| 341 } | 341 } |
| 342 } | 342 } |
| 343 | 343 |
| 344 void Database::scheduleTransactionStep(SQLTransactionBackend* transaction) | 344 void Database::scheduleTransactionStep(SQLTransactionBackend* transaction) |
| 345 { | 345 { |
| 346 if (!getDatabaseContext()->databaseThreadAvailable()) | 346 if (!getDatabaseContext()->databaseThreadAvailable()) |
| 347 return; | 347 return; |
| 348 | 348 |
| 349 std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask::cre
ate(transaction); | 349 std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask::cre
ate(transaction); |
| 350 WTF_LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transacti
on step\n", task.get()); | 350 STORAGE_DVLOG(1) << "Scheduling DatabaseTransactionTask " << task.get() << "
for the transaction step"; |
| 351 getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); | 351 getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); |
| 352 } | 352 } |
| 353 | 353 |
| 354 SQLTransactionClient* Database::transactionClient() const | 354 SQLTransactionClient* Database::transactionClient() const |
| 355 { | 355 { |
| 356 return getDatabaseContext()->databaseThread()->transactionClient(); | 356 return getDatabaseContext()->databaseThread()->transactionClient(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 SQLTransactionCoordinator* Database::transactionCoordinator() const | 359 SQLTransactionCoordinator* Database::transactionCoordinator() const |
| 360 { | 360 { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 438 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 439 | 439 |
| 440 String currentVersion; | 440 String currentVersion; |
| 441 { | 441 { |
| 442 SafePointAwareMutexLocker locker(guidMutex()); | 442 SafePointAwareMutexLocker locker(guidMutex()); |
| 443 | 443 |
| 444 GuidVersionMap::iterator entry = guidToVersionMap().find(m_guid); | 444 GuidVersionMap::iterator entry = guidToVersionMap().find(m_guid); |
| 445 if (entry != guidToVersionMap().end()) { | 445 if (entry != guidToVersionMap().end()) { |
| 446 // Map null string to empty string (see updateGuidVersionMap()). | 446 // Map null string to empty string (see updateGuidVersionMap()). |
| 447 currentVersion = entry->value.isNull() ? emptyString() : entry->valu
e.isolatedCopy(); | 447 currentVersion = entry->value.isNull() ? emptyString() : entry->valu
e.isolatedCopy(); |
| 448 WTF_LOG(StorageAPI, "Current cached version for guid %i is %s", m_gu
id, currentVersion.ascii().data()); | 448 STORAGE_DVLOG(1) << "Current cached version for guid " << m_guid <<
" is " << currentVersion; |
| 449 | 449 |
| 450 // Note: In multi-process browsers the cached value may be | 450 // Note: In multi-process browsers the cached value may be |
| 451 // inaccurate, but we cannot read the actual version from the | 451 // inaccurate, but we cannot read the actual version from the |
| 452 // database without potentially inducing a form of deadlock, a | 452 // database without potentially inducing a form of deadlock, a |
| 453 // busytimeout error when trying to access the database. So we'll | 453 // busytimeout error when trying to access the database. So we'll |
| 454 // use the cached value if we're unable to read the value from the | 454 // use the cached value if we're unable to read the value from the |
| 455 // database file without waiting. | 455 // database file without waiting. |
| 456 // FIXME: Add an async openDatabase method to the DatabaseAPI. | 456 // FIXME: Add an async openDatabase method to the DatabaseAPI. |
| 457 const int noSqliteBusyWaitTime = 0; | 457 const int noSqliteBusyWaitTime = 0; |
| 458 m_sqliteDatabase.setBusyTimeout(noSqliteBusyWaitTime); | 458 m_sqliteDatabase.setBusyTimeout(noSqliteBusyWaitTime); |
| 459 String versionFromDatabase; | 459 String versionFromDatabase; |
| 460 if (getVersionFromDatabase(versionFromDatabase, false)) { | 460 if (getVersionFromDatabase(versionFromDatabase, false)) { |
| 461 currentVersion = versionFromDatabase; | 461 currentVersion = versionFromDatabase; |
| 462 updateGuidVersionMap(m_guid, currentVersion); | 462 updateGuidVersionMap(m_guid, currentVersion); |
| 463 } | 463 } |
| 464 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); | 464 m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); |
| 465 } else { | 465 } else { |
| 466 WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); | 466 STORAGE_DVLOG(1) << "No cached version for guid " << m_guid; |
| 467 | 467 |
| 468 SQLiteTransaction transaction(m_sqliteDatabase); | 468 SQLiteTransaction transaction(m_sqliteDatabase); |
| 469 transaction.begin(); | 469 transaction.begin(); |
| 470 if (!transaction.inProgress()) { | 470 if (!transaction.inProgress()) { |
| 471 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); | 471 reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 472 errorMessage = formatErrorMessage("unable to open database, fail
ed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErr
orMsg()); | 472 errorMessage = formatErrorMessage("unable to open database, fail
ed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErr
orMsg()); |
| 473 m_sqliteDatabase.close(); | 473 m_sqliteDatabase.close(); |
| 474 return false; | 474 return false; |
| 475 } | 475 } |
| 476 | 476 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 487 } | 487 } |
| 488 } else if (!getVersionFromDatabase(currentVersion, false)) { | 488 } else if (!getVersionFromDatabase(currentVersion, false)) { |
| 489 reportOpenDatabaseResult(4, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); | 489 reportOpenDatabaseResult(4, InvalidStateError, m_sqliteDatabase.
lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 490 errorMessage = formatErrorMessage("unable to open database, fail
ed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.last
ErrorMsg()); | 490 errorMessage = formatErrorMessage("unable to open database, fail
ed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.last
ErrorMsg()); |
| 491 transaction.rollback(); | 491 transaction.rollback(); |
| 492 m_sqliteDatabase.close(); | 492 m_sqliteDatabase.close(); |
| 493 return false; | 493 return false; |
| 494 } | 494 } |
| 495 | 495 |
| 496 if (currentVersion.length()) { | 496 if (currentVersion.length()) { |
| 497 WTF_LOG(StorageAPI, "Retrieved current version %s from database
%s", currentVersion.ascii().data(), databaseDebugName().ascii().data()); | 497 STORAGE_DVLOG(1) << "Retrieved current version " << currentVersi
on << " from database " << databaseDebugName(); |
| 498 } else if (!m_new || shouldSetVersionInNewDatabase) { | 498 } else if (!m_new || shouldSetVersionInNewDatabase) { |
| 499 WTF_LOG(StorageAPI, "Setting version %s in database %s that was
just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().dat
a()); | 499 STORAGE_DVLOG(1) << "Setting version " << m_expectedVersion << "
in database " << databaseDebugName() << " that was just created"; |
| 500 if (!setVersionInDatabase(m_expectedVersion, false)) { | 500 if (!setVersionInDatabase(m_expectedVersion, false)) { |
| 501 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab
ase.lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); | 501 reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatab
ase.lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); |
| 502 errorMessage = formatErrorMessage("unable to open database,
failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase
.lastErrorMsg()); | 502 errorMessage = formatErrorMessage("unable to open database,
failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase
.lastErrorMsg()); |
| 503 transaction.rollback(); | 503 transaction.rollback(); |
| 504 m_sqliteDatabase.close(); | 504 m_sqliteDatabase.close(); |
| 505 return false; | 505 return false; |
| 506 } | 506 } |
| 507 currentVersion = m_expectedVersion; | 507 currentVersion = m_expectedVersion; |
| 508 } | 508 } |
| 509 updateGuidVersionMap(m_guid, currentVersion); | 509 updateGuidVersionMap(m_guid, currentVersion); |
| 510 transaction.commit(); | 510 transaction.commit(); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 | 513 |
| 514 if (currentVersion.isNull()) { | 514 if (currentVersion.isNull()) { |
| 515 WTF_LOG(StorageAPI, "Database %s does not have its version set", databas
eDebugName().ascii().data()); | 515 STORAGE_DVLOG(1) << "Database " << databaseDebugName() << " does not hav
e its version set"; |
| 516 currentVersion = ""; | 516 currentVersion = ""; |
| 517 } | 517 } |
| 518 | 518 |
| 519 // If the expected version isn't the empty string, ensure that the current | 519 // If the expected version isn't the empty string, ensure that the current |
| 520 // database version we have matches that version. Otherwise, set an | 520 // database version we have matches that version. Otherwise, set an |
| 521 // exception. | 521 // exception. |
| 522 // If the expected version is the empty string, then we always return with | 522 // If the expected version is the empty string, then we always return with |
| 523 // whatever version of the database we have. | 523 // whatever version of the database we have. |
| 524 if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length()
&& m_expectedVersion != currentVersion) { | 524 if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length()
&& m_expectedVersion != currentVersion) { |
| 525 reportOpenDatabaseResult(6, InvalidStateError, 0, WTF::monotonicallyIncr
easingTime() - callStartTime); | 525 reportOpenDatabaseResult(6, InvalidStateError, 0, WTF::monotonicallyIncr
easingTime() - callStartTime); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 return m_databaseThreadSecurityOrigin.get(); | 903 return m_databaseThreadSecurityOrigin.get(); |
| 904 return 0; | 904 return 0; |
| 905 } | 905 } |
| 906 | 906 |
| 907 bool Database::opened() | 907 bool Database::opened() |
| 908 { | 908 { |
| 909 return static_cast<bool>(acquireLoad(&m_opened)); | 909 return static_cast<bool>(acquireLoad(&m_opened)); |
| 910 } | 910 } |
| 911 | 911 |
| 912 } // namespace blink | 912 } // namespace blink |
| OLD | NEW |