Changeset 30104
- Timestamp:
- 02/08/08 20:15:27 (10 months ago)
- Location:
- trunk/WebCore
- Files:
-
- 8 modified
-
ChangeLog (modified) (1 diff)
-
storage/Database.cpp (modified) (5 diffs)
-
storage/Database.h (modified) (2 diffs)
-
storage/DatabaseTracker.cpp (modified) (3 diffs)
-
storage/DatabaseTracker.h (modified) (3 diffs)
-
storage/SQLStatement.cpp (modified) (1 diff)
-
storage/SQLStatement.h (modified) (1 diff)
-
storage/SQLTransaction.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r30102 r30104 1 2008-02-08 Timothy Hatcher <timothy@apple.com> 2 3 Reviewed by Brady Eidson. 4 5 <rdar://problem/5640896> Removing database then trying 6 to recreate it causes trouble 7 8 Added open Database support to DatabaseTracker. So any Database that 9 is deleted will be marked as deleted and will fail to open any transaction 10 or execute any new SQL queries. 11 12 * storage/Database.cpp: 13 (WebCore::Database::Database): Call DatabaseTracker::addOpenDatabase. 14 (WebCore::Database::~Database): Call DatabaseTracker::removeOpenDatabase. 15 (WebCore::Database::markAsDeleted): Set the m_deleted flag. 16 (WebCore::Database::version): Return a null String if m_deleted is true. 17 * storage/Database.h: 18 (WebCore::Database::deleted): Return m_deleted. 19 * storage/DatabaseTracker.cpp: 20 (WebCore::DatabaseTracker::addOpenDatabase): Add the Database to a map of origins and names. 21 (WebCore::DatabaseTracker::removeOpenDatabase): Remove the Database from the map. 22 (WebCore::DatabaseTracker::deleteDatabaseFile): Call markAsDeleted on all the open Databases 23 matching the origin/name. 24 * storage/DatabaseTracker.h: 25 * storage/SQLStatement.cpp: 26 (WebCore::SQLStatement::setDatabaseDeletedError): Set the error about the user deleting the database. 27 * storage/SQLStatement.h: 28 * storage/SQLTransaction.cpp: 29 (WebCore::SQLTransaction::executeSQL): If the Database is deleted, call setDatabaseDeletedError. 30 (WebCore::SQLTransaction::openTransactionAndPreflight): Set the error about the user deleting the database 31 if the Database was marked as deleted. 32 1 33 2008-02-08 Darin Adler <darin@apple.com> 2 34 -
trunk/WebCore/storage/Database.cpp
r30076 r30104 146 146 , m_guid(0) 147 147 , m_expectedVersion(expectedVersion) 148 , m_deleted(0) 148 149 , m_databaseThread(0) 149 150 #ifndef NDEBUG … … 177 178 178 179 m_filename = DatabaseTracker::tracker().fullPathForDatabase(m_securityOrigin.get(), m_name); 180 181 DatabaseTracker::tracker().addOpenDatabase(this); 179 182 } 180 183 … … 192 195 guidToVersionMap().remove(m_guid); 193 196 } 197 198 DatabaseTracker::tracker().removeOpenDatabase(this); 194 199 } 195 200 … … 292 297 293 298 return true; 299 } 300 301 void Database::markAsDeleted() 302 { 303 if (m_deleted) 304 return; 305 LOG(StorageAPI, "Marking %s (%p) as deleted", stringIdentifier().ascii().data(), this); 306 m_deleted = true; 294 307 } 295 308 … … 557 570 String Database::version() const 558 571 { 572 if (m_deleted) 573 return String(); 559 574 MutexLocker locker(guidMutex()); 560 575 return guidToVersionMap().get(m_guid).copy(); -
trunk/WebCore/storage/Database.h
r29983 r30104 90 90 void setExpectedVersion(const String&); 91 91 bool versionMatchesExpected() const; 92 92 93 void markAsDeleted(); 94 bool deleted() const { return m_deleted; } 95 93 96 unsigned long long databaseSize() const; 94 97 unsigned long long maximumSize() const; … … 127 130 String m_filename; 128 131 132 bool m_deleted; 133 129 134 SQLiteDatabase m_sqliteDatabase; 130 135 RefPtr<DatabaseAuthorizer> m_databaseAuthorizer; -
trunk/WebCore/storage/DatabaseTracker.cpp
r30076 r30104 35 35 #include "Document.h" 36 36 #include "FileSystem.h" 37 #include "Logging.h" 37 38 #include "OriginQuotaManager.h" 38 39 #include "Page.h" … … 421 422 } 422 423 424 void DatabaseTracker::addOpenDatabase(Database* database) 425 { 426 if (!database) 427 return; 428 429 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 430 431 if (!m_openDatabaseMap) 432 m_openDatabaseMap.set(new DatabaseOriginMap); 433 434 RefPtr<SecurityOrigin> origin(database->securityOriginCopy()); 435 String name(database->stringIdentifier()); 436 437 DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin); 438 if (!nameMap) { 439 nameMap = new DatabaseNameMap; 440 m_openDatabaseMap->set(origin, nameMap); 441 } 442 443 DatabaseSet* databaseSet = nameMap->get(name); 444 if (!databaseSet) { 445 databaseSet = new DatabaseSet; 446 nameMap->set(name, databaseSet); 447 } 448 449 databaseSet->add(database); 450 451 LOG(StorageAPI, "Added open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database); 452 } 453 454 void DatabaseTracker::removeOpenDatabase(Database* database) 455 { 456 if (!database) 457 return; 458 459 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 460 461 if (!m_openDatabaseMap) { 462 ASSERT_NOT_REACHED(); 463 return; 464 } 465 466 RefPtr<SecurityOrigin> origin(database->securityOriginCopy()); 467 String name(database->stringIdentifier()); 468 469 DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin); 470 if (!nameMap) { 471 ASSERT_NOT_REACHED(); 472 return; 473 } 474 475 DatabaseSet* databaseSet = nameMap->get(name); 476 if (!databaseSet) { 477 ASSERT_NOT_REACHED(); 478 return; 479 } 480 481 databaseSet->remove(database); 482 483 LOG(StorageAPI, "Removed open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database); 484 485 if (!databaseSet->isEmpty()) 486 return; 487 488 nameMap->remove(name); 489 delete databaseSet; 490 491 if (!nameMap->isEmpty()) 492 return; 493 494 m_openDatabaseMap->remove(origin); 495 delete nameMap; 496 } 497 423 498 unsigned long long DatabaseTracker::usageForOrigin(SecurityOrigin* origin) 424 499 { … … 650 725 if (fullPath.isEmpty()) 651 726 return true; 652 727 728 { 729 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 730 if (m_openDatabaseMap) { 731 // There are some open databases, lets check if they are for this origin. 732 DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin); 733 if (nameMap && nameMap->size()) { 734 // There are some open databases for this origin, lets check 735 // if they are this database by name. 736 DatabaseSet* databaseSet = nameMap->get(name); 737 if (databaseSet && databaseSet->size()) { 738 // We have some database open with this name. Mark them as deleted. 739 DatabaseSet::const_iterator end = databaseSet->end(); 740 for (DatabaseSet::const_iterator it = databaseSet->begin(); it != end; ++it) 741 (*it)->markAsDeleted(); 742 } 743 } 744 } 745 } 746 653 747 return deleteFile(fullPath); 654 748 } -
trunk/WebCore/storage/DatabaseTracker.h
r29983 r30104 39 39 namespace WebCore { 40 40 41 class Database; 41 42 class DatabaseTrackerClient; 42 43 class Document; … … 60 61 61 62 DatabaseDetails detailsForNameAndOrigin(const String&, SecurityOrigin*); 62 63 64 void addOpenDatabase(Database*); 65 void removeOpenDatabase(Database*); 66 63 67 unsigned long long usageForDatabase(const String&, SecurityOrigin*); 64 68 unsigned long long usageForOrigin(SecurityOrigin*); … … 100 104 Mutex m_quotaMapGuard; 101 105 mutable OwnPtr<QuotaMap> m_quotaMap; 102 106 107 typedef HashSet<Database*> DatabaseSet; 108 typedef HashMap<String, DatabaseSet*> DatabaseNameMap; 109 typedef HashMap<RefPtr<SecurityOrigin>, DatabaseNameMap*, SecurityOriginHash, SecurityOriginTraits> DatabaseOriginMap; 110 111 Mutex m_openDatabaseMapGuard; 112 mutable OwnPtr<DatabaseOriginMap> m_openDatabaseMap; 113 103 114 OwnPtr<OriginQuotaManager> m_quotaManager; 104 115 -
trunk/WebCore/storage/SQLStatement.cpp
r30087 r30104 140 140 } 141 141 142 void SQLStatement::setDatabaseDeletedError() 143 { 144 ASSERT(!m_error && !m_resultSet); 145 m_error = new SQLError(0, "unable to execute statement, because the user deleted the database"); 146 } 147 142 148 void SQLStatement::setVersionMismatchedError() 143 149 { -
trunk/WebCore/storage/SQLStatement.h
r29663 r30104 57 57 bool hasStatementCallback() const { return m_statementCallback; } 58 58 bool hasStatementErrorCallback() const { return m_statementErrorCallback; } 59 60 void setDatabaseDeletedError(); 59 61 void setVersionMismatchedError(); 60 62 -
trunk/WebCore/storage/SQLTransaction.cpp
r29983 r30104 79 79 80 80 RefPtr<SQLStatement> statement = new SQLStatement(sqlStatement.copy(), arguments, callback, callbackError); 81 81 82 if (m_database->deleted()) 83 statement->setDatabaseDeletedError(); 84 82 85 if (!m_database->versionMatchesExpected()) 83 86 statement->setVersionMismatchedError(); … … 120 123 121 124 LOG(StorageAPI, "Opening and preflighting transaction %p", this); 122 125 126 // If the database was deleted, jump to the error callback 127 if (m_database->deleted()) { 128 m_transactionError = new SQLError(0, "unable to open a transaction, because the user deleted the database"); 129 handleTransactionError(false); 130 return; 131 } 132 123 133 // Set the maximum usage for this transaction 124 134 m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize());