[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