WebCore: Implementing DatabaseSync::transaction() and DatabaseSync::changeVersion().
authordumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Jul 2010 04:46:52 +0000 (04:46 +0000)
committerdumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Jul 2010 04:46:52 +0000 (04:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=40607

Reviewed by Darin Fisher

Tests: fast/workers/storage/change-version-handle-reuse-sync.html
       fast/workers/storage/change-version-sync.html
       fast/workers/storage/empty-statement-sync.html
       fast/workers/storage/execute-sql-args-sync.html
       fast/workers/storage/executesql-accepts-only-one-statement-sync.html
       fast/workers/storage/multiple-transactions-on-different-handles-sync.html
       fast/workers/storage/open-database-creation-callback-sync.html
       fast/workers/storage/open-database-empty-version-sync.html
       fast/workers/storage/open-database-inputs-sync.html
       fast/workers/storage/open-database-set-empty-version-sync.html
       fast/workers/storage/open-database-while-transaction-in-progress-sync.html
       fast/workers/storage/sql-data-types-sync.html
       fast/workers/storage/sql-exception-codes-sync.html
       fast/workers/storage/test-authorizer-sync.html
       fast/workers/storage/transaction-in-transaction-sync.html

* CMakeLists.txt:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* storage/AbstractDatabase.cpp:
(WebCore::AbstractDatabase::maximumSize):
(WebCore::AbstractDatabase::incrementalVacuumIfNeeded):
* storage/AbstractDatabase.h:
(WebCore::AbstractDatabase::sqliteDatabase):
* storage/ChangeVersionWrapper.cpp:
(WebCore::ChangeVersionWrapper::performPreflight):
(WebCore::ChangeVersionWrapper::performPostflight):
* storage/Database.cpp:
(WebCore::Database::performGetTableNames):
* storage/Database.h:
* storage/DatabaseAuthorizer.cpp:
(WebCore::DatabaseAuthorizer::createVTable):
(WebCore::DatabaseAuthorizer::dropVTable):
* storage/DatabaseCallback.h:
* storage/DatabaseSync.cpp:
(WebCore::ChangeVersionPreflightStep::create):
(WebCore::ChangeVersionPreflightStep::performStep):
(WebCore::ChangeVersionPreflightStep::ChangeVersionPreflightStep):
(WebCore::ChangeVersionPostflightStep::create):
(WebCore::ChangeVersionPostflightStep::performStep):
(WebCore::ChangeVersionPostflightStep::ChangeVersionPostflightStep):
(WebCore::DatabaseSync::changeVersion):
(WebCore::DatabaseSync::transaction):
(WebCore::DatabaseSync::runTransaction):
* storage/DatabaseSync.h:
* storage/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::getMaxSizeForDatabase):
* storage/SQLError.h:
* storage/SQLResultSet.cpp:
* storage/SQLResultSet.h:
* storage/SQLStatementCallback.h:
* storage/SQLStatementErrorCallback.h:
* storage/SQLStatementSync.cpp: Copied from WebCore/storage/SQLStatement.cpp.
(WebCore::SQLStatementSync::SQLStatementSync):
(WebCore::SQLStatementSync::execute):
* storage/SQLStatementSync.h: Added.
* storage/SQLTransaction.cpp:
(WebCore::SQLTransaction::runCurrentStatement):
(WebCore::SQLTransaction::deliverQuotaIncreaseCallback):
(WebCore::SQLTransaction::postflightAndCommit):
* storage/SQLTransaction.h:
* storage/SQLTransactionCallback.h:
* storage/SQLTransactionClient.cpp:
(WebCore::SQLTransactionClient::didCommitWriteTransaction):
(WebCore::SQLTransactionClient::didExecuteStatement):
(WebCore::SQLTransactionClient::didExceedQuota):
* storage/SQLTransactionClient.h:
* storage/SQLTransactionErrorCallback.h:
* storage/SQLTransactionSync.cpp:
(WebCore::transactionClient):
(WebCore::SQLTransactionSync::create):
(WebCore::SQLTransactionSync::SQLTransactionSync):
(WebCore::SQLTransactionSync::~SQLTransactionSync):
(WebCore::SQLTransactionSync::executeSQL):
(WebCore::SQLTransactionSync::begin):
(WebCore::SQLTransactionSync::execute):
(WebCore::SQLTransactionSync::commit):
(WebCore::SQLTransactionSync::rollback):
* storage/SQLTransactionSync.h:
(WebCore::SQLTransactionSync::SQLTransactionSyncOptionalStep::~SQLTransactionSyncOptionalStep):
* storage/SQLTransactionSyncCallback.h:
* storage/chromium/SQLTransactionClientChromium.cpp:
(WebCore::SQLTransactionClient::didCommitWriteTransaction):
(WebCore::SQLTransactionClient::didExecuteStatement):
(WebCore::SQLTransactionClient::didExceedQuota):

LayoutTests: Porting as many async DB tests as possible to sync DBs.
https://bugs.webkit.org/show_bug.cgi?id=40607

Reviewed by Darin Fisher.

* fast/workers/storage/change-version-handle-reuse-sync-expected.txt: Added.
* fast/workers/storage/change-version-handle-reuse-sync.html: Added.
* fast/workers/storage/change-version-sync-expected.txt: Added.
* fast/workers/storage/change-version-sync.html: Added.
* fast/workers/storage/empty-statement-sync-expected.txt: Added.
* fast/workers/storage/empty-statement-sync.html: Added.
* fast/workers/storage/execute-sql-args-sync-expected.txt: Added.
* fast/workers/storage/execute-sql-args-sync.html: Added.
* fast/workers/storage/executesql-accepts-only-one-statement-sync-expected.txt: Added.
* fast/workers/storage/executesql-accepts-only-one-statement-sync.html: Added.
* fast/workers/storage/multiple-transactions-on-different-handles-sync-expected.txt: Added.
* fast/workers/storage/multiple-transactions-on-different-handles-sync.html: Added.
* fast/workers/storage/open-database-creation-callback-sync-expected.txt: Added.
* fast/workers/storage/open-database-creation-callback-sync.html: Added.
* fast/workers/storage/open-database-empty-version-sync-expected.txt: Added.
* fast/workers/storage/open-database-empty-version-sync.html: Added.
* fast/workers/storage/open-database-inputs-sync-expected.txt: Copied from LayoutTests/fast/workers/storage/open-database-sync-inputs-expected.txt.
* fast/workers/storage/open-database-inputs-sync.html: Copied from LayoutTests/fast/workers/storage/open-database-sync-inputs.html.
* fast/workers/storage/open-database-set-empty-version-sync-expected.txt: Added.
* fast/workers/storage/open-database-set-empty-version-sync.html: Added.
* fast/workers/storage/open-database-sync-inputs-expected.txt: Removed.
* fast/workers/storage/open-database-sync-inputs.html: Removed.
* fast/workers/storage/open-database-while-transaction-in-progress-sync-expected.txt: Added.
* fast/workers/storage/open-database-while-transaction-in-progress-sync.html: Added.
* fast/workers/storage/resources/change-version-handle-reuse-sync.js: Added.
(catch):
* fast/workers/storage/resources/change-version-sync-1.js: Added.
():
(try):
* fast/workers/storage/resources/change-version-sync-2.js: Added.
* fast/workers/storage/resources/empty-statement-sync.js: Added.
* fast/workers/storage/resources/execute-sql-args-sync.js: Added.
(throwOnToStringObject.toString):
(var):
():
(runTransactionTest):
(runTransactionTests):
* fast/workers/storage/resources/executesql-accepts-only-one-statement-sync.js: Added.
(executeStatement):
* fast/workers/storage/resources/multiple-transactions-on-different-handles-sync.js: Added.
(runTransaction):
(var):
* fast/workers/storage/resources/multiple-transactions-sync.js: Added.
(checkCompletion):
(runTest.db):
(runTest):
* fast/workers/storage/resources/open-database-creation-callback-sync.js: Added.
* fast/workers/storage/resources/open-database-empty-version-sync.js: Added.
* fast/workers/storage/resources/open-database-inputs-sync.js: Copied from LayoutTests/fast/workers/storage/resources/open-database-sync-inputs.js.
* fast/workers/storage/resources/open-database-set-empty-version-sync.js: Added.
* fast/workers/storage/resources/open-database-sync-inputs.js: Removed.
* fast/workers/storage/resources/open-database-while-transaction-in-progress-sync.js: Added.
(openTestDatabase):
* fast/workers/storage/resources/sql-data-types-sync.js: Added.
():
(testDBValues):
* fast/workers/storage/resources/sql-exception-codes-sync.js: Added.
(testTransaction):
():
(testInvalidStatement):
(testIncorrectNumberOfBindParameters):
(testBindParameterOfWrongType.badString.toString):
(testBindParameterOfWrongType):
(testVersionMismatch.testTransaction):
(testVersionMismatch):
* fast/workers/storage/resources/test-authorizer-sync.js: Added.
(cleanup):
(executeStatement):
(createTableCallback):
(createStatementsCallback):
(otherStatementsCallback):
(dropStatementsCallback):
(testReadWriteMode):
(testReadOnlyMode):
* fast/workers/storage/resources/transaction-in-transaction-sync.js: Added.
* fast/workers/storage/sql-data-types-sync-expected.txt: Added.
* fast/workers/storage/sql-data-types-sync.html: Added.
* fast/workers/storage/sql-exception-codes-sync-expected.txt: Added.
* fast/workers/storage/sql-exception-codes-sync.html: Added.
* fast/workers/storage/test-authorizer-sync-expected.txt: Added.
* fast/workers/storage/test-authorizer-sync.html: Added.
* fast/workers/storage/transaction-in-transaction-sync-expected.txt: Added.
* fast/workers/storage/transaction-in-transaction-sync.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@63278 268f45cc-cd09-0410-ab3c-d52691b4dbfc

85 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/workers/storage/change-version-handle-reuse-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/change-version-handle-reuse-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/change-version-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/change-version-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/empty-statement-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/empty-statement-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/execute-sql-args-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/execute-sql-args-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-creation-callback-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-creation-callback-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-empty-version-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-empty-version-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-inputs-sync-expected.txt [moved from LayoutTests/fast/workers/storage/open-database-sync-inputs-expected.txt with 100% similarity]
LayoutTests/fast/workers/storage/open-database-inputs-sync.html [moved from LayoutTests/fast/workers/storage/open-database-sync-inputs.html with 77% similarity]
LayoutTests/fast/workers/storage/open-database-set-empty-version-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-set-empty-version-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/change-version-handle-reuse-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/change-version-sync-1.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/change-version-sync-2.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/empty-statement-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/execute-sql-args-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/executesql-accepts-only-one-statement-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/multiple-transactions-on-different-handles-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/multiple-transactions-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/open-database-creation-callback-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/open-database-empty-version-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/open-database-inputs-sync.js [moved from LayoutTests/fast/workers/storage/resources/open-database-sync-inputs.js with 100% similarity]
LayoutTests/fast/workers/storage/resources/open-database-set-empty-version-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/open-database-while-transaction-in-progress-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/sql-data-types-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/sql-exception-codes-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/test-authorizer-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/transaction-in-transaction-sync.js [new file with mode: 0644]
LayoutTests/fast/workers/storage/sql-data-types-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/sql-data-types-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/sql-exception-codes-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/sql-exception-codes-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/test-authorizer-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/test-authorizer-sync.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/transaction-in-transaction-sync-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/transaction-in-transaction-sync.html [new file with mode: 0644]
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/storage/AbstractDatabase.cpp
WebCore/storage/AbstractDatabase.h
WebCore/storage/ChangeVersionWrapper.cpp
WebCore/storage/Database.cpp
WebCore/storage/Database.h
WebCore/storage/DatabaseAuthorizer.cpp
WebCore/storage/DatabaseCallback.h
WebCore/storage/DatabaseSync.cpp
WebCore/storage/DatabaseSync.h
WebCore/storage/DatabaseSync.idl
WebCore/storage/DatabaseTracker.cpp
WebCore/storage/SQLError.h
WebCore/storage/SQLResultSet.cpp
WebCore/storage/SQLResultSet.h
WebCore/storage/SQLStatementCallback.h
WebCore/storage/SQLStatementErrorCallback.h
WebCore/storage/SQLStatementSync.cpp [new file with mode: 0644]
WebCore/storage/SQLStatementSync.h [new file with mode: 0644]
WebCore/storage/SQLTransaction.cpp
WebCore/storage/SQLTransaction.h
WebCore/storage/SQLTransactionCallback.h
WebCore/storage/SQLTransactionClient.cpp
WebCore/storage/SQLTransactionClient.h
WebCore/storage/SQLTransactionErrorCallback.h
WebCore/storage/SQLTransactionSync.cpp
WebCore/storage/SQLTransactionSync.h
WebCore/storage/SQLTransactionSync.idl
WebCore/storage/SQLTransactionSyncCallback.h
WebCore/storage/SQLTransactionSyncCallback.idl
WebCore/storage/chromium/SQLTransactionClientChromium.cpp

index 3c759ae..5e5f6f6 100644 (file)
@@ -1,3 +1,94 @@
+2010-07-13  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        Porting as many async DB tests as possible to sync DBs.
+        https://bugs.webkit.org/show_bug.cgi?id=40607
+
+        * fast/workers/storage/change-version-handle-reuse-sync-expected.txt: Added.
+        * fast/workers/storage/change-version-handle-reuse-sync.html: Added.
+        * fast/workers/storage/change-version-sync-expected.txt: Added.
+        * fast/workers/storage/change-version-sync.html: Added.
+        * fast/workers/storage/empty-statement-sync-expected.txt: Added.
+        * fast/workers/storage/empty-statement-sync.html: Added.
+        * fast/workers/storage/execute-sql-args-sync-expected.txt: Added.
+        * fast/workers/storage/execute-sql-args-sync.html: Added.
+        * fast/workers/storage/executesql-accepts-only-one-statement-sync-expected.txt: Added.
+        * fast/workers/storage/executesql-accepts-only-one-statement-sync.html: Added.
+        * fast/workers/storage/multiple-transactions-on-different-handles-sync-expected.txt: Added.
+        * fast/workers/storage/multiple-transactions-on-different-handles-sync.html: Added.
+        * fast/workers/storage/open-database-creation-callback-sync-expected.txt: Added.
+        * fast/workers/storage/open-database-creation-callback-sync.html: Added.
+        * fast/workers/storage/open-database-empty-version-sync-expected.txt: Added.
+        * fast/workers/storage/open-database-empty-version-sync.html: Added.
+        * fast/workers/storage/open-database-inputs-sync-expected.txt: Copied from LayoutTests/fast/workers/storage/open-database-sync-inputs-expected.txt.
+        * fast/workers/storage/open-database-inputs-sync.html: Copied from LayoutTests/fast/workers/storage/open-database-sync-inputs.html.
+        * fast/workers/storage/open-database-set-empty-version-sync-expected.txt: Added.
+        * fast/workers/storage/open-database-set-empty-version-sync.html: Added.
+        * fast/workers/storage/open-database-sync-inputs-expected.txt: Removed.
+        * fast/workers/storage/open-database-sync-inputs.html: Removed.
+        * fast/workers/storage/open-database-while-transaction-in-progress-sync-expected.txt: Added.
+        * fast/workers/storage/open-database-while-transaction-in-progress-sync.html: Added.
+        * fast/workers/storage/resources/change-version-handle-reuse-sync.js: Added.
+        (catch):
+        * fast/workers/storage/resources/change-version-sync-1.js: Added.
+        ():
+        (try):
+        * fast/workers/storage/resources/change-version-sync-2.js: Added.
+        * fast/workers/storage/resources/empty-statement-sync.js: Added.
+        * fast/workers/storage/resources/execute-sql-args-sync.js: Added.
+        (throwOnToStringObject.toString):
+        (var):
+        ():
+        (runTransactionTest):
+        (runTransactionTests):
+        * fast/workers/storage/resources/executesql-accepts-only-one-statement-sync.js: Added.
+        (executeStatement):
+        * fast/workers/storage/resources/multiple-transactions-on-different-handles-sync.js: Added.
+        (runTransaction):
+        (var):
+        * fast/workers/storage/resources/multiple-transactions-sync.js: Added.
+        (checkCompletion):
+        (runTest.db):
+        (runTest):
+        * fast/workers/storage/resources/open-database-creation-callback-sync.js: Added.
+        * fast/workers/storage/resources/open-database-empty-version-sync.js: Added.
+        * fast/workers/storage/resources/open-database-inputs-sync.js: Copied from LayoutTests/fast/workers/storage/resources/open-database-sync-inputs.js.
+        * fast/workers/storage/resources/open-database-set-empty-version-sync.js: Added.
+        * fast/workers/storage/resources/open-database-sync-inputs.js: Removed.
+        * fast/workers/storage/resources/open-database-while-transaction-in-progress-sync.js: Added.
+        (openTestDatabase):
+        * fast/workers/storage/resources/sql-data-types-sync.js: Added.
+        ():
+        (testDBValues):
+        * fast/workers/storage/resources/sql-exception-codes-sync.js: Added.
+        (testTransaction):
+        ():
+        (testInvalidStatement):
+        (testIncorrectNumberOfBindParameters):
+        (testBindParameterOfWrongType.badString.toString):
+        (testBindParameterOfWrongType):
+        (testVersionMismatch.testTransaction):
+        (testVersionMismatch):
+        * fast/workers/storage/resources/test-authorizer-sync.js: Added.
+        (cleanup):
+        (executeStatement):
+        (createTableCallback):
+        (createStatementsCallback):
+        (otherStatementsCallback):
+        (dropStatementsCallback):
+        (testReadWriteMode):
+        (testReadOnlyMode):
+        * fast/workers/storage/resources/transaction-in-transaction-sync.js: Added.
+        * fast/workers/storage/sql-data-types-sync-expected.txt: Added.
+        * fast/workers/storage/sql-data-types-sync.html: Added.
+        * fast/workers/storage/sql-exception-codes-sync-expected.txt: Added.
+        * fast/workers/storage/sql-exception-codes-sync.html: Added.
+        * fast/workers/storage/test-authorizer-sync-expected.txt: Added.
+        * fast/workers/storage/test-authorizer-sync.html: Added.
+        * fast/workers/storage/transaction-in-transaction-sync-expected.txt: Added.
+        * fast/workers/storage/transaction-in-transaction-sync.html: Added.
+
 2010-07-13  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/LayoutTests/fast/workers/storage/change-version-handle-reuse-sync-expected.txt b/LayoutTests/fast/workers/storage/change-version-handle-reuse-sync-expected.txt
new file mode 100644 (file)
index 0000000..8c58718
--- /dev/null
@@ -0,0 +1,5 @@
+Test that the database can be accessed after changing its version.
+PASS: changeVersion() transaction callback was called.
+PASS: No exception thrown while executing statements.
+PASS: No exception thrown while running a transaction.
+
diff --git a/LayoutTests/fast/workers/storage/change-version-handle-reuse-sync.html b/LayoutTests/fast/workers/storage/change-version-handle-reuse-sync.html
new file mode 100644 (file)
index 0000000..c6d5ba6
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/change-version-handle-reuse-sync.js')">
+Test that the database can be accessed after changing its version.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/change-version-sync-expected.txt b/LayoutTests/fast/workers/storage/change-version-sync-expected.txt
new file mode 100644 (file)
index 0000000..59cca8c
--- /dev/null
@@ -0,0 +1,3 @@
+Test that version updates in sync databases work correctly.
+PASS: db.version is 3 as expected.
+
diff --git a/LayoutTests/fast/workers/storage/change-version-sync.html b/LayoutTests/fast/workers/storage/change-version-sync.html
new file mode 100644 (file)
index 0000000..9864b18
--- /dev/null
@@ -0,0 +1,49 @@
+<html>
+<head>
+<script>
+function log(message)
+{
+    document.getElementById("console").innerHTML += message + "<br>";
+}
+
+function finishTest()
+{
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function runTest()
+{
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    if (window.location.search == "?2") {
+        var worker = new Worker("resources/change-version-sync-2.js");
+        worker.onmessage = function(event) {
+            if (event.data == "done")
+                finishTest();
+            else
+                log(event.data);
+        };
+    } else {
+        var worker = new Worker("resources/change-version-sync-1.js");
+        worker.onmessage = function(event) {
+            if (event.data == "done")
+                window.location.href = window.location + "?2";
+            else if (event.data == "fail")
+                finishTest();
+            else
+                log(event.data);
+        };
+    }
+}
+</script>
+</head>
+<body onload="runTest()">
+Test that version updates in sync databases work correctly.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/empty-statement-sync-expected.txt b/LayoutTests/fast/workers/storage/empty-statement-sync-expected.txt
new file mode 100644 (file)
index 0000000..bbb2f9e
--- /dev/null
@@ -0,0 +1,4 @@
+This test tries to execute an empty statement.
+PASS: result is null
+PASS
+
diff --git a/LayoutTests/fast/workers/storage/empty-statement-sync.html b/LayoutTests/fast/workers/storage/empty-statement-sync.html
new file mode 100644 (file)
index 0000000..2174e6f
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/empty-statement-sync.js')">
+This test tries to execute an empty statement.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/execute-sql-args-sync-expected.txt b/LayoutTests/fast/workers/storage/execute-sql-args-sync-expected.txt
new file mode 100644 (file)
index 0000000..b33b45a
--- /dev/null
@@ -0,0 +1,20 @@
+Test various inputs to executeSql().
+PASS: executeSql("") did not throw an exception.
+PASS: executeSql("", null) did not throw an exception.
+PASS: executeSql("", undefined) did not throw an exception.
+PASS: executeSql("", []) did not throw an exception.
+PASS: executeSql("", [ "arg0" ]) did not throw an exception.
+PASS: executeSql("", { }) did not throw an exception.
+PASS: executeSql("", { length: 0 }) did not throw an exception.
+PASS: executeSql("", { length: 1, 0: "arg0" }) did not throw an exception.
+PASS: executeSql() threw an exception as expected.
+PASS: executeSql(null) threw an exception as expected.
+PASS: executeSql(undefined) threw an exception as expected.
+PASS: executeSql(0) threw an exception as expected.
+PASS: executeSql(throwOnToStringObject) threw an exception as expected.
+PASS: executeSql("", throwOnGetLengthObject) threw an exception as expected.
+PASS: executeSql("", throwOnGetZeroObject) threw an exception as expected.
+PASS: executeSql("", [ throwOnToStringObject ]) threw an exception as expected.
+PASS: executeSql("", 0) threw an exception as expected.
+PASS: executeSql("", "") threw an exception as expected.
+
diff --git a/LayoutTests/fast/workers/storage/execute-sql-args-sync.html b/LayoutTests/fast/workers/storage/execute-sql-args-sync.html
new file mode 100644 (file)
index 0000000..8b2176c
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/execute-sql-args-sync.js')">
+Test various inputs to executeSql().
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync-expected.txt b/LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync-expected.txt
new file mode 100644 (file)
index 0000000..bff901f
--- /dev/null
@@ -0,0 +1,10 @@
+Test that executeSql() accepts only one statement.
+PASS: INSERT INTO Test VALUES (1)
+PASS: INSERT INTO Test VALUES (2);
+PASS:    INSERT INTO Test VALUES (3)    
+PASS:    INSERT INTO Test VALUES (4);   
+PASS: INSERT INTO Test VALUES (5)   ;
+PASS: INSERT INTO Test VALUES (6); garbage
+PASS: INSERT INTO Test VALUES (7); INSERT INTO Test VALUES (8)
+PASS:   INSERT INTO Test VALUES (9);   INSERT INTO Test VALUES (10);   
+
diff --git a/LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync.html b/LayoutTests/fast/workers/storage/executesql-accepts-only-one-statement-sync.html
new file mode 100644 (file)
index 0000000..716e9fd
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/executesql-accepts-only-one-statement-sync.js')">
+Test that executeSql() accepts only one statement.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync-expected.txt b/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync-expected.txt
new file mode 100644 (file)
index 0000000..869f1bb
--- /dev/null
@@ -0,0 +1,3 @@
+Test that executing multiple transactions on different handles to the same database doesn't cause deadlocks.
+PASS
+
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync.html b/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-sync.html
new file mode 100644 (file)
index 0000000..b080a51
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/multiple-transactions-on-different-handles-sync.js')">
+Test that executing multiple transactions on different handles to the same database doesn't cause deadlocks.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/open-database-creation-callback-sync-expected.txt b/LayoutTests/fast/workers/storage/open-database-creation-callback-sync-expected.txt
new file mode 100644 (file)
index 0000000..7d08215
--- /dev/null
@@ -0,0 +1,5 @@
+This test tests openDatabaseSync()'s creation callback.
+PASS: Creation callback was called.
+PASS: Version set to empty string as expected.
+PASS: An exception was thrown and db1Fail is null as expected.
+
diff --git a/LayoutTests/fast/workers/storage/open-database-creation-callback-sync.html b/LayoutTests/fast/workers/storage/open-database-creation-callback-sync.html
new file mode 100644 (file)
index 0000000..7e583a6
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/open-database-creation-callback-sync.js')">
+This test tests openDatabaseSync()'s creation callback.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/open-database-empty-version-sync-expected.txt b/LayoutTests/fast/workers/storage/open-database-empty-version-sync-expected.txt
new file mode 100644 (file)
index 0000000..4d4d479
--- /dev/null
@@ -0,0 +1,3 @@
+Test that no exception is thrown when the database is opened with an empty version.
+PASS
+
diff --git a/LayoutTests/fast/workers/storage/open-database-empty-version-sync.html b/LayoutTests/fast/workers/storage/open-database-empty-version-sync.html
new file mode 100644 (file)
index 0000000..c6f1f43
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/open-database-empty-version-sync.js')">
+Test that no exception is thrown when the database is opened with an empty version.
+<pre id="console">
+</pre>
+</body>
+</html>
@@ -4,7 +4,7 @@
 <script src="resources/test-inputs-common.js"></script>
 </head>
 
-<body onload="runTest('resources/open-database-sync-inputs.js')">
+<body onload="runTest('resources/open-database-inputs-sync.js')">
 This test makes sure that openDatabaseSync() accepts only valid parameters.
 <pre id="console">
 </pre>
diff --git a/LayoutTests/fast/workers/storage/open-database-set-empty-version-sync-expected.txt b/LayoutTests/fast/workers/storage/open-database-set-empty-version-sync-expected.txt
new file mode 100644 (file)
index 0000000..833ef9a
--- /dev/null
@@ -0,0 +1,3 @@
+This tests that calling openDatabase with an empty version string sets the current version of that database to the empty string and subsequent attempts to open the database with a different expected version throw an exception.
+PASS
+
diff --git a/LayoutTests/fast/workers/storage/open-database-set-empty-version-sync.html b/LayoutTests/fast/workers/storage/open-database-set-empty-version-sync.html
new file mode 100644 (file)
index 0000000..5a716af
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/open-database-set-empty-version-sync.js')">
+This tests that calling openDatabase with an empty version string sets the current version of that database to the empty string and subsequent attempts to open the database with a different expected version throw an exception.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync-expected.txt b/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync-expected.txt
new file mode 100644 (file)
index 0000000..b2da76b
--- /dev/null
@@ -0,0 +1,3 @@
+Test that a second handle to the same database can be opened inside a transaction running on the first handle.
+PASS: second handle opened successfully.
+
diff --git a/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync.html b/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-sync.html
new file mode 100644 (file)
index 0000000..08bd396
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/open-database-while-transaction-in-progress-sync.js')">
+Test that a second handle to the same database can be opened inside a transaction running on the first handle.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/resources/change-version-handle-reuse-sync.js b/LayoutTests/fast/workers/storage/resources/change-version-handle-reuse-sync.js
new file mode 100644 (file)
index 0000000..3733094
--- /dev/null
@@ -0,0 +1,29 @@
+var db = null;
+try {
+    var dbName = "ChangeVersionHandleReuseTest" + (new Date()).getTime();
+    db = openDatabaseSync(dbName, "", "Test that the DB handle is valid after changing the version.", 1);
+    var version = db.version;
+    var newVersion = version ? (parseInt(version) + 1).toString() : "1";
+    db.changeVersion(version, newVersion, function(tx) {
+        postMessage("PASS: changeVersion() transaction callback was called.");
+    });
+} catch (err) {
+    postMessage("FAIL: changeVersion() threw an exception: " + err);
+}
+
+try {
+    db.transaction(function(tx) {
+        try {
+            tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo INT)");
+            tx.executeSql("SELECT * from Test");
+            postMessage("PASS: No exception thrown while executing statements.");
+        } catch (err) {
+            postMessage("FAIL: An exception was thrown while executing statements: " + err);
+        }
+    });
+    postMessage("PASS: No exception thrown while running a transaction.");
+} catch (err) {
+    postMessage("FAIL: An exception was thrown while running a transaction: " + err);
+}
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/change-version-sync-1.js b/LayoutTests/fast/workers/storage/resources/change-version-sync-1.js
new file mode 100644 (file)
index 0000000..8ce92c2
--- /dev/null
@@ -0,0 +1,50 @@
+var EXPECTED_VERSION_AFTER_HIXIE_TEST = "2";
+var EXPECTED_VERSION_AFTER_RELOAD = "3";
+
+function emptyFunction() { }
+
+var db1 = openDatabaseSync("ChangeVersionTest", "1", "Test for the database.changeVersion() function", 1);
+var db2 = openDatabaseSync("ChangeVersionTest", "1", "Test for the database.changeVersion() function", 1);
+
+// First run Hixie's test to ensure basic changeVersion() functionality works (see bug 28418).
+db1.changeVersion("1", EXPECTED_VERSION_AFTER_HIXIE_TEST, emptyFunction);
+if (db2.version != db1.version) {
+    postMessage("FAIL: changing db1's version (" + db1.version + ") did not change db2's version (" + db2.version + ") as expected.");
+    postMessage("fail");
+} else
+    postMessage("PASS: changing db1's version (" + db1.version + ") changed db2's version too.");
+
+db2.transaction(function(tx) {
+    try {
+        tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo INT)");
+        postMessage("FAIL: The DB version changed, executing any statement on db2 should fail.");
+        postMessage("fail");
+    } catch(err) {
+      postMessage("PASS: Executing a statement on db2 threw an exception as expected.");
+    }
+});
+
+// Make sure any new handle to the same DB sees the new version
+try {
+    var db3 = openDatabaseSync("ChangeVersionTest", EXPECTED_VERSION_AFTER_HIXIE_TEST, "", 1);
+    postMessage("PASS: Successfully opened a new DB handle.");
+} catch (err) {
+    postMessage("FAIL: Unexpected exception thrown while trying to open a new DB handle: " + err);
+    postMessage("fail");
+}
+
+if (db1.version != db3.version) {
+    postMessage("FAIL: db1.version (" + db1.version + ") does not match db3.version(" + db3.version +")");
+    postMessage("fail");
+} else
+    postMessage("PASS: db1.version (" + db1.version + ") matches db3.version.");
+
+// Now try a test to ensure the version persists after reloading (see bug 27836)
+db1.changeVersion(EXPECTED_VERSION_AFTER_HIXIE_TEST, EXPECTED_VERSION_AFTER_RELOAD,
+                  function(tx) {
+                      tx.executeSql("DROP TABLE IF EXISTS Info");
+                      tx.executeSql("CREATE TABLE IF NOT EXISTS Info (Version INTEGER)");
+                      tx.executeSql("INSERT INTO Info VALUES (?)", [EXPECTED_VERSION_AFTER_RELOAD]);
+                  });
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/change-version-sync-2.js b/LayoutTests/fast/workers/storage/resources/change-version-sync-2.js
new file mode 100644 (file)
index 0000000..ca82e90
--- /dev/null
@@ -0,0 +1,12 @@
+var EXPECTED_VERSION_AFTER_RELOAD = '3';
+
+var db = openDatabaseSync("ChangeVersionTest", "", "Test the changeVersion() function.", 1);
+if (db.version == EXPECTED_VERSION_AFTER_RELOAD)
+    postMessage("PASS: db.version is " + EXPECTED_VERSION_AFTER_RELOAD + " as expected.");
+else
+    postMessage("FAIL: db.version is " + db.version + "; expected " + EXPECTED_VERSION_AFTER_RELOAD);
+
+// Reset the version; otherwise this test will fail the next time it's run
+db.changeVersion(db.version, "1", function(tx) { });
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/empty-statement-sync.js b/LayoutTests/fast/workers/storage/resources/empty-statement-sync.js
new file mode 100644 (file)
index 0000000..0f45e34
--- /dev/null
@@ -0,0 +1,12 @@
+try {
+    var db = openDatabaseSync("EmptyStatementSync", "1.0", "Test an empty statement.", 1);
+    db.transaction(function(tx) {
+        var result = tx.executeSql("");
+        postMessage(result ? "FAIL: result is not null" : "PASS: result is null");
+    });
+    postMessage("PASS");
+} catch (err) {
+    postMessage("FAIL");
+}
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/execute-sql-args-sync.js b/LayoutTests/fast/workers/storage/resources/execute-sql-args-sync.js
new file mode 100644 (file)
index 0000000..aca97b3
--- /dev/null
@@ -0,0 +1,70 @@
+var throwOnToStringObject = { };
+throwOnToStringObject.toString = function () { throw "Cannot call toString on this object." };
+
+var throwOnGetLengthObject = { };
+throwOnGetLengthObject.__defineGetter__("length", function () { throw "Cannot get length of this object."; });
+
+var throwOnGetZeroObject = { length: 1 };
+throwOnGetZeroObject.__defineGetter__("0", function () { throw "Cannot get 0 property of this object."; });
+
+var expectNoException = [
+    '""',
+    '"", null',
+    '"", undefined',
+    '"", []',
+    '"", [ "arg0" ]',
+    '"", { }',
+    '"", { length: 0 }',
+    '"", { length: 1, 0: "arg0" }',
+];
+
+var expectException = [
+    '',
+    'null',
+    'undefined',
+    '0',
+    'throwOnToStringObject',
+    '"", throwOnGetLengthObject',
+    '"", throwOnGetZeroObject',
+    '"", [ throwOnToStringObject ]',
+    '"", 0',
+    '"", ""',
+];
+
+function tryExecuteSql(transaction, parameterList)
+{
+    try {
+        eval('transaction.executeSql(' + parameterList + ')');
+        return null;
+    } catch (exception) {
+        return exception;
+    }
+}
+
+function runTransactionTest(transaction, parameterList, expectException)
+{
+    var exception = tryExecuteSql(transaction, parameterList);
+    if (expectException) {
+        if (exception)
+            postMessage("PASS: executeSql(" + parameterList + ") threw an exception as expected.");
+        else
+            postMessage("FAIL: executeSql(" + parameterList + ") did not throw an exception.");
+    } else {
+        if (exception)
+            postMessage("FAIL: executeSql(" + parameterList + ") threw an exception: " + exception);
+        else
+            postMessage("PASS: executeSql(" + parameterList + ") did not throw an exception.");
+    }
+}
+
+function runTransactionTests(transaction)
+{
+    for (i in expectNoException)
+        runTransactionTest(transaction, expectNoException[i], false);
+    for (i in expectException)
+        runTransactionTest(transaction, expectException[i], true);
+}
+
+var db = openDatabaseSync("ExecuteSQLArgsTest", "1.0", "Test of handling of the arguments to SQLTransactionSync.executeSql", 1);
+db.transaction(runTransactionTests);
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/executesql-accepts-only-one-statement-sync.js b/LayoutTests/fast/workers/storage/resources/executesql-accepts-only-one-statement-sync.js
new file mode 100644 (file)
index 0000000..20aa595
--- /dev/null
@@ -0,0 +1,23 @@
+function executeStatement(tx, expectedToPass, statement)
+{
+    try {
+        tx.executeSql(statement);
+        postMessage(expectedToPass ? "PASS: " + statement : "FAIL: " + statement);
+    } catch (err) {
+        postMessage(!expectedToPass ? "PASS: " + statement : "FAIL: " + statement);
+    }
+}
+
+var db = openDatabaseSync("ExecuteSQLAcceptsOnlyOneStatementTest", "1.0", "", 1);
+db.transaction(function(tx) {
+    tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo INT)");
+    executeStatement(tx, true, "INSERT INTO Test VALUES (1)");
+    executeStatement(tx, true, "INSERT INTO Test VALUES (2);");
+    executeStatement(tx, true, "   INSERT INTO Test VALUES (3)    ");
+    executeStatement(tx, true, "   INSERT INTO Test VALUES (4);   ");
+    executeStatement(tx, true, "INSERT INTO Test VALUES (5)   ;");
+    executeStatement(tx, false, "INSERT INTO Test VALUES (6); garbage");
+    executeStatement(tx, false, "INSERT INTO Test VALUES (7); INSERT INTO Test VALUES (8)");
+    executeStatement(tx, false, "  INSERT INTO Test VALUES (9);   INSERT INTO Test VALUES (10);   ");
+});
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/multiple-transactions-on-different-handles-sync.js b/LayoutTests/fast/workers/storage/resources/multiple-transactions-on-different-handles-sync.js
new file mode 100644 (file)
index 0000000..f08e449
--- /dev/null
@@ -0,0 +1,32 @@
+function runTransaction(db)
+{
+    db.transaction(function(tx) {
+       // Execute a read-only statement
+       tx.executeSql("SELECT COUNT(*) FROM Test;");
+
+       // Execute a write statement to make sure SQLite tries to acquire an exclusive lock on the DB file
+       tx.executeSql("INSERT INTO Test VALUES (?);", [1]);
+    });
+}
+
+var db1 = openDatabaseSync("MultipleTransactionsOnDifferentHandlesTest", "1.0",
+                           "Test transactions on different handles to the same DB.", 1);
+db1.transaction(function(tx) {
+    tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo int);");
+});
+
+var db2 = openDatabaseSync("MultipleTransactionsOnDifferentHandlesTest", "1.0",
+                           "Test transactions on different handles to the same DB.", 1);
+if (db1 == db2)
+    postMessage("FAIL: db1 == db2");
+else {
+    try {
+        runTransaction(db1);
+        runTransaction(db2);
+        postMessage("PASS");
+    } catch (err) {
+        postMessage("FAIL: " + err);
+    }
+}
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/multiple-transactions-sync.js b/LayoutTests/fast/workers/storage/resources/multiple-transactions-sync.js
new file mode 100644 (file)
index 0000000..85cdabc
--- /dev/null
@@ -0,0 +1,32 @@
+var complete = 0;
+
+function checkCompletion()
+{
+    if (++complete == 2 && window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function runTest()
+{
+    var db = openDatabaseWithSuffix("MultipleTransactionsTest", "1.0", "Test to make sure multiple transactions can be queued at once for an HTML5 database", 32768);
+
+    db.transaction(function(tx) {
+        log("Transaction 1 Started");
+    }, function(err) {
+        log("Transaction 1 Errored - " + err);
+        checkCompletion();
+    }, function() {
+        log("Transaction 1 Succeeded");
+        checkCompletion();
+    });
+
+    db.transaction(function(tx) {
+        log("Transaction 2 Started");
+    }, function(err) {
+        log("Transaction 2 Errored - " + err);
+        checkCompletion();
+    }, function() {
+        log("Transaction 2 Succeeded");
+        checkCompletion();
+    });
+}
diff --git a/LayoutTests/fast/workers/storage/resources/open-database-creation-callback-sync.js b/LayoutTests/fast/workers/storage/resources/open-database-creation-callback-sync.js
new file mode 100644 (file)
index 0000000..70ad676
--- /dev/null
@@ -0,0 +1,29 @@
+var creationCallbackCalled1 = false;
+var db1Name = "OpenDatabaseCreationCallback1" + (new Date()).getTime();
+var db2Name = "OpenDatabaseCreationCallback2" + (new Date()).getTime();
+var db1 = openDatabaseSync(db1Name, "1.0", "", 1,
+                           function(db) {
+                               postMessage("PASS: Creation callback was called.");
+                               if (db.version != "")
+                                   postMessage("FAIL: Wrong version " + db.version + "; empty string expected.");
+                               else
+                                   postMessage("PASS: Version set to empty string as expected.");
+                           });
+
+var db1Fail = null;
+try {
+    db1Fail = openDatabaseSync(db1Name, "1.0", "", 1);
+    postMessage("FAIL: An INVALID_STATE_ERR exception should've been thrown.");
+} catch(err) {
+    if (db1Fail)
+        postMessage("FAIL: db1Fail should have been null.");
+    else
+        postMessage("PASS: An exception was thrown and db1Fail is null as expected.");
+}
+
+// Open a handle to another database, first without a creation callback, then with one.
+// Make sure the creation callback is not called.
+var db2 = openDatabaseSync(db2Name, "1.0", "", 1);
+db2 = openDatabaseSync(db2Name, "1.0", "", 1, function(db) { postMessage("FAIL: Creation callback should not have been called."); });
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/open-database-empty-version-sync.js b/LayoutTests/fast/workers/storage/resources/open-database-empty-version-sync.js
new file mode 100644 (file)
index 0000000..fab21ab
--- /dev/null
@@ -0,0 +1,7 @@
+try {
+    var db = openDatabaseSync("OpenDatabaseEmptyVersionTest", "", "Test that we can open databases with an empty version.", 1);
+    postMessage("PASS");
+} catch (err) {
+    postMessage("FAIL: " + err);
+}
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/open-database-set-empty-version-sync.js b/LayoutTests/fast/workers/storage/resources/open-database-set-empty-version-sync.js
new file mode 100644 (file)
index 0000000..77727f8
--- /dev/null
@@ -0,0 +1,9 @@
+var db = openDatabaseSync("OpenDatabaseSetEmptyVersionTest", "", "Test that the DB version is set to the empty string.", 1);
+
+try {
+    var db2 = openDatabaseSync("OpenDatabaseSetEmptyVersionTest", "test", "Test that the DB version is set to the empty string.", 1);
+    postMessage("FAIL: An exception should've been thrown.");
+} catch (err) {
+    postMessage("PASS");
+}
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/open-database-while-transaction-in-progress-sync.js b/LayoutTests/fast/workers/storage/resources/open-database-while-transaction-in-progress-sync.js
new file mode 100644 (file)
index 0000000..ee4241f
--- /dev/null
@@ -0,0 +1,28 @@
+function openTestDatabase()
+{
+    return openDatabaseSync("OpenDatabaseWhileTransactionInProgressTest",
+                            "1.0",
+                            "Test to make sure that calling openDatabase() while a transaction is in progress on a different handle to the same database does not result in a deadlock.",
+                            2100000); // 2MB + epsilon
+}
+
+// See https://bugs.webkit.org/show_bug.cgi?id=28207
+// In order to trigger this bug, the transaction must acquire an exclusive
+// lock on the DB file before trying to obtain a second handle to the same DB.
+// The only way to force SQLite to obtain an exclusive lock is to change more
+// than cache_size * page_size bytes in the database. The default value for
+// cache_size is 2000 pages, and the default page_size is 1024 bytes. So the
+// size of the blob must be at least 2MB.
+var db1 = openTestDatabase();
+db1.transaction(function(tx) {
+    tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo BLOB);");
+    tx.executeSql("INSERT INTO Test VALUES (ZEROBLOB(2097152));");
+    var db2 = openTestDatabase();
+    postMessage("PASS: second handle opened successfully.");
+
+    // Clean up the DB to allow for repeated runs of this test
+    // without needing to increase the default allowed quota (5MB)
+    tx.executeSql("DELETE FROM Test;");
+});
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/sql-data-types-sync.js b/LayoutTests/fast/workers/storage/resources/sql-data-types-sync.js
new file mode 100644 (file)
index 0000000..b088792
--- /dev/null
@@ -0,0 +1,36 @@
+var testValues = {
+    timestamp: new Date("Wed Feb 06 2008 12:16:52 GMT+0200 (EET)").valueOf(),
+    id: 1001,
+    real: 101.444,
+    text: "WebKit db TEXT",
+    blob: "supercalifragilistic"
+};
+
+function shouldBeSameTypeAndValue(propName, testValue, result) {
+    if (testValue == result && typeof testValue == typeof result)
+        postMessage("PASS: property '" + propName + "' OK, type was " + typeof result);
+    else
+        postMessage("FAIL: property '" + propName + "' failed; " +
+                    "expected " + typeof testValue + ":'" + testValue + "', " +
+                    "got " + typeof result + ":'" + result +"'");
+}
+
+function testDBValues(result) {
+    var i = "timestamp"; shouldBeSameTypeAndValue(i, testValues[i], result[i]);
+    i = "id"; shouldBeSameTypeAndValue(i, testValues[i], result[i]);
+    i = "real"; shouldBeSameTypeAndValue(i, testValues[i], result[i]);
+    i = "text"; shouldBeSameTypeAndValue(i, testValues[i], result[i]);
+    i = "blob"; shouldBeSameTypeAndValue(i, testValues[i], result[i]);
+}
+
+var db = openDatabaseSync("SQLDataTypesTest", "1.0", "Database for SQL data type test", 1);
+db.transaction(function(tx) {
+    tx.executeSql("CREATE TABLE IF NOT EXISTS DataTypeTestTable (id INTEGER UNIQUE, real REAL, timestamp INTEGER, text TEXT, blob BLOB)");
+    tx.executeSql("INSERT INTO DataTypeTestTable (id, real, timestamp, text, blob) VALUES (?,?,?,?,?)",
+                  [testValues.id, testValues.real, testValues.timestamp, testValues.text, testValues.blob]);
+    var result = tx.executeSql("SELECT * FROM DataTypeTestTable");
+    testDBValues(result.rows.item(0));
+    tx.executeSql("DROP TABLE DataTypeTestTable");
+});
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/sql-exception-codes-sync.js b/LayoutTests/fast/workers/storage/resources/sql-exception-codes-sync.js
new file mode 100644 (file)
index 0000000..d9e4b1a
--- /dev/null
@@ -0,0 +1,86 @@
+var dbName = "SQLExceptionCodesTest" + (new Date()).getTime();
+
+function testTransaction(db, executeStatementsCallback, expectedErrorCodeName)
+{
+    db.transaction(function(tx) {
+        try {
+            executeStatementsCallback(tx);
+            postMessage("FAIL: an exception (" + expectedErrorCodeName + ") should've been thrown.");
+        } catch (err) {
+            if (err.code == err[expectedErrorCodeName])
+                postMessage("PASS: expected and got error code " + expectedErrorCodeName);
+            else
+                postMessage("FAIL: expected error code " + expectedErrorCodeName + " (" +
+                            err[expectedErrorCodeName] + "), got " + err.code);
+        }
+      });
+}
+
+function testTransactionThrowsException(db)
+{
+    testTransaction(db, function(tx) { throw "Exception thrown in transaction callback."; }, "UNKNOWN_ERR");
+}
+
+function testInvalidStatement(db)
+{
+    testTransaction(db, function(tx) { tx.executeSql("BAD STATEMENT"); }, "SYNTAX_ERR");
+}
+
+function testIncorrectNumberOfBindParameters(db)
+{
+    testTransaction(db,
+                    function(tx) {
+                        tx.executeSql("CREATE TABLE IF NOT EXISTS BadBindNumberTest (Foo INT, Bar INT)");
+                        tx.executeSql("INSERT INTO BadBindNumberTest VALUES (?, ?)", [1]);
+                    }, "SYNTAX_ERR");
+}
+
+function testBindParameterOfWrongType(db)
+{
+    var badString = { };
+    badString.toString = function() { throw "Cannot call toString() on this object." };
+
+    testTransaction(db, function(tx) {
+        tx.executeSql("CREATE TABLE IF NOT EXISTS BadBindTypeTest (Foo TEXT)");
+        tx.executeSql("INSERT INTO BadBindTypeTest VALUES (?)", [badString]);
+    }, "UNKNOWN_ERR");
+}
+
+function testQuotaExceeded(db)
+{
+    // Sometimes, SQLite automatically rolls back a transaction if executing a statement fails.
+    // This seems to be one of those cases.
+    try {
+        testTransaction(db,
+                        function(tx) {
+                            tx.executeSql("CREATE TABLE IF NOT EXISTS QuotaTest (Foo BLOB)");
+                            tx.executeSql("INSERT INTO QuotaTest VALUES (ZEROBLOB(10 * 1024 * 1024))");
+                        }, "QUOTA_ERR");
+        postMessage("FAIL: Transaction should've been rolled back by SQLite.");
+    } catch (err) {
+        if (err.code == err["DATABASE_ERR"])
+            postMessage("PASS: Transaction was rolled back by SQLite as expected.");
+        else
+            postMessage("FAIL: An unexpected exception was thrown: " + err);
+    }
+}
+
+function testVersionMismatch(db)
+{
+    var db2 = openDatabaseSync(dbName, "1.0", "Tests the error codes.", 1);
+    db2.changeVersion("1.0", "2.0", function(tx) { });
+    testTransaction(db,
+                    function(tx) {
+                        tx.executeSql("THIS STATEMENT SHOULD NEVER GET EXECUTED");
+                    }, "VERSION_ERR");
+}
+
+var db = openDatabaseSync(dbName, "1.0", "Tests the exception codes.", 1);
+testTransactionThrowsException(db);
+testInvalidStatement(db);
+testIncorrectNumberOfBindParameters(db);
+testBindParameterOfWrongType(db);
+testQuotaExceeded(db);
+testVersionMismatch(db);
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/test-authorizer-sync.js b/LayoutTests/fast/workers/storage/resources/test-authorizer-sync.js
new file mode 100644 (file)
index 0000000..73584c0
--- /dev/null
@@ -0,0 +1,126 @@
+function cleanup(db)
+{
+    db.transaction(function(tx) {
+            tx.executeSql("DROP TABLE IF EXISTS Test");
+            tx.executeSql("DROP INDEX IF EXISTS TestIndex");
+            tx.executeSql("DROP VIEW IF EXISTS TestView");
+            tx.executeSql("DROP TRIGGER IF EXISTS TestTrigger");
+    });
+}
+
+function executeStatement(tx, statement, operation)
+{
+    try {
+        tx.executeSql(statement);
+        postMessage(operation + " statement succeeded.");
+    } catch (err) {
+        postMessage(operation + " statement failed: " + err + " (" + err.code + ")");
+    }
+}
+
+function createTableCallback(tx)
+{
+    executeStatement(tx, "CREATE TABLE Test (Foo int)", "SQLITE_CREATE_TABLE");
+}
+
+function createStatementsCallback(tx)
+{
+    executeStatement(tx, "CREATE INDEX TestIndex ON Test (Foo)", "SQLITE_CREATE_INDEX");
+
+    // Even though the following query should trigger a SQLITE_CREATE_TEMP_INDEX operation
+    // (according to http://www.sqlite.org/tempfiles.html), it doesn't, and I'm not aware
+    // of any other way to trigger this operation. So we'll skip it for now.
+    //executeStatement(tx, "SELECT * FROM Test WHERE Foo IN (1, 2, 3)", "SQLITE_CREATE_TEMP_INDEX");
+
+    executeStatement(tx, "CREATE TEMP TABLE TestTempTable (Foo int)", "SQLITE_CREATE_TEMP_TABLE");
+    executeStatement(tx, "CREATE TEMP TRIGGER TestTempTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END", "SQLITE_CREATE_TEMP_TRIGGER");
+    executeStatement(tx, "CREATE TEMP VIEW TestTempView AS SELECT COUNT(*) FROM Test", "SQLITE_CREATE_TEMP_VIEW");
+    executeStatement(tx, "CREATE TRIGGER TestTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END", "SQLITE_CREATE_TRIGGER");
+    executeStatement(tx, "CREATE VIEW TestView AS SELECT COUNT(*) FROM Test", "SQLITE_CREATE_VIEW");
+
+    // We should try to create a virtual table using fts3, when WebKit's sqlite library supports it.
+    executeStatement(tx, "CREATE VIRTUAL TABLE TestVirtualTable USING UnsupportedModule", "SQLITE_CREATE_VTABLE");
+}
+
+function otherStatementsCallback(tx)
+{
+    executeStatement(tx, "SELECT COUNT(*) FROM Test", "SQLITE_READ");
+    executeStatement(tx, "SELECT COUNT(*) FROM Test", "SQLITE_SELECT");
+    executeStatement(tx, "DELETE FROM Test", "SQLITE_DELETE");
+    executeStatement(tx, "INSERT INTO Test VALUES (1)", "SQLITE_INSERT");
+    executeStatement(tx, "UPDATE Test SET Foo = 2 WHERE Foo = 1", "SQLITE_UPDATE");
+    executeStatement(tx, "PRAGMA cache_size", "SQLITE_PRAGMA");
+
+    executeStatement(tx, "ALTER TABLE Test RENAME TO TestTable", "SQLITE_ALTER_TABLE");
+    // Rename the table back to its original name
+    executeStatement(tx, "ALTER TABLE TestTable RENAME To Test", "SQLITE_ALTER_TABLE");
+
+    executeStatement(tx, "BEGIN TRANSACTION", "SQLITE_TRANSACTION");
+    executeStatement(tx, "ATTACH main AS TestMain", "SQLITE_ATTACH");
+    executeStatement(tx, "DETACH TestMain", "SQLITE_DETACH");
+    executeStatement(tx, "REINDEX", "SQLITE_REINDEX");
+    executeStatement(tx, "ANALYZE", "SQLITE_ANALYZE");
+
+    // SQLITE_FUNCTION: allowed in write mode
+    // There is no SQL/Javascript API to add user-defined functions to SQLite,
+    // so we cannot test this operation
+}
+
+function dropStatementsCallback(tx)
+{
+    executeStatement(tx, "DROP INDEX TestIndex", "SQLITE_DROP_INDEX");
+
+    // SQLITE_DROP_TEMP_INDEX: allowed in write mode
+    // Not sure how to test this: temp indexes are automatically dropped when
+    // the database is closed, but HTML5 doesn't specify a closeDatabase() call.
+
+    executeStatement(tx, "DROP TABLE TestTempTable", "SQLITE_DROP_TEMP_TABLE");
+    executeStatement(tx, "DROP TRIGGER TestTempTrigger", "SQLITE_DROP_TEMP_TRIGGER");
+    executeStatement(tx, "DROP VIEW TestTempView", "SQLITE_DROP_TEMP_VIEW");
+    executeStatement(tx, "DROP TRIGGER TestTrigger", "SQLITE_DROP_TRIGGER");
+    executeStatement(tx, "DROP VIEW TestView", "SQLITE_DROP_VIEW");
+
+    // SQLITE_DROP_VTABLE: allowed in write mode
+    // Not sure how to test this: we cannot create a virtual table because we do not
+    // have SQL/Javascript APIs to register a module that implements a virtual table.
+    // Therefore, trying to drop a virtual table will always fail (no such table)
+    // before even getting to the authorizer.
+
+    executeStatement(tx, "DROP TABLE Test", "SQLITE_DROP_TABLE");
+}
+
+function testReadWriteMode(db)
+{
+    db.transaction(function(tx) {
+        postMessage("Beginning write transaction:");
+        createTableCallback(tx);
+        createStatementsCallback(tx);
+        otherStatementsCallback(tx);
+        dropStatementsCallback(tx);
+        postMessage("Write transaction succeeded.\n");
+    });
+}
+
+function testReadOnlyMode(db)
+{
+    postMessage("Beginning read transactions:");
+    // Test the 'CREATE TABLE' operation; it should be disallowed
+    db.readTransaction(createTableCallback);
+
+    // In order to test all other 'CREATE' operations, we must create the table first
+    db.transaction(createTableCallback);
+    db.readTransaction(createStatementsCallback);
+
+    // In order to test the 'DROP' and 'other' operations, we need to first create the respective entities
+    db.transaction(createStatementsCallback);
+    db.readTransaction(otherStatementsCallback);
+    db.readTransaction(dropStatementsCallback);
+    postMessage("Read transactions succeeded.");
+}
+
+var db = openDatabaseSync("TestAuthorizerTest", "1.0", "Test the database authorizer.", 1);
+cleanup(db);
+testReadWriteMode(db);
+testReadOnlyMode(db);
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/resources/transaction-in-transaction-sync.js b/LayoutTests/fast/workers/storage/resources/transaction-in-transaction-sync.js
new file mode 100644 (file)
index 0000000..81e14f6
--- /dev/null
@@ -0,0 +1,11 @@
+var db = openDatabaseSync("TransactionInTransactionTest", "1.0", "Test that trying to run a nested transaction fails.", 1);
+db.transaction(function(tx) {
+    try {
+        db.transaction(function(nestedTx) { });
+        postMessage("FAIL: Trying to run a nested transaction should throw an exception.");
+    } catch (err) {
+        postMessage("PASS: Exception thrown while trying to run a nested transaction.");
+    }
+});
+
+postMessage("done");
diff --git a/LayoutTests/fast/workers/storage/sql-data-types-sync-expected.txt b/LayoutTests/fast/workers/storage/sql-data-types-sync-expected.txt
new file mode 100644 (file)
index 0000000..95b8db5
--- /dev/null
@@ -0,0 +1,7 @@
+Test that the values returned by DB queries are of the same type as the values inserted in the database.
+PASS: property 'timestamp' OK, type was number
+PASS: property 'id' OK, type was number
+PASS: property 'real' OK, type was number
+PASS: property 'text' OK, type was string
+PASS: property 'blob' OK, type was string
+
diff --git a/LayoutTests/fast/workers/storage/sql-data-types-sync.html b/LayoutTests/fast/workers/storage/sql-data-types-sync.html
new file mode 100644 (file)
index 0000000..cd639f6
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/sql-data-types-sync.js')">
+Test that the values returned by DB queries are of the same type as the values inserted in the database.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/sql-exception-codes-sync-expected.txt b/LayoutTests/fast/workers/storage/sql-exception-codes-sync-expected.txt
new file mode 100644 (file)
index 0000000..6bdaa15
--- /dev/null
@@ -0,0 +1,9 @@
+Test that the correct exceptions are thrown in exceptional situations.
+PASS: expected and got error code UNKNOWN_ERR
+PASS: expected and got error code SYNTAX_ERR
+PASS: expected and got error code SYNTAX_ERR
+PASS: expected and got error code UNKNOWN_ERR
+PASS: expected and got error code QUOTA_ERR
+PASS: Transaction was rolled back by SQLite as expected.
+PASS: expected and got error code VERSION_ERR
+
diff --git a/LayoutTests/fast/workers/storage/sql-exception-codes-sync.html b/LayoutTests/fast/workers/storage/sql-exception-codes-sync.html
new file mode 100644 (file)
index 0000000..2cb4901
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/sql-exception-codes-sync.js')">
+Test that the correct exceptions are thrown in exceptional situations.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/test-authorizer-sync-expected.txt b/LayoutTests/fast/workers/storage/test-authorizer-sync-expected.txt
new file mode 100644 (file)
index 0000000..a06c780
--- /dev/null
@@ -0,0 +1,71 @@
+Test the database authorizer.
+Beginning write transaction:
+SQLITE_CREATE_TABLE statement succeeded.
+SQLITE_CREATE_INDEX statement succeeded.
+SQLITE_CREATE_TEMP_TABLE statement succeeded.
+SQLITE_CREATE_TEMP_TRIGGER statement succeeded.
+SQLITE_CREATE_TEMP_VIEW statement succeeded.
+SQLITE_CREATE_TRIGGER statement succeeded.
+SQLITE_CREATE_VIEW statement succeeded.
+SQLITE_CREATE_VTABLE statement failed: [object SQLException] (5)
+SQLITE_READ statement succeeded.
+SQLITE_SELECT statement succeeded.
+SQLITE_DELETE statement succeeded.
+SQLITE_INSERT statement succeeded.
+SQLITE_UPDATE statement succeeded.
+SQLITE_PRAGMA statement failed: [object SQLException] (5)
+SQLITE_ALTER_TABLE statement succeeded.
+SQLITE_ALTER_TABLE statement succeeded.
+SQLITE_TRANSACTION statement failed: [object SQLException] (5)
+SQLITE_ATTACH statement failed: [object SQLException] (5)
+SQLITE_DETACH statement failed: [object SQLException] (5)
+SQLITE_REINDEX statement succeeded.
+SQLITE_ANALYZE statement failed: [object SQLException] (5)
+SQLITE_DROP_INDEX statement succeeded.
+SQLITE_DROP_TEMP_TABLE statement succeeded.
+SQLITE_DROP_TEMP_TRIGGER statement succeeded.
+SQLITE_DROP_TEMP_VIEW statement succeeded.
+SQLITE_DROP_TRIGGER statement succeeded.
+SQLITE_DROP_VIEW statement succeeded.
+SQLITE_DROP_TABLE statement succeeded.
+Write transaction succeeded.
+
+Beginning read transactions:
+SQLITE_CREATE_TABLE statement failed: [object SQLException] (5)
+SQLITE_CREATE_TABLE statement succeeded.
+SQLITE_CREATE_INDEX statement failed: [object SQLException] (5)
+SQLITE_CREATE_TEMP_TABLE statement failed: [object SQLException] (5)
+SQLITE_CREATE_TEMP_TRIGGER statement failed: [object SQLException] (5)
+SQLITE_CREATE_TEMP_VIEW statement failed: [object SQLException] (5)
+SQLITE_CREATE_TRIGGER statement failed: [object SQLException] (5)
+SQLITE_CREATE_VIEW statement failed: [object SQLException] (5)
+SQLITE_CREATE_VTABLE statement failed: [object SQLException] (5)
+SQLITE_CREATE_INDEX statement succeeded.
+SQLITE_CREATE_TEMP_TABLE statement succeeded.
+SQLITE_CREATE_TEMP_TRIGGER statement succeeded.
+SQLITE_CREATE_TEMP_VIEW statement succeeded.
+SQLITE_CREATE_TRIGGER statement succeeded.
+SQLITE_CREATE_VIEW statement succeeded.
+SQLITE_CREATE_VTABLE statement failed: [object SQLException] (5)
+SQLITE_READ statement succeeded.
+SQLITE_SELECT statement succeeded.
+SQLITE_DELETE statement failed: [object SQLException] (5)
+SQLITE_INSERT statement failed: [object SQLException] (5)
+SQLITE_UPDATE statement failed: [object SQLException] (5)
+SQLITE_PRAGMA statement failed: [object SQLException] (5)
+SQLITE_ALTER_TABLE statement failed: [object SQLException] (5)
+SQLITE_ALTER_TABLE statement failed: [object SQLException] (5)
+SQLITE_TRANSACTION statement failed: [object SQLException] (5)
+SQLITE_ATTACH statement failed: [object SQLException] (5)
+SQLITE_DETACH statement failed: [object SQLException] (5)
+SQLITE_REINDEX statement failed: [object SQLException] (5)
+SQLITE_ANALYZE statement failed: [object SQLException] (5)
+SQLITE_DROP_INDEX statement failed: [object SQLException] (5)
+SQLITE_DROP_TEMP_TABLE statement failed: [object SQLException] (5)
+SQLITE_DROP_TEMP_TRIGGER statement failed: [object SQLException] (5)
+SQLITE_DROP_TEMP_VIEW statement failed: [object SQLException] (5)
+SQLITE_DROP_TRIGGER statement failed: [object SQLException] (5)
+SQLITE_DROP_VIEW statement failed: [object SQLException] (5)
+SQLITE_DROP_TABLE statement failed: [object SQLException] (5)
+Read transactions succeeded.
+
diff --git a/LayoutTests/fast/workers/storage/test-authorizer-sync.html b/LayoutTests/fast/workers/storage/test-authorizer-sync.html
new file mode 100644 (file)
index 0000000..75622ed
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/test-authorizer-sync.js')">
+Test the database authorizer.
+<pre id="console">
+</pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/transaction-in-transaction-sync-expected.txt b/LayoutTests/fast/workers/storage/transaction-in-transaction-sync-expected.txt
new file mode 100644 (file)
index 0000000..f029aff
--- /dev/null
@@ -0,0 +1,3 @@
+Test that trying to run a transaction inside another transaction throws an exception.
+PASS: Exception thrown while trying to run a nested transaction.
+
diff --git a/LayoutTests/fast/workers/storage/transaction-in-transaction-sync.html b/LayoutTests/fast/workers/storage/transaction-in-transaction-sync.html
new file mode 100644 (file)
index 0000000..033ba1f
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script src="resources/test-inputs-common.js"></script>
+</head>
+
+<body onload="runTest('resources/transaction-in-transaction-sync.js')">
+Test that trying to run a transaction inside another transaction throws an exception.
+<pre id="console">
+</pre>
+</body>
+</html>
index 2a4f42e..8488c2c 100644 (file)
@@ -1428,6 +1428,7 @@ SET(WebCore_SOURCES
     storage/SQLResultSet.cpp
     storage/SQLResultSetRowList.cpp
     storage/SQLStatement.cpp
+    storage/SQLStatementSync.cpp
     storage/SQLTransaction.cpp
     storage/SQLTransactionClient.cpp
     storage/SQLTransactionCoordinator.cpp
index 326349b..54111c8 100644 (file)
@@ -1,3 +1,99 @@
+2010-07-13  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Darin Fisher
+
+        Implementing DatabaseSync::transaction() and DatabaseSync::changeVersion().
+        https://bugs.webkit.org/show_bug.cgi?id=40607
+
+        Tests: fast/workers/storage/change-version-handle-reuse-sync.html
+               fast/workers/storage/change-version-sync.html
+               fast/workers/storage/empty-statement-sync.html
+               fast/workers/storage/execute-sql-args-sync.html
+               fast/workers/storage/executesql-accepts-only-one-statement-sync.html
+               fast/workers/storage/multiple-transactions-on-different-handles-sync.html
+               fast/workers/storage/open-database-creation-callback-sync.html
+               fast/workers/storage/open-database-empty-version-sync.html
+               fast/workers/storage/open-database-inputs-sync.html
+               fast/workers/storage/open-database-set-empty-version-sync.html
+               fast/workers/storage/open-database-while-transaction-in-progress-sync.html
+               fast/workers/storage/sql-data-types-sync.html
+               fast/workers/storage/sql-exception-codes-sync.html
+               fast/workers/storage/test-authorizer-sync.html
+               fast/workers/storage/transaction-in-transaction-sync.html
+
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * storage/AbstractDatabase.cpp:
+        (WebCore::AbstractDatabase::maximumSize):
+        (WebCore::AbstractDatabase::incrementalVacuumIfNeeded):
+        * storage/AbstractDatabase.h:
+        (WebCore::AbstractDatabase::sqliteDatabase):
+        * storage/ChangeVersionWrapper.cpp:
+        (WebCore::ChangeVersionWrapper::performPreflight):
+        (WebCore::ChangeVersionWrapper::performPostflight):
+        * storage/Database.cpp:
+        (WebCore::Database::performGetTableNames):
+        * storage/Database.h:
+        * storage/DatabaseAuthorizer.cpp:
+        (WebCore::DatabaseAuthorizer::createVTable):
+        (WebCore::DatabaseAuthorizer::dropVTable):
+        * storage/DatabaseCallback.h:
+        * storage/DatabaseSync.cpp:
+        (WebCore::ChangeVersionPreflightStep::create):
+        (WebCore::ChangeVersionPreflightStep::performStep):
+        (WebCore::ChangeVersionPreflightStep::ChangeVersionPreflightStep):
+        (WebCore::ChangeVersionPostflightStep::create):
+        (WebCore::ChangeVersionPostflightStep::performStep):
+        (WebCore::ChangeVersionPostflightStep::ChangeVersionPostflightStep):
+        (WebCore::DatabaseSync::changeVersion):
+        (WebCore::DatabaseSync::transaction):
+        (WebCore::DatabaseSync::runTransaction):
+        * storage/DatabaseSync.h:
+        * storage/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::getMaxSizeForDatabase):
+        * storage/SQLError.h:
+        * storage/SQLResultSet.cpp:
+        * storage/SQLResultSet.h:
+        * storage/SQLStatementCallback.h:
+        * storage/SQLStatementErrorCallback.h:
+        * storage/SQLStatementSync.cpp: Copied from WebCore/storage/SQLStatement.cpp.
+        (WebCore::SQLStatementSync::SQLStatementSync):
+        (WebCore::SQLStatementSync::execute):
+        * storage/SQLStatementSync.h: Added.
+        * storage/SQLTransaction.cpp:
+        (WebCore::SQLTransaction::runCurrentStatement):
+        (WebCore::SQLTransaction::deliverQuotaIncreaseCallback):
+        (WebCore::SQLTransaction::postflightAndCommit):
+        * storage/SQLTransaction.h:
+        * storage/SQLTransactionCallback.h:
+        * storage/SQLTransactionClient.cpp:
+        (WebCore::SQLTransactionClient::didCommitWriteTransaction):
+        (WebCore::SQLTransactionClient::didExecuteStatement):
+        (WebCore::SQLTransactionClient::didExceedQuota):
+        * storage/SQLTransactionClient.h:
+        * storage/SQLTransactionErrorCallback.h:
+        * storage/SQLTransactionSync.cpp:
+        (WebCore::transactionClient):
+        (WebCore::SQLTransactionSync::create):
+        (WebCore::SQLTransactionSync::SQLTransactionSync):
+        (WebCore::SQLTransactionSync::~SQLTransactionSync):
+        (WebCore::SQLTransactionSync::executeSQL):
+        (WebCore::SQLTransactionSync::begin):
+        (WebCore::SQLTransactionSync::execute):
+        (WebCore::SQLTransactionSync::commit):
+        (WebCore::SQLTransactionSync::rollback):
+        * storage/SQLTransactionSync.h:
+        (WebCore::SQLTransactionSync::SQLTransactionSyncOptionalStep::~SQLTransactionSyncOptionalStep):
+        * storage/SQLTransactionSyncCallback.h:
+        * storage/chromium/SQLTransactionClientChromium.cpp:
+        (WebCore::SQLTransactionClient::didCommitWriteTransaction):
+        (WebCore::SQLTransactionClient::didExecuteStatement):
+        (WebCore::SQLTransactionClient::didExceedQuota):
+
 2010-07-13  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r63162.
index 7aa9142..92af51a 100644 (file)
@@ -2527,6 +2527,8 @@ webcore_sources += \
        WebCore/storage/SQLStatement.h \
        WebCore/storage/SQLStatementCallback.h \
        WebCore/storage/SQLStatementErrorCallback.h \
+       WebCore/storage/SQLStatementSync.cpp \
+       WebCore/storage/SQLStatementSync.h \
        WebCore/storage/SQLTransaction.cpp \
        WebCore/storage/SQLTransaction.h \
        WebCore/storage/SQLTransactionCallback.h \
index d62509b..9dbc80a 100644 (file)
             'storage/SQLStatement.h',
             'storage/SQLStatementCallback.h',
             'storage/SQLStatementErrorCallback.h',
+            'storage/SQLStatementSync.cpp',
+            'storage/SQLStatementSync.h',
             'storage/SQLTransaction.cpp',
             'storage/SQLTransaction.h',
             'storage/SQLTransactionCallback.h',
index 89d3ae7..3f94ca7 100644 (file)
@@ -2379,6 +2379,7 @@ contains(DEFINES, ENABLE_DATABASE=1) {
         storage/SQLResultSet.cpp \
         storage/SQLResultSetRowList.cpp \
         storage/SQLStatement.cpp \
+        storage/SQLStatementSync.cpp \
         storage/SQLTransaction.cpp \
         storage/SQLTransactionClient.cpp \
         storage/SQLTransactionCoordinator.cpp \
@@ -2457,6 +2458,7 @@ contains(DEFINES, ENABLE_DOM_STORAGE=1) {
         storage/SQLResultSet.h \
         storage/SQLResultSetRowList.h \
         storage/SQLStatement.h \
+        storage/SQLStatementSync.h \
         storage/SQLTransaction.h \
         storage/SQLTransactionClient.h \
         storage/SQLTransactionCoordinator.h \
index ba80b5c..c0473e9 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\storage\SQLStatementSync.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\storage\SQLStatementSync.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\storage\SQLTransaction.cpp"\r
                                >\r
                        </File>\r
index 8f3e754..adefe7f 100644 (file)
                B523CF0B1182675400EBB29C /* DatabaseSync.h in Headers */ = {isa = PBXBuildFile; fileRef = B523CF041182675400EBB29C /* DatabaseSync.h */; };
                B525A96511CA2340003A23A8 /* JSSQLException.h in Headers */ = {isa = PBXBuildFile; fileRef = B525A96311CA2340003A23A8 /* JSSQLException.h */; };
                B525A96611CA2340003A23A8 /* JSSQLException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B525A96411CA2340003A23A8 /* JSSQLException.cpp */; };
+               B550B52511DC68A800923885 /* SQLStatementSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B550B52111DC68A800923885 /* SQLStatementSync.cpp */; };
+               B550B52611DC68A800923885 /* SQLStatementSync.h in Headers */ = {isa = PBXBuildFile; fileRef = B550B52211DC68A800923885 /* SQLStatementSync.h */; };
                B55D5AA4119131FC00BCC315 /* JSSQLTransactionSyncCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B55D5AA2119131FC00BCC315 /* JSSQLTransactionSyncCallback.h */; };
                B55D5AA5119131FC00BCC315 /* JSSQLTransactionSyncCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B55D5AA3119131FC00BCC315 /* JSSQLTransactionSyncCallback.cpp */; };
                B55D5AA81191325000BCC315 /* JSDatabaseSyncCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B55D5AA61191325000BCC315 /* JSDatabaseSyncCustom.cpp */; };
                B523CF041182675400EBB29C /* DatabaseSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseSync.h; sourceTree = "<group>"; };
                B525A96311CA2340003A23A8 /* JSSQLException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLException.h; sourceTree = "<group>"; };
                B525A96411CA2340003A23A8 /* JSSQLException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLException.cpp; sourceTree = "<group>"; };
+               B550B52111DC68A800923885 /* SQLStatementSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLStatementSync.cpp; sourceTree = "<group>"; };
+               B550B52211DC68A800923885 /* SQLStatementSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLStatementSync.h; sourceTree = "<group>"; };
                B55D5AA2119131FC00BCC315 /* JSSQLTransactionSyncCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLTransactionSyncCallback.h; sourceTree = "<group>"; };
                B55D5AA3119131FC00BCC315 /* JSSQLTransactionSyncCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLTransactionSyncCallback.cpp; sourceTree = "<group>"; };
                B55D5AA61191325000BCC315 /* JSDatabaseSyncCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDatabaseSyncCustom.cpp; sourceTree = "<group>"; };
                                B59DD68E1190298E007E9684 /* SQLStatementCallback.idl */,
                                1A7CCB160CD9469A00B7B64E /* SQLStatementErrorCallback.h */,
                                B59DD68F1190298E007E9684 /* SQLStatementErrorCallback.idl */,
+                               B550B52111DC68A800923885 /* SQLStatementSync.cpp */,
+                               B550B52211DC68A800923885 /* SQLStatementSync.h */,
                                1ABFE7520CD968D000FE4834 /* SQLTransaction.cpp */,
                                1A7CCB220CD946FD00B7B64E /* SQLTransaction.h */,
                                1A7CCB230CD946FD00B7B64E /* SQLTransaction.idl */,
                                515B03990CD1642A00B7EA9C /* SQLStatement.h in Headers */,
                                1A7CCB190CD9469A00B7B64E /* SQLStatementCallback.h in Headers */,
                                1A7CCB1A0CD9469A00B7B64E /* SQLStatementErrorCallback.h in Headers */,
+                               B550B52611DC68A800923885 /* SQLStatementSync.h in Headers */,
                                1A7CCB240CD946FD00B7B64E /* SQLTransaction.h in Headers */,
                                1A7CCB1B0CD9469A00B7B64E /* SQLTransactionCallback.h in Headers */,
                                B51BF6F1102C9E590002C15A /* SQLTransactionClient.h in Headers */,
                                519611730CAC56570010A80C /* SQLResultSet.cpp in Sources */,
                                1AFE117D0CBFFB36003017FA /* SQLResultSetRowList.cpp in Sources */,
                                515B039A0CD1642A00B7EA9C /* SQLStatement.cpp in Sources */,
+                               B550B52511DC68A800923885 /* SQLStatementSync.cpp in Sources */,
                                1ABFE7530CD968D000FE4834 /* SQLTransaction.cpp in Sources */,
                                B51BF6F0102C9E590002C15A /* SQLTransactionClient.cpp in Sources */,
                                B5C1123B102B6C4600096578 /* SQLTransactionCoordinator.cpp in Sources */,
index ca9a1b5..bcc5d06 100644 (file)
@@ -32,7 +32,6 @@
 #if ENABLE(DATABASE)
 #include "DatabaseAuthorizer.h"
 #include "DatabaseTracker.h"
-#include "ExceptionCode.h"
 #include "Logging.h"
 #include "SQLiteStatement.h"
 #include "ScriptExecutionContext.h"
@@ -462,6 +461,19 @@ void AbstractDatabase::resetAuthorizer()
         m_databaseAuthorizer->reset();
 }
 
+unsigned long long AbstractDatabase::maximumSize() const
+{
+    return DatabaseTracker::tracker().getMaxSizeForDatabase(this);
+}
+
+void AbstractDatabase::incrementalVacuumIfNeeded()
+{
+    int64_t freeSpaceSize = m_sqliteDatabase.freeSpaceSize();
+    int64_t totalSize = m_sqliteDatabase.totalSize();
+    if (totalSize <= 10 * freeSpaceSize)
+        m_sqliteDatabase.runIncrementalVacuumCommand();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(DATABASE)
index d38a819..e302909 100644 (file)
@@ -31,6 +31,7 @@
 
 #if ENABLE(DATABASE)
 
+#include "ExceptionCode.h"
 #include "PlatformString.h"
 #include "SQLiteDatabase.h"
 #include <wtf/Forward.h>
@@ -45,8 +46,6 @@ class DatabaseAuthorizer;
 class ScriptExecutionContext;
 class SecurityOrigin;
 
-typedef int ExceptionCode;
-
 class AbstractDatabase : public ThreadSafeShared<AbstractDatabase> {
 public:
     static bool isAvailable();
@@ -65,6 +64,10 @@ public:
     virtual String displayName() const;
     virtual unsigned long estimatedSize() const;
     virtual String fileName() const;
+    SQLiteDatabase& sqliteDatabase() { return m_sqliteDatabase; }
+
+    unsigned long long maximumSize() const;
+    void incrementalVacuumIfNeeded();
 
     // FIXME: move all version-related methods to a DatabaseVersionTracker class
     bool versionMatchesExpected() const;
@@ -103,8 +106,6 @@ protected:
     unsigned long m_estimatedSize;
     String m_filename;
 
-    SQLiteDatabase m_sqliteDatabase;
-
 #ifndef NDEBUG
     String databaseDebugName() const { return m_contextThreadSecurityOrigin->toString() + "::" + m_name; }
 #endif
@@ -116,6 +117,8 @@ private:
     bool m_opened;
     bool m_new;
 
+    SQLiteDatabase m_sqliteDatabase;
+
     RefPtr<DatabaseAuthorizer> m_databaseAuthorizer;
 };
 
index 66ca63f..17be716 100644 (file)
@@ -50,13 +50,13 @@ bool ChangeVersionWrapper::performPreflight(SQLTransaction* transaction)
 
     if (!transaction->database()->getVersionFromDatabase(actualVersion)) {
         LOG_ERROR("Unable to retrieve actual current version from database");
-        m_sqlError = SQLError::create(0, "unable to verify current version of database");
+        m_sqlError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to verify current version of database");
         return false;
     }
 
     if (actualVersion != m_oldVersion) {
         LOG_ERROR("Old version doesn't match actual version");
-        m_sqlError = SQLError::create(2, "current version of the database and `oldVersion` argument do not match");
+        m_sqlError = SQLError::create(SQLError::VERSION_ERR, "current version of the database and `oldVersion` argument do not match");
         return false;
     }
 
@@ -69,7 +69,7 @@ bool ChangeVersionWrapper::performPostflight(SQLTransaction* transaction)
 
     if (!transaction->database()->setVersionInDatabase(m_newVersion)) {
         LOG_ERROR("Unable to set new version in database");
-        m_sqlError = SQLError::create(0, "unable to set new version in database");
+        m_sqlError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to set new version in database");
         return false;
     }
 
index 30087ee..19f582d 100644 (file)
@@ -36,7 +36,6 @@
 #include "DatabaseThread.h"
 #include "DatabaseTracker.h"
 #include "Document.h"
-#include "ExceptionCode.h"
 #include "InspectorController.h"
 #include "Logging.h"
 #include "NotImplemented.h"
@@ -336,7 +335,7 @@ Vector<String> Database::performGetTableNames()
 {
     disableAuthorizer();
 
-    SQLiteStatement statement(m_sqliteDatabase, "SELECT name FROM sqlite_master WHERE type='table';");
+    SQLiteStatement statement(sqliteDatabase(), "SELECT name FROM sqlite_master WHERE type='table';");
     if (statement.prepare() != SQLResultOk) {
         LOG_ERROR("Unable to retrieve list of tables for database %s", databaseDebugName().ascii().data());
         enableAuthorizer();
@@ -397,14 +396,6 @@ SecurityOrigin* Database::securityOrigin() const
     return 0;
 }
 
-void Database::incrementalVacuumIfNeeded()
-{
-    int64_t freeSpaceSize = m_sqliteDatabase.freeSpaceSize();
-    int64_t totalSize = m_sqliteDatabase.totalSize();
-    if (totalSize <= 10 * freeSpaceSize)
-        m_sqliteDatabase.runIncrementalVacuumCommand();
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(DATABASE)
index 22ef55e..e8482a7 100644 (file)
@@ -31,8 +31,8 @@
 
 #if ENABLE(DATABASE)
 #include "AbstractDatabase.h"
+#include "ExceptionCode.h"
 #include "PlatformString.h"
-#include "SQLiteDatabase.h"
 
 #include <wtf/Deque.h>
 #include <wtf/Forward.h>
@@ -66,7 +66,6 @@ public:
     Vector<String> tableNames();
 
     virtual SecurityOrigin* securityOrigin() const;
-    SQLiteDatabase& sqliteDatabase() { return m_sqliteDatabase; }
 
     virtual void markAsDeletedAndClose();
     bool deleted() const { return m_deleted; }
@@ -83,8 +82,6 @@ public:
     SQLTransactionClient* transactionClient() const;
     SQLTransactionCoordinator* transactionCoordinator() const;
 
-    void incrementalVacuumIfNeeded();
-
 private:
     class DatabaseOpenTask;
     class DatabaseCloseTask;
index d155d6c..17abebd 100644 (file)
@@ -290,7 +290,7 @@ int DatabaseAuthorizer::createVTable(const String& tableName, const String& modu
         return SQLAuthDeny;
 
     // Allow only the FTS3 extension
-    if (moduleName != "fts3")
+    if (!equalIgnoringCase(moduleName, "fts3"))
         return SQLAuthDeny;
 
     m_lastActionChangedDatabase = true;
@@ -303,7 +303,7 @@ int DatabaseAuthorizer::dropVTable(const String& tableName, const String& module
         return SQLAuthDeny;
 
     // Allow only the FTS3 extension
-    if (moduleName != "fts3")
+    if (!equalIgnoringCase(moduleName, "fts3"))
         return SQLAuthDeny;
 
     return updateDeletesBasedOnTableName(tableName);
index dfdc038..9ece2a3 100644 (file)
@@ -33,7 +33,7 @@
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
index 8de9680..f64c27f 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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"
@@ -32,8 +34,9 @@
 #if ENABLE(DATABASE)
 #include "DatabaseCallback.h"
 #include "DatabaseTracker.h"
-#include "ExceptionCode.h"
 #include "Logging.h"
+#include "SQLException.h"
+#include "SQLTransactionSync.h"
 #include "SQLTransactionSyncCallback.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
@@ -87,14 +90,56 @@ DatabaseSync::~DatabaseSync()
     }
 }
 
-void DatabaseSync::changeVersion(const String&, const String&, PassRefPtr<SQLTransactionSyncCallback>, ExceptionCode&)
+void DatabaseSync::changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<SQLTransactionSyncCallback> changeVersionCallback, ExceptionCode& ec)
 {
     ASSERT(m_scriptExecutionContext->isContextThread());
+
+    if (sqliteDatabase().transactionInProgress()) {
+        ec = SQLException::DATABASE_ERR;
+        return;
+    }
+
+    RefPtr<SQLTransactionSync> transaction = SQLTransactionSync::create(this, changeVersionCallback, false);
+    if ((ec = transaction->begin()))
+        return;
+
+    String actualVersion;
+    if (!getVersionFromDatabase(actualVersion)) {
+        ec = SQLException::UNKNOWN_ERR;
+        return;
+    }
+
+    if (actualVersion != oldVersion) {
+        ec = SQLException::VERSION_ERR;
+        return;
+    }
+
+    if ((ec = transaction->execute()))
+        return;
+
+    if (!setVersionInDatabase(newVersion)) {
+        ec = SQLException::UNKNOWN_ERR;
+        return;
+    }
+
+    if ((ec = transaction->commit()))
+        return;
+
+    setExpectedVersion(newVersion);
 }
 
-void DatabaseSync::transaction(PassRefPtr<SQLTransactionSyncCallback>, bool, ExceptionCode&)
+void DatabaseSync::transaction(PassRefPtr<SQLTransactionSyncCallback> callback, bool readOnly, ExceptionCode& ec)
 {
     ASSERT(m_scriptExecutionContext->isContextThread());
+
+    if (sqliteDatabase().transactionInProgress()) {
+        ec = SQLException::DATABASE_ERR;
+        return;
+    }
+
+    RefPtr<SQLTransactionSync> transaction = SQLTransactionSync::create(this, callback, readOnly);
+    if ((ec = transaction->begin()) || (ec = transaction->execute()) || (ec = transaction->commit()))
+        transaction->rollback();
 }
 
 void DatabaseSync::markAsDeletedAndClose()
index 96b4f7d..2019f85 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
 
 #ifndef DatabaseSync_h
@@ -31,6 +33,7 @@
 
 #if ENABLE(DATABASE)
 #include "AbstractDatabase.h"
+#include "ExceptionCode.h"
 #include "PlatformString.h"
 #include <wtf/Forward.h>
 #ifndef NDEBUG
@@ -40,6 +43,7 @@
 namespace WebCore {
 
 class DatabaseCallback;
+class SQLTransactionSync;
 class SQLTransactionSyncCallback;
 class ScriptExecutionContext;
 class SecurityOrigin;
index 29b87a7..30adf38 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
 
 module storage {
index 8d23a4f..de38ec3 100644 (file)
@@ -221,7 +221,6 @@ bool DatabaseTracker::hasEntryForDatabase(SecurityOrigin* origin, const String&
 
 unsigned long long DatabaseTracker::getMaxSizeForDatabase(const AbstractDatabase* database)
 {
-    ASSERT(currentThread() == database->scriptExecutionContext()->databaseThread()->getThreadID());
     // The maximum size for a database is the full quota for its origin, minus the current usage within the origin,
     // plus the current usage of the given database
     MutexLocker lockDatabase(m_databaseGuard);
index efbe4ec..496145a 100644 (file)
@@ -32,7 +32,7 @@
 #if ENABLE(DATABASE)
 
 #include "PlatformString.h"
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
index 19c66c7..7482628 100644 (file)
@@ -31,9 +31,6 @@
 
 #if ENABLE(DATABASE)
 
-#include "ExceptionCode.h"
-#include "SQLValue.h"
-
 namespace WebCore {
 
 static unsigned const MaxErrorCode = 2;
index 5a0ff78..268472f 100644 (file)
 
 #if ENABLE(DATABASE)
 
+#include "ExceptionCode.h"
 #include "SQLResultSetRowList.h"
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
-typedef int ExceptionCode;
-
 class SQLResultSet : public ThreadSafeShared<SQLResultSet> {
 public:
     static PassRefPtr<SQLResultSet> create() { return adoptRef(new SQLResultSet); }
index 68e7cb8..4bb2e06 100644 (file)
@@ -30,7 +30,7 @@
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
index 8db98be..7c45afd 100644 (file)
@@ -31,7 +31,7 @@
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
diff --git a/WebCore/storage/SQLStatementSync.cpp b/WebCore/storage/SQLStatementSync.cpp
new file mode 100644 (file)
index 0000000..7be3f50
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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 "SQLStatementSync.h"
+
+#if ENABLE(DATABASE)
+
+#include "DatabaseSync.h"
+#include "SQLException.h"
+#include "SQLResultSet.h"
+#include "SQLValue.h"
+#include "SQLiteDatabase.h"
+#include "SQLiteStatement.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+SQLStatementSync::SQLStatementSync(const String& statement, const Vector<SQLValue>& arguments, bool readOnly)
+    : m_statement(statement)
+    , m_arguments(arguments)
+    , m_readOnly(readOnly)
+{
+    ASSERT(!m_statement.isEmpty());
+}
+
+PassRefPtr<SQLResultSet> SQLStatementSync::execute(DatabaseSync* db, ExceptionCode& ec)
+{
+    if (m_readOnly)
+        db->setAuthorizerReadOnly();
+
+    SQLiteDatabase* database = &db->sqliteDatabase();
+
+    SQLiteStatement statement(*database, m_statement);
+    int result = statement.prepare();
+    if (result != SQLResultOk) {
+        ec = SQLException::SYNTAX_ERR;
+        return 0;
+    }
+
+    if (statement.bindParameterCount() != m_arguments.size()) {
+        ec = SQLException::SYNTAX_ERR;
+        return 0;
+    }
+
+    for (unsigned i = 0; i < m_arguments.size(); ++i) {
+        result = statement.bindValue(i + 1, m_arguments[i]);
+        if (result == SQLResultFull) {
+            ec = SQLException::QUOTA_ERR;
+            return 0;
+        }
+
+        if (result != SQLResultOk) {
+            ec = SQLException::DATABASE_ERR;
+            return 0;
+        }
+    }
+
+    RefPtr<SQLResultSet> resultSet = SQLResultSet::create();
+
+    // Step so we can fetch the column names.
+    result = statement.step();
+    if (result == SQLResultRow) {
+        int columnCount = statement.columnCount();
+        SQLResultSetRowList* rows = resultSet->rows();
+
+        for (int i = 0; i < columnCount; i++)
+            rows->addColumn(statement.getColumnName(i));
+
+        do {
+            for (int i = 0; i < columnCount; i++)
+                rows->addResult(statement.getColumnValue(i));
+
+            result = statement.step();
+        } while (result == SQLResultRow);
+
+        if (result != SQLResultDone) {
+            ec = SQLException::DATABASE_ERR;
+            return 0;
+        }
+    } else if (result == SQLResultDone) {
+        // Didn't find anything, or was an insert.
+        if (db->lastActionWasInsert())
+            resultSet->setInsertId(database->lastInsertRowID());
+    } else if (result == SQLResultFull) {
+        // Quota error, the delegate will be asked for more space and this statement might be re-run.
+        ec = SQLException::QUOTA_ERR;
+        return 0;
+    } else {
+        ec = SQLException::DATABASE_ERR;
+        return 0;
+    }
+
+    resultSet->setRowsAffected(database->lastChanges());
+    return resultSet.release();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/storage/SQLStatementSync.h b/WebCore/storage/SQLStatementSync.h
new file mode 100644 (file)
index 0000000..dc0394c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+#ifndef SQLStatementSync_h
+#define SQLStatementSync_h
+
+#if ENABLE(DATABASE)
+
+#include "ExceptionCode.h"
+#include "PlatformString.h"
+#include "SQLValue.h"
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class DatabaseSync;
+class SQLResultSet;
+
+class SQLStatementSync {
+public:
+    SQLStatementSync(const String& statement, const Vector<SQLValue>& arguments, bool readOnly);
+
+    PassRefPtr<SQLResultSet> execute(DatabaseSync*, ExceptionCode&);
+
+private:
+    String m_statement;
+    Vector<SQLValue> m_arguments;
+    bool m_readOnly;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
+
+#endif // SQLStatementSync_h
index 960427b..decdf24 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "Database.h"
 #include "DatabaseThread.h"
-#include "ExceptionCode.h"
 #include "Logging.h"
 #include "PlatformString.h"
 #include "ScriptExecutionContext.h"
@@ -370,7 +369,7 @@ bool SQLTransaction::runCurrentStatement()
             // Flag this transaction as having changed the database for later delegate notification
             m_modifiedDatabase = true;
             // Also dirty the size of this database file for calculating quota usage
-            m_database->transactionClient()->didExecuteStatement(this);
+            m_database->transactionClient()->didExecuteStatement(database());
         }
 
         if (m_currentStatement->hasStatementCallback()) {
@@ -432,7 +431,7 @@ void SQLTransaction::deliverQuotaIncreaseCallback()
     ASSERT(m_currentStatement);
     ASSERT(!m_shouldRetryCurrentStatement);
 
-    m_shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(this);
+    m_shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(database());
 
     m_nextStep = &SQLTransaction::runStatements;
     LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this);
@@ -472,7 +471,7 @@ void SQLTransaction::postflightAndCommit()
 
     // The commit was successful. If the transaction modified this database, notify the delegates.
     if (m_modifiedDatabase)
-        m_database->transactionClient()->didCommitTransaction(this);
+        m_database->transactionClient()->didCommitWriteTransaction(database());
 
     // Now release our unneeded callbacks, to break reference cycles.
     m_callback = 0;
index 3cef036..5c62ca2 100644 (file)
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
-
+#include "ExceptionCode.h"
 #include "SQLStatement.h"
 #include <wtf/Deque.h>
 #include <wtf/Forward.h>
+#include <wtf/ThreadSafeShared.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
-typedef int ExceptionCode;
-
 class Database;
 class SQLError;
 class SQLiteTransaction;
index 048410f..73123ee 100644 (file)
@@ -31,7 +31,7 @@
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
index 32c8e07..6b95606 100644 (file)
 
 #if ENABLE(DATABASE)
 
-#include "Chrome.h"
-#include "ChromeClient.h"
-#include "Database.h"
-#include "DatabaseThread.h"
+#include "AbstractDatabase.h"
 #include "DatabaseTracker.h"
-#include "Document.h"
-#include "Page.h"
-#include "SQLTransaction.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
 
 namespace WebCore {
 
-void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction)
+void SQLTransactionClient::didCommitWriteTransaction(AbstractDatabase* database)
 {
-    ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
-    Database* database = transaction->database();
     DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(
         database->securityOrigin(), database->stringIdentifier());
 }
 
-void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction)
+void SQLTransactionClient::didExecuteStatement(AbstractDatabase* database)
 {
-    ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
-    DatabaseTracker::tracker().databaseChanged(transaction->database());
+    DatabaseTracker::tracker().databaseChanged(database);
 }
 
-bool SQLTransactionClient::didExceedQuota(SQLTransaction* transaction)
+bool SQLTransactionClient::didExceedQuota(AbstractDatabase* database)
 {
-    ASSERT(transaction->database()->scriptExecutionContext()->isContextThread());
-    Database* database = transaction->database();
-
+    ASSERT(database->scriptExecutionContext()->isContextThread());
     unsigned long long currentQuota = DatabaseTracker::tracker().quotaForOrigin(database->securityOrigin());
     database->scriptExecutionContext()->databaseExceededQuota(database->stringIdentifier());
     unsigned long long newQuota = DatabaseTracker::tracker().quotaForOrigin(database->securityOrigin());
index 801647b..fed0657 100644 (file)
 
 namespace WebCore {
 
-    class SQLTransaction;
-
-    // A client to the SQLTransaction class. Allows SQLTransaction to notify interested
-    // parties that certain things have happened in a transaction.
-    class SQLTransactionClient : public Noncopyable {
-    public:
-        void didCommitTransaction(SQLTransaction*);
-        void didExecuteStatement(SQLTransaction*);
-        bool didExceedQuota(SQLTransaction*);
-    };
+class AbstractDatabase;
+
+// A client to the SQLTransaction class. Allows SQLTransaction to notify interested
+// parties that certain things have happened in a transaction.
+class SQLTransactionClient : public Noncopyable {
+public:
+    void didCommitWriteTransaction(AbstractDatabase*);
+    void didExecuteStatement(AbstractDatabase*);
+    bool didExceedQuota(AbstractDatabase*);
+};
+
 }
 
 #endif // ENABLE(DATABASE)
index 2fe2cb3..71580eb 100644 (file)
@@ -31,7 +31,7 @@
 
 #if ENABLE(DATABASE)
 
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
index 5e7c879..af98f8f 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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"
 #if ENABLE(DATABASE)
 
 #include "DatabaseSync.h"
-#include "ExceptionCode.h"
 #include "PlatformString.h"
+#include "SQLException.h"
 #include "SQLResultSet.h"
+#include "SQLStatementSync.h"
+#include "SQLTransactionClient.h"
 #include "SQLTransactionSyncCallback.h"
 #include "SQLValue.h"
+#include "SQLiteTransaction.h"
 #include "ScriptExecutionContext.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
@@ -52,22 +57,150 @@ SQLTransactionSync::SQLTransactionSync(DatabaseSync* db, PassRefPtr<SQLTransacti
     : m_database(db)
     , m_callback(callback)
     , m_readOnly(readOnly)
+    , m_modifiedDatabase(false)
+    , m_transactionClient(new SQLTransactionClient())
 {
     ASSERT(m_database->scriptExecutionContext()->isContextThread());
-    ASSERT(callback);
 }
 
 SQLTransactionSync::~SQLTransactionSync()
 {
     ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    if (m_sqliteTransaction && m_sqliteTransaction->inProgress())
+        rollback();
 }
 
-PassRefPtr<SQLResultSet> SQLTransactionSync::executeSQL(const String&, const Vector<SQLValue>&, ExceptionCode&)
+PassRefPtr<SQLResultSet> SQLTransactionSync::executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, ExceptionCode& ec)
 {
     ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    if (!m_database->opened()) {
+        ec = SQLException::UNKNOWN_ERR;
+        return 0;
+    }
+
+    if (!m_database->versionMatchesExpected()) {
+        ec = SQLException::VERSION_ERR;
+        return 0;
+    }
+
+    if (sqlStatement.isEmpty())
+        return 0;
+
+    bool readOnlyMode = m_readOnly || m_database->scriptExecutionContext()->isDatabaseReadOnly();
+    SQLStatementSync statement(sqlStatement, arguments, readOnlyMode);
+
+    m_database->resetAuthorizer();
+    bool retryStatement = true;
+    RefPtr<SQLResultSet> resultSet;
+    while (retryStatement) {
+        retryStatement = false;
+        resultSet = statement.execute(m_database.get(), ec);
+        if (!resultSet) {
+            if (m_sqliteTransaction->wasRolledBackBySqlite())
+                return 0;
+
+            if (ec == SQLException::QUOTA_ERR) {
+                if (m_transactionClient->didExceedQuota(database())) {
+                    ec = 0;
+                    retryStatement = true;
+                } else
+                    return 0;
+            }
+        }
+    }
+
+    if (m_database->lastActionChangedDatabase()) {
+        m_modifiedDatabase = true;
+        m_transactionClient->didExecuteStatement(database());
+    }
+
+    return resultSet.release();
+}
+
+ExceptionCode SQLTransactionSync::begin()
+{
+    ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    if (!m_database->opened())
+        return SQLException::UNKNOWN_ERR;
+
+    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
+
+    // Set the maximum usage for this transaction if this transactions is not read-only.
+    if (!m_readOnly)
+        m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
+
+    ASSERT(!m_sqliteTransaction);
+    m_sqliteTransaction.set(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
+
+    m_database->resetDeletes();
+    m_database->disableAuthorizer();
+    m_sqliteTransaction->begin();
+    m_database->enableAuthorizer();
+
+    // Check if begin() succeeded.
+    if (!m_sqliteTransaction->inProgress()) {
+        ASSERT(!m_database->sqliteDatabase().transactionInProgress());
+        m_sqliteTransaction.clear();
+        return SQLException::DATABASE_ERR;
+    }
+
+    return 0;
+}
+
+ExceptionCode SQLTransactionSync::execute()
+{
+    ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    if (!m_database->opened() || !m_callback || !m_callback->handleEvent(m_database->scriptExecutionContext(), this)) {
+        m_callback = 0;
+        return SQLException::UNKNOWN_ERR;
+    }
+
+    m_callback = 0;
+    return 0;
+}
+
+ExceptionCode SQLTransactionSync::commit()
+{
+    ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    if (!m_database->opened())
+        return SQLException::UNKNOWN_ERR;
+
+    ASSERT(m_sqliteTransaction);
+
+    m_database->disableAuthorizer();
+    m_sqliteTransaction->commit();
+    m_database->enableAuthorizer();
+
+    // If the commit failed, the transaction will still be marked as "in progress"
+    if (m_sqliteTransaction->inProgress())
+        return SQLException::DATABASE_ERR;
+
+    m_sqliteTransaction.clear();
+
+    // Vacuum the database if anything was deleted.
+    if (m_database->hadDeletes())
+        m_database->incrementalVacuumIfNeeded();
+
+    // The commit was successful. If the transaction modified this database, notify the delegates.
+    if (m_modifiedDatabase)
+        m_transactionClient->didCommitWriteTransaction(database());
+
     return 0;
 }
 
+void SQLTransactionSync::rollback()
+{
+    ASSERT(m_database->scriptExecutionContext()->isContextThread());
+    m_database->disableAuthorizer();
+    if (m_sqliteTransaction) {
+        m_sqliteTransaction->rollback();
+        m_sqliteTransaction.clear();
+    }
+    m_database->enableAuthorizer();
+
+    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(DATABASE)
index 7c03927..025215b 100644 (file)
@@ -2,46 +2,50 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
+
 #ifndef SQLTransactionSync_h
 #define SQLTransactionSync_h
 
 #if ENABLE(DATABASE)
 
+#include "ExceptionCode.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
-typedef int ExceptionCode;
-
 class DatabaseSync;
 class SQLResultSet;
+class SQLTransactionClient;
 class SQLTransactionSyncCallback;
 class SQLValue;
+class SQLiteTransaction;
 class String;
 
 // Instances of this class should be created and used only on the worker's context thread.
@@ -56,12 +60,21 @@ public:
     DatabaseSync* database() { return m_database.get(); }
     bool isReadOnly() const { return m_readOnly; }
 
+    ExceptionCode begin();
+    ExceptionCode execute();
+    ExceptionCode commit();
+    void rollback();
+
 private:
     SQLTransactionSync(DatabaseSync*, PassRefPtr<SQLTransactionSyncCallback>, bool readOnly);
 
     RefPtr<DatabaseSync> m_database;
     RefPtr<SQLTransactionSyncCallback> m_callback;
     bool m_readOnly;
+
+    bool m_modifiedDatabase;
+    OwnPtr<SQLTransactionClient> m_transactionClient;
+    OwnPtr<SQLiteTransaction> m_sqliteTransaction;
 };
 
 } // namespace WebCore
index a4002b1..003a21d 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
 
 module storage {
index eba82b0..557db86 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
- *Transaction
- * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * 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.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
 
 #ifndef SQLTransactionSyncCallback_h
@@ -32,7 +34,6 @@
 #if ENABLE(DATABASE)
 
 #include <wtf/RefCounted.h>
-#include <wtf/Threading.h>
 
 namespace WebCore {
 
index 1bff22b..b0fffca 100644 (file)
@@ -2,28 +2,30 @@
  * Copyright (C) 2010 Google 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:
+ * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
  */
 
 module storage {
index a10ca3e..22d95e6 100644 (file)
 #include "config.h"
 #include "SQLTransactionClient.h"
 
-#include "Database.h"
+#include "AbstractDatabase.h"
 #include "DatabaseObserver.h"
-#include "DatabaseThread.h"
-#include "Document.h"
-#include "SQLTransaction.h"
-#include <wtf/MainThread.h>
+#include "ScriptExecutionContext.h"
 
 namespace WebCore {
 
 class NotifyDatabaseChangedTask : public ScriptExecutionContext::Task {
 public:
-    static PassOwnPtr<NotifyDatabaseChangedTask> create(Database *database)
+    static PassOwnPtr<NotifyDatabaseChangedTask> create(AbstractDatabase *database)
     {
         return new NotifyDatabaseChangedTask(database);
     }
@@ -53,34 +50,35 @@ public:
     }
 
 private:
-    NotifyDatabaseChangedTask(PassRefPtr<Database> database)
+    NotifyDatabaseChangedTask(PassRefPtr<AbstractDatabase> database)
         : m_database(database)
     {
     }
 
-    RefPtr<Database> m_database;
+    RefPtr<AbstractDatabase> m_database;
 };
 
-void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction)
+void SQLTransactionClient::didCommitWriteTransaction(AbstractDatabase* database)
 {
-    ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
-    if (!transaction->isReadOnly()) {
-        transaction->database()->scriptExecutionContext()->postTask(NotifyDatabaseChangedTask::create(transaction->database()));
+    if (!database->scriptExecutionContext()->isContextThread()) {
+        database->scriptExecutionContext()->postTask(NotifyDatabaseChangedTask::create(database));
+        return;
     }
+
+    WebCore::DatabaseObserver::databaseModified(database);
 }
 
-void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction)
+void SQLTransactionClient::didExecuteStatement(AbstractDatabase* database)
 {
     // This method is called after executing every statement that changes the DB.
     // Chromium doesn't need to do anything at that point.
-    ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
 }
 
-bool SQLTransactionClient::didExceedQuota(SQLTransaction* transaction)
+bool SQLTransactionClient::didExceedQuota(AbstractDatabase* database)
 {
     // Chromium does not allow users to manually change the quota for an origin (for now, at least).
     // Don't do anything.
-    ASSERT(transaction->database()->scriptExecutionContext()->isContextThread());
+    ASSERT(database->scriptExecutionContext()->isContextThread());
     return false;
 }