<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[213547] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/213547">213547</a></dd>
<dt>Author</dt> <dd>ryanhaddad@apple.com</dd>
<dt>Date</dt> <dd>2017-03-07 15:12:34 -0800 (Tue, 07 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Correctly check for an empty database file.
&lt;rdar://problem/30542242&gt; Removing Website Data not working (WebSQL directories being left behind)
https://bugs.webkit.org/show_bug.cgi?id=169256

Patch by Maureen Daum &lt;mdaum@apple.com&gt; on 2017-03-07
Reviewed by Brady Eidson.

Source/WebCore:

Tests: DatabaseTrackerTest.DeleteDatabaseFileIfEmpty verifies that we actually delete an empty file.

Instead of checking that a database file's size is zero bytes, we should check if it contains
any tables. Once we open an empty database file and set its journal mode to WAL, it will have a
valid SQLite header and therefore will no longer be empty. We can know that the database was empty
if it does not contain any tables.

* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
Use BEGIN EXCLUSIVE TRANSACTION in order to obtain the exclusive lock. If the database doesn't contain
any tables, it is empty and can be deleted.

Source/WebKit/mac:

Check if the folder for an origin's WebSQL databases is empty after trying to delete
all of its files. Currently we check if the deletedDatabaseFileCount matches the number
of files that were in the folder. However, when we delete the actual database file in
DatabaseTracker::deleteDatabaseFileIfEmpty(), the shm and wal files get deleted along with
the database file, but deletedDatabaseFileCount only gets incremented once.

* Storage/WebDatabaseManager.mm:
(+[WebDatabaseManager removeEmptyDatabaseFiles]):
Delete the folder if it is empty.

Tools:

Add a test for DatabaseTracker::deleteDatabaseFileIfEmpty that verifies
that if we pass in an empty file it actually gets deleted.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
Add TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp.
* TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp: Added.
(TestWebKitAPI::TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacStorageWebDatabaseManagermm">trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreDatabaseTrackerTestcpp">trunk/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Source/WebCore/ChangeLog        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2017-03-07  Maureen Daum  &lt;mdaum@apple.com&gt;
+
+        Correctly check for an empty database file.
+        &lt;rdar://problem/30542242&gt; Removing Website Data not working (WebSQL directories being left behind)
+        https://bugs.webkit.org/show_bug.cgi?id=169256
+
+        Reviewed by Brady Eidson.
+
+        Tests: DatabaseTrackerTest.DeleteDatabaseFileIfEmpty verifies that we actually delete an empty file.
+
+        Instead of checking that a database file's size is zero bytes, we should check if it contains
+        any tables. Once we open an empty database file and set its journal mode to WAL, it will have a
+        valid SQLite header and therefore will no longer be empty. We can know that the database was empty
+        if it does not contain any tables.
+
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
+        Use BEGIN EXCLUSIVE TRANSACTION in order to obtain the exclusive lock. If the database doesn't contain
+        any tables, it is empty and can be deleted.
+
</ins><span class="cx"> 2017-03-07  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [URLParser] Fix file URLs that are just file:// and a Windows drive letter
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -1216,7 +1216,7 @@
</span><span class="cx">     if (!database.open(path))
</span><span class="cx">         return false;
</span><span class="cx">     
</span><del>-    // Specify that we want the exclusive locking mode, so after the next read,
</del><ins>+    // Specify that we want the exclusive locking mode, so after the next write,
</ins><span class="cx">     // we'll be holding the lock to this database file.
</span><span class="cx">     SQLiteStatement lockStatement(database, &quot;PRAGMA locking_mode=EXCLUSIVE;&quot;);
</span><span class="cx">     if (lockStatement.prepare() != SQLITE_OK)
</span><span class="lines">@@ -1226,21 +1226,18 @@
</span><span class="cx">         return false;
</span><span class="cx">     lockStatement.finalize();
</span><span class="cx"> 
</span><del>-    // Every sqlite database has a sqlite_master table that contains the schema for the database.
-    // http://www.sqlite.org/faq.html#q7
-    SQLiteStatement readStatement(database, &quot;SELECT * FROM sqlite_master LIMIT 1;&quot;);    
-    if (readStatement.prepare() != SQLITE_OK)
</del><ins>+    if (!database.executeCommand(&quot;BEGIN EXCLUSIVE TRANSACTION;&quot;))
</ins><span class="cx">         return false;
</span><del>-    // We shouldn't expect any result.
-    if (readStatement.step() != SQLITE_DONE)
</del><ins>+
+    // At this point, we hold the exclusive lock to this file.
+    // Check that the database doesn't contain any tables.
+    if (!database.executeCommand(&quot;SELECT name FROM sqlite_master WHERE type='table';&quot;))
</ins><span class="cx">         return false;
</span><del>-    readStatement.finalize();
-    
-    // At this point, we hold the exclusive lock to this file.  Double-check again to make sure
-    // it's still zero bytes.
-    if (!isZeroByteFile(path))
-        return false;
-    
</del><ins>+
+    database.executeCommand(&quot;COMMIT TRANSACTION;&quot;);
+
+    database.close();
+
</ins><span class="cx">     return SQLiteFileSystem::deleteDatabaseFile(path);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Source/WebKit/mac/ChangeLog        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2017-03-07  Maureen Daum  &lt;mdaum@apple.com&gt;
+
+        Correctly check for an empty database file.
+        &lt;rdar://problem/30542242&gt; Removing Website Data not working (WebSQL directories being left behind)
+        https://bugs.webkit.org/show_bug.cgi?id=169256
+
+        Reviewed by Brady Eidson.
+
+        Check if the folder for an origin's WebSQL databases is empty after trying to delete
+        all of its files. Currently we check if the deletedDatabaseFileCount matches the number
+        of files that were in the folder. However, when we delete the actual database file in
+        DatabaseTracker::deleteDatabaseFileIfEmpty(), the shm and wal files get deleted along with
+        the database file, but deletedDatabaseFileCount only gets incremented once.
+
+        * Storage/WebDatabaseManager.mm:
+        (+[WebDatabaseManager removeEmptyDatabaseFiles]):
+        Delete the folder if it is empty.
+
</ins><span class="cx"> 2017-03-06  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix to add
</span></span></pre></div>
<a id="trunkSourceWebKitmacStorageWebDatabaseManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Source/WebKit/mac/Storage/WebDatabaseManager.mm        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -213,7 +213,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         // If we have removed every database file for this origin, delete the folder for this origin.
</span><del>-        if (databaseFileCount == deletedDatabaseFileCount) {
</del><ins>+        if (databaseFileCount == deletedDatabaseFileCount || ![fileManager contentsOfDirectoryAtPath:path error:nullptr].count) {
</ins><span class="cx">             // Use rmdir - we don't want the deletion to happen if the folder is not empty.
</span><span class="cx">             rmdir([path fileSystemRepresentation]);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Tools/ChangeLog        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2017-03-07  Maureen Daum  &lt;mdaum@apple.com&gt;
+
+        Correctly check for an empty database file.
+        &lt;rdar://problem/30542242&gt; Removing Website Data not working (WebSQL directories being left behind)
+        https://bugs.webkit.org/show_bug.cgi?id=169256
+
+        Reviewed by Brady Eidson.
+
+        Add a test for DatabaseTracker::deleteDatabaseFileIfEmpty that verifies
+        that if we pass in an empty file it actually gets deleted.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        Add TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp.
+        * TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp: Added.
+        (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2017-03-07  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [URLParser] Fix file URLs that are just file:// and a Windows drive letter
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (213546 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-03-07 23:07:56 UTC (rev 213546)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -188,6 +188,7 @@
</span><span class="cx">                 5C9E59431D3EB5AC00E3C62E /* ApplicationCache.db-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */; };
</span><span class="cx">                 5E4B1D2E1D404C6100053621 /* WKScrollViewDelegateCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegateCrash.mm */; };
</span><span class="cx">                 6BFD294C1D5E6C1D008EC968 /* HashCountedSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */; };
</span><ins>+                755A20AF1E6E38630093C69F /* DatabaseTrackerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */; };
</ins><span class="cx">                 764322D71B61CCC30024F801 /* WordBoundaryTypingAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */; };
</span><span class="cx">                 7673499D1930C5BB00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7673499A1930182E00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp */; };
</span><span class="cx">                 76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; };
</span><span class="lines">@@ -1086,6 +1087,7 @@
</span><span class="cx">                 5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */ = {isa = PBXFileReference; lastKnownFileType = file; path = &quot;ApplicationCache.db-shm&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = &quot;ApplicationCache.db-wal&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegateCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKScrollViewDelegateCrash.mm; path = ../ios/WKScrollViewDelegateCrash.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseTrackerTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheAddImageToCacheIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 75F3133F18C171B70041CAEC /* EphemeralSessionPushStateNoHistoryCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EphemeralSessionPushStateNoHistoryCallback.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WordBoundaryTypingAttributes.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1681,6 +1683,7 @@
</span><span class="cx">                                 1C9EB8401E380DA1005C6442 /* ComplexTextController.cpp */,
</span><span class="cx">                                 7CB184C41AA3F2100066EDFD /* ContentExtensions.cpp */,
</span><span class="cx">                                 CD5451E919E41F9D0016936F /* CSSParser.cpp */,
</span><ins>+                                755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */,
</ins><span class="cx">                                 260BA5781B1D2E7B004FA07C /* DFACombiner.cpp */,
</span><span class="cx">                                 260BA57A1B1D2EE2004FA07C /* DFAHelpers.h */,
</span><span class="cx">                                 26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
</span><span class="lines">@@ -2799,6 +2802,7 @@
</span><span class="cx">                                 7C83E0C11D0A652F00FEBCF3 /* ProvisionalURLNotChange.mm in Sources */,
</span><span class="cx">                                 7CCE7EC81A411A7E00447C4C /* PublicSuffix.mm in Sources */,
</span><span class="cx">                                 7C83E0C21D0A653500FEBCF3 /* QuickLook.mm in Sources */,
</span><ins>+                                755A20AF1E6E38630093C69F /* DatabaseTrackerTest.cpp in Sources */,
</ins><span class="cx">                                 7CCE7F0D1A411AE600447C4C /* ReloadPageAfterCrash.cpp in Sources */,
</span><span class="cx">                                 7C83E0C31D0A653A00FEBCF3 /* RemoteObjectRegistry.mm in Sources */,
</span><span class="cx">                                 7CCE7EC91A411A7E00447C4C /* RenderedImageFromDOMNode.mm in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreDatabaseTrackerTestcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp (0 => 213547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp        2017-03-07 23:12:34 UTC (rev 213547)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#if PLATFORM(IOS)
+
+#include &lt;WebCore/DatabaseTracker.h&gt;
+#include &lt;WebCore/FileSystem.h&gt;
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+TEST(DatabaseTracker, DeleteDatabaseFileIfEmpty)
+{
+    PlatformFileHandle handle;
+    String databaseFilePath = openTemporaryFile(&quot;tempEmptyDatabase&quot;, handle);
+    closeFile(handle);
+
+    long long fileSize;
+    getFileSize(databaseFilePath, fileSize);
+    EXPECT_EQ(0, fileSize);
+
+    EXPECT_TRUE(DatabaseTracker::deleteDatabaseFileIfEmpty(databaseFilePath));
+
+    bool fileStillExists = fileExists(databaseFilePath);
+    EXPECT_FALSE(fileStillExists);
+
+    if (fileStillExists)
+        deleteFile(databaseFilePath);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(IOS)
</ins></span></pre>
</div>
</div>

</body>
</html>