[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

jorlow at chromium.org jorlow at chromium.org
Wed Dec 22 12:13:48 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 5615fc7e5951015222429cc59223963d115750b7
Author: jorlow at chromium.org <jorlow at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Aug 17 16:18:21 2010 +0000

    2010-08-09  Jeremy Orlow  <jorlow at chromium.org>
    
            Reviewed by Steve Block.
    
            Beginnings of IndexedDB persistance + IDBDatabase.description fleshed out
            https://bugs.webkit.org/show_bug.cgi?id=43744
    
            Add a layout test for IDBDatabase.description.
    
            * storage/indexeddb/database-description-expected.txt: Added.
            * storage/indexeddb/database-description.html: Added.
            * storage/indexeddb/script-tests/database-description.js: Added.
            (test):
            (firstSuccess):
            (secondSuccess):
            (thirdSuccess):
    2010-08-11  Jeremy Orlow  <jorlow at chromium.org>
    
            Beginnings of IndexedDB persistance + IDBDatabase.description fleshed out
            https://bugs.webkit.org/show_bug.cgi?id=43744
    
            The beginnings of a SQLite backend for IndexedDB.  Right now, only persists
            meta-data for the database.  The rest is coming in future patches.  Adds
            a manual test to verify persistance.
    
            Test: storage/indexeddb/database-description.html
                  + a manual test
    
            * Android.mk:
            * CMakeLists.txt:
            * GNUmakefile.am:
            * WebCore.gypi:
            * WebCore.vcproj/WebCore.vcproj:
            * WebCore.xcodeproj/project.pbxproj:
            * manual-tests/indexed-database.html: Added.
            * page/SecurityOrigin.cpp:
            (WebCore::SecurityOrigin::databaseIdentifier):
            * platform/FileSystem.cpp: Added.
            (WebCore::):
            (WebCore::shouldEscapeUChar):
            (WebCore::encodeForFileName):
            * platform/FileSystem.h:
            * storage/IDBDatabase.cpp:
            (WebCore::IDBDatabase::IDBDatabase):
            * storage/IDBDatabase.h:
            (WebCore::IDBDatabase::description):
            * storage/IDBDatabaseBackendImpl.cpp:
            (WebCore::extractMetaData):
            (WebCore::setMetaData):
            (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
            (WebCore::IDBDatabaseBackendImpl::setDescription):
            * storage/IDBDatabaseBackendImpl.h:
            (WebCore::IDBDatabaseBackendImpl::create):
            * storage/IDBFactory.h:
            * storage/IDBFactory.idl:
            * storage/IDBFactoryBackendImpl.cpp:
            (WebCore::IDBFactoryBackendImpl::IDBFactoryBackendImpl):
            (WebCore::IDBFactoryBackendImpl::~IDBFactoryBackendImpl):
            (WebCore::openSQLiteDatabase):
            (WebCore::createTables):
            (WebCore::IDBFactoryBackendImpl::open):
            * storage/IDBFactoryBackendImpl.h:
            (WebCore::IDBFactoryBackendImpl::create):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65509 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d64b177..93b3f0a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,20 @@
+2010-08-09  Jeremy Orlow  <jorlow at chromium.org>
+
+        Reviewed by Steve Block.
+
+        Beginnings of IndexedDB persistance + IDBDatabase.description fleshed out
+        https://bugs.webkit.org/show_bug.cgi?id=43744
+
+        Add a layout test for IDBDatabase.description.
+
+        * storage/indexeddb/database-description-expected.txt: Added.
+        * storage/indexeddb/database-description.html: Added.
+        * storage/indexeddb/script-tests/database-description.js: Added.
+        (test):
+        (firstSuccess):
+        (secondSuccess):
+        (thirdSuccess):
+
 2010-08-17  Yury Semikhatsky  <yurys at chromium.org>
 
         Unreviewed. Revert r41142. Unskipped tests are still failing.
diff --git a/LayoutTests/storage/indexeddb/database-description-expected.txt b/LayoutTests/storage/indexeddb/database-description-expected.txt
new file mode 100644
index 0000000..c90d33d
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/database-description-expected.txt
@@ -0,0 +1,74 @@
+Test IDBFactory.open's description parameter.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS 'indexedDB' in window is true
+PASS indexedDB == null is false
+indexedDB.open('abcd', 'first')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'abort' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.result.description is "first"
+indexedDB.open('abcd', 'second')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'abort' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS firstDB.description is "first"
+PASS secondDB.description is "second"
+indexedDB.open('abcd')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'abort' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS firstDB.description is "first"
+PASS secondDB.description is "second"
+PASS event.result.description is "second"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/database-description.html b/LayoutTests/storage/indexeddb/database-description.html
new file mode 100644
index 0000000..ca6a4d6
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/database-description.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../fast/js/resources/js-test-post-function.js"></script>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/database-description.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/indexeddb/script-tests/database-description.js b/LayoutTests/storage/indexeddb/script-tests/database-description.js
new file mode 100644
index 0000000..bb4acba
--- /dev/null
+++ b/LayoutTests/storage/indexeddb/script-tests/database-description.js
@@ -0,0 +1,56 @@
+description("Test IDBFactory.open's description parameter.");
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function test()
+{
+    shouldBeTrue("'indexedDB' in window");
+    shouldBeFalse("indexedDB == null");
+
+    result = evalAndLog("indexedDB.open('abcd', 'first')");
+    verifyResult(result);
+    result.onsuccess = firstSuccess;
+    result.onerror = unexpectedErrorCallback;
+}
+
+function firstSuccess()
+{
+    verifySuccessEvent(event);
+    window.firstDB = event.result;
+
+    shouldBeEqualToString('event.result.description', 'first');
+
+    result = evalAndLog("indexedDB.open('abcd', 'second')");
+    verifyResult(result);
+    result.onsuccess = secondSuccess;
+    result.onerror = unexpectedErrorCallback;
+}
+
+function secondSuccess()
+{
+    verifySuccessEvent(event);
+    window.secondDB = event.result;
+
+    shouldBeEqualToString('firstDB.description', 'first');
+    shouldBeEqualToString('secondDB.description', 'second');
+
+    result = evalAndLog("indexedDB.open('abcd')");
+    verifyResult(result);
+    result.onsuccess = thirdSuccess;
+    result.onerror = unexpectedErrorCallback;
+}
+
+function thirdSuccess()
+{
+    verifySuccessEvent(event);
+
+    shouldBeEqualToString('firstDB.description', 'first');
+    shouldBeEqualToString('secondDB.description', 'second');
+    shouldBeEqualToString('event.result.description', 'second');
+
+    done();
+}
+
+test();
+
+var successfullyParsed = true;
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 348c178..3f65276 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -416,6 +416,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
 	platform/DragData.cpp \
 	platform/DragImage.cpp \
 	platform/FileChooser.cpp \
+	platform/FileSystem.cpp \
 	platform/GeolocationService.cpp \
 	platform/KURL.cpp \
 	platform/KURLGoogle.cpp \
diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt
index 17f18e6..58a3612 100644
--- a/WebCore/CMakeLists.txt
+++ b/WebCore/CMakeLists.txt
@@ -1218,6 +1218,7 @@ SET(WebCore_SOURCES
     platform/DragData.cpp
     platform/DragImage.cpp
     platform/FileChooser.cpp
+    platform/FileSystem.cpp
     platform/GeolocationService.cpp
     platform/KURL.cpp
     platform/KillRingNone.cpp
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4cdff45..589580b 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,51 @@
+2010-08-11  Jeremy Orlow  <jorlow at chromium.org>
+
+        Beginnings of IndexedDB persistance + IDBDatabase.description fleshed out
+        https://bugs.webkit.org/show_bug.cgi?id=43744
+
+        The beginnings of a SQLite backend for IndexedDB.  Right now, only persists
+        meta-data for the database.  The rest is coming in future patches.  Adds
+        a manual test to verify persistance.
+
+        Test: storage/indexeddb/database-description.html
+              + a manual test
+
+        * Android.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * manual-tests/indexed-database.html: Added.
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::databaseIdentifier):
+        * platform/FileSystem.cpp: Added.
+        (WebCore::):
+        (WebCore::shouldEscapeUChar):
+        (WebCore::encodeForFileName):
+        * platform/FileSystem.h:
+        * storage/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::IDBDatabase):
+        * storage/IDBDatabase.h:
+        (WebCore::IDBDatabase::description):
+        * storage/IDBDatabaseBackendImpl.cpp:
+        (WebCore::extractMetaData):
+        (WebCore::setMetaData):
+        (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
+        (WebCore::IDBDatabaseBackendImpl::setDescription):
+        * storage/IDBDatabaseBackendImpl.h:
+        (WebCore::IDBDatabaseBackendImpl::create):
+        * storage/IDBFactory.h:
+        * storage/IDBFactory.idl:
+        * storage/IDBFactoryBackendImpl.cpp:
+        (WebCore::IDBFactoryBackendImpl::IDBFactoryBackendImpl):
+        (WebCore::IDBFactoryBackendImpl::~IDBFactoryBackendImpl):
+        (WebCore::openSQLiteDatabase):
+        (WebCore::createTables):
+        (WebCore::IDBFactoryBackendImpl::open):
+        * storage/IDBFactoryBackendImpl.h:
+        (WebCore::IDBFactoryBackendImpl::create):
+
 2010-08-17  Dimitri Glazkov  <dglazkov at chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 3b9f37d..9df578c 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -1905,6 +1905,7 @@ webcore_sources += \
 	WebCore/platform/EventLoop.h \
 	WebCore/platform/FileChooser.cpp \
 	WebCore/platform/FileChooser.h \
+	WebCore/platform/FileSystem.cpp \
 	WebCore/platform/FileSystem.h \
 	WebCore/platform/FloatConversion.h \
 	WebCore/platform/GeolocationService.cpp \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 6157610..a5dcdfa 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -3058,6 +3058,7 @@
             'platform/EventLoop.h',
             'platform/FileChooser.cpp',
             'platform/FileChooser.h',
+            'platform/FileSystem.cpp',
             'platform/FileSystem.h',
             'platform/FloatConversion.h',
             'platform/GeolocationService.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 5f6fec3..55bd70e 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -877,6 +877,7 @@ SOURCES += \
     platform/DragData.cpp \
     platform/DragImage.cpp \
     platform/FileChooser.cpp \
+    platform/FileSystem.cpp \
     platform/GeolocationService.cpp \
     platform/image-decoders/qt/RGBA32BufferQt.cpp \
     platform/graphics/FontDescription.cpp \
@@ -1655,6 +1656,7 @@ HEADERS += \
     platform/DragData.h \
     platform/DragImage.h \
     platform/FileChooser.h \
+    platform/FileSystem.h \
     platform/GeolocationService.h \
     platform/image-decoders/ImageDecoder.h \
     platform/mock/DeviceOrientationClientMock.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index fc628d7..203a887 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -24021,6 +24021,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\platform\FileSystem.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\platform\FileSystem.h"
 				>
 			</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 43325ec..6a81fa4 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5028,6 +5028,7 @@
 		C572EE0F1201C736007D8F82 /* IDBIndexBackendInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = C572EE091201C736007D8F82 /* IDBIndexBackendInterface.h */; };
 		C572EE1E1201C9BC007D8F82 /* JSIDBIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C572EE1C1201C9BC007D8F82 /* JSIDBIndex.cpp */; };
 		C572EE1F1201C9BC007D8F82 /* JSIDBIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = C572EE1D1201C9BC007D8F82 /* JSIDBIndex.h */; };
+		C57FEDE11212EE9C0097BE65 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C57FEDE01212EE9C0097BE65 /* FileSystem.cpp */; };
 		C585A65E11D4FAB2004C3E4B /* JSIDBAnyCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C585A65C11D4FAB2004C3E4B /* JSIDBAnyCustom.cpp */; };
 		C585A65F11D4FAB2004C3E4B /* JSIDBKeyCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C585A65D11D4FAB2004C3E4B /* JSIDBKeyCustom.cpp */; };
 		C585A66211D4FAC5004C3E4B /* IDBBindingUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C585A66011D4FAC5004C3E4B /* IDBBindingUtilities.cpp */; };
@@ -10820,6 +10821,7 @@
 		C572EE091201C736007D8F82 /* IDBIndexBackendInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBIndexBackendInterface.h; sourceTree = "<group>"; };
 		C572EE1C1201C9BC007D8F82 /* JSIDBIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBIndex.cpp; sourceTree = "<group>"; };
 		C572EE1D1201C9BC007D8F82 /* JSIDBIndex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSIDBIndex.h; sourceTree = "<group>"; };
+		C57FEDE01212EE9C0097BE65 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystem.cpp; sourceTree = "<group>"; };
 		C585A65C11D4FAB2004C3E4B /* JSIDBAnyCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBAnyCustom.cpp; sourceTree = "<group>"; };
 		C585A65D11D4FAB2004C3E4B /* JSIDBKeyCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBKeyCustom.cpp; sourceTree = "<group>"; };
 		C585A66011D4FAC5004C3E4B /* IDBBindingUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBBindingUtilities.cpp; sourceTree = "<group>"; };
@@ -16580,6 +16582,7 @@
 				1CA19E150DC255CA0065A994 /* EventLoop.h */,
 				934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
 				066C772A0AB603B700238CC4 /* FileChooser.h */,
+				C57FEDE01212EE9C0097BE65 /* FileSystem.cpp */,
 				514B3F720C722047000530DF /* FileSystem.h */,
 				BC073BA90C399B1F000F5979 /* FloatConversion.h */,
 				BC3BC29B0E91AB0F00835588 /* HostWindow.h */,
@@ -22751,6 +22754,7 @@
 				899ABC841215F03D00F9F219 /* JSFileSystemCallback.cpp in Sources */,
 				899ABC861215F0D800F9F219 /* DOMFileSystem.cpp in Sources */,
 				899ABCBA1215FAB800F9F219 /* Entry.cpp in Sources */,
+				C57FEDE11212EE9C0097BE65 /* FileSystem.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebCore/manual-tests/indexed-database.html b/WebCore/manual-tests/indexed-database.html
new file mode 100644
index 0000000..d0fb381
--- /dev/null
+++ b/WebCore/manual-tests/indexed-database.html
@@ -0,0 +1,67 @@
+<html>
+<body>
+<p>This is a test that only applies to IndexedDB.  <span id=enabled>Our test for whether you have it enabled seems to have failed.</span></p>
+
+<p>This page opens up a database with the name "name" and a description of "description".  Result of open: <span id=result>Pending...</span></p>
+
+<p>The first time you open this page up, the message should be a success.  Now, lets make it fail.  Find where the associated .indexeddb file is
+   for this page, replace it with something that's not a sqlite database, and make it read only to your user.  Now close and re-open the browser.
+   When you re-open it, you should get an internal error from the page.</p>
+
+<p>Now delete all IndexedDB files (including the one you just made), restart the browser, and come back to this page.  It should start up fine again.</p>
+
+<p>Now click <a href="javascript:updateDescription()">here</a>, close the browser, come back, and click <a href="javascript:readDescription()">here</a>.  If everything worked well, this should be a success here: <span id=description>...</span></p>
+
+<p>That's it!</p>
+
+<script>
+
+    if (!('indexedDB' in window))
+        document.getElementById("enabled").innerHTML = "<font color=red>Your build does NOT seem to have it enabled.  So all code on this page is disabled.</font>";
+    else {
+        document.getElementById("enabled").innerHTML = "<font color=green>Your build seems to have it enabled.</font>";
+
+        request = indexedDB.open("name");
+        request.onsuccess = function() {
+            document.getElementById("result").innerHTML = "<font color=green>Success!</font>";
+            window.nameDB = event.result;
+        };
+        request.onerror = function() {
+            document.getElementById("result").innerHTML = "<font color=red>Error: " + event.message + ".</font>";
+        };
+
+        request = indexedDB.open("another", "test of the description attribute");
+        request.onsuccess = function() {
+            window.anotherDB = event.result;
+        };
+    }
+
+    function updateDescription()
+    {
+        indexedDB.open("name", "test of the description attribute");
+        indexedDB.open("another", "xyz");
+    }
+
+    function readDescription()
+    {
+        if (window.nameDB.description != "test of the description attribute") {
+            // Since we passed in nothing, the description should not be reset.
+            document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'name' was this: " + window.nameDB.description + ").</font>";
+        } else if (window.anotherDB.description != "test of the description attribute") {
+            // But in this case we did pass something in, so it should have been reset.
+            document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'another' was this: " + window.anotherDB.description + ").</font>";
+        } else {
+            request = indexedDB.open("another", "123");
+            request.onsuccess = function() {
+                // And here it should have been reset again.
+                if (event.result.description != "123")
+                    document.getElementById("description").innerHTML = "<font color=red>Failure: (Database 'another' was this: " + event.result.description + ").</font>";
+                else
+                    document.getElementById("description").innerHTML = "<font color=green>Success!</font>";
+            };
+        }
+    }
+
+</script>
+</body>
+</html>
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index e306486..f759402 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -30,6 +30,7 @@
 #include "SecurityOrigin.h"
 
 #include "Document.h"
+#include "FileSystem.h"
 #include "KURL.h"
 #include "OriginAccessEntry.h"
 #include "SchemeRegistry.h"
@@ -399,85 +400,12 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
     return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(port)));
 }
 
-// The following lower-ASCII characters need escaping to be used in a filename
-// across all systems, including Windows:
-//     - Unprintable ASCII (00-1F)
-//     - Space             (20)
-//     - Double quote      (22)
-//     - Percent           (25) (escaped because it is our escape character)
-//     - Asterisk          (2A)
-//     - Slash             (2F)
-//     - Colon             (3A)
-//     - Less-than         (3C)
-//     - Greater-than      (3E)
-//     - Question Mark     (3F)
-//     - Backslash         (5C)
-//     - Pipe              (7C)
-//     - Delete            (7F)
-
-static const bool needsEscaping[128] = {
-    /* 00-07 */ true,  true,  true,  true,  true,  true,  true,  true, 
-    /* 08-0F */ true,  true,  true,  true,  true,  true,  true,  true, 
-
-    /* 10-17 */ true,  true,  true,  true,  true,  true,  true,  true, 
-    /* 18-1F */ true,  true,  true,  true,  true,  true,  true,  true, 
-
-    /* 20-27 */ true,  false, true,  false, false, true,  false, false, 
-    /* 28-2F */ false, false, true,  false, false, false, false, true, 
-    
-    /* 30-37 */ false, false, false, false, false, false, false, false, 
-    /* 38-3F */ false, false, true,  false, true,  false, true,  true, 
-    
-    /* 40-47 */ false, false, false, false, false, false, false, false, 
-    /* 48-4F */ false, false, false, false, false, false, false, false,
-    
-    /* 50-57 */ false, false, false, false, false, false, false, false, 
-    /* 58-5F */ false, false, false, false, true,  false, false, false,
-    
-    /* 60-67 */ false, false, false, false, false, false, false, false, 
-    /* 68-6F */ false, false, false, false, false, false, false, false,
-    
-    /* 70-77 */ false, false, false, false, false, false, false, false, 
-    /* 78-7F */ false, false, false, false, true,  false, false, true, 
-};
-
-static inline bool shouldEscapeUChar(UChar c)
-{
-    return c > 127 ? false : needsEscaping[c];
-}
-
-static const char hexDigits[17] = "0123456789ABCDEF";
-
-static String encodedHost(const String& host)
-{
-    unsigned length = host.length();
-    Vector<UChar, 512> buffer(length * 3 + 1);
-    UChar* p = buffer.data();
-
-    const UChar* str = host.characters();
-    const UChar* strEnd = str + length;
-
-    while (str < strEnd) {
-        UChar c = *str++;
-        if (shouldEscapeUChar(c)) {
-            *p++ = '%';
-            *p++ = hexDigits[(c >> 4) & 0xF];
-            *p++ = hexDigits[c & 0xF];
-        } else
-            *p++ = c;
-    }
-
-    ASSERT(p - buffer.data() <= static_cast<int>(buffer.size()));
-
-    return String(buffer.data(), p - buffer.data());
-}
-
 String SecurityOrigin::databaseIdentifier() const 
 {
     String separatorString(&SeparatorCharacter, 1);
 
     if (m_encodedHost.isEmpty())
-        m_encodedHost = encodedHost(m_host);
+        m_encodedHost = encodeForFileName(m_host);
 
     return m_protocol + separatorString + m_encodedHost + separatorString + String::number(m_port); 
 }
diff --git a/WebCore/platform/FileSystem.cpp b/WebCore/platform/FileSystem.cpp
new file mode 100644
index 0000000..511f8aa
--- /dev/null
+++ b/WebCore/platform/FileSystem.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007 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 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 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 "config.h"
+#include "FileSystem.h"
+
+namespace WebCore {
+
+// The following lower-ASCII characters need escaping to be used in a filename
+// across all systems, including Windows:
+//     - Unprintable ASCII (00-1F)
+//     - Space             (20)
+//     - Double quote      (22)
+//     - Percent           (25) (escaped because it is our escape character)
+//     - Asterisk          (2A)
+//     - Slash             (2F)
+//     - Colon             (3A)
+//     - Less-than         (3C)
+//     - Greater-than      (3E)
+//     - Question Mark     (3F)
+//     - Backslash         (5C)
+//     - Pipe              (7C)
+//     - Delete            (7F)
+
+static const bool needsEscaping[128] = {
+    /* 00-07 */ true,  true,  true,  true,  true,  true,  true,  true, 
+    /* 08-0F */ true,  true,  true,  true,  true,  true,  true,  true, 
+
+    /* 10-17 */ true,  true,  true,  true,  true,  true,  true,  true, 
+    /* 18-1F */ true,  true,  true,  true,  true,  true,  true,  true, 
+
+    /* 20-27 */ true,  false, true,  false, false, true,  false, false, 
+    /* 28-2F */ false, false, true,  false, false, false, false, true, 
+    
+    /* 30-37 */ false, false, false, false, false, false, false, false, 
+    /* 38-3F */ false, false, true,  false, true,  false, true,  true, 
+    
+    /* 40-47 */ false, false, false, false, false, false, false, false, 
+    /* 48-4F */ false, false, false, false, false, false, false, false,
+    
+    /* 50-57 */ false, false, false, false, false, false, false, false, 
+    /* 58-5F */ false, false, false, false, true,  false, false, false,
+    
+    /* 60-67 */ false, false, false, false, false, false, false, false, 
+    /* 68-6F */ false, false, false, false, false, false, false, false,
+    
+    /* 70-77 */ false, false, false, false, false, false, false, false, 
+    /* 78-7F */ false, false, false, false, true,  false, false, true, 
+};
+
+static inline bool shouldEscapeUChar(UChar c)
+{
+    return c > 127 ? false : needsEscaping[c];
+}
+
+static const char hexDigits[17] = "0123456789ABCDEF";
+
+String encodeForFileName(const String& inputStr)
+{
+    unsigned length = inputStr.length();
+    Vector<UChar, 512> buffer(length * 3 + 1);
+    UChar* p = buffer.data();
+
+    const UChar* str = inputStr.characters();
+    const UChar* strEnd = str + length;
+
+    while (str < strEnd) {
+        UChar c = *str++;
+        if (shouldEscapeUChar(c)) {
+            *p++ = '%';
+            *p++ = hexDigits[(c >> 4) & 0xF];
+            *p++ = hexDigits[c & 0xF];
+        } else
+            *p++ = c;
+    }
+
+    ASSERT(p - buffer.data() <= static_cast<int>(buffer.size()));
+
+    return String(buffer.data(), p - buffer.data());
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index 617470b..ec75a21 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -170,6 +170,9 @@ int readFromFile(PlatformFileHandle, char* data, int length);
 // Methods for dealing with loadable modules
 bool unloadModule(PlatformModule);
 
+// Encode a string for use within a file name.
+String encodeForFileName(const String&);
+
 #if PLATFORM(WIN)
 String localUserSpecificStorageDirectory();
 String roamingUserSpecificStorageDirectory();
diff --git a/WebCore/storage/IDBDatabase.cpp b/WebCore/storage/IDBDatabase.cpp
index fa1807c..b00695b 100644
--- a/WebCore/storage/IDBDatabase.cpp
+++ b/WebCore/storage/IDBDatabase.cpp
@@ -39,6 +39,7 @@ namespace WebCore {
 
 IDBDatabase::IDBDatabase(PassRefPtr<IDBDatabaseBackendInterface> backend)
     : m_backend(backend)
+    , m_description(m_backend->description())
 {
     // We pass a reference to this object before it can be adopted.
     relaxAdoptionRequirement();
diff --git a/WebCore/storage/IDBDatabase.h b/WebCore/storage/IDBDatabase.h
index 6900efd..1ad3c65 100644
--- a/WebCore/storage/IDBDatabase.h
+++ b/WebCore/storage/IDBDatabase.h
@@ -52,7 +52,7 @@ public:
 
     // Implement the IDL
     String name() const { return m_backend->name(); }
-    String description() const { return m_backend->description(); }
+    String description() const { return m_description; }
     String version() const { return m_backend->version(); }
     PassRefPtr<DOMStringList> objectStores() const { return m_backend->objectStores(); }
 
@@ -65,6 +65,8 @@ private:
     IDBDatabase(PassRefPtr<IDBDatabaseBackendInterface>);
 
     RefPtr<IDBDatabaseBackendInterface> m_backend;
+
+    String m_description;
 };
 
 } // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseBackendImpl.cpp b/WebCore/storage/IDBDatabaseBackendImpl.cpp
index 09b9dee..e550e18 100644
--- a/WebCore/storage/IDBDatabaseBackendImpl.cpp
+++ b/WebCore/storage/IDBDatabaseBackendImpl.cpp
@@ -29,22 +29,89 @@
 #include "DOMStringList.h"
 #include "IDBDatabaseException.h"
 #include "IDBObjectStoreBackendImpl.h"
+#include "SQLiteDatabase.h"
+#include "SQLiteStatement.h"
 
 #if ENABLE(INDEXED_DATABASE)
 
 namespace WebCore {
 
-IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, const String& version)
-    : m_name(name)
-    , m_description(description)
-    , m_version(version)
+static bool extractMetaData(SQLiteDatabase* sqliteDatabase, const String& expectedName, String& foundDescription, String& foundVersion)
 {
+    SQLiteStatement metaDataQuery(*sqliteDatabase, "SELECT name, description, version FROM MetaData");
+    if (metaDataQuery.prepare() != SQLResultOk || metaDataQuery.step() != SQLResultRow)
+        return false;
+
+    if (metaDataQuery.getColumnText(0) != expectedName) {
+        LOG_ERROR("Name in MetaData (%s) doesn't match expected (%s) for IndexedDB", metaDataQuery.getColumnText(0).utf8().data(), expectedName.utf8().data());
+        ASSERT_NOT_REACHED();
+    }
+    foundDescription = metaDataQuery.getColumnText(1);
+    foundVersion = metaDataQuery.getColumnText(2);
+
+    if (metaDataQuery.step() == SQLResultRow) {
+        LOG_ERROR("More than one row found in MetaData table");
+        ASSERT_NOT_REACHED();
+    }
+
+    return true;
+}
+
+static bool setMetaData(SQLiteDatabase* sqliteDatabase, const String& name, const String& description, const String& version)
+{
+    ASSERT(!name.isNull() && !description.isNull() && !version.isNull());
+
+    sqliteDatabase->executeCommand("DELETE FROM MetaData");
+
+    SQLiteStatement insert(*sqliteDatabase, "INSERT INTO MetaData (name, description, version) VALUES (?, ?, ?)");
+    if (insert.prepare() != SQLResultOk) {
+        LOG_ERROR("Failed to prepare MetaData insert statement for IndexedDB");
+        return false;
+    }
+
+    insert.bindText(1, name);
+    insert.bindText(2, description);
+    insert.bindText(3, version);
+
+    if (insert.step() != SQLResultDone) {
+        LOG_ERROR("Failed to insert row into MetaData for IndexedDB");
+        return false;
+    }
+
+    // FIXME: Should we assert there's only one row?
+
+    return true;
+}
+
+IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> sqliteDatabase)
+    : m_sqliteDatabase(sqliteDatabase)
+    , m_name(name)
+    , m_version("")
+{
+    ASSERT(!m_name.isNull());
+
+    // FIXME: The spec is in flux about how to handle description. Sync it up once a final decision is made.
+    String foundDescription = "";
+    bool result = extractMetaData(m_sqliteDatabase.get(), m_name, foundDescription, m_version);
+    m_description = description.isNull() ? foundDescription : description;
+
+    if (!result || m_description != foundDescription)
+        setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version);
 }
 
 IDBDatabaseBackendImpl::~IDBDatabaseBackendImpl()
 {
 }
 
+void IDBDatabaseBackendImpl::setDescription(const String& description)
+{
+    if (description == m_description)
+        return;
+
+    m_description = description;
+    setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version);
+}
+
 PassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStores() const
 {
     RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
diff --git a/WebCore/storage/IDBDatabaseBackendImpl.h b/WebCore/storage/IDBDatabaseBackendImpl.h
index 4d01a93..60bec1f 100644
--- a/WebCore/storage/IDBDatabaseBackendImpl.h
+++ b/WebCore/storage/IDBDatabaseBackendImpl.h
@@ -35,14 +35,18 @@
 
 namespace WebCore {
 
+class SQLiteDatabase;
+
 class IDBDatabaseBackendImpl : public IDBDatabaseBackendInterface {
 public:
-    static PassRefPtr<IDBDatabaseBackendInterface> create(const String& name, const String& description, const String& version)
+    static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database)
     {
-        return adoptRef(new IDBDatabaseBackendImpl(name, description, version));
+        return adoptRef(new IDBDatabaseBackendImpl(name, description, database));
     }
     virtual ~IDBDatabaseBackendImpl();
 
+    void setDescription(const String& description);
+
     // Implements IDBDatabase
     virtual String name() const { return m_name; }
     virtual String description() const { return m_description; }
@@ -54,7 +58,9 @@ public:
     virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>);
     virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, unsigned long timeout);
 private:
-    IDBDatabaseBackendImpl(const String& name, const String& description, const String& version);
+    IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database);
+
+    OwnPtr<SQLiteDatabase> m_sqliteDatabase;
 
     String m_name;
     String m_description;
diff --git a/WebCore/storage/IDBFactory.h b/WebCore/storage/IDBFactory.h
index 61619b9..a96aa38 100644
--- a/WebCore/storage/IDBFactory.h
+++ b/WebCore/storage/IDBFactory.h
@@ -54,7 +54,7 @@ public:
     }
     ~IDBFactory();
 
-    PassRefPtr<IDBRequest> open(ScriptExecutionContext*, const String& name, const String& description);
+    PassRefPtr<IDBRequest> open(ScriptExecutionContext*, const String& name, const String& description = String());
 
 private:
     IDBFactory(IDBFactoryBackendInterface*);
diff --git a/WebCore/storage/IDBFactory.idl b/WebCore/storage/IDBFactory.idl
index cd887f0..215d67c 100644
--- a/WebCore/storage/IDBFactory.idl
+++ b/WebCore/storage/IDBFactory.idl
@@ -28,7 +28,7 @@ module storage {
     interface [
         Conditional=INDEXED_DATABASE
     ] IDBFactory {
-        [CallWith=ScriptExecutionContext] IDBRequest open(in DOMString name, in DOMString description);
+        [CallWith=ScriptExecutionContext] IDBRequest open(in DOMString name, in [Optional, ConvertUndefinedOrNullToNullString] DOMString description);
     };
 
 }
diff --git a/WebCore/storage/IDBFactoryBackendImpl.cpp b/WebCore/storage/IDBFactoryBackendImpl.cpp
index 7bdd70d..905726f 100644
--- a/WebCore/storage/IDBFactoryBackendImpl.cpp
+++ b/WebCore/storage/IDBFactoryBackendImpl.cpp
@@ -30,7 +30,10 @@
 #include "IDBFactoryBackendImpl.h"
 
 #include "DOMStringList.h"
+#include "FileSystem.h"
 #include "IDBDatabaseBackendImpl.h"
+#include "IDBDatabaseException.h"
+#include "SQLiteDatabase.h"
 #include "SecurityOrigin.h"
 #include <wtf/Threading.h>
 #include <wtf/UnusedParam.h>
@@ -39,31 +42,74 @@
 
 namespace WebCore {
 
-PassRefPtr<IDBFactoryBackendImpl> IDBFactoryBackendImpl::create()
+IDBFactoryBackendImpl::IDBFactoryBackendImpl()
 {
-    return adoptRef(new IDBFactoryBackendImpl);
 }
 
-IDBFactoryBackendImpl::IDBFactoryBackendImpl()
+IDBFactoryBackendImpl::~IDBFactoryBackendImpl()
 {
 }
 
-IDBFactoryBackendImpl::~IDBFactoryBackendImpl()
+static PassOwnPtr<SQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOrigin, String name)
 {
+    String pathBase = "/tmp/temporary-indexed-db-files"; // FIXME: Write a PageGroupSettings class and have this value come from that.
+    if (!makeAllDirectories(pathBase)) {
+        // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out.
+        LOG_ERROR("Unabled to create LocalStorage database path %s", pathBase.utf8().data());
+        return 0;
+    }
+
+    String databaseIdentifier = securityOrigin->databaseIdentifier();
+    String santizedName = encodeForFileName(name);
+    String path = pathByAppendingComponent(pathBase, databaseIdentifier + "_" + santizedName + ".indexeddb");
+    
+    OwnPtr<SQLiteDatabase> sqliteDatabase = adoptPtr(new SQLiteDatabase());
+    if (!sqliteDatabase->open(path)) {
+        // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out.
+        LOG_ERROR("Failed to open database file %s for IndexedDB", path.utf8().data());
+        return 0;
+    }
+
+    return sqliteDatabase.release();
 }
 
-void IDBFactoryBackendImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin>, Frame*)
+static bool createTables(SQLiteDatabase* sqliteDatabase)
+{
+    static const char* commands[] = {
+        "CREATE TABLE IF NOT EXISTS MetaData (name TEXT, description TEXT, version TEXT)"
+        };
+
+    for (size_t i = 0; i < arraysize(commands); ++i) {
+        if (!sqliteDatabase->executeCommand(commands[i])) {
+            // FIXME: We should try to recover from this situation. Maybe nuke the database and start over?
+            LOG_ERROR("Failed to run the following command for IndexedDB: %s", commands[i]);
+            return false;
+        }
+    }
+    return true;
+}
+
+void IDBFactoryBackendImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*)
 {
-    RefPtr<IDBDatabaseBackendInterface> databaseBackend;
     IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(name);
-    if (it == m_databaseBackendMap.end()) {
-        // FIXME: What should the version be?  The spec doesn't define it yet.
-        databaseBackend = IDBDatabaseBackendImpl::create(name, description, "");
-        m_databaseBackendMap.set(name, databaseBackend);
-    } else
-        databaseBackend = it->second;
-
-    callbacks->onSuccess(databaseBackend.release());
+    if (it != m_databaseBackendMap.end()) {
+        if (!description.isNull())
+            it->second->setDescription(description); // The description may have changed.
+        callbacks->onSuccess(it->second.get());
+        return;
+    }
+
+    // FIXME: Everything from now on should be done on another thread.
+
+    OwnPtr<SQLiteDatabase> sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), name);
+    if (!sqliteDatabase || !createTables(sqliteDatabase.get())) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
+        return;
+    }
+
+    RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.release());
+    callbacks->onSuccess(databaseBackend.get());
+    m_databaseBackendMap.set(name, databaseBackend.release());
 }
 
 } // namespace WebCore
diff --git a/WebCore/storage/IDBFactoryBackendImpl.h b/WebCore/storage/IDBFactoryBackendImpl.h
index 270fb75..e87ea39 100644
--- a/WebCore/storage/IDBFactoryBackendImpl.h
+++ b/WebCore/storage/IDBFactoryBackendImpl.h
@@ -37,10 +37,14 @@
 namespace WebCore {
 
 class DOMStringList;
+class IDBDatabaseBackendImpl;
 
 class IDBFactoryBackendImpl : public IDBFactoryBackendInterface {
 public:
-    static PassRefPtr<IDBFactoryBackendImpl> create();
+    static PassRefPtr<IDBFactoryBackendImpl> create()
+    {
+        return adoptRef(new IDBFactoryBackendImpl());
+    }
     virtual ~IDBFactoryBackendImpl();
 
     virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*);
@@ -48,7 +52,7 @@ public:
 private:
     IDBFactoryBackendImpl();
 
-    typedef HashMap<String, RefPtr<IDBDatabaseBackendInterface> > IDBDatabaseBackendMap;
+    typedef HashMap<String, RefPtr<IDBDatabaseBackendImpl> > IDBDatabaseBackendMap;
     IDBDatabaseBackendMap m_databaseBackendMap;
 
     // We only create one instance of this class at a time.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list