Title: [199309] trunk/Source
Revision
199309
Author
[email protected]
Date
2016-04-11 13:10:36 -0700 (Mon, 11 Apr 2016)

Log Message

WebKit should adopt journal_mode=wal for all SQLite databases.
https://bugs.webkit.org/show_bug.cgi?id=133496

Reviewed by Darin Adler.

Source/WebCore:

The statement intended to enable WAL mode is always failing because it is missing a
prepare(). Fix this. We were also previously permitting SQLITE_OK results - this
was in error (we were only getting these because stepping the unprepared statement
returned SQLITE_OK). Also set the SQLITE_OPEN_AUTOPROXY flag when opening the
database - this will improve perfomance when the database is accessed via an AFP
mount.

This exposed a bug, that deleteAllDatabases does not actually delete the databases on
iOS, for testing to reset back to a known state between tests it should be doing so.

* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::deleteAllDatabases):
    - force databases to actually be deleted on iOS.
      This method is only used from testing code (DumpRenderTree / WebKitTestRunner).
(WebCore::DatabaseTracker::deleteOrigin):
    - added IOSDeletionMode.
(WebCore::DatabaseTracker::deleteDatabaseFile):
    - added IOSDeletionMode, modified to actually delete if this is set.
* Modules/webdatabase/DatabaseTracker.h:
    - added IOSDeletionMode.
* platform/sql/SQLiteDatabase.cpp:
(WebCore::SQLiteDatabase::open):
    - call prepareAndStep(), only check for SQLITE_ROW result.
* platform/sql/SQLiteFileSystem.cpp:
(WebCore::SQLiteFileSystem::openDatabase):
    - should set SQLITE_OPEN_AUTOPROXY flag when opening database.

Source/WebKit/mac:

* Storage/WebDatabaseManagerPrivate.h:
    - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.

Source/WebKit/win:

* WebDatabaseManager.cpp:
(WebDatabaseManager::deleteAllDatabases):
    - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.

Source/WebKit2:

* WebProcess/InjectedBundle/API/c/WKBundle.cpp:
(WKBundleClearAllDatabases):
    - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (199308 => 199309)


--- trunk/Source/WebCore/ChangeLog	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/ChangeLog	2016-04-11 20:10:36 UTC (rev 199309)
@@ -1,3 +1,37 @@
+2016-04-09  Gavin Barraclough  <[email protected]>
+
+        WebKit should adopt journal_mode=wal for all SQLite databases.
+        https://bugs.webkit.org/show_bug.cgi?id=133496
+
+        Reviewed by Darin Adler.
+
+        The statement intended to enable WAL mode is always failing because it is missing a
+        prepare(). Fix this. We were also previously permitting SQLITE_OK results - this
+        was in error (we were only getting these because stepping the unprepared statement
+        returned SQLITE_OK). Also set the SQLITE_OPEN_AUTOPROXY flag when opening the
+        database - this will improve perfomance when the database is accessed via an AFP
+        mount.
+
+        This exposed a bug, that deleteAllDatabases does not actually delete the databases on
+        iOS, for testing to reset back to a known state between tests it should be doing so.
+
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::deleteAllDatabases):
+            - force databases to actually be deleted on iOS.
+              This method is only used from testing code (DumpRenderTree / WebKitTestRunner).
+        (WebCore::DatabaseTracker::deleteOrigin):
+            - added IOSDeletionMode.
+        (WebCore::DatabaseTracker::deleteDatabaseFile):
+            - added IOSDeletionMode, modified to actually delete if this is set.
+        * Modules/webdatabase/DatabaseTracker.h:
+            - added IOSDeletionMode.
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::open):
+            - call prepareAndStep(), only check for SQLITE_ROW result.
+        * platform/sql/SQLiteFileSystem.cpp:
+        (WebCore::SQLiteFileSystem::openDatabase):
+            - should set SQLITE_OPEN_AUTOPROXY flag when opening database.
+
 2016-04-11  Zalan Bujtas  <[email protected]>
 
         Simplify InlineTextBox::selectionStartEnd()

Modified: trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h	2016-04-11 20:10:36 UTC (rev 199309)
@@ -69,7 +69,7 @@
 
     virtual void setQuota(SecurityOrigin*, unsigned long long) = 0;
 
-    virtual void deleteAllDatabases() = 0;
+    virtual void deleteAllDatabasesImmediately() = 0;
     virtual bool deleteOrigin(SecurityOrigin*) = 0;
     virtual bool deleteDatabase(SecurityOrigin*, const String& name) = 0;
 

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -378,9 +378,9 @@
     m_server->setQuota(origin, quotaSize);
 }
 
-void DatabaseManager::deleteAllDatabases()
+void DatabaseManager::deleteAllDatabasesImmediately()
 {
-    m_server->deleteAllDatabases();
+    m_server->deleteAllDatabasesImmediately();
 }
 
 bool DatabaseManager::deleteOrigin(SecurityOrigin* origin)

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h	2016-04-11 20:10:36 UTC (rev 199309)
@@ -101,7 +101,7 @@
 
     WEBCORE_EXPORT void setQuota(SecurityOrigin*, unsigned long long);
 
-    WEBCORE_EXPORT void deleteAllDatabases();
+    WEBCORE_EXPORT void deleteAllDatabasesImmediately();
     WEBCORE_EXPORT bool deleteOrigin(SecurityOrigin*);
     WEBCORE_EXPORT bool deleteDatabase(SecurityOrigin*, const String& name);
 

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -92,9 +92,9 @@
     DatabaseTracker::tracker().setQuota(origin, quotaSize);
 }
 
-void DatabaseServer::deleteAllDatabases()
+void DatabaseServer::deleteAllDatabasesImmediately()
 {
-    DatabaseTracker::tracker().deleteAllDatabases();
+    DatabaseTracker::tracker().deleteAllDatabasesImmediately();
 }
 
 bool DatabaseServer::deleteOrigin(SecurityOrigin* origin)

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h	2016-04-11 20:10:36 UTC (rev 199309)
@@ -58,7 +58,7 @@
 
     void setQuota(SecurityOrigin*, unsigned long long) override;
 
-    void deleteAllDatabases() override;
+    void deleteAllDatabasesImmediately() override;
     bool deleteOrigin(SecurityOrigin*) override;
     bool deleteDatabase(SecurityOrigin*, const String& name) override;
 

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -776,16 +776,13 @@
             LOG_ERROR("Failed to set quota %llu in tracker database for origin %s", quota, origin->databaseIdentifier().ascii().data());
     }
 
-    if (m_client)
+    if (m_client) {
 #if PLATFORM(IOS)
-    {
         if (insertedNewOrigin)
             m_client->dispatchDidAddNewOrigin(origin);
 #endif
         m_client->dispatchDidModifyOrigin(origin);
-#if PLATFORM(IOS)
     }
-#endif
 }
 
 bool DatabaseTracker::addDatabase(SecurityOrigin* origin, const String& name, const String& path)
@@ -818,13 +815,17 @@
     return true;
 }
 
-void DatabaseTracker::deleteAllDatabases()
+void DatabaseTracker::deleteAllDatabasesImmediately()
 {
     Vector<RefPtr<SecurityOrigin>> originsCopy;
     origins(originsCopy);
 
+    // This method is only intended for use by DumpRenderTree / WebKitTestRunner.
+    // Actually deleting the databases is necessary to reset to a known state before running
+    // each test case, but may be unsafe in deployment use cases (where multiple applications
+    // may be accessing the same databases concurrently).
     for (auto& origin : originsCopy)
-        deleteOrigin(origin.get());
+        deleteOrigin(origin.get(), DeletionMode::Immediate);
 }
 
 void DatabaseTracker::deleteDatabasesModifiedSince(std::chrono::system_clock::time_point time)
@@ -862,6 +863,11 @@
 // taking place.
 bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
 {
+    return deleteOrigin(origin, DeletionMode::Default);
+}
+
+bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin, DeletionMode deletionMode)
+{
     Vector<String> databaseNames;
     {
         LockHolder lockDatabase(m_databaseGuard);
@@ -883,7 +889,7 @@
 
     // We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
     for (auto& name : databaseNames) {
-        if (!deleteDatabaseFile(origin, name)) {
+        if (!deleteDatabaseFile(origin, name, deletionMode)) {
             // Even if the file can't be deleted, we want to try and delete the rest, don't return early here.
             LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin->databaseIdentifier().ascii().data());
         }
@@ -1084,7 +1090,7 @@
     }
 
     // We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
-    if (!deleteDatabaseFile(origin, name)) {
+    if (!deleteDatabaseFile(origin, name, DeletionMode::Default)) {
         LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin->databaseIdentifier().ascii().data());
         LockHolder lockDatabase(m_databaseGuard);
         doneDeletingDatabase(origin, name);
@@ -1123,7 +1129,7 @@
 
 // deleteDatabaseFile has to release locks between looking up the list of databases to close and closing them.  While this is in progress, the caller
 // is responsible for making sure no new databases are opened in the file to be deleted.
-bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& name)
+bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& name, DeletionMode deletionMode)
 {
     String fullPath = fullPathForDatabase(origin, name, false);
     if (fullPath.isEmpty())
@@ -1162,19 +1168,23 @@
     for (auto& database : deletedDatabases)
         database->markAsDeletedAndClose();
 
-#if !PLATFORM(IOS)
-    return SQLiteFileSystem::deleteDatabaseFile(fullPath);
+#if PLATFORM(IOS)
+    if (deletionMode == DeletionMode::Deferred) {
+        // On the phone, other background processes may still be accessing this database. Deleting the database directly
+        // would nuke the POSIX file locks, potentially causing Safari/WebApp to corrupt the new db if it's running in the background.
+        // We'll instead truncate the database file to 0 bytes. If another process is operating on this same database file after
+        // the truncation, it should get an error since the database file is no longer valid. When Safari is launched
+        // next time, it'll go through the database files and clean up any zero-bytes ones.
+        SQLiteDatabase database;
+        if (!database.open(fullPath))
+            return false;
+        return SQLiteFileSystem::truncateDatabaseFile(database.sqlite3Handle());
+    }
 #else
-    // On the phone, other background processes may still be accessing this database.  Deleting the database directly
-    // would nuke the POSIX file locks, potentially causing Safari/WebApp to corrupt the new db if it's running in the background.
-    // We'll instead truncate the database file to 0 bytes.  If another process is operating on this same database file after
-    // the truncation, it should get an error since the database file is no longer valid.  When Safari is launched
-    // next time, it'll go through the database files and clean up any zero-bytes ones.
-    SQLiteDatabase database;
-    if (database.open(fullPath))
-        return SQLiteFileSystem::truncateDatabaseFile(database.sqlite3Handle());
-    return false;
+    UNUSED_PARAM(deletionMode);
 #endif
+
+    return SQLiteFileSystem::deleteDatabaseFile(fullPath);
 }
     
 #if PLATFORM(IOS)

Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h (199308 => 199309)


--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2016-04-11 20:10:36 UTC (rev 199309)
@@ -95,7 +95,7 @@
     void setQuota(SecurityOrigin*, unsigned long long);
     RefPtr<OriginLock> originLockFor(SecurityOrigin*);
 
-    void deleteAllDatabases();
+    void deleteAllDatabasesImmediately();
     WEBCORE_EXPORT void deleteDatabasesModifiedSince(std::chrono::system_clock::time_point);
     WEBCORE_EXPORT bool deleteOrigin(SecurityOrigin*);
     bool deleteDatabase(SecurityOrigin*, const String& name);
@@ -142,8 +142,21 @@
 
     bool addDatabase(SecurityOrigin*, const String& name, const String& path);
 
-    bool deleteDatabaseFile(SecurityOrigin*, const String& name);
+    enum class DeletionMode {
+        Immediate,
+#if PLATFORM(IOS)
+        // Deferred deletion is currently only supported on iOS
+        // (see removeDeletedOpenedDatabases etc, above).
+        Deferred,
+        Default = Deferred
+#else
+        Default = Immediate
+#endif
+    };
 
+    bool deleteOrigin(SecurityOrigin*, DeletionMode);
+    bool deleteDatabaseFile(SecurityOrigin*, const String& name, DeletionMode);
+
     void deleteOriginLockFor(SecurityOrigin*);
 
     typedef HashSet<Database*> DatabaseSet;

Modified: trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp (199308 => 199309)


--- trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -116,17 +116,14 @@
         LOG_ERROR("SQLite database could not set temp_store to memory");
 
     SQLiteStatement walStatement(*this, ASCIILiteral("PRAGMA journal_mode=WAL;"));
-    int result = walStatement.step();
-    if (result != SQLITE_OK && result != SQLITE_ROW)
-        LOG_ERROR("SQLite database failed to set journal_mode to WAL, error: %s", lastErrorMsg());
-
+    if (walStatement.prepareAndStep() == SQLITE_ROW) {
 #ifndef NDEBUG
-    if (result == SQLITE_ROW) {
         String mode = walStatement.getColumnText(0);
         if (!equalLettersIgnoringASCIICase(mode, "wal"))
-            LOG_ERROR("journal_mode of database should be 'wal', but is '%s'", mode.utf8().data());
-    }
+            LOG_ERROR("journal_mode of database should be 'WAL', but is '%s'", mode.utf8().data());
 #endif
+    } else
+        LOG_ERROR("SQLite database failed to set journal_mode to WAL, error: %s", lastErrorMsg());
 
     return isOpen();
 }

Modified: trunk/Source/WebCore/platform/sql/SQLiteFileSystem.cpp (199308 => 199309)


--- trunk/Source/WebCore/platform/sql/SQLiteFileSystem.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebCore/platform/sql/SQLiteFileSystem.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -50,7 +50,7 @@
 
 int SQLiteFileSystem::openDatabase(const String& filename, sqlite3** database, bool)
 {
-    return sqlite3_open(fileSystemRepresentation(filename).data(), database);
+    return sqlite3_open_v2(fileSystemRepresentation(filename).data(), database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_AUTOPROXY, nullptr);
 }
 
 String SQLiteFileSystem::appendDatabaseFileNameToPath(const String& path, const String& fileName)

Modified: trunk/Source/WebKit/mac/ChangeLog (199308 => 199309)


--- trunk/Source/WebKit/mac/ChangeLog	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit/mac/ChangeLog	2016-04-11 20:10:36 UTC (rev 199309)
@@ -1,3 +1,13 @@
+2016-04-09  Gavin Barraclough  <[email protected]>
+
+        WebKit should adopt journal_mode=wal for all SQLite databases.
+        https://bugs.webkit.org/show_bug.cgi?id=133496
+
+        Reviewed by Darin Adler.
+
+        * Storage/WebDatabaseManagerPrivate.h:
+            - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.
+
 2016-04-05  Oliver Hunt  <[email protected]>
 
         Remove compile time define for SEPARATED_HEAP

Modified: trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm (199308 => 199309)


--- trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm	2016-04-11 20:10:36 UTC (rev 199309)
@@ -133,7 +133,7 @@
 
 - (void)deleteAllDatabases
 {
-    DatabaseManager::singleton().deleteAllDatabases();
+    DatabaseManager::singleton().deleteAllDatabasesImmediately();
 #if PLATFORM(IOS)
     // FIXME: This needs to be removed once DatabaseTrackers in multiple processes
     // are in sync: <rdar://problem/9567500> Remove Website Data pane is not kept in sync with Safari

Modified: trunk/Source/WebKit/win/ChangeLog (199308 => 199309)


--- trunk/Source/WebKit/win/ChangeLog	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit/win/ChangeLog	2016-04-11 20:10:36 UTC (rev 199309)
@@ -1,3 +1,14 @@
+2016-04-11  Gavin Barraclough  <[email protected]>
+
+        WebKit should adopt journal_mode=wal for all SQLite databases.
+        https://bugs.webkit.org/show_bug.cgi?id=133496
+
+        Reviewed by Darin Adler.
+
+        * WebDatabaseManager.cpp:
+        (WebDatabaseManager::deleteAllDatabases):
+            - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.
+
 2016-04-08  Joanmarie Diggs  <[email protected]>
 
         AX: "AXLandmarkApplication" is an inappropriate subrole for ARIA "application" since it's no longer a landmark

Modified: trunk/Source/WebKit/win/WebDatabaseManager.cpp (199308 => 199309)


--- trunk/Source/WebKit/win/WebDatabaseManager.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit/win/WebDatabaseManager.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -285,7 +285,7 @@
     if (this != s_sharedWebDatabaseManager)
         return E_FAIL;
 
-    DatabaseManager::singleton().deleteAllDatabases();
+    DatabaseManager::singleton().deleteAllDatabasesImmediately();
 
     return S_OK;
 }

Modified: trunk/Source/WebKit2/ChangeLog (199308 => 199309)


--- trunk/Source/WebKit2/ChangeLog	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit2/ChangeLog	2016-04-11 20:10:36 UTC (rev 199309)
@@ -1,3 +1,14 @@
+2016-04-09  Gavin Barraclough  <[email protected]>
+
+        WebKit should adopt journal_mode=wal for all SQLite databases.
+        https://bugs.webkit.org/show_bug.cgi?id=133496
+
+        Reviewed by Darin Adler.
+
+        * WebProcess/InjectedBundle/API/c/WKBundle.cpp:
+        (WKBundleClearAllDatabases):
+            - renamed deleteAllDatabases -> deleteAllDatabasesImmediately.
+
 2016-04-11  Daniel Bates  <[email protected]>
 
         REGRESSION (r198933): Unable to login to Google account from Internet Accounts preference pane

Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp (199308 => 199309)


--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp	2016-04-11 20:00:31 UTC (rev 199308)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp	2016-04-11 20:10:36 UTC (rev 199309)
@@ -202,7 +202,7 @@
 
 void WKBundleClearAllDatabases(WKBundleRef)
 {
-    DatabaseManager::singleton().deleteAllDatabases();
+    DatabaseManager::singleton().deleteAllDatabasesImmediately();
 }
 
 void WKBundleSetDatabaseQuota(WKBundleRef bundleRef, uint64_t quota)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to