WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-46823-20100929190803.patch (text/plain), 157.43 KB, created by
Jeremy Orlow
on 2010-09-29 11:08:07 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jeremy Orlow
Created:
2010-09-29 11:08:07 PDT
Size:
157.43 KB
patch
obsolete
>diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 763eed8d8c1337a01ec9182d7b9862a03bf313e0..764ea3841a604748fafd8c4cb0dc3ba46f319d18 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2010-09-29 Jeremy Orlow <jorlow@chromium.org> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Finished IDBTransaction for IndexedDB >+ https://bugs.webkit.org/show_bug.cgi?id=46823 >+ >+ * storage/indexeddb/database-basics.html: >+ * storage/indexeddb/index-basics.html: >+ * storage/indexeddb/index-cursor.html: >+ * storage/indexeddb/objectstore-basics.html: >+ * storage/indexeddb/objectstore-cursor.html: >+ * storage/indexeddb/objectstore-removeobjectstore.html: >+ * storage/indexeddb/open-cursor.html: >+ * storage/indexeddb/transaction-basics.html: >+ > 2010-09-28 Csaba Osztrogonác <ossy@webkit.org> > > Unreviewed. >diff --git a/LayoutTests/storage/indexeddb/database-basics.html b/LayoutTests/storage/indexeddb/database-basics.html >index b099a491cabacb41821682899fa855b1b36a5bac..d1bef3bfb2076522881d189dcc3c3d18c11147b4 100644 >--- a/LayoutTests/storage/indexeddb/database-basics.html >+++ b/LayoutTests/storage/indexeddb/database-basics.html >@@ -14,11 +14,32 @@ description("Test the basics of IndexedDB's IDBDatabase."); > if (window.layoutTestController) > layoutTestController.waitUntilDone(); > >+function test() >+{ >+ result = evalAndLog("indexedDB.open('name', 'description')"); >+ verifyResult(result); >+ result.onsuccess = openSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ > function openSuccess() > { > verifySuccessEvent(event); >+ window.db = evalAndLog("db = event.result"); >+ >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); > >- var db = evalAndLog("db = event.result"); > deleteAllObjectStores(db); > > // We must do something asynchronous before anything synchronous since >@@ -70,14 +91,6 @@ function checkObjectStore() > done(); > } > >-function test() >-{ >- result = evalAndLog("indexedDB.open('name', 'description')"); >- verifyResult(result); >- result.onsuccess = openSuccess; >- result.onerror = unexpectedErrorCallback; >-} >- > test(); > > var successfullyParsed = true; >diff --git a/LayoutTests/storage/indexeddb/index-basics.html b/LayoutTests/storage/indexeddb/index-basics.html >index c23f14102a9134f8ed6411ab9753950d54f876aa..28f53bcfd293f354041b9c9f8ee9ffd66e929e94 100644 >--- a/LayoutTests/storage/indexeddb/index-basics.html >+++ b/LayoutTests/storage/indexeddb/index-basics.html >@@ -27,6 +27,19 @@ function createObjectStore() > verifySuccessEvent(event); > db = evalAndLog("db = event.result"); > >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > deleteAllObjectStores(db); > > result = evalAndLog("db.createObjectStore('storeName', null)"); >diff --git a/LayoutTests/storage/indexeddb/index-cursor.html b/LayoutTests/storage/indexeddb/index-cursor.html >index 9541d6006af186865dd2fd924ff4669122819d57..31a4ed96030c5b8d4b52d548747923c53ca3d527 100644 >--- a/LayoutTests/storage/indexeddb/index-cursor.html >+++ b/LayoutTests/storage/indexeddb/index-cursor.html >@@ -40,6 +40,19 @@ function openObjectStore() > verifySuccessEvent(event); > window.db = evalAndLog("db = event.result"); > >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > deleteAllObjectStores(db); > > result = evalAndLog("db.createObjectStore('someObjectStore')"); >@@ -105,7 +118,7 @@ function scheduleTests() > } > > debug("Running tests..."); >- setTimeout(runNextTest, 0); >+ runNextTest(); > } > > function runNextTest() >@@ -213,12 +226,12 @@ function cursorIteration() > { > if (expectedIndex === null) { > shouldBeNull("event.result"); >- setTimeout(runNextTest, 0); >+ runNextTest(); > return; > } > if (event.result === null) { >- testFailed("Event.result should not be null.") >- setTimeout(runNextTest, 0); >+ testFailed("Event.result should not be null."); >+ runNextTest(); > return; > } > >diff --git a/LayoutTests/storage/indexeddb/objectstore-basics.html b/LayoutTests/storage/indexeddb/objectstore-basics.html >index b2d383a1b9cfe5ad6fa659856b3676bfb23b857c..c2fe2f1ac102fd8f343140a3a7db7ddf348870eb 100644 >--- a/LayoutTests/storage/indexeddb/objectstore-basics.html >+++ b/LayoutTests/storage/indexeddb/objectstore-basics.html >@@ -26,7 +26,20 @@ function openSuccess() > { > debug("openSuccess():"); > verifySuccessEvent(event); >- db = evalAndLog("db = event.result"); >+ window.db = evalAndLog("db = event.result"); >+ >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); > > deleteAllObjectStores(db); > >diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor.html b/LayoutTests/storage/indexeddb/objectstore-cursor.html >index 25e9456c0e2d30b6ae37f12f84ac17ed13d4a657..c2480ed7f74d4a02b4fb796b010edfa02b2a7073 100644 >--- a/LayoutTests/storage/indexeddb/objectstore-cursor.html >+++ b/LayoutTests/storage/indexeddb/objectstore-cursor.html >@@ -39,6 +39,19 @@ function openObjectStore() > verifySuccessEvent(event); > window.db = evalAndLog("db = event.result"); > >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > deleteAllObjectStores(db); > > result = evalAndLog("db.createObjectStore('someObjectStore')"); >@@ -93,7 +106,7 @@ function scheduleTests() > } > > debug("Running tests..."); >- setTimeout(runNextTest, 0); >+ runNextTest(); > } > > function runNextTest() >@@ -182,12 +195,12 @@ function cursorIteration() > { > if (expectedIndex === null) { > shouldBeNull("event.result"); >- setTimeout(runNextTest, 0); >+ runNextTest(); > return; > } > if (event.result === null) { >- testFailed("Event.result should not be null.") >- setTimeout(runNextTest, 0); >+ testFailed("Event.result should not be null."); >+ runNextTest(); > return; > } > >diff --git a/LayoutTests/storage/indexeddb/objectstore-removeobjectstore.html b/LayoutTests/storage/indexeddb/objectstore-removeobjectstore.html >index 7878c7fae1a664529e022868fbfcf416bce2c887..f32b117e5e236d462f27900f6e573bb205246c69 100644 >--- a/LayoutTests/storage/indexeddb/objectstore-removeobjectstore.html >+++ b/LayoutTests/storage/indexeddb/objectstore-removeobjectstore.html >@@ -27,6 +27,19 @@ function createObjectStore() > verifySuccessEvent(event); > db = evalAndLog("db = event.result"); > >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > deleteAllObjectStores(db); > > result = evalAndLog("db.createObjectStore('storeName', null)"); >@@ -75,11 +88,24 @@ function commitTransaction() > verifySuccessEvent(event); > shouldBeTrue("event.source.indexNames.contains('indexName')"); > // Let the transaction commit. >- window.setTimeout('removeObjectStore()', 0); >+ window.setTimeout('secondSetVersion()', 0); >+} >+ >+function secondSetVersion() >+{ >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = removeObjectStore; >+ result.onerror = unexpectedErrorCallback; > } > > function removeObjectStore() > { >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > result = evalAndLog("db.removeObjectStore('storeName')"); > verifyResult(result); > result.onsuccess = createObjectStoreAgain; >diff --git a/LayoutTests/storage/indexeddb/open-cursor.html b/LayoutTests/storage/indexeddb/open-cursor.html >index 03d1da09962efd3e820f799d618b9fab072280b8..89996c6f866f6ca5e2ad5431c6129be43aa76892 100644 >--- a/LayoutTests/storage/indexeddb/open-cursor.html >+++ b/LayoutTests/storage/indexeddb/open-cursor.html >@@ -69,10 +69,12 @@ function createObjectStoreSuccess() > populateObjectStore(objectStore); > } > >-function openSuccess() >+function setVersionSuccess() > { >+ debug("setVersionSuccess():"); > verifySuccessEvent(event); >- var db = evalAndLog("db = event.result"); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); > > deleteAllObjectStores(db); > >@@ -82,6 +84,17 @@ function openSuccess() > result.onerror = unexpectedErrorCallback; > } > >+function openSuccess() >+{ >+ verifySuccessEvent(event); >+ var db = evalAndLog("db = event.result"); >+ >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ > function test() > { > result = evalAndLog("indexedDB.open('name', 'description')"); >diff --git a/LayoutTests/storage/indexeddb/transaction-basics.html b/LayoutTests/storage/indexeddb/transaction-basics.html >index cea5d5dcfcd00a008f40e5419df11d074db16d21..e5d5ae2ff89dc6c17870691e429a4eb83614d3f2 100644 >--- a/LayoutTests/storage/indexeddb/transaction-basics.html >+++ b/LayoutTests/storage/indexeddb/transaction-basics.html >@@ -31,6 +31,19 @@ function openSuccess() > verifySuccessEvent(event); > db = evalAndLog("db = event.result"); > >+ result = evalAndLog("db.setVersion('new version')"); >+ verifyResult(result); >+ result.onsuccess = setVersionSuccess; >+ result.onerror = unexpectedErrorCallback; >+} >+ >+function setVersionSuccess() >+{ >+ debug("setVersionSuccess():"); >+ verifySuccessEvent(event); >+ window.trans = evalAndLog("trans = event.result"); >+ shouldBeTrue("trans !== null"); >+ > deleteAllObjectStores(db); > > result = evalAndLog("db.createObjectStore('storeName', null)"); >diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog >index b7d118052922e3da9c8e5dd794051794b8426cdb..2797c84e74a55d561d585442968d7942914f5745 100644 >--- a/WebCore/ChangeLog >+++ b/WebCore/ChangeLog >@@ -1,3 +1,129 @@ >+2010-09-29 Jeremy Orlow <jorlow@chromium.org> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Finished IDBTransaction for IndexedDB >+ https://bugs.webkit.org/show_bug.cgi?id=46823 >+ >+ * bindings/js/JSIDBAnyCustom.cpp: >+ (WebCore::toJS): >+ * bindings/v8/IDBBindingUtilities.cpp: >+ (WebCore::LocalContext::LocalContext): >+ (WebCore::LocalContext::~LocalContext): >+ (WebCore::createIDBKeyFromSerializedValueAndKeyPath): >+ * bindings/v8/SerializedScriptValue.cpp: >+ (WebCore::SerializedScriptValue::release): >+ (WebCore::SerializedScriptValue::SerializedScriptValue): >+ * bindings/v8/SerializedScriptValue.h: >+ * bindings/v8/custom/V8IDBAnyCustom.cpp: >+ (WebCore::toV8): >+ * platform/CrossThreadCopier.cpp: >+ * storage/IDBAny.cpp: >+ (WebCore::IDBAny::idbFactory): >+ (WebCore::IDBAny::idbTransaction): >+ (WebCore::IDBAny::set): >+ * storage/IDBAny.h: >+ * storage/IDBCallbacks.h: >+ * storage/IDBCursor.cpp: >+ (WebCore::IDBCursor::IDBCursor): >+ (WebCore::IDBCursor::update): >+ (WebCore::IDBCursor::continueFunction): >+ (WebCore::IDBCursor::remove): >+ * storage/IDBCursor.h: >+ (WebCore::IDBCursor::create): >+ * storage/IDBCursorBackendImpl.cpp: >+ (WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl): >+ (WebCore::IDBCursorBackendImpl::update): >+ (WebCore::IDBCursorBackendImpl::updateInternal): >+ (WebCore::IDBCursorBackendImpl::continueFunction): >+ (WebCore::IDBCursorBackendImpl::continueFunctionInternal): >+ (WebCore::IDBCursorBackendImpl::remove): >+ (WebCore::IDBCursorBackendImpl::removeInternal): >+ * storage/IDBCursorBackendImpl.h: >+ (WebCore::IDBCursorBackendImpl::create): >+ * storage/IDBDatabase.cpp: >+ (WebCore::IDBDatabase::setSetVersionTransaction): >+ (WebCore::IDBDatabase::createObjectStore): >+ (WebCore::IDBDatabase::removeObjectStore): >+ (WebCore::IDBDatabase::setVersion): >+ (WebCore::IDBDatabase::close): >+ * storage/IDBDatabase.h: >+ * storage/IDBDatabase.idl: >+ * storage/IDBDatabaseBackendImpl.cpp: >+ (WebCore::IDBDatabaseBackendImpl::createObjectStore): >+ (WebCore::IDBDatabaseBackendImpl::createObjectStoreInternal): >+ (WebCore::IDBDatabaseBackendImpl::removeObjectStore): >+ (WebCore::IDBDatabaseBackendImpl::removeObjectStoreInternal): >+ (WebCore::IDBDatabaseBackendImpl::setVersion): >+ (WebCore::IDBDatabaseBackendImpl::setVersionInternal): >+ (WebCore::IDBDatabaseBackendImpl::close): >+ * storage/IDBDatabaseBackendImpl.h: >+ * storage/IDBDatabaseBackendInterface.h: >+ * storage/IDBFactory.cpp: >+ (WebCore::IDBFactory::open): >+ * storage/IDBIndex.cpp: >+ (WebCore::IDBIndex::IDBIndex): >+ (WebCore::IDBIndex::openObjectCursor): >+ (WebCore::IDBIndex::openCursor): >+ (WebCore::IDBIndex::getObject): >+ (WebCore::IDBIndex::get): >+ * storage/IDBIndex.h: >+ (WebCore::IDBIndex::create): >+ * storage/IDBIndexBackendImpl.cpp: >+ (WebCore::IDBIndexBackendImpl::openCursorInternal): >+ (WebCore::IDBIndexBackendImpl::openObjectCursor): >+ (WebCore::IDBIndexBackendImpl::openCursor): >+ (WebCore::IDBIndexBackendImpl::getInternal): >+ (WebCore::IDBIndexBackendImpl::getObject): >+ (WebCore::IDBIndexBackendImpl::get): >+ * storage/IDBIndexBackendImpl.h: >+ * storage/IDBIndexBackendInterface.h: >+ * storage/IDBKey.cpp: >+ (WebCore::IDBKey::IDBKey): >+ * storage/IDBKey.h: >+ * storage/IDBKeyRange.h: >+ * storage/IDBObjectStore.cpp: >+ (WebCore::IDBObjectStore::IDBObjectStore): >+ (WebCore::IDBObjectStore::add): >+ (WebCore::IDBObjectStore::put): >+ (WebCore::IDBObjectStore::remove): >+ (WebCore::IDBObjectStore::createIndex): >+ (WebCore::IDBObjectStore::index): >+ (WebCore::IDBObjectStore::removeIndex): >+ (WebCore::IDBObjectStore::openCursor): >+ * storage/IDBObjectStore.idl: >+ * storage/IDBObjectStoreBackendImpl.cpp: >+ (WebCore::IDBObjectStoreBackendImpl::get): >+ (WebCore::IDBObjectStoreBackendImpl::getInternal): >+ (WebCore::IDBObjectStoreBackendImpl::put): >+ (WebCore::IDBObjectStoreBackendImpl::putInternal): >+ (WebCore::IDBObjectStoreBackendImpl::remove): >+ (WebCore::IDBObjectStoreBackendImpl::removeInternal): >+ (WebCore::IDBObjectStoreBackendImpl::createIndex): >+ (WebCore::IDBObjectStoreBackendImpl::createIndexInternal): >+ (WebCore::IDBObjectStoreBackendImpl::removeIndex): >+ (WebCore::IDBObjectStoreBackendImpl::removeIndexInternal): >+ (WebCore::IDBObjectStoreBackendImpl::openCursor): >+ (WebCore::IDBObjectStoreBackendImpl::openCursorInternal): >+ * storage/IDBObjectStoreBackendImpl.h: >+ * storage/IDBObjectStoreBackendInterface.h: >+ * storage/IDBRequest.cpp: >+ (WebCore::IDBRequest::IDBRequest): >+ (WebCore::IDBRequest::resetReadyState): >+ (WebCore::IDBRequest::onSuccess): >+ (WebCore::IDBRequest::timerFired): >+ * storage/IDBRequest.h: >+ (WebCore::IDBRequest::create): >+ * storage/IDBTransactionBackendImpl.cpp: >+ (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl): >+ (WebCore::IDBTransactionBackendImpl::scheduleTask): >+ (WebCore::IDBTransactionBackendImpl::didCompleteTaskEvents): >+ (WebCore::IDBTransactionBackendImpl::run): >+ (WebCore::IDBTransactionBackendImpl::start): >+ (WebCore::IDBTransactionBackendImpl::commit): >+ (WebCore::IDBTransactionBackendImpl::timerFired): >+ * storage/IDBTransactionBackendImpl.h: >+ > 2010-09-28 Kent Tamura <tkent@chromium.org> > > Unreviewed, run sort-Xcode-project-file >diff --git a/WebCore/bindings/js/JSIDBAnyCustom.cpp b/WebCore/bindings/js/JSIDBAnyCustom.cpp >index e428bf66a2f4bca6dc7c3081129f69ccc3df3e6d..506f15f2cd5d10aef963331462e1f9d7c300411d 100644 >--- a/WebCore/bindings/js/JSIDBAnyCustom.cpp >+++ b/WebCore/bindings/js/JSIDBAnyCustom.cpp >@@ -44,6 +44,7 @@ > #include "JSIDBIndex.h" > #include "JSIDBKey.h" > #include "JSIDBObjectStore.h" >+#include "JSIDBTransaction.h" > #include "SerializedScriptValue.h" > > using namespace JSC; >@@ -64,14 +65,16 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, IDBAny* idbAny) > return toJS(exec, globalObject, idbAny->idbCursor()); > case IDBAny::IDBDatabaseType: > return toJS(exec, globalObject, idbAny->idbDatabase()); >+ case IDBAny::IDBFactoryType: >+ return toJS(exec, globalObject, idbAny->idbFactory()); > case IDBAny::IDBIndexType: > return toJS(exec, globalObject, idbAny->idbIndex()); > case IDBAny::IDBKeyType: > return toJS(exec, globalObject, idbAny->idbKey()); > case IDBAny::IDBObjectStoreType: > return toJS(exec, globalObject, idbAny->idbObjectStore()); >- case IDBAny::IDBFactoryType: >- return toJS(exec, globalObject, idbAny->idbFactory()); >+ case IDBAny::IDBTransactionType: >+ return toJS(exec, globalObject, idbAny->idbTransaction()); > case IDBAny::SerializedScriptValueType: > return idbAny->serializedScriptValue()->deserialize(exec, globalObject); > } >diff --git a/WebCore/bindings/v8/IDBBindingUtilities.cpp b/WebCore/bindings/v8/IDBBindingUtilities.cpp >index a000a7de119421195a9e0b7d92acfdfa1d5cc4d1..4a588537320a696dc5de5efcc9f400b4bf579c33 100644 >--- a/WebCore/bindings/v8/IDBBindingUtilities.cpp >+++ b/WebCore/bindings/v8/IDBBindingUtilities.cpp >@@ -58,9 +58,28 @@ bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value) > return true; > } > >+class LocalContext { >+public: >+ LocalContext() >+ : m_context(v8::Context::New()) >+ { >+ m_context->Enter(); >+ } >+ >+ ~LocalContext() >+ { >+ m_context->Exit(); >+ m_context.Dispose(); >+ } >+ >+private: >+ v8::HandleScope m_scope; >+ v8::Persistent<v8::Context> m_context; >+}; >+ > PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const Vector<IDBKeyPathElement>& keyPath) > { >- v8::HandleScope scope; >+ LocalContext localContext; > v8::Handle<v8::Value> v8Value(value->deserialize()); > for (size_t i = 0; i < keyPath.size(); ++i) { > switch (keyPath[i].type) { >diff --git a/WebCore/bindings/v8/SerializedScriptValue.cpp b/WebCore/bindings/v8/SerializedScriptValue.cpp >index 4e5354e980b4976a9dc3740a25a798409e83aebf..ff92167249a3bc8597161a53be28f6150b4983b4 100644 >--- a/WebCore/bindings/v8/SerializedScriptValue.cpp >+++ b/WebCore/bindings/v8/SerializedScriptValue.cpp >@@ -1105,7 +1105,7 @@ SerializedScriptValue* SerializedScriptValue::nullValue() > PassRefPtr<SerializedScriptValue> SerializedScriptValue::release() > { > RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data, WireData)); >- m_data = String(); >+ m_data = String().crossThreadString(); > return result.release(); > } > >@@ -1123,18 +1123,18 @@ SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& > didThrow = true; > return; > } >- m_data = StringImpl::adopt(writer.data()); >+ m_data = String(StringImpl::adopt(writer.data())).crossThreadString(); > } > > SerializedScriptValue::SerializedScriptValue(String data, StringDataMode mode) > { > if (mode == WireData) >- m_data = data; >+ m_data = data.crossThreadString(); > else { > ASSERT(mode == StringValue); > Writer writer; > writer.writeWebCoreString(data); >- m_data = StringImpl::adopt(writer.data()); >+ m_data = String(StringImpl::adopt(writer.data())).crossThreadString(); > } > } > >diff --git a/WebCore/bindings/v8/SerializedScriptValue.h b/WebCore/bindings/v8/SerializedScriptValue.h >index 275e5f2de5ca2d6babc4ca4592d2b798faecef55..b534a575d4f932bc9ee4785303d2937097e1508c 100644 >--- a/WebCore/bindings/v8/SerializedScriptValue.h >+++ b/WebCore/bindings/v8/SerializedScriptValue.h >@@ -33,11 +33,11 @@ > > #include "ScriptValue.h" > #include <v8.h> >-#include <wtf/RefCounted.h> >+#include <wtf/Threading.h> > > namespace WebCore { > >-class SerializedScriptValue : public RefCounted<SerializedScriptValue> { >+class SerializedScriptValue : public ThreadSafeShared<SerializedScriptValue> { > public: > static void deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName, > v8::PropertyAttribute, SerializedScriptValue*); >diff --git a/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp b/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp >index 3dffeb5a2f0ccc8ee4aa8cbd5c3103ec82b3c832..fd6f1a5fa091bab52e032b43b19a1ff7ca5961fa 100644 >--- a/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp >+++ b/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp >@@ -38,6 +38,7 @@ > #include "V8IDBIndex.h" > #include "V8IDBKey.h" > #include "V8IDBObjectStore.h" >+#include "V8IDBTransaction.h" > > namespace WebCore { > >@@ -55,14 +56,16 @@ v8::Handle<v8::Value> toV8(IDBAny* impl) > return toV8(impl->idbCursor()); > case IDBAny::IDBDatabaseType: > return toV8(impl->idbDatabase()); >+ case IDBAny::IDBFactoryType: >+ return toV8(impl->idbFactory()); > case IDBAny::IDBIndexType: > return toV8(impl->idbIndex()); > case IDBAny::IDBKeyType: > return toV8(impl->idbKey()); > case IDBAny::IDBObjectStoreType: > return toV8(impl->idbObjectStore()); >- case IDBAny::IDBFactoryType: >- return toV8(impl->idbFactory()); >+ case IDBAny::IDBTransactionType: >+ return toV8(impl->idbTransaction()); > case IDBAny::SerializedScriptValueType: > return impl->serializedScriptValue()->deserialize(); > } >diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp >index 683ba5436f26afef4ad0dc4a091a4e35d1eede8d..4280486c21176560be7498888ec6d2462ed78d87 100644 >--- a/WebCore/platform/CrossThreadCopier.cpp >+++ b/WebCore/platform/CrossThreadCopier.cpp >@@ -37,6 +37,7 @@ > #include "ResourceError.h" > #include "ResourceRequest.h" > #include "ResourceResponse.h" >+#include "SerializedScriptValue.h" > > namespace WebCore { > >diff --git a/WebCore/storage/IDBAny.cpp b/WebCore/storage/IDBAny.cpp >index 45b166d4220ca4ce3d5f42393d2c94bb30311aa2..3a049c018abb84b9a138e465cab9518e0e4293bd 100644 >--- a/WebCore/storage/IDBAny.cpp >+++ b/WebCore/storage/IDBAny.cpp >@@ -70,6 +70,12 @@ PassRefPtr<IDBDatabase> IDBAny::idbDatabase() > return m_idbDatabase; > } > >+PassRefPtr<IDBFactory> IDBAny::idbFactory() >+{ >+ ASSERT(m_type == IDBFactoryType); >+ return m_idbFactory; >+} >+ > PassRefPtr<IDBIndex> IDBAny::idbIndex() > { > ASSERT(m_type == IDBIndexType); >@@ -88,10 +94,10 @@ PassRefPtr<IDBObjectStore> IDBAny::idbObjectStore() > return m_idbObjectStore; > } > >-PassRefPtr<IDBFactory> IDBAny::idbFactory() >+PassRefPtr<IDBTransaction> IDBAny::idbTransaction() > { >- ASSERT(m_type == IDBFactoryType); >- return m_idbFactory; >+ ASSERT(m_type == IDBTransactionType); >+ return m_idbTransaction; > } > > PassRefPtr<SerializedScriptValue> IDBAny::serializedScriptValue() >@@ -120,6 +126,13 @@ void IDBAny::set(PassRefPtr<IDBDatabase> value) > m_idbDatabase = value; > } > >+void IDBAny::set(PassRefPtr<IDBFactory> value) >+{ >+ ASSERT(m_type == UndefinedType); >+ m_type = IDBFactoryType; >+ m_idbFactory = value; >+} >+ > void IDBAny::set(PassRefPtr<IDBIndex> value) > { > ASSERT(m_type == UndefinedType); >@@ -134,18 +147,18 @@ void IDBAny::set(PassRefPtr<IDBKey> value) > m_idbKey = value; > } > >-void IDBAny::set(PassRefPtr<IDBObjectStore> value) >+void IDBAny::set(PassRefPtr<IDBTransaction> value) > { > ASSERT(m_type == UndefinedType); >- m_type = IDBObjectStoreType; >- m_idbObjectStore = value; >+ m_type = IDBTransactionType; >+ m_idbTransaction = value; > } > >-void IDBAny::set(PassRefPtr<IDBFactory> value) >+void IDBAny::set(PassRefPtr<IDBObjectStore> value) > { > ASSERT(m_type == UndefinedType); >- m_type = IDBFactoryType; >- m_idbFactory = value; >+ m_type = IDBObjectStoreType; >+ m_idbObjectStore = value; > } > > void IDBAny::set(PassRefPtr<SerializedScriptValue> value) >diff --git a/WebCore/storage/IDBAny.h b/WebCore/storage/IDBAny.h >index 9066e13790777f4acb7c85009de9456e86fd835b..8e3f83e9dbe9f7ed0407b0e4933c598fb68e514f 100644 >--- a/WebCore/storage/IDBAny.h >+++ b/WebCore/storage/IDBAny.h >@@ -36,10 +36,11 @@ namespace WebCore { > > class IDBCursor; > class IDBDatabase; >+class IDBFactory; > class IDBIndex; > class IDBKey; > class IDBObjectStore; >-class IDBFactory; >+class IDBTransaction; > class SerializedScriptValue; > > class IDBAny : public RefCounted<IDBAny> { >@@ -71,6 +72,7 @@ public: > IDBIndexType, > IDBKeyType, > IDBObjectStoreType, >+ IDBTransactionType, > SerializedScriptValueType > }; > >@@ -82,6 +84,7 @@ public: > PassRefPtr<IDBIndex> idbIndex(); > PassRefPtr<IDBKey> idbKey(); > PassRefPtr<IDBObjectStore> idbObjectStore(); >+ PassRefPtr<IDBTransaction> idbTransaction(); > PassRefPtr<SerializedScriptValue> serializedScriptValue(); > > // Set can only be called once. >@@ -92,6 +95,7 @@ public: > void set(PassRefPtr<IDBIndex>); > void set(PassRefPtr<IDBKey>); > void set(PassRefPtr<IDBObjectStore>); >+ void set(PassRefPtr<IDBTransaction>); > void set(PassRefPtr<SerializedScriptValue>); > > private: >@@ -106,6 +110,7 @@ private: > RefPtr<IDBIndex> m_idbIndex; > RefPtr<IDBKey> m_idbKey; > RefPtr<IDBObjectStore> m_idbObjectStore; >+ RefPtr<IDBTransaction> m_idbTransaction; > RefPtr<SerializedScriptValue> m_serializedScriptValue; > }; > >diff --git a/WebCore/storage/IDBCallbacks.h b/WebCore/storage/IDBCallbacks.h >index bc48477c770bea63057036ebdfad7976a77d33ba..e62c085b91ef59cc05fe6a3aedd1ee1a0fc828cf 100644 >--- a/WebCore/storage/IDBCallbacks.h >+++ b/WebCore/storage/IDBCallbacks.h >@@ -35,14 +35,16 @@ > #include "IDBIndexBackendInterface.h" > #include "IDBKey.h" > #include "IDBObjectStoreBackendInterface.h" >+#include "IDBTransactionBackendInterface.h" > #include "SerializedScriptValue.h" >-#include <wtf/RefCounted.h> >+#include <wtf/Threading.h> > > #if ENABLE(INDEXED_DATABASE) > > namespace WebCore { > >-class IDBCallbacks : public RefCounted<IDBCallbacks> { >+// FIXME: All child classes need to be made threadsafe. >+class IDBCallbacks : public ThreadSafeShared<IDBCallbacks> { > public: > virtual ~IDBCallbacks() { } > >@@ -53,6 +55,7 @@ public: > virtual void onSuccess(PassRefPtr<IDBIndexBackendInterface>) = 0; > virtual void onSuccess(PassRefPtr<IDBKey>) = 0; > virtual void onSuccess(PassRefPtr<IDBObjectStoreBackendInterface>) = 0; >+ virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>) = 0; > virtual void onSuccess(PassRefPtr<SerializedScriptValue>) = 0; > }; > >diff --git a/WebCore/storage/IDBCursor.cpp b/WebCore/storage/IDBCursor.cpp >index c1c077b23a1f13a03c16411e551e0ac1c8a8f41a..d2eaa61f6983feefd571ec697905b2cfbae94d87 100644 >--- a/WebCore/storage/IDBCursor.cpp >+++ b/WebCore/storage/IDBCursor.cpp >@@ -35,13 +35,18 @@ > #include "IDBRequest.h" > #include "ScriptExecutionContext.h" > #include "SerializedScriptValue.h" >+#include "IDBTransactionBackendInterface.h" > > namespace WebCore { > >-IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request) >+IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request, IDBTransactionBackendInterface* transaction) > : m_backend(backend) > , m_request(request) >+ , m_transaction(transaction) > { >+ ASSERT(m_backend); >+ ASSERT(m_request); >+ ASSERT(m_transaction); > } > > IDBCursor::~IDBCursor() >@@ -65,7 +70,7 @@ PassRefPtr<IDBAny> IDBCursor::value() const > > PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->update(value, request); > return request.release(); > } >@@ -74,14 +79,14 @@ void IDBCursor::continueFunction(PassRefPtr<IDBKey> key) > { > // FIXME: We're not using the context from when continue was called, which means the callback > // will be on the original context openCursor was called on. Is this right? >- if (m_request->resetReadyState()) >+ if (m_request->resetReadyState(m_transaction.get())) > m_backend->continueFunction(key, m_request); > // FIXME: Else throw? > } > > PassRefPtr<IDBRequest> IDBCursor::remove(ScriptExecutionContext* context) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); > m_backend->remove(request); > return request.release(); > } >diff --git a/WebCore/storage/IDBCursor.h b/WebCore/storage/IDBCursor.h >index 0c438c4e692544b04573183174548af54b4872b4..5ad2d616df31d47bc83d173fecac0d3f1033d983 100644 >--- a/WebCore/storage/IDBCursor.h >+++ b/WebCore/storage/IDBCursor.h >@@ -41,6 +41,7 @@ class IDBKey; > class IDBRequest; > class ScriptExecutionContext; > class SerializedScriptValue; >+class IDBTransactionBackendInterface; > > class IDBCursor : public RefCounted<IDBCursor> { > public: >@@ -50,9 +51,9 @@ public: > PREV = 2, > PREV_NO_DUPLICATE = 3, > }; >- static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request) >+ static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request, IDBTransactionBackendInterface* transaction) > { >- return adoptRef(new IDBCursor(backend, request)); >+ return adoptRef(new IDBCursor(backend, request, transaction)); > } > ~IDBCursor(); > >@@ -65,10 +66,11 @@ public: > PassRefPtr<IDBRequest> remove(ScriptExecutionContext*); > > private: >- explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*); >+ explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*, IDBTransactionBackendInterface*); > > RefPtr<IDBCursorBackendInterface> m_backend; > RefPtr<IDBRequest> m_request; >+ RefPtr<IDBTransactionBackendInterface> m_transaction; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBCursorBackendImpl.cpp b/WebCore/storage/IDBCursorBackendImpl.cpp >index 13df5f02154e55d1626d0622e0bd25c5ce0bd98a..aef1d2cf19e2cc0881d25daedf50796ca8df69ed 100644 >--- a/WebCore/storage/IDBCursorBackendImpl.cpp >+++ b/WebCore/storage/IDBCursorBackendImpl.cpp >@@ -28,6 +28,7 @@ > > #if ENABLE(INDEXED_DATABASE) > >+#include "CrossThreadTask.h" > #include "IDBCallbacks.h" > #include "IDBDatabaseBackendImpl.h" > #include "IDBDatabaseError.h" >@@ -43,22 +44,24 @@ > > namespace WebCore { > >-IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl> idbObjectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query) >+IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl> idbObjectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface* transaction) > : m_idbObjectStore(idbObjectStore) > , m_keyRange(keyRange) > , m_direction(direction) > , m_query(query) > , m_isSerializedScriptValueCursor(true) >+ , m_transaction(transaction) > { > loadCurrentRow(); > } > >-IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl> idbIndex, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor) >+IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl> idbIndex, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) > : m_idbIndex(idbIndex) > , m_keyRange(keyRange) > , m_direction(direction) > , m_query(query) > , m_isSerializedScriptValueCursor(isSerializedScriptValueCursor) >+ , m_transaction(transaction) > { > loadCurrentRow(); > } >@@ -85,7 +88,15 @@ PassRefPtr<IDBAny> IDBCursorBackendImpl::value() const > return IDBAny::create(m_currentIDBKeyValue.get()); > } > >-void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBCallbacks> callbacks) >+void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBCallbacks> prpCallbacks) >+{ >+ RefPtr<SerializedScriptValue> value = prpValue; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::updateInternal, this, value, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "update must be called in the context of a transaction.")); >+} >+ >+void IDBCursorBackendImpl::updateInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> cursor, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBCallbacks> callbacks) > { > // FIXME: This method doesn't update indexes. It's dangerous to call in its current state. > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Not implemented.")); >@@ -93,82 +104,98 @@ void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> prpValue, Pa > > RefPtr<SerializedScriptValue> value = prpValue; > >- if (!m_query || m_currentId == InvalidId) { >+ if (!cursor->m_query || cursor->m_currentId == InvalidId) { > // FIXME: Use the proper error code when it's specced. > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Operation not possible.")); > return; > } > > String sql = "UPDATE ObjectStoreData SET value = ? WHERE id = ?"; >- SQLiteStatement updateQuery(database()->sqliteDatabase(), sql); >+ SQLiteStatement updateQuery(cursor->database()->sqliteDatabase(), sql); > > bool ok = updateQuery.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > updateQuery.bindText(1, value->toWireString()); >- updateQuery.bindInt64(2, m_currentId); >+ updateQuery.bindInt64(2, cursor->m_currentId); > ok = updateQuery.step() == SQLResultDone; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > >- if (m_isSerializedScriptValueCursor) >- m_currentSerializedScriptValue = value.release(); >+ if (cursor->m_isSerializedScriptValueCursor) >+ cursor->m_currentSerializedScriptValue = value.release(); > callbacks->onSuccess(); > } > >-void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> callbacks) >+void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks) >+{ >+ RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "continue must be called in the context of a transaction.")); >+} >+ >+void IDBCursorBackendImpl::continueFunctionInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> callbacks) > { >+ RefPtr<IDBCursorBackendImpl> cursor = prpCursor; > RefPtr<IDBKey> key = prpKey; > while (true) { >- if (!m_query || m_query->step() != SQLResultRow) { >- m_query = 0; >- m_currentId = InvalidId; >- m_currentKey = 0; >- m_currentSerializedScriptValue = 0; >- m_currentIDBKeyValue = 0; >+ if (!cursor->m_query || cursor->m_query->step() != SQLResultRow) { >+ cursor->m_query = 0; >+ cursor->m_currentId = InvalidId; >+ cursor->m_currentKey = 0; >+ cursor->m_currentSerializedScriptValue = 0; >+ cursor->m_currentIDBKeyValue = 0; > callbacks->onSuccess(); > return; > } > >- RefPtr<IDBKey> oldKey = m_currentKey; >- loadCurrentRow(); >+ RefPtr<IDBKey> oldKey = cursor->m_currentKey; >+ cursor->loadCurrentRow(); > > // If a key was supplied, we must loop until we find that key (or hit the end). >- if (key && !key->isEqual(m_currentKey.get())) >+ if (key && !key->isEqual(cursor->m_currentKey.get())) > continue; > > // If we don't have a uniqueness constraint, we can stop now. >- if (m_direction == IDBCursor::NEXT || m_direction == IDBCursor::PREV) >+ if (cursor->m_direction == IDBCursor::NEXT || cursor->m_direction == IDBCursor::PREV) > break; >- if (!m_currentKey->isEqual(oldKey.get())) >+ if (!cursor->m_currentKey->isEqual(oldKey.get())) > break; > } > >- callbacks->onSuccess(this); >+ callbacks->onSuccess(cursor.get()); >+} >+ >+void IDBCursorBackendImpl::remove(PassRefPtr<IDBCallbacks> prpCallbacks) >+{ >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::removeInternal, this, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "remove must be called in the context of a transaction.")); > } > >-void IDBCursorBackendImpl::remove(PassRefPtr<IDBCallbacks> callbacks) >+void IDBCursorBackendImpl::removeInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> cursor, PassRefPtr<IDBCallbacks> callbacks) > { > // FIXME: This method doesn't update indexes. It's dangerous to call in its current state. > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Not implemented.")); > return; > >- if (!m_query || m_currentId == InvalidId) { >+ if (!cursor->m_query || cursor->m_currentId == InvalidId) { > // FIXME: Use the proper error code when it's specced. > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Operation not possible.")); > return; > } > > String sql = "DELETE FROM ObjectStoreData WHERE id = ?"; >- SQLiteStatement deleteQuery(database()->sqliteDatabase(), sql); >+ SQLiteStatement deleteQuery(cursor->database()->sqliteDatabase(), sql); > > bool ok = deleteQuery.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. >- deleteQuery.bindInt64(1, m_currentId); >+ deleteQuery.bindInt64(1, cursor->m_currentId); > ok = deleteQuery.step() == SQLResultDone; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > >- m_currentId = InvalidId; >- m_currentSerializedScriptValue = 0; >- m_currentIDBKeyValue = 0; >+ cursor->m_currentId = InvalidId; >+ cursor->m_currentSerializedScriptValue = 0; >+ cursor->m_currentIDBKeyValue = 0; > callbacks->onSuccess(); > } > >diff --git a/WebCore/storage/IDBCursorBackendImpl.h b/WebCore/storage/IDBCursorBackendImpl.h >index b67ec70bc933590b7049f64d7a62e9d941452c5f..211d38d0ae0653318fda8ee0ae537e9b0ee48af2 100644 >--- a/WebCore/storage/IDBCursorBackendImpl.h >+++ b/WebCore/storage/IDBCursorBackendImpl.h >@@ -41,18 +41,19 @@ class IDBDatabaseBackendImpl; > class IDBIndexBackendImpl; > class IDBKeyRange; > class IDBObjectStoreBackendImpl; >+class IDBTransactionBackendInterface; > class SQLiteStatement; > class SerializedScriptValue; > > class IDBCursorBackendImpl : public IDBCursorBackendInterface { > public: >- static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query) >+ static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface* transaction) > { >- return adoptRef(new IDBCursorBackendImpl(objectStore, keyRange, direction, query)); >+ return adoptRef(new IDBCursorBackendImpl(objectStore, keyRange, direction, query, transaction)); > } >- static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor) >+ static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) > { >- return adoptRef(new IDBCursorBackendImpl(index, keyRange, direction, query, isSerializedScriptValueCursor)); >+ return adoptRef(new IDBCursorBackendImpl(index, keyRange, direction, query, isSerializedScriptValueCursor, transaction)); > } > virtual ~IDBCursorBackendImpl(); > >@@ -64,12 +65,16 @@ public: > virtual void remove(PassRefPtr<IDBCallbacks>); > > private: >- IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query); >- IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor); >+ IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface*); >+ IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface*); > > void loadCurrentRow(); > IDBDatabaseBackendImpl* database() const; > >+ static void updateInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBCallbacks>); >+ static void continueFunctionInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); >+ static void removeInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<IDBCallbacks>); >+ > static const int64_t InvalidId = -1; > > // Only one or the other should be used. >@@ -86,6 +91,8 @@ private: > // Only one of these will ever be used for each instance. Which depends on m_isSerializedScriptValueCursor. > RefPtr<SerializedScriptValue> m_currentSerializedScriptValue; > RefPtr<IDBKey> m_currentIDBKeyValue; >+ >+ RefPtr<IDBTransactionBackendInterface> m_transaction; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBDatabase.cpp b/WebCore/storage/IDBDatabase.cpp >index 0ea7ac292674cea6097035fa5fe5c897f44db6b7..4d322138f7b1530ded0c38484ddcdf5afed8a5af 100644 >--- a/WebCore/storage/IDBDatabase.cpp >+++ b/WebCore/storage/IDBDatabase.cpp >@@ -27,6 +27,8 @@ > #include "IDBDatabase.h" > > #include "IDBAny.h" >+#include "IDBDatabaseError.h" >+#include "IDBDatabaseException.h" > #include "IDBFactoryBackendInterface.h" > #include "IDBObjectStore.h" > #include "IDBRequest.h" >@@ -48,31 +50,36 @@ IDBDatabase::~IDBDatabase() > { > } > >-PassRefPtr<IDBRequest> IDBDatabase::createObjectStore(ScriptExecutionContext* context, const String& name, const String& keyPath, bool autoIncrement) >+void IDBDatabase::setSetVersionTransaction(IDBTransactionBackendInterface* transaction) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->createObjectStore(name, keyPath, autoIncrement, request); >- return request; >+ m_setVersionTransaction = transaction; > } > >-// FIXME: remove this method. >-PassRefPtr<IDBObjectStore> IDBDatabase::objectStore(const String& name, unsigned short mode) >+// FIXME: Should be synchronous. >+PassRefPtr<IDBRequest> IDBDatabase::createObjectStore(ScriptExecutionContext* context, const String& name, const String& keyPath, bool autoIncrement) > { >- RefPtr<IDBObjectStoreBackendInterface> objectStore = m_backend->objectStore(name, mode); >- ASSERT(objectStore); // FIXME: If this is null, we should raise a NOT_FOUND_ERR. >- return IDBObjectStore::create(objectStore.release(), 0); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_setVersionTransaction.get()); >+ if (!m_setVersionTransaction) >+ request->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "createObjectStore must be called from within a setVersion transaction.")); >+ else >+ m_backend->createObjectStore(name, keyPath, autoIncrement, request, m_setVersionTransaction.get()); >+ return request; > } > >+// FIXME: Should be synchronous. > PassRefPtr<IDBRequest> IDBDatabase::removeObjectStore(ScriptExecutionContext* context, const String& name) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->removeObjectStore(name, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_setVersionTransaction.get()); >+ if (!m_setVersionTransaction) >+ request->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "removeObjectStore must be called from within a setVersion transaction.")); >+ else >+ m_backend->removeObjectStore(name, request, m_setVersionTransaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBDatabase::setVersion(ScriptExecutionContext* context, const String& version) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), 0); > m_backend->setVersion(version, request); > return request; > } >@@ -89,6 +96,11 @@ PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont > return transaction.release(); > } > >+void IDBDatabase::close() >+{ >+ m_backend->close(); >+} >+ > } // namespace WebCore > > #endif // ENABLE(INDEXED_DATABASE) >diff --git a/WebCore/storage/IDBDatabase.h b/WebCore/storage/IDBDatabase.h >index dc7011449b184ffc568594be0de114e682ba6cb5..cf95317a7f43ea02abb1a4a5aab6fb1b5a0cebc1 100644 >--- a/WebCore/storage/IDBDatabase.h >+++ b/WebCore/storage/IDBDatabase.h >@@ -50,22 +50,25 @@ public: > } > ~IDBDatabase(); > >+ void setSetVersionTransaction(IDBTransactionBackendInterface*); >+ > // Implement the IDL > String name() const { return m_backend->name(); } > String version() const { return m_backend->version(); } > PassRefPtr<DOMStringList> objectStores() const { return m_backend->objectStores(); } > > PassRefPtr<IDBRequest> createObjectStore(ScriptExecutionContext*, const String& name, const String& keyPath = String(), bool autoIncrement = false); >- PassRefPtr<IDBObjectStore> objectStore(const String& name, unsigned short mode = IDBTransaction::READ_ONLY); > PassRefPtr<IDBRequest> removeObjectStore(ScriptExecutionContext*, const String& name); > PassRefPtr<IDBRequest> setVersion(ScriptExecutionContext*, const String& version); > PassRefPtr<IDBTransaction> transaction(ScriptExecutionContext*, DOMStringList* storeNames = 0, unsigned short mode = IDBTransaction::READ_ONLY, > unsigned long timeout = 0); // FIXME: what should the default timeout be? >+ void close(); > > private: > IDBDatabase(PassRefPtr<IDBDatabaseBackendInterface>); > > RefPtr<IDBDatabaseBackendInterface> m_backend; >+ RefPtr<IDBTransactionBackendInterface> m_setVersionTransaction; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBDatabase.idl b/WebCore/storage/IDBDatabase.idl >index 347b3a7c841f97d5ab41eda625f24be3a1191cdc..30cdf303e55e79e2a0c0ce9a1b589e0da4671465 100644 >--- a/WebCore/storage/IDBDatabase.idl >+++ b/WebCore/storage/IDBDatabase.idl >@@ -32,14 +32,11 @@ module storage { > readonly attribute DOMString version; > readonly attribute DOMStringList objectStores; > >- > [CallWith=ScriptExecutionContext] IDBRequest createObjectStore(in DOMString name, in [Optional, ConvertNullToNullString] DOMString keyPath, in [Optional] boolean autoIncrement); >- // FIXME: objectStore needs to be able to raise an IDBDatabaseException. >- IDBObjectStore objectStore(in DOMString name, in [Optional] unsigned short mode); > [CallWith=ScriptExecutionContext] IDBRequest removeObjectStore(in DOMString name); > [CallWith=ScriptExecutionContext] IDBRequest setVersion(in DOMString version); > [CallWith=ScriptExecutionContext] IDBTransaction transaction (in [Optional] DOMStringList storeNames, in [Optional] unsigned short mode, in [Optional] unsigned long timeout); >- // FIXME: Add close. >+ void close(); > }; > > } >diff --git a/WebCore/storage/IDBDatabaseBackendImpl.cpp b/WebCore/storage/IDBDatabaseBackendImpl.cpp >index b8fe9b5062f6d60305bc1d5c6015dd0022fc7541..321fdca4a62009be8425b6fea39ade722129c8ed 100644 >--- a/WebCore/storage/IDBDatabaseBackendImpl.cpp >+++ b/WebCore/storage/IDBDatabaseBackendImpl.cpp >@@ -26,16 +26,18 @@ > #include "config.h" > #include "IDBDatabaseBackendImpl.h" > >+#if ENABLE(INDEXED_DATABASE) >+ >+#include "CrossThreadTask.h" > #include "DOMStringList.h" > #include "IDBDatabaseException.h" > #include "IDBObjectStoreBackendImpl.h" >+#include "IDBTransactionBackendInterface.h" > #include "IDBTransactionCoordinator.h" > #include "SQLiteDatabase.h" > #include "SQLiteStatement.h" > #include "SQLiteTransaction.h" > >-#if ENABLE(INDEXED_DATABASE) >- > namespace WebCore { > > static bool extractMetaData(SQLiteDatabase* sqliteDatabase, const String& expectedName, String& foundDescription, String& foundVersion) >@@ -125,14 +127,21 @@ PassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStores() const > return objectStoreNames.release(); > } > >-void IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks) >+void IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- if (m_objectStores.contains(name)) { >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::createObjectStoreInternal, this, name, keyPath, autoIncrement, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "createObjectStore must be called from within a setVersion transaction.")); >+} >+ >+void IDBDatabaseBackendImpl::createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks) >+{ >+ if (database->m_objectStores.contains(name)) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "An objectStore with that name already exists.")); > return; > } > >- SQLiteStatement insert(sqliteDatabase(), "INSERT INTO ObjectStores (name, keyPath, doAutoIncrement) VALUES (?, ?, ?)"); >+ SQLiteStatement insert(database->sqliteDatabase(), "INSERT INTO ObjectStores (name, keyPath, doAutoIncrement) VALUES (?, ?, ?)"); > bool ok = insert.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > insert.bindText(1, name); >@@ -140,11 +149,11 @@ void IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& > insert.bindInt(3, static_cast<int>(autoIncrement)); > ok = insert.step() == SQLResultDone; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. >- int64_t id = sqliteDatabase().lastInsertRowID(); >+ int64_t id = database->sqliteDatabase().lastInsertRowID(); > >- RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(this, id, name, keyPath, autoIncrement); >+ RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(database.get(), id, name, keyPath, autoIncrement); > ASSERT(objectStore->name() == name); >- m_objectStores.set(name, objectStore); >+ database->m_objectStores.set(name, objectStore); > callbacks->onSuccess(objectStore.get()); > } > >@@ -166,31 +175,44 @@ static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id) > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > } > >-void IDBDatabaseBackendImpl::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks) >+void IDBDatabaseBackendImpl::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) >+{ >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::removeObjectStoreInternal, this, name, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "removeObjectStore must be called from within a setVersion transaction.")); >+} >+ >+void IDBDatabaseBackendImpl::removeObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& name, PassRefPtr<IDBCallbacks> callbacks) > { >- RefPtr<IDBObjectStoreBackendImpl> objectStore = m_objectStores.get(name); >+ RefPtr<IDBObjectStoreBackendImpl> objectStore = database->m_objectStores.get(name); > if (!objectStore) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "No objectStore with that name exists.")); > return; > } > >- SQLiteTransaction transaction(sqliteDatabase()); >- transaction.begin(); >- doDelete(sqliteDatabase(), "DELETE FROM ObjectStores WHERE id = ?", objectStore->id()); >- doDelete(sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id()); >- doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId IN (SELECT id FROM Indexes WHERE objectStoreId = ?)", objectStore->id()); >- doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE objectStoreId = ?", objectStore->id()); >- transaction.commit(); >+ doDelete(database->sqliteDatabase(), "DELETE FROM ObjectStores WHERE id = ?", objectStore->id()); >+ doDelete(database->sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id()); >+ doDelete(database->sqliteDatabase(), "DELETE FROM IndexData WHERE indexId IN (SELECT id FROM Indexes WHERE objectStoreId = ?)", objectStore->id()); >+ doDelete(database->sqliteDatabase(), "DELETE FROM Indexes WHERE objectStoreId = ?", objectStore->id()); > >- m_objectStores.remove(name); >+ database->m_objectStores.remove(name); > callbacks->onSuccess(); > } > >-void IDBDatabaseBackendImpl::setVersion(const String& version, PassRefPtr<IDBCallbacks> callbacks) >+void IDBDatabaseBackendImpl::setVersion(const String& version, PassRefPtr<IDBCallbacks> prpCallbacks) > { >- m_version = version; >- setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version); >- callbacks->onSuccess(); >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ RefPtr<DOMStringList> objectStores = DOMStringList::create(); >+ RefPtr<IDBTransactionBackendInterface> transaction = m_transactionCoordinator->createTransaction(objectStores.get(), IDBTransaction::VERSION_CHANGE, 0, this); >+ if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::setVersionInternal, this, version, callbacks, transaction))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "setVersion must be called from within a setVersion transaction.")); >+} >+ >+void IDBDatabaseBackendImpl::setVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) >+{ >+ database->m_version = version; >+ setMetaData(database->m_sqliteDatabase.get(), database->m_name, database->m_description, database->m_version); >+ callbacks->onSuccess(transaction); > } > > PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout) >@@ -198,6 +220,11 @@ PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(D > return m_transactionCoordinator->createTransaction(objectStores, mode, timeout, this); > } > >+void IDBDatabaseBackendImpl::close() >+{ >+ // FIXME: Implement. >+} >+ > void IDBDatabaseBackendImpl::loadObjectStores() > { > SQLiteStatement objectStoresQuery(sqliteDatabase(), "SELECT id, name, keyPath, doAutoIncrement FROM ObjectStores"); >diff --git a/WebCore/storage/IDBDatabaseBackendImpl.h b/WebCore/storage/IDBDatabaseBackendImpl.h >index 7e08ad65afe46ca3e4363eaef60b257053ce33b1..b576fa5b88b18d3bc977cf51ca67dae8fee03629 100644 >--- a/WebCore/storage/IDBDatabaseBackendImpl.h >+++ b/WebCore/storage/IDBDatabaseBackendImpl.h >@@ -50,17 +50,17 @@ public: > void setDescription(const String& description); > SQLiteDatabase& sqliteDatabase() const { return *m_sqliteDatabase.get(); } > >- // Implements IDBDatabase > virtual String name() const { return m_name; } > virtual String description() const { return m_description; } > virtual String version() const { return m_version; } > virtual PassRefPtr<DOMStringList> objectStores() const; > >- virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>); >+ virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(const String& name, unsigned short mode); >- virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>); >+ virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > virtual void setVersion(const String& version, PassRefPtr<IDBCallbacks>); > virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, unsigned long timeout); >+ virtual void close(); > > IDBTransactionCoordinator* transactionCoordinator() const { return m_transactionCoordinator.get(); } > >@@ -69,6 +69,10 @@ private: > > void loadObjectStores(); > >+ static void createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>); >+ static void removeObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& name, PassRefPtr<IDBCallbacks>); >+ static void setVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>); >+ > OwnPtr<SQLiteDatabase> m_sqliteDatabase; > String m_name; > String m_description; >diff --git a/WebCore/storage/IDBDatabaseBackendInterface.h b/WebCore/storage/IDBDatabaseBackendInterface.h >index a2e042ae20000a41c2f6d50509fda475f7553845..c01dadfecdef6620769d9d8e46927cc1a8b59805 100644 >--- a/WebCore/storage/IDBDatabaseBackendInterface.h >+++ b/WebCore/storage/IDBDatabaseBackendInterface.h >@@ -54,12 +54,12 @@ public: > virtual String version() const = 0; > virtual PassRefPtr<DOMStringList> objectStores() const = 0; > >- virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(const String& name, unsigned short mode) = 0; >- virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > virtual void setVersion(const String& version, PassRefPtr<IDBCallbacks>) = 0; > virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, unsigned long timeout) = 0; >- // FIXME: Add close. >+ virtual void close() = 0; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBFactory.cpp b/WebCore/storage/IDBFactory.cpp >index 06c06ea47141e673828b0534236fccc0eec040b3..e1c8c07ce94d0a5baaa8bd7a5794b461c8ae397a 100644 >--- a/WebCore/storage/IDBFactory.cpp >+++ b/WebCore/storage/IDBFactory.cpp >@@ -67,7 +67,7 @@ PassRefPtr<IDBRequest> IDBFactory::open(ScriptExecutionContext* context, const S > if (!document->frame() || !document->page()) > return 0; > >- RefPtr<IDBRequest> request = IDBRequest::create(document, IDBAny::create(this)); >+ RefPtr<IDBRequest> request = IDBRequest::create(document, IDBAny::create(this), 0); > m_factoryBackend->open(name, description, request, document->securityOrigin(), document->frame(), document->page()->group().groupSettings()->indexedDBDatabasePath()); > return request; > } >diff --git a/WebCore/storage/IDBIndex.cpp b/WebCore/storage/IDBIndex.cpp >index 5cd12dd400348bf05939f00d173a4f5d5e8c097c..8d784666397b3c8ec90acb7b44fe2f14a48cbd92 100644 >--- a/WebCore/storage/IDBIndex.cpp >+++ b/WebCore/storage/IDBIndex.cpp >@@ -33,12 +33,16 @@ > #include "IDBKey.h" > #include "IDBKeyRange.h" > #include "IDBRequest.h" >+#include "IDBTransactionBackendInterface.h" > > namespace WebCore { > >-IDBIndex::IDBIndex(PassRefPtr<IDBIndexBackendInterface> backend) >+IDBIndex::IDBIndex(PassRefPtr<IDBIndexBackendInterface> backend, IDBTransactionBackendInterface* transaction) > : m_backend(backend) >+ , m_transaction(transaction) > { >+ ASSERT(m_backend); >+ ASSERT(m_transaction); > } > > IDBIndex::~IDBIndex() >@@ -47,29 +51,29 @@ IDBIndex::~IDBIndex() > > PassRefPtr<IDBRequest> IDBIndex::openObjectCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->openObjectCursor(keyRange, direction, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_backend->openObjectCursor(keyRange, direction, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->openCursor(keyRange, direction, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_backend->openCursor(keyRange, direction, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBIndex::getObject(ScriptExecutionContext* context, PassRefPtr<IDBKey> key) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->getObject(key, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_backend->getObject(key, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_backend->get(key, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_backend->get(key, request, m_transaction.get()); > return request; > } > >diff --git a/WebCore/storage/IDBIndex.h b/WebCore/storage/IDBIndex.h >index 45fcfa18774d25b09c2040000ef0c982e81b7878..b258077177c7f5a07acf1e0f49e1bf2388bddb49 100644 >--- a/WebCore/storage/IDBIndex.h >+++ b/WebCore/storage/IDBIndex.h >@@ -37,9 +37,9 @@ namespace WebCore { > > class IDBIndex : public RefCounted<IDBIndex> { > public: >- static PassRefPtr<IDBIndex> create(PassRefPtr<IDBIndexBackendInterface> backend) >+ static PassRefPtr<IDBIndex> create(PassRefPtr<IDBIndexBackendInterface> backend, IDBTransactionBackendInterface* transaction) > { >- return adoptRef(new IDBIndex(backend)); >+ return adoptRef(new IDBIndex(backend, transaction)); > } > ~IDBIndex(); > >@@ -55,9 +55,10 @@ public: > PassRefPtr<IDBRequest> get(ScriptExecutionContext*, PassRefPtr<IDBKey>); > > private: >- IDBIndex(PassRefPtr<IDBIndexBackendInterface>); >+ IDBIndex(PassRefPtr<IDBIndexBackendInterface>, IDBTransactionBackendInterface* transaction); > > RefPtr<IDBIndexBackendInterface> m_backend; >+ RefPtr<IDBTransactionBackendInterface> m_transaction; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBIndexBackendImpl.cpp b/WebCore/storage/IDBIndexBackendImpl.cpp >index 6f698c648534071561755ed5b4addf6ade18f406..390a3c6de482697f3f9a39c6c6738c69d9a87410 100644 >--- a/WebCore/storage/IDBIndexBackendImpl.cpp >+++ b/WebCore/storage/IDBIndexBackendImpl.cpp >@@ -28,6 +28,7 @@ > > #if ENABLE(INDEXED_DATABASE) > >+#include "CrossThreadTask.h" > #include "IDBCallbacks.h" > #include "IDBCursorBackendImpl.h" > #include "IDBDatabaseBackendImpl.h" >@@ -58,7 +59,7 @@ String IDBIndexBackendImpl::storeName() > return m_objectStore->name(); > } > >-static void openCursorInternal(SQLiteDatabase& database, IDBIndexBackendImpl* index, IDBKeyRange* range, unsigned short untypedDirection, bool objectCursor, IDBCallbacks* callbacks) >+void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, bool objectCursor, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) > { > // Several files depend on this order of selects. > String sql = String("SELECT IndexData.id, IndexData.keyString, IndexData.keyDate, IndexData.keyNumber, ") >@@ -80,7 +81,7 @@ static void openCursorInternal(SQLiteDatabase& database, IDBIndexBackendImpl* in > else > sql += "IndexData.keyString DESC, IndexData.keyDate DESC, IndexData.keyNumber DESC, IndexData.id DESC"; > >- OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(database, sql)); >+ OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(index->sqliteDatabase(), sql)); > bool ok = query->prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >@@ -96,32 +97,38 @@ static void openCursorInternal(SQLiteDatabase& database, IDBIndexBackendImpl* in > return; > } > >- RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(index, range, direction, query.release(), objectCursor); >+ RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(index, range, direction, query.release(), objectCursor, transaction.get()); > callbacks->onSuccess(cursor.release()); > } > >-void IDBIndexBackendImpl::openObjectCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendImpl::openObjectCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- openCursorInternal(sqliteDatabase(), this, keyRange.get(), direction, true, callbacks.get()); >+ RefPtr<IDBKeyRange> keyRange = prpKeyRange; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, this, keyRange, direction, true, callbacks, transaction))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "Get must be called in the context of a transaction.")); > } > >-void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- openCursorInternal(sqliteDatabase(), this, keyRange.get(), direction, false, callbacks.get()); >+ RefPtr<IDBKeyRange> keyRange = prpKeyRange; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, this, keyRange, direction, false, callbacks, transaction))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "Get must be called in the context of a transaction.")); > } > >-static void getInternal(SQLiteDatabase& database, int64 id, IDBKey* key, bool getObject, IDBCallbacks* callbacks) >+void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKey> key, bool getObject, PassRefPtr<IDBCallbacks> callbacks) > { > String sql = String("SELECT ") > + (getObject ? "ObjectStoreData.value " : "ObjectStoreData.keyString, ObjectStoreData.keyDate, ObjectStoreData.keyNumber ") > + "FROM IndexData INNER JOIN ObjectStoreData ON IndexData.objectStoreDataId = ObjectStoreData.id " > + "WHERE IndexData.indexId = ? AND " + key->whereSyntax("IndexData.") > + "ORDER BY IndexData.id LIMIT 1"; // Order by insertion order when all else fails. >- SQLiteStatement query(database, sql); >+ SQLiteStatement query(index->sqliteDatabase(), sql); > bool ok = query.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >- query.bindInt64(1, id); >+ query.bindInt64(1, index->id()); > key->bind(query, 2); > if (query.step() != SQLResultRow) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the index.")); >@@ -135,14 +142,20 @@ static void getInternal(SQLiteDatabase& database, int64 id, IDBKey* key, bool ge > ASSERT(query.step() != SQLResultRow); > } > >-void IDBIndexBackendImpl::getObject(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendImpl::getObject(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- getInternal(sqliteDatabase(), m_id, key.get(), true, callbacks.get()); >+ RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&getInternal, this, key, true, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "Get must be called in the context of a transaction.")); > } > >-void IDBIndexBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- getInternal(sqliteDatabase(), m_id, key.get(), false, callbacks.get()); >+ RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&getInternal, this, key, false, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "Get must be called in the context of a transaction.")); > } > > static String whereClause(IDBKey* key) >diff --git a/WebCore/storage/IDBIndexBackendImpl.h b/WebCore/storage/IDBIndexBackendImpl.h >index a98ed2a8e3dd070ab5cd7c94b3920a5814518cc1..2d06c697ec98a8e18e7efef9a9a7d18a48944624 100644 >--- a/WebCore/storage/IDBIndexBackendImpl.h >+++ b/WebCore/storage/IDBIndexBackendImpl.h >@@ -35,6 +35,7 @@ namespace WebCore { > class IDBKey; > class IDBObjectStoreBackendImpl; > class SQLiteDatabase; >+class ScriptExecutionContext; > > class IDBIndexBackendImpl : public IDBIndexBackendInterface { > public: >@@ -53,10 +54,10 @@ public: > virtual String keyPath() { return m_keyPath; } > virtual bool unique() { return m_unique; } > >- virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>); >- virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>); >- virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); >- virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); >+ virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > > IDBObjectStoreBackendImpl* objectStore() const { return m_objectStore.get(); } > >@@ -65,6 +66,9 @@ private: > > SQLiteDatabase& sqliteDatabase() const; > >+ static void openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, unsigned short direction, bool objectCursor, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>); >+ static void getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKey>, bool getObject, PassRefPtr<IDBCallbacks>); >+ > RefPtr<IDBObjectStoreBackendImpl> m_objectStore; > > int64_t m_id; >diff --git a/WebCore/storage/IDBIndexBackendInterface.h b/WebCore/storage/IDBIndexBackendInterface.h >index ff2316f3415c8e50742eed8027dbc1b68a3aa43f..fa395a04a21bad0e9e50f7d1282da1d20b50ec93 100644 >--- a/WebCore/storage/IDBIndexBackendInterface.h >+++ b/WebCore/storage/IDBIndexBackendInterface.h >@@ -36,6 +36,7 @@ namespace WebCore { > class IDBCallbacks; > class IDBKey; > class IDBKeyRange; >+class IDBTransactionBackendInterface; > > class IDBIndexBackendInterface : public ThreadSafeShared<IDBIndexBackendInterface> { > public: >@@ -46,10 +47,10 @@ public: > virtual String keyPath() = 0; > virtual bool unique() = 0; > >- virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>) = 0; >- virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>) = 0; >- virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>) = 0; >- virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; >+ virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; >+ virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; >+ virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBKey.cpp b/WebCore/storage/IDBKey.cpp >index 3eec36c7853322301f9b5cffb8f4ff51a6dff2bd..d0f3c2b3c27dae3242131a3b2240501e42221686 100644 >--- a/WebCore/storage/IDBKey.cpp >+++ b/WebCore/storage/IDBKey.cpp >@@ -46,7 +46,7 @@ IDBKey::IDBKey(int32_t number) > > IDBKey::IDBKey(const String& string) > : m_type(StringType) >- , m_string(string) >+ , m_string(string.crossThreadString()) > { > } > >diff --git a/WebCore/storage/IDBKey.h b/WebCore/storage/IDBKey.h >index 3175e7e8deb3fdf64496cd32af8a8821ba491e47..0303a382a44b5afb4f88420ed0739019c2268f7f 100644 >--- a/WebCore/storage/IDBKey.h >+++ b/WebCore/storage/IDBKey.h >@@ -26,17 +26,18 @@ > #ifndef IDBKey_h > #define IDBKey_h > >+#if ENABLE(INDEXED_DATABASE) >+ > #include "PlatformString.h" > #include <wtf/Forward.h> >- >-#if ENABLE(INDEXED_DATABASE) >+#include <wtf/Threading.h> > > namespace WebCore { > > class SQLiteStatement; > > // FIXME: Add dates. >-class IDBKey : public RefCounted<IDBKey> { >+class IDBKey : public ThreadSafeShared<IDBKey> { > public: > static PassRefPtr<IDBKey> create() > { >@@ -82,6 +83,9 @@ public: > int bind(SQLiteStatement& query, int column) const; > void bindWithNulls(SQLiteStatement& query, int baseColumn) const; > >+ using ThreadSafeShared<IDBKey>::ref; >+ using ThreadSafeShared<IDBKey>::deref; >+ > private: > IDBKey(); > explicit IDBKey(int32_t); >diff --git a/WebCore/storage/IDBKeyRange.h b/WebCore/storage/IDBKeyRange.h >index 4621a5035255f620c00f8b7dbdaa545b4743d8c9..d246ebcc1bc6c9126721aad5f2c30505f2ffdddb 100644 >--- a/WebCore/storage/IDBKeyRange.h >+++ b/WebCore/storage/IDBKeyRange.h >@@ -30,11 +30,11 @@ > > #include "IDBKey.h" > #include <wtf/PassRefPtr.h> >-#include <wtf/RefCounted.h> >+#include <wtf/Threading.h> > > namespace WebCore { > >-class IDBKeyRange : public RefCounted<IDBKeyRange> { >+class IDBKeyRange : public ThreadSafeShared<IDBKeyRange> { > public: > // Keep in sync with what's in the .idl file. > enum Flags { >diff --git a/WebCore/storage/IDBObjectStore.cpp b/WebCore/storage/IDBObjectStore.cpp >index 4c5cf340ed93d839c2193602aa1d2f2453b47826..a81e17fff61f822f9351e5186309e5ebce04cca0 100644 >--- a/WebCore/storage/IDBObjectStore.cpp >+++ b/WebCore/storage/IDBObjectStore.cpp >@@ -43,6 +43,8 @@ IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObj > : m_objectStore(idbObjectStore) > , m_transaction(transaction) > { >+ ASSERT(m_objectStore); >+ ASSERT(m_transaction); > // We pass a reference to this object before it can be adopted. > relaxAdoptionRequirement(); > } >@@ -71,29 +73,29 @@ PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, Pass > > PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->put(value, key, true, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->put(value, key, true, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->put(value, key, false, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->put(value, key, false, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBObjectStore::remove(ScriptExecutionContext* context, PassRefPtr<IDBKey> key) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->remove(key, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->remove(key, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const String& keyPath, bool unique) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->createIndex(name, keyPath, unique, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->createIndex(name, keyPath, unique, request, m_transaction.get()); > return request; > } > >@@ -103,20 +105,20 @@ PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name) > RefPtr<IDBIndexBackendInterface> index = m_objectStore->index(name); > if (!index) > return 0; >- return IDBIndex::create(index.release()); >+ return IDBIndex::create(index.release(), m_transaction.get()); > } > > PassRefPtr<IDBRequest> IDBObjectStore::removeIndex(ScriptExecutionContext* context, const String& name) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->removeIndex(name, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->removeIndex(name, request, m_transaction.get()); > return request; > } > > PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, unsigned short direction) > { >- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this)); >- m_objectStore->openCursor(range, direction, request); >+ RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); >+ m_objectStore->openCursor(range, direction, request, m_transaction.get()); > return request.release(); > } > >diff --git a/WebCore/storage/IDBObjectStore.idl b/WebCore/storage/IDBObjectStore.idl >index ccd0311c80beb5f0ec840704d6fd2e7e94b7096b..c8aa35d280c072d6b1ae13bcae128f0bc05849ac 100644 >--- a/WebCore/storage/IDBObjectStore.idl >+++ b/WebCore/storage/IDBObjectStore.idl >@@ -28,21 +28,18 @@ module storage { > interface [ > Conditional=INDEXED_DATABASE > ] IDBObjectStore { >+ readonly attribute DOMString name; >+ readonly attribute [ConvertNullStringTo=Null] DOMString keyPath; >+ readonly attribute DOMStringList indexNames; >+ > // FIXME: Many of these should raise on certain errors. > [CallWith=ScriptExecutionContext] IDBRequest get(in IDBKey key); > [CallWith=ScriptExecutionContext] IDBRequest add(in SerializedScriptValue value, in [Optional] IDBKey key); > [CallWith=ScriptExecutionContext] IDBRequest put(in SerializedScriptValue value, in [Optional] IDBKey key); > [CallWith=ScriptExecutionContext] IDBRequest remove(in IDBKey key); >- // FIXME: write openCursor > [CallWith=ScriptExecutionContext] IDBRequest createIndex(in DOMString name, in [ConvertNullToNullString] DOMString keyPath, in [Optional] boolean unique); >- // FIXME: This needs to raise an IDBDatabaseException on errors. > IDBIndex index(in DOMString name); > [CallWith=ScriptExecutionContext] IDBRequest removeIndex(in DOMString name); >- > [CallWith=ScriptExecutionContext] IDBRequest openCursor(in [Optional] IDBKeyRange range, in [Optional] unsigned short direction); >- >- readonly attribute DOMString name; >- readonly attribute [ConvertNullStringTo=Null] DOMString keyPath; >- readonly attribute DOMStringList indexNames; > }; > } >diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/WebCore/storage/IDBObjectStoreBackendImpl.cpp >index 18d6b0c2806a297f962481d4f7d6a03f105e418b..f8d372166e4088ebcb85fe5693351c47f58cb6ab 100644 >--- a/WebCore/storage/IDBObjectStoreBackendImpl.cpp >+++ b/WebCore/storage/IDBObjectStoreBackendImpl.cpp >@@ -26,6 +26,9 @@ > #include "config.h" > #include "IDBObjectStoreBackendImpl.h" > >+#if ENABLE(INDEXED_DATABASE) >+ >+#include "CrossThreadTask.h" > #include "DOMStringList.h" > #include "IDBBindingUtilities.h" > #include "IDBCallbacks.h" >@@ -33,6 +36,7 @@ > #include "IDBDatabaseBackendImpl.h" > #include "IDBDatabaseException.h" > #include "IDBIndexBackendImpl.h" >+#include "IDBKey.h" > #include "IDBKeyPath.h" > #include "IDBKeyPathBackendImpl.h" > #include "IDBKeyRange.h" >@@ -42,37 +46,8 @@ > #include "SQLiteStatement.h" > #include "SQLiteTransaction.h" > >-#if ENABLE(INDEXED_DATABASE) >- > namespace WebCore { > >-template <class T, class Method, class Param1, class Param2> >-class IDBTask : public ScriptExecutionContext::Task { >-public: >- IDBTask(T* obj, Method method, const Param1& param1, const Param2& param2) >- : m_obj(obj), m_method(method), m_param1(param1), m_param2(param2) >- { >- } >- >- virtual void performTask(ScriptExecutionContext*) >- { >- if (m_obj) >- (m_obj->*m_method)(m_param1, m_param2); >- } >- >-private: >- T* m_obj; >- Method m_method; >- Param1 m_param1; >- Param2 m_param2; >-}; >- >-template <class T, class Method, class Param1, class Param2> >-PassOwnPtr<ScriptExecutionContext::Task> createTask(T* object, Method method, const Param1& param1, const Param2& param2) >-{ >- return adoptPtr(new IDBTask<T, Method, Param1, Param2>(object, method, param1, param2)); >-} >- > IDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl() > { > } >@@ -106,19 +81,21 @@ static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key) > key->bind(query, 2); > } > >-void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) >+void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- if (!transaction->scheduleTask(createTask(this, &IDBObjectStoreBackendImpl::getInternal, key, callbacks))) >- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "Get must be called in the context of a transaction.")); >+ RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::getInternal, this, key, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "get must be called in the context of a transaction.")); > } > >-void IDBObjectStoreBackendImpl::getInternal(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) > { >- SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key.get())); >+ SQLiteStatement query(objectStore->sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key.get())); > bool ok = query.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >- bindWhereClause(query, m_id, key.get()); >+ bindWhereClause(query, objectStore->id(), key.get()); > if (query.step() != SQLResultRow) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store.")); > return; >@@ -185,17 +162,26 @@ static void putIndexData(SQLiteDatabase& db, IDBKey* key, int64_t indexId, int64 > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > } > >-void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { > RefPtr<SerializedScriptValue> value = prpValue; > RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, this, value, key, addOnly, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "put must be called in the context of a transaction.")); >+} > >- if (!m_keyPath.isNull()) { >+void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> callbacks) >+{ >+ RefPtr<SerializedScriptValue> value = prpValue; >+ RefPtr<IDBKey> key = prpKey; >+ >+ if (!objectStore->m_keyPath.isNull()) { > if (key) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "A key was supplied for an objectStore that has a keyPath.")); > return; > } >- key = fetchKeyFromKeyPath(value.get(), m_keyPath); >+ key = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath); > if (!key) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from the keyPath.")); > return; >@@ -206,7 +192,7 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, > } > > Vector<RefPtr<IDBKey> > indexKeys; >- for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) { >+ for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) { > RefPtr<IDBKey> key = fetchKeyFromKeyPath(value.get(), it->second->keyPath()); > if (!key) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from an index's keyPath.")); >@@ -219,11 +205,11 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, > indexKeys.append(key.release()); > } > >- SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get())); >+ SQLiteStatement getQuery(objectStore->sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get())); > bool ok = getQuery.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >- bindWhereClause(getQuery, m_id, key.get()); >+ bindWhereClause(getQuery, objectStore->id(), key.get()); > bool isExistingValue = getQuery.step() == SQLResultRow; > if (addOnly && isExistingValue) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); >@@ -233,22 +219,30 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, > // Before this point, don't do any mutation. After this point, don't error out. > > int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : -1; >- putObjectStoreData(sqliteDatabase(), key.get(), value.get(), m_id, &dataRowId); >+ putObjectStoreData(objectStore->sqliteDatabase(), key.get(), value.get(), objectStore->id(), &dataRowId); > > int i = 0; >- for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it, ++i) >- putIndexData(sqliteDatabase(), indexKeys[i].get(), it->second->id(), dataRowId); >+ for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it, ++i) >+ putIndexData(objectStore->sqliteDatabase(), indexKeys[i].get(), it->second->id(), dataRowId); > > callbacks->onSuccess(key.get()); > } > >-void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) >+{ >+ RefPtr<IDBKey> key = prpKey; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::removeInternal, this, key, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "remove must be called in the context of a transaction.")); >+} >+ >+void IDBObjectStoreBackendImpl::removeInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) > { >- SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key.get())); >+ SQLiteStatement query(objectStore->sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key.get())); > bool ok = query.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >- bindWhereClause(query, m_id, key.get()); >+ bindWhereClause(query, objectStore->id(), key.get()); > if (query.step() != SQLResultDone) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store.")); > return; >@@ -257,27 +251,34 @@ void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCal > callbacks->onSuccess(); > } > >-void IDBObjectStoreBackendImpl::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) > { >- if (m_indexes.contains(name)) { >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::createIndexInternal, this, name, keyPath, unique, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "createIndex must be called in the context of a transaction.")); >+} >+ >+void IDBObjectStoreBackendImpl::createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks) >+{ >+ if (objectStore->m_indexes.contains(name)) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Index name already exists.")); > return; > } > >- SQLiteStatement insert(sqliteDatabase(), "INSERT INTO Indexes (objectStoreId, name, keyPath, isUnique) VALUES (?, ?, ?, ?)"); >+ SQLiteStatement insert(objectStore->sqliteDatabase(), "INSERT INTO Indexes (objectStoreId, name, keyPath, isUnique) VALUES (?, ?, ?, ?)"); > bool ok = insert.prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. >- insert.bindInt64(1, m_id); >+ insert.bindInt64(1, objectStore->m_id); > insert.bindText(2, name); > insert.bindText(3, keyPath); > insert.bindInt(4, static_cast<int>(unique)); > ok = insert.step() == SQLResultDone; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. >- int64_t id = sqliteDatabase().lastInsertRowID(); >+ int64_t id = objectStore->sqliteDatabase().lastInsertRowID(); > >- RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique); >+ RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(objectStore.get(), id, name, keyPath, unique); > ASSERT(index->name() == name); >- m_indexes.set(name, index); >+ objectStore->m_indexes.set(name, index); > callbacks->onSuccess(index.get()); > } > >@@ -296,25 +297,37 @@ static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id) > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. > } > >-void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) >+{ >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::removeIndexInternal, this, name, callbacks))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "createIndex must be called in the context of a transaction.")); >+} >+ >+void IDBObjectStoreBackendImpl::removeIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, const String& name, PassRefPtr<IDBCallbacks> callbacks) > { >- RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name); >+ RefPtr<IDBIndexBackendImpl> index = objectStore->m_indexes.get(name); > if (!index) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Index name does not exist.")); > return; > } > >- SQLiteTransaction transaction(sqliteDatabase()); >- transaction.begin(); >- doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE id = ?", index->id()); >- doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId = ?", index->id()); >- transaction.commit(); >+ doDelete(objectStore->sqliteDatabase(), "DELETE FROM Indexes WHERE id = ?", index->id()); >+ doDelete(objectStore->sqliteDatabase(), "DELETE FROM IndexData WHERE indexId = ?", index->id()); > >- m_indexes.remove(name); >+ objectStore->m_indexes.remove(name); > callbacks->onSuccess(); > } > >-void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction) >+{ >+ RefPtr<IDBKeyRange> range = prpRange; >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal, this, range, direction, callbacks, transaction))) >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_ALLOWED_ERR, "openCursor must be called in the context of a transaction.")); >+} >+ >+void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) > { > // Several files depend on this order of selects. > String sql = "SELECT id, keyString, keyDate, keyNumber, value FROM ObjectStoreData WHERE "; >@@ -330,7 +343,7 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, unsign > else > sql += "keyString DESC, keyDate DESC, keyNumber DESC"; > >- OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(sqliteDatabase(), sql)); >+ OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(objectStore->sqliteDatabase(), sql)); > bool ok = query->prepare() == SQLResultOk; > ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? > >@@ -339,14 +352,14 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, unsign > currentColumn += range->left()->bind(*query, currentColumn); > if (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE) > currentColumn += range->right()->bind(*query, currentColumn); >- query->bindInt64(currentColumn, m_id); >+ query->bindInt64(currentColumn, objectStore->id()); > > if (query->step() != SQLResultRow) { > callbacks->onSuccess(); > return; > } > >- RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(this, range, direction, query.release()); >+ RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(objectStore, range, direction, query.release(), transaction.get()); > callbacks->onSuccess(cursor.release()); > } > >diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.h b/WebCore/storage/IDBObjectStoreBackendImpl.h >index 36c00144a07fd418710f1a4d5e0dd474a7958aa3..ed994fb49fe3a0edeb66cb8bf5f91f2a65705031 100644 >--- a/WebCore/storage/IDBObjectStoreBackendImpl.h >+++ b/WebCore/storage/IDBObjectStoreBackendImpl.h >@@ -38,6 +38,7 @@ class IDBDatabaseBackendImpl; > class IDBIndexBackendImpl; > class IDBTransactionBackendInterface; > class SQLiteDatabase; >+class ScriptExecutionContext; > > class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface { > public: >@@ -52,15 +53,15 @@ public: > String keyPath() const { return m_keyPath; } > PassRefPtr<DOMStringList> indexNames() const; > >- void get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface* transaction); >- void put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>); >- void remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); >+ void get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ void put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ void remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > >- void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>); >+ void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > PassRefPtr<IDBIndexBackendInterface> index(const String& name); >- void removeIndex(const String& name, PassRefPtr<IDBCallbacks>); >+ void removeIndex(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > >- void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>); >+ void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > > IDBDatabaseBackendImpl* database() const { return m_database.get(); } > >@@ -70,7 +71,12 @@ private: > void loadIndexes(); > SQLiteDatabase& sqliteDatabase() const; > >- void getInternal(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); >+ static void getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); >+ static void putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>); >+ static void removeInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); >+ static void createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>); >+ static void removeIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, const String& name, PassRefPtr<IDBCallbacks>); >+ static void openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>); > > RefPtr<IDBDatabaseBackendImpl> m_database; > >diff --git a/WebCore/storage/IDBObjectStoreBackendInterface.h b/WebCore/storage/IDBObjectStoreBackendInterface.h >index c19855c76de1e6252438592177e9c01f7723219d..53ade62872dc7f623b629df3e37d6562f8f65232 100644 >--- a/WebCore/storage/IDBObjectStoreBackendInterface.h >+++ b/WebCore/storage/IDBObjectStoreBackendInterface.h >@@ -49,15 +49,15 @@ public: > virtual String keyPath() const = 0; > virtual PassRefPtr<DOMStringList> indexNames() const = 0; > >- virtual void get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface* transaction) = 0; >- virtual void put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>) = 0; >- virtual void remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; >+ virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, bool addOnly, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; >+ virtual void remove(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > >- virtual void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name) = 0; >- virtual void removeIndex(const String& name, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void removeIndex(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > >- virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>) = 0; >+ virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*) = 0; > }; > > } // namespace WebCore >diff --git a/WebCore/storage/IDBRequest.cpp b/WebCore/storage/IDBRequest.cpp >index a7760f49b94836670ec9016847d3a952d3c3308a..76b1d38b31d195596fb1d3f9294271e703cc4f63 100644 >--- a/WebCore/storage/IDBRequest.cpp >+++ b/WebCore/storage/IDBRequest.cpp >@@ -54,8 +54,8 @@ IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> sourc > , m_aborted(false) > , m_readyState(LOADING) > { >- if (transaction) >- IDBPendingTransactionMonitor::removePendingTransaction(transaction); >+ if (m_transaction) >+ IDBPendingTransactionMonitor::removePendingTransaction(m_transaction.get()); > } > > IDBRequest::~IDBRequest() >@@ -72,12 +72,15 @@ IDBRequest::~IDBRequest() > abort(); > } > >-bool IDBRequest::resetReadyState() >+bool IDBRequest::resetReadyState(IDBTransactionBackendInterface* transaction) > { > if (m_aborted) > return false; > ASSERT(m_readyState == DONE); > m_readyState = LOADING; >+ ASSERT(!m_transaction); >+ m_transaction = transaction; >+ IDBPendingTransactionMonitor::removePendingTransaction(m_transaction.get()); > return true; > } > >@@ -93,7 +96,7 @@ void IDBRequest::onSuccess() > > void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend) > { >- scheduleEvent(IDBAny::create(IDBCursor::create(backend, this)), 0); >+ scheduleEvent(IDBAny::create(IDBCursor::create(backend, this, m_transaction.get())), 0); > } > > void IDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend) >@@ -103,7 +106,7 @@ void IDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend) > > void IDBRequest::onSuccess(PassRefPtr<IDBIndexBackendInterface> backend) > { >- scheduleEvent(IDBAny::create(IDBIndex::create(backend)), 0); >+ scheduleEvent(IDBAny::create(IDBIndex::create(backend, m_transaction.get())), 0); > } > > void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey) >@@ -113,9 +116,20 @@ void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey) > > void IDBRequest::onSuccess(PassRefPtr<IDBObjectStoreBackendInterface> backend) > { >- // FIXME: the transaction pointer should be the one of the setVersion transaction. This is because >- // this callback is only executed for operations that neen to run in a setVersion transaction. >- scheduleEvent(IDBAny::create(IDBObjectStore::create(backend, 0)), 0); >+ // FIXME: This function should go away once createObjectStore is sync. >+ scheduleEvent(IDBAny::create(IDBObjectStore::create(backend, m_transaction.get())), 0); >+} >+ >+void IDBRequest::onSuccess(PassRefPtr<IDBTransactionBackendInterface> prpBackend) >+{ >+ RefPtr<IDBTransactionBackendInterface> backend = prpBackend; >+ // This is only used by setVersion which will always have a source that's an IDBDatabase. >+ m_source->idbDatabase()->setSetVersionTransaction(backend.get()); >+ RefPtr<IDBTransaction> frontend = IDBTransaction::create(scriptExecutionContext(), backend, m_source->idbDatabase().get()); >+ backend->setCallbacks(frontend.get()); >+ m_transaction = backend; >+ IDBPendingTransactionMonitor::removePendingTransaction(m_transaction.get()); >+ scheduleEvent(IDBAny::create(frontend.release()), 0); > } > > void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue) >@@ -165,6 +179,10 @@ void IDBRequest::timerFired(Timer<IDBRequest>*) > // need to make sure that resume() doesn't re-start the timer based on m_selfRef being set. > RefPtr<IDBRequest> selfRef = m_selfRef.release(); > >+ // readyStateReset can be called synchronously while we're dispatching the event. >+ RefPtr<IDBTransactionBackendInterface> transaction = m_transaction; >+ m_transaction.clear(); >+ > Vector<PendingEvent> pendingEvents; > pendingEvents.swap(m_pendingEvents); > for (size_t i = 0; i < pendingEvents.size(); ++i) { >@@ -176,12 +194,11 @@ void IDBRequest::timerFired(Timer<IDBRequest>*) > dispatchEvent(IDBSuccessEvent::create(m_source, pendingEvents[i].m_result)); > } > } >- if (m_transaction) { >+ if (transaction) { > // Now that we processed all pending events, let the transaction monitor check if > // it can commit the current transaction or if there's anything new pending. > // FIXME: Handle the workers case. >- m_transaction->didCompleteTaskEvents(); >- m_transaction.clear(); >+ transaction->didCompleteTaskEvents(); > } > } > >diff --git a/WebCore/storage/IDBRequest.h b/WebCore/storage/IDBRequest.h >index c0515aae2660c463ca9a841a7ac7995d4ff389e8..bab8df8f4d940a126b17eed6802526c285ba7f3b 100644 >--- a/WebCore/storage/IDBRequest.h >+++ b/WebCore/storage/IDBRequest.h >@@ -46,7 +46,7 @@ class IDBTransactionBackendInterface; > > class IDBRequest : public IDBCallbacks, public EventTarget, public ActiveDOMObject { > public: >- static PassRefPtr<IDBRequest> create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface* transaction = 0) { return adoptRef(new IDBRequest(context, source, transaction)); } >+ static PassRefPtr<IDBRequest> create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface* transaction) { return adoptRef(new IDBRequest(context, source, transaction)); } > virtual ~IDBRequest(); > > // Defined in the IDL >@@ -59,7 +59,7 @@ public: > DEFINE_ATTRIBUTE_EVENT_LISTENER(success); > DEFINE_ATTRIBUTE_EVENT_LISTENER(error); > >- bool resetReadyState(); >+ bool resetReadyState(IDBTransactionBackendInterface*); > > // IDBCallbacks > virtual void onError(PassRefPtr<IDBDatabaseError>); >@@ -69,6 +69,7 @@ public: > virtual void onSuccess(PassRefPtr<IDBIndexBackendInterface>); > virtual void onSuccess(PassRefPtr<IDBKey>); > virtual void onSuccess(PassRefPtr<IDBObjectStoreBackendInterface>); >+ virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>); > virtual void onSuccess(PassRefPtr<SerializedScriptValue>); > > // EventTarget >@@ -78,8 +79,8 @@ public: > virtual ScriptExecutionContext* scriptExecutionContext() const; > virtual bool canSuspend() const; > >- using RefCounted<IDBCallbacks>::ref; >- using RefCounted<IDBCallbacks>::deref; >+ using ThreadSafeShared<IDBCallbacks>::ref; >+ using ThreadSafeShared<IDBCallbacks>::deref; > > private: > IDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface* transaction); >diff --git a/WebCore/storage/IDBTransactionBackendImpl.cpp b/WebCore/storage/IDBTransactionBackendImpl.cpp >index 4f18437f0be44efc692f61a7cc82076e8cb745e1..861c6fd7c47862de097f732fc3f118a2632f673a 100644 >--- a/WebCore/storage/IDBTransactionBackendImpl.cpp >+++ b/WebCore/storage/IDBTransactionBackendImpl.cpp >@@ -44,7 +44,7 @@ IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores > , m_mode(mode) > , m_timeout(timeout) > , m_id(id) >- , m_state(NotStarted) >+ , m_state(Unused) > , m_database(database) > , m_transaction(new SQLiteTransaction(database->sqliteDatabase())) > , m_timer(this, &IDBTransactionBackendImpl::timerFired) >@@ -65,7 +65,7 @@ bool IDBTransactionBackendImpl::scheduleTask(PassOwnPtr<ScriptExecutionContext:: > return false; > > m_taskQueue.append(task); >- if (m_state == NotStarted) >+ if (m_state == Unused) > start(); > > return true; >@@ -84,7 +84,10 @@ void IDBTransactionBackendImpl::abort() > > void IDBTransactionBackendImpl::didCompleteTaskEvents() > { >- ASSERT(m_state == Started); >+ if (m_state == Finished) >+ return; >+ >+ ASSERT(m_state == Running); > ASSERT(m_pendingEvents); > > m_pendingEvents--; >@@ -105,7 +108,7 @@ void IDBTransactionBackendImpl::didCompleteTaskEvents() > > void IDBTransactionBackendImpl::run() > { >- ASSERT(m_state == Started); >+ ASSERT(m_state == StartPending || m_state == Running); > ASSERT(!m_timer.isActive()); > > m_timer.startOneShot(0); >@@ -113,16 +116,15 @@ void IDBTransactionBackendImpl::run() > > void IDBTransactionBackendImpl::start() > { >- ASSERT(m_state == NotStarted); >+ ASSERT(m_state == Unused); > >- m_state = Started; >- m_transaction->begin(); >+ m_state = StartPending; > m_database->transactionCoordinator()->didStartTransaction(this); > } > > void IDBTransactionBackendImpl::commit() > { >- ASSERT(m_state == Started); >+ ASSERT(m_state == Running); > > m_state = Finished; > m_transaction->commit(); >@@ -132,7 +134,12 @@ void IDBTransactionBackendImpl::commit() > void IDBTransactionBackendImpl::timerFired(Timer<IDBTransactionBackendImpl>*) > { > ASSERT(!m_taskQueue.isEmpty()); >- ASSERT(m_state == Started); >+ >+ if (m_state == StartPending) { >+ m_transaction->begin(); >+ m_state = Running; >+ } else >+ ASSERT(m_state == Running); > > TaskQueue queue; > queue.swap(m_taskQueue); >diff --git a/WebCore/storage/IDBTransactionBackendImpl.h b/WebCore/storage/IDBTransactionBackendImpl.h >index c037a11568386bf94240a5c525e3244459fbe23f..09a6a1c6d7e210262c2b0dcdaaed9284517439f8 100644 >--- a/WebCore/storage/IDBTransactionBackendImpl.h >+++ b/WebCore/storage/IDBTransactionBackendImpl.h >@@ -60,9 +60,10 @@ private: > IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl*); > > enum State { >- NotStarted, >- Started, >- Finished, >+ Unused, // Created, but no tasks yet. >+ StartPending, // Enqueued tasks, but SQLite transaction not yet started. >+ Running, // SQLite transaction started but not yet finished. >+ Finished, // Either aborted or committed. > }; > > void start(); >diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog >index eb5c2efa51bf2ac310f51d80afcfa45d45fd4dbc..553faa58c4fca68c0dc4b5857c0cba5b91431591 100644 >--- a/WebKit/chromium/ChangeLog >+++ b/WebKit/chromium/ChangeLog >@@ -1,3 +1,76 @@ >+2010-09-29 Jeremy Orlow <jorlow@chromium.org> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Finished IDBTransaction for IndexedDB >+ https://bugs.webkit.org/show_bug.cgi?id=46823 >+ >+ * public/WebIDBCallbacks.h: >+ (WebKit::WebIDBCallbacks::onSuccess): >+ * public/WebIDBDatabase.h: >+ (WebKit::WebIDBDatabase::createObjectStore): >+ (WebKit::WebIDBDatabase::removeObjectStore): >+ (WebKit::WebIDBDatabase::close): >+ * public/WebIDBIndex.h: >+ (WebKit::WebIDBIndex::openObjectCursor): >+ (WebKit::WebIDBIndex::openCursor): >+ (WebKit::WebIDBIndex::getObject): >+ (WebKit::WebIDBIndex::get): >+ * public/WebIDBObjectStore.h: >+ (WebKit::WebIDBObjectStore::get): >+ (WebKit::WebIDBObjectStore::put): >+ (WebKit::WebIDBObjectStore::remove): >+ (WebKit::WebIDBObjectStore::createIndex): >+ (WebKit::WebIDBObjectStore::removeIndex): >+ (WebKit::WebIDBObjectStore::openCursor): >+ * public/WebIDBTransaction.h: >+ (WebKit::WebIDBTransaction::id): >+ (WebKit::WebIDBTransaction::getIDBTransactionBackendInterface): >+ * src/IDBCallbacksProxy.cpp: >+ (WebCore::IDBCallbacksProxy::onSuccess): >+ * src/IDBCallbacksProxy.h: >+ * src/IDBDatabaseProxy.cpp: >+ (WebCore::IDBDatabaseProxy::createObjectStore): >+ (WebCore::IDBDatabaseProxy::removeObjectStore): >+ (WebCore::IDBDatabaseProxy::close): >+ * src/IDBDatabaseProxy.h: >+ * src/IDBIndexBackendProxy.cpp: >+ (WebCore::IDBIndexBackendProxy::openObjectCursor): >+ (WebCore::IDBIndexBackendProxy::openCursor): >+ (WebCore::IDBIndexBackendProxy::getObject): >+ (WebCore::IDBIndexBackendProxy::get): >+ * src/IDBIndexBackendProxy.h: >+ * src/IDBObjectStoreProxy.cpp: >+ (WebCore::IDBObjectStoreProxy::put): >+ (WebCore::IDBObjectStoreProxy::remove): >+ (WebCore::IDBObjectStoreProxy::createIndex): >+ (WebCore::IDBObjectStoreProxy::removeIndex): >+ (WebCore::IDBObjectStoreProxy::openCursor): >+ * src/IDBObjectStoreProxy.h: >+ * src/IDBTransactionBackendProxy.cpp: >+ (WebCore::IDBTransactionBackendProxy::IDBTransactionBackendProxy): >+ * src/WebIDBCallbacksImpl.cpp: >+ (WebCore::WebIDBCallbacksImpl::onSuccess): >+ * src/WebIDBCallbacksImpl.h: >+ * src/WebIDBDatabaseImpl.cpp: >+ (WebKit::WebIDBDatabaseImpl::createObjectStore): >+ (WebKit::WebIDBDatabaseImpl::removeObjectStore): >+ (WebKit::WebIDBDatabaseImpl::close): >+ * src/WebIDBDatabaseImpl.h: >+ * src/WebIDBIndexImpl.cpp: >+ (WebKit::WebIDBIndexImpl::openCursor): >+ (WebKit::WebIDBIndexImpl::openObjectCursor): >+ (WebKit::WebIDBIndexImpl::getObject): >+ (WebKit::WebIDBIndexImpl::get): >+ * src/WebIDBIndexImpl.h: >+ * src/WebIDBObjectStoreImpl.cpp: >+ (WebKit::WebIDBObjectStoreImpl::put): >+ (WebKit::WebIDBObjectStoreImpl::remove): >+ (WebKit::WebIDBObjectStoreImpl::createIndex): >+ (WebKit::WebIDBObjectStoreImpl::removeIndex): >+ (WebKit::WebIDBObjectStoreImpl::openCursor): >+ * src/WebIDBObjectStoreImpl.h: >+ > 2010-09-28 Andrei Popescu <andreip@google.com> > > Reviewed by Jeremy Orlow. >diff --git a/WebKit/chromium/public/WebIDBCallbacks.h b/WebKit/chromium/public/WebIDBCallbacks.h >index 2e2c4d299e0c8c7f575daf2b4e807fe7753cd6d1..64ffc08deb517c6a7b4a17d7c400883847249a0d 100644 >--- a/WebKit/chromium/public/WebIDBCallbacks.h >+++ b/WebKit/chromium/public/WebIDBCallbacks.h >@@ -36,6 +36,7 @@ class WebIDBDatabaseError; > class WebIDBKey; > class WebIDBIndex; > class WebIDBObjectStore; >+class WebIDBTransaction; > class WebSerializedScriptValue; > > class WebIDBCallbacks { >@@ -51,6 +52,7 @@ public: > virtual void onSuccess(const WebIDBKey&) { WEBKIT_ASSERT_NOT_REACHED(); } > virtual void onSuccess(WebIDBIndex*) { WEBKIT_ASSERT_NOT_REACHED(); } > virtual void onSuccess(WebIDBObjectStore*) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void onSuccess(WebIDBTransaction*) { WEBKIT_ASSERT_NOT_REACHED(); } > virtual void onSuccess(const WebSerializedScriptValue&) { WEBKIT_ASSERT_NOT_REACHED(); } > }; > >diff --git a/WebKit/chromium/public/WebIDBDatabase.h b/WebKit/chromium/public/WebIDBDatabase.h >index 4e5cdcbcd18e220f05ecfdf250574baf67af40eb..2021f6f220c91d4e9c39d1aa3311bcad5faa0976 100644 >--- a/WebKit/chromium/public/WebIDBDatabase.h >+++ b/WebKit/chromium/public/WebIDBDatabase.h >@@ -61,14 +61,14 @@ public: > WEBKIT_ASSERT_NOT_REACHED(); > return WebDOMStringList(); > } >- virtual void createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } > // Transfers ownership of the WebIDBObjectStore to the caller. > virtual WebIDBObjectStore* objectStore(const WebString& name, unsigned short mode) > { > WEBKIT_ASSERT_NOT_REACHED(); > return 0; > } >- virtual void removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } > virtual void setVersion(const WebString& version, WebIDBCallbacks* callbacks) { WEBKIT_ASSERT_NOT_REACHED(); } > // Transfers ownership of the WebIDBTransaction to the caller. > virtual WebIDBTransaction* transaction(const WebDOMStringList& names, unsigned short mode, unsigned long timeout) >@@ -76,7 +76,7 @@ public: > WEBKIT_ASSERT_NOT_REACHED(); > return 0; > } >- >+ virtual void close() { WEBKIT_ASSERT_NOT_REACHED(); } > }; > > } // namespace WebKit >diff --git a/WebKit/chromium/public/WebIDBIndex.h b/WebKit/chromium/public/WebIDBIndex.h >index b4ba1f40aff390edaa8c330fe9ca21f23eec2136..e52b4870ffd789ae3f43f386604ff663f55a528e 100644 >--- a/WebKit/chromium/public/WebIDBIndex.h >+++ b/WebKit/chromium/public/WebIDBIndex.h >@@ -61,43 +61,10 @@ public: > return false; > } > >- // FIXME: Remove the versions without transaction parameters. >- virtual void openObjectCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- openObjectCursor(range, direction, callbacks); >- } >- virtual void openObjectCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- openObjectCursor(range, direction, callbacks, transaction); >- } >- virtual void openCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- openCursor(range, direction, callbacks); >- } >- virtual void openCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- openCursor(range, direction, callbacks, transaction); >- } >- virtual void getObject(const WebIDBKey& key, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- getObject(key, callbacks); >- } >- virtual void getObject(const WebIDBKey& key, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- getObject(key, callbacks, transaction); >- } >- virtual void get(const WebIDBKey& key, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- get(key, callbacks); >- } >- virtual void get(const WebIDBKey& key, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- get(key, callbacks, transaction); >- } >+ virtual void openObjectCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void getObject(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void get(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } > }; > > } // namespace WebKit >diff --git a/WebKit/chromium/public/WebIDBObjectStore.h b/WebKit/chromium/public/WebIDBObjectStore.h >index 19efd489cf1b7d0e8643845688e39b76ec7df92e..51a8d8c85d612f64e0af1242829574b160a24936 100755 >--- a/WebKit/chromium/public/WebIDBObjectStore.h >+++ b/WebKit/chromium/public/WebIDBObjectStore.h >@@ -58,51 +58,18 @@ public: > return WebDOMStringList(); > } > >- // FIXME: Remove the default parameters for transactionIds. >- virtual void get(const WebIDBKey& key, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- get(key, callbacks); >- } >- virtual void get(const WebIDBKey& key, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- get(key, callbacks, transaction); >- } >- virtual void put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- put(value, key, addOnly, callbacks); >- } >- virtual void put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- put(value, key, addOnly, callbacks, transaction); >- } >- virtual void remove(const WebIDBKey& key, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- remove(key, callbacks); >- } >- virtual void remove(const WebIDBKey& key, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- remove(key, callbacks, transaction); >- } >- virtual void createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void get(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void put(const WebSerializedScriptValue&, const WebIDBKey&, bool addOnly, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void remove(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } > // Transfers ownership of the WebIDBIndex to the caller. > virtual WebIDBIndex* index(const WebString& name) > { > WEBKIT_ASSERT_NOT_REACHED(); > return 0; > } >- virtual void removeIndex(const WebString& name, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } >- virtual void openCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction&) >- { >- openCursor(range, direction, callbacks); >- } >- virtual void openCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks) >- { >- WebIDBTransaction transaction; >- openCursor(range, direction, callbacks, transaction); >- } >+ virtual void removeIndex(const WebString& name, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } >+ virtual void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&) { WEBKIT_ASSERT_NOT_REACHED(); } > // FIXME: finish. > }; > >diff --git a/WebKit/chromium/public/WebIDBTransaction.h b/WebKit/chromium/public/WebIDBTransaction.h >index 7b51b97e0b366aa3b42ca5eeabb39ef0d3b1e5df..6a739c34d4a984797f1b932699ba85fcd326e84e 100644 >--- a/WebKit/chromium/public/WebIDBTransaction.h >+++ b/WebKit/chromium/public/WebIDBTransaction.h >@@ -54,8 +54,7 @@ public: > virtual void didCompleteTaskEvents() { WEBKIT_ASSERT_NOT_REACHED(); } > virtual int id() const > { >- // FIXME: Uncomment this after the next Chromium WebKit roll. >- //WEBKIT_ASSERT_NOT_REACHED(); >+ WEBKIT_ASSERT_NOT_REACHED(); > return 0; > } > virtual void setCallbacks(WebIDBTransactionCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } >@@ -63,7 +62,6 @@ public: > // FIXME: this is never called from WebCore. Find a cleaner solution. > virtual WebCore::IDBTransactionBackendInterface* getIDBTransactionBackendInterface() const > { >- WEBKIT_ASSERT_NOT_REACHED(); > return 0; > } > >diff --git a/WebKit/chromium/src/IDBCallbacksProxy.cpp b/WebKit/chromium/src/IDBCallbacksProxy.cpp >index 3eab6224a979b0713fd9fe7aafa574ff814c4381..69051d0a6da7c66c0d075f3fb99cab9d2933dec2 100644 >--- a/WebKit/chromium/src/IDBCallbacksProxy.cpp >+++ b/WebKit/chromium/src/IDBCallbacksProxy.cpp >@@ -38,6 +38,7 @@ > #include "WebIDBIndexImpl.h" > #include "WebIDBKey.h" > #include "WebIDBObjectStoreImpl.h" >+#include "WebIDBTransactionImpl.h" > #include "WebSerializedScriptValue.h" > > #if ENABLE(INDEXED_DATABASE) >@@ -100,6 +101,12 @@ void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBObjectStoreBackendInterface> bac > m_callbacks.clear(); > } > >+void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBTransactionBackendInterface> backend) >+{ >+ m_callbacks->onSuccess(new WebKit::WebIDBTransactionImpl(backend)); >+ m_callbacks.clear(); >+} >+ > void IDBCallbacksProxy::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue) > { > m_callbacks->onSuccess(WebKit::WebSerializedScriptValue(serializedScriptValue)); >diff --git a/WebKit/chromium/src/IDBCallbacksProxy.h b/WebKit/chromium/src/IDBCallbacksProxy.h >index 506dbb0f6ca98fc49d682fafced47f9ccbd41ebc..8c261612a467e98df4233951e236148c63428583 100644 >--- a/WebKit/chromium/src/IDBCallbacksProxy.h >+++ b/WebKit/chromium/src/IDBCallbacksProxy.h >@@ -54,6 +54,7 @@ public: > virtual void onSuccess(PassRefPtr<IDBIndexBackendInterface>); > virtual void onSuccess(PassRefPtr<IDBKey>); > virtual void onSuccess(PassRefPtr<IDBObjectStoreBackendInterface>); >+ virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>); > virtual void onSuccess(PassRefPtr<SerializedScriptValue>); > > private: >diff --git a/WebKit/chromium/src/IDBDatabaseProxy.cpp b/WebKit/chromium/src/IDBDatabaseProxy.cpp >index ce5e0a6ccfd320bbe637e3df7bac279a8bfb38d6..564fddb6e6ab8ff2f46e48442d578f9ba4674e5b 100644 >--- a/WebKit/chromium/src/IDBDatabaseProxy.cpp >+++ b/WebKit/chromium/src/IDBDatabaseProxy.cpp >@@ -76,9 +76,12 @@ PassRefPtr<DOMStringList> IDBDatabaseProxy::objectStores() const > return m_webIDBDatabase->objectStores(); > } > >-void IDBDatabaseProxy::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks) >+void IDBDatabaseProxy::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBDatabase->createObjectStore(name, keyPath, autoIncrement, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBDatabase->createObjectStore(name, keyPath, autoIncrement, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > > PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseProxy::objectStore(const String& name, unsigned short mode) >@@ -89,9 +92,12 @@ PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseProxy::objectStore(const S > return IDBObjectStoreProxy::create(objectStore); > } > >-void IDBDatabaseProxy::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks) >+void IDBDatabaseProxy::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBDatabase->removeObjectStore(name, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBDatabase->removeObjectStore(name, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > > void IDBDatabaseProxy::setVersion(const String& version, PassRefPtr<IDBCallbacks> callbacks) >@@ -106,6 +112,11 @@ PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseProxy::transaction(DOMStri > return IDBTransactionBackendProxy::create(transaction); > } > >+void IDBDatabaseProxy::close() >+{ >+ m_webIDBDatabase->close(); >+} >+ > } // namespace WebCore > > #endif // ENABLE(INDEXED_DATABASE) >diff --git a/WebKit/chromium/src/IDBDatabaseProxy.h b/WebKit/chromium/src/IDBDatabaseProxy.h >index fffd23ee852a6136c41a5cebe0a08dc4ddaf65ab..eaeeb27b55b337686f4c923f14914c3f761492fa 100644 >--- a/WebKit/chromium/src/IDBDatabaseProxy.h >+++ b/WebKit/chromium/src/IDBDatabaseProxy.h >@@ -47,13 +47,12 @@ public: > virtual String version() const; > virtual PassRefPtr<DOMStringList> objectStores() const; > >- // FIXME: Add setVersion. >- >- virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>); >+ virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(const String& name, unsigned short mode); >- virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>); >+ virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > virtual void setVersion(const String& version, PassRefPtr<IDBCallbacks>); > virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, unsigned long timeout); >+ virtual void close(); > > private: > IDBDatabaseProxy(PassOwnPtr<WebKit::WebIDBDatabase>); >diff --git a/WebKit/chromium/src/IDBIndexBackendProxy.cpp b/WebKit/chromium/src/IDBIndexBackendProxy.cpp >index f92f4f2b356253a3d503d2eeb3d376b49df04254..8f26bf197e39d7c8878f0b0609eaa4b4883fd315 100644 >--- a/WebKit/chromium/src/IDBIndexBackendProxy.cpp >+++ b/WebKit/chromium/src/IDBIndexBackendProxy.cpp >@@ -30,6 +30,7 @@ > > #include "IDBCallbacks.h" > #include "IDBKeyRange.h" >+#include "IDBTransactionBackendProxy.h" > #include "WebIDBCallbacksImpl.h" > #include "WebIDBDatabaseError.h" > #include "WebIDBIndex.h" >@@ -72,24 +73,36 @@ bool IDBIndexBackendProxy::unique() > return m_webIDBIndex->unique(); > } > >-void IDBIndexBackendProxy::openObjectCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendProxy::openObjectCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBIndex->openObjectCursor(keyRange, direction, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBIndex->openObjectCursor(keyRange, direction, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBIndexBackendProxy::openCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendProxy::openCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBIndex->openCursor(keyRange, direction, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBIndex->openCursor(keyRange, direction, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBIndexBackendProxy::getObject(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendProxy::getObject(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBIndex->getObject(key, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBIndex->getObject(key, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBIndexBackendProxy::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBIndexBackendProxy::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBIndex->get(key, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBIndex->get(key, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > > } // namespace WebCore >diff --git a/WebKit/chromium/src/IDBIndexBackendProxy.h b/WebKit/chromium/src/IDBIndexBackendProxy.h >index 6aafdfac97e88784c419932536b2dc6846ba9f45..031ed4087c4ed6ff5ea7417caf895a5515603783 100644 >--- a/WebKit/chromium/src/IDBIndexBackendProxy.h >+++ b/WebKit/chromium/src/IDBIndexBackendProxy.h >@@ -46,10 +46,10 @@ public: > virtual String keyPath(); > virtual bool unique(); > >- virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>); >- virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>); >- virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); >- virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); >+ virtual void openObjectCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void getObject(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > > private: > IDBIndexBackendProxy(PassOwnPtr<WebKit::WebIDBIndex>); >diff --git a/WebKit/chromium/src/IDBObjectStoreProxy.cpp b/WebKit/chromium/src/IDBObjectStoreProxy.cpp >index 82ca5f66cf097fc39086dbe643e63dab6ff8fcfd..69aa8ca895050d51e722ba2e5bb498a508aa9fa7 100755 >--- a/WebKit/chromium/src/IDBObjectStoreProxy.cpp >+++ b/WebKit/chromium/src/IDBObjectStoreProxy.cpp >@@ -80,19 +80,28 @@ void IDBObjectStoreProxy::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> c > m_webIDBObjectStore->get(key, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBObjectStoreProxy::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreProxy::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBObjectStore->put(value, key, addOnly, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBObjectStore->put(value, key, addOnly, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBObjectStoreProxy::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreProxy::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBObjectStore->remove(key, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBObjectStore->remove(key, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBObjectStoreProxy::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreProxy::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBObjectStore->createIndex(name, keyPath, unique, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBObjectStore->createIndex(name, keyPath, unique, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > > PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreProxy::index(const String& name) >@@ -103,14 +112,20 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreProxy::index(const String& na > return IDBIndexBackendProxy::create(index); > } > >-void IDBObjectStoreProxy::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreProxy::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBObjectStore->removeIndex(name, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBObjectStore->removeIndex(name, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > >-void IDBObjectStoreProxy::openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks) >+void IDBObjectStoreProxy::openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction) > { >- m_webIDBObjectStore->openCursor(range, direction, new WebIDBCallbacksImpl(callbacks)); >+ // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, >+ // all implementations of IDB interfaces are proxy objects. >+ IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); >+ m_webIDBObjectStore->openCursor(range, direction, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction()); > } > > } // namespace WebCore >diff --git a/WebKit/chromium/src/IDBObjectStoreProxy.h b/WebKit/chromium/src/IDBObjectStoreProxy.h >index 13dfe236de6ee45c5a5f18c46676167d44230bb2..80e4668c5ed05a9012e9eab9f0e7e15790ac78a4 100755 >--- a/WebKit/chromium/src/IDBObjectStoreProxy.h >+++ b/WebKit/chromium/src/IDBObjectStoreProxy.h >@@ -40,21 +40,21 @@ namespace WebCore { > class IDBObjectStoreProxy : public IDBObjectStoreBackendInterface { > public: > static PassRefPtr<IDBObjectStoreBackendInterface> create(PassOwnPtr<WebKit::WebIDBObjectStore>); >- ~IDBObjectStoreProxy(); >+ virtual ~IDBObjectStoreProxy(); > >- String name() const; >- String keyPath() const; >- PassRefPtr<DOMStringList> indexNames() const; >+ virtual String name() const; >+ virtual String keyPath() const; >+ virtual PassRefPtr<DOMStringList> indexNames() const; > >- void get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >- void put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>); >- void remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); >+ virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, bool addOnly, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual void remove(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > >- void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>); >- PassRefPtr<IDBIndexBackendInterface> index(const String& name); >- void removeIndex(const String& name, PassRefPtr<IDBCallbacks>); >+ virtual void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); >+ virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name); >+ virtual void removeIndex(const String& name, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > >- virtual void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>); >+ virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*); > > private: > IDBObjectStoreProxy(PassOwnPtr<WebKit::WebIDBObjectStore>); >diff --git a/WebKit/chromium/src/IDBTransactionBackendProxy.cpp b/WebKit/chromium/src/IDBTransactionBackendProxy.cpp >index 59e88d893e152e759ad1c06a1bc0faa5be838b28..81b7ceeaef7c44c6bceff074ca4e30fed251fd67 100644 >--- a/WebKit/chromium/src/IDBTransactionBackendProxy.cpp >+++ b/WebKit/chromium/src/IDBTransactionBackendProxy.cpp >@@ -45,6 +45,8 @@ PassRefPtr<IDBTransactionBackendInterface> IDBTransactionBackendProxy::create(Pa > IDBTransactionBackendProxy::IDBTransactionBackendProxy(PassOwnPtr<WebKit::WebIDBTransaction> transaction) > : m_webIDBTransaction(transaction) > { >+ if (!m_webIDBTransaction) >+ m_webIDBTransaction = adoptPtr(new WebKit::WebIDBTransaction()); > } > > IDBTransactionBackendProxy::~IDBTransactionBackendProxy() >diff --git a/WebKit/chromium/src/WebIDBCallbacksImpl.cpp b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp >index fe67789a517de1fb6584693e2dccf9fc4ac7341b..14ed02ee5ef820264aac619551f47b9784fac625 100644 >--- a/WebKit/chromium/src/WebIDBCallbacksImpl.cpp >+++ b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp >@@ -33,12 +33,14 @@ > #include "IDBIndexBackendProxy.h" > #include "IDBKey.h" > #include "IDBObjectStoreProxy.h" >+#include "IDBTransactionBackendProxy.h" > #include "WebIDBCallbacks.h" > #include "WebIDBDatabase.h" > #include "WebIDBDatabaseError.h" > #include "WebIDBIndex.h" > #include "WebIDBKey.h" > #include "WebIDBObjectStore.h" >+#include "WebIDBTransaction.h" > #include "WebSerializedScriptValue.h" > > #if ENABLE(INDEXED_DATABASE) >@@ -89,6 +91,11 @@ void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBObjectStore* webKitInstance) > m_callbacks->onSuccess(IDBObjectStoreProxy::create(webKitInstance)); > } > >+void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBTransaction* webKitInstance) >+{ >+ m_callbacks->onSuccess(IDBTransactionBackendProxy::create(webKitInstance)); >+} >+ > void WebIDBCallbacksImpl::onSuccess(const WebKit::WebSerializedScriptValue& serializedScriptValue) > { > m_callbacks->onSuccess(serializedScriptValue); >diff --git a/WebKit/chromium/src/WebIDBCallbacksImpl.h b/WebKit/chromium/src/WebIDBCallbacksImpl.h >index 1835c60c2c45fdc2081e99f6d7480df1ae491dca..33a72f4734628664f43cf2c8eae136de0dad9020 100644 >--- a/WebKit/chromium/src/WebIDBCallbacksImpl.h >+++ b/WebKit/chromium/src/WebIDBCallbacksImpl.h >@@ -48,6 +48,7 @@ public: > virtual void onSuccess(const WebKit::WebIDBKey&); > virtual void onSuccess(WebKit::WebIDBIndex*); > virtual void onSuccess(WebKit::WebIDBObjectStore*); >+ virtual void onSuccess(WebKit::WebIDBTransaction*); > virtual void onSuccess(const WebKit::WebSerializedScriptValue&); > > private: >diff --git a/WebKit/chromium/src/WebIDBDatabaseImpl.cpp b/WebKit/chromium/src/WebIDBDatabaseImpl.cpp >index 8870ff94ceb92eb69a42b9f1fa80f44692513d2f..abe6fbd0817d6195e0a9fc0d98847d1c31d54d76 100644 >--- a/WebKit/chromium/src/WebIDBDatabaseImpl.cpp >+++ b/WebKit/chromium/src/WebIDBDatabaseImpl.cpp >@@ -69,9 +69,9 @@ WebDOMStringList WebIDBDatabaseImpl::objectStores() const > return m_databaseBackend->objectStores(); > } > >-void WebIDBDatabaseImpl::createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks) >+void WebIDBDatabaseImpl::createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_databaseBackend->createObjectStore(name, keyPath, autoIncrement, IDBCallbacksProxy::create(callbacks)); >+ m_databaseBackend->createObjectStore(name, keyPath, autoIncrement, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > > WebIDBObjectStore* WebIDBDatabaseImpl::objectStore(const WebString& name, unsigned short mode) >@@ -82,9 +82,9 @@ WebIDBObjectStore* WebIDBDatabaseImpl::objectStore(const WebString& name, unsign > return new WebIDBObjectStoreImpl(objectStore); > } > >-void WebIDBDatabaseImpl::removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks) >+void WebIDBDatabaseImpl::removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_databaseBackend->removeObjectStore(name, IDBCallbacksProxy::create(callbacks)); >+ m_databaseBackend->removeObjectStore(name, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > > void WebIDBDatabaseImpl::setVersion(const WebString& version, WebIDBCallbacks* callbacks) >@@ -101,6 +101,11 @@ WebIDBTransaction* WebIDBDatabaseImpl::transaction(const WebDOMStringList& names > return new WebIDBTransactionImpl(transaction); > } > >+void WebIDBDatabaseImpl::close() >+{ >+ m_databaseBackend->close(); >+} >+ > } // namespace WebCore > > #endif // ENABLE(INDEXED_DATABASE) >diff --git a/WebKit/chromium/src/WebIDBDatabaseImpl.h b/WebKit/chromium/src/WebIDBDatabaseImpl.h >index e0eaaa58bf9ee036a2ce825f2b934b4e61212148..2274e48cfd598055a3317d586844fc4d1e6bd8b9 100644 >--- a/WebKit/chromium/src/WebIDBDatabaseImpl.h >+++ b/WebKit/chromium/src/WebIDBDatabaseImpl.h >@@ -49,11 +49,12 @@ public: > virtual WebString version() const; > virtual WebDOMStringList objectStores() const; > >- virtual void createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks); >+ virtual void createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks, const WebIDBTransaction&); > virtual WebIDBObjectStore* objectStore(const WebString& name, unsigned short mode); >- virtual void removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks); >+ virtual void removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks, const WebIDBTransaction&); > virtual void setVersion(const WebString& version, WebIDBCallbacks* callbacks); > virtual WebIDBTransaction* transaction(const WebDOMStringList& names, unsigned short mode, unsigned long timeout); >+ virtual void close(); > > private: > WTF::RefPtr<WebCore::IDBDatabaseBackendInterface> m_databaseBackend; >diff --git a/WebKit/chromium/src/WebIDBIndexImpl.cpp b/WebKit/chromium/src/WebIDBIndexImpl.cpp >index c049aac4b8bd06494e60b64360e473b2f7f0920f..87957781a5bab615553d8949e66a9d2f05b72ef3 100644 >--- a/WebKit/chromium/src/WebIDBIndexImpl.cpp >+++ b/WebKit/chromium/src/WebIDBIndexImpl.cpp >@@ -68,24 +68,24 @@ bool WebIDBIndexImpl::unique() const > return m_backend->unique(); > } > >-void WebIDBIndexImpl::openCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks) >+void WebIDBIndexImpl::openCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_backend->openCursor(keyRange, direction, IDBCallbacksProxy::create(callbacks)); >+ m_backend->openCursor(keyRange, direction, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBIndexImpl::openObjectCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks) >+void WebIDBIndexImpl::openObjectCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_backend->openObjectCursor(keyRange, direction, IDBCallbacksProxy::create(callbacks)); >+ m_backend->openObjectCursor(keyRange, direction, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBIndexImpl::getObject(const WebIDBKey& keyRange, WebIDBCallbacks* callbacks) >+void WebIDBIndexImpl::getObject(const WebIDBKey& keyRange, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_backend->getObject(keyRange, IDBCallbacksProxy::create(callbacks)); >+ m_backend->getObject(keyRange, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBIndexImpl::get(const WebIDBKey& keyRange, WebIDBCallbacks* callbacks) >+void WebIDBIndexImpl::get(const WebIDBKey& keyRange, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_backend->get(keyRange, IDBCallbacksProxy::create(callbacks)); >+ m_backend->get(keyRange, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > > } // namespace WebCore >diff --git a/WebKit/chromium/src/WebIDBIndexImpl.h b/WebKit/chromium/src/WebIDBIndexImpl.h >index 2108001ccdc2f798ef08debd789879e2bb32a909..cb2efc7756c1b8de8bdb36c64c9b69abcb27249b 100644 >--- a/WebKit/chromium/src/WebIDBIndexImpl.h >+++ b/WebKit/chromium/src/WebIDBIndexImpl.h >@@ -46,10 +46,10 @@ public: > virtual WebString keyPath() const; > virtual bool unique() const; > >- virtual void openObjectCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*); >- virtual void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*); >- virtual void getObject(const WebIDBKey&, WebIDBCallbacks*); >- virtual void get(const WebIDBKey&, WebIDBCallbacks*); >+ virtual void openObjectCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&); >+ virtual void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&); >+ virtual void getObject(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&); >+ virtual void get(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&); > > private: > WTF::RefPtr<WebCore::IDBIndexBackendInterface> m_backend; >diff --git a/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp >index 36d8ace4e9d2ef04112b4f2c1008f78eecbdac6a..3cf7f2579ea7396ce52a1f904d34470b0cee1a3f 100755 >--- a/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp >+++ b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp >@@ -71,19 +71,19 @@ void WebIDBObjectStoreImpl::get(const WebIDBKey& key, WebIDBCallbacks* callbacks > m_objectStore->get(key, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBObjectStoreImpl::put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks* callbacks) >+void WebIDBObjectStoreImpl::put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_objectStore->put(value, key, addOnly, IDBCallbacksProxy::create(callbacks)); >+ m_objectStore->put(value, key, addOnly, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBObjectStoreImpl::remove(const WebIDBKey& key, WebIDBCallbacks* callbacks) >+void WebIDBObjectStoreImpl::remove(const WebIDBKey& key, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_objectStore->remove(key, IDBCallbacksProxy::create(callbacks)); >+ m_objectStore->remove(key, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBObjectStoreImpl::createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks* callbacks) >+void WebIDBObjectStoreImpl::createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_objectStore->createIndex(name, keyPath, unique, IDBCallbacksProxy::create(callbacks)); >+ m_objectStore->createIndex(name, keyPath, unique, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > > WebIDBIndex* WebIDBObjectStoreImpl::index(const WebString& name) >@@ -94,14 +94,14 @@ WebIDBIndex* WebIDBObjectStoreImpl::index(const WebString& name) > return new WebIDBIndexImpl(index); > } > >-void WebIDBObjectStoreImpl::removeIndex(const WebString& name, WebIDBCallbacks* callbacks) >+void WebIDBObjectStoreImpl::removeIndex(const WebString& name, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_objectStore->removeIndex(name, IDBCallbacksProxy::create(callbacks)); >+ m_objectStore->removeIndex(name, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > >-void WebIDBObjectStoreImpl::openCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks) >+void WebIDBObjectStoreImpl::openCursor(const WebIDBKeyRange& keyRange, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction) > { >- m_objectStore->openCursor(IDBKeyRange::create(keyRange.left(), keyRange.right(), keyRange.flags()), direction, IDBCallbacksProxy::create(callbacks)); >+ m_objectStore->openCursor(IDBKeyRange::create(keyRange.left(), keyRange.right(), keyRange.flags()), direction, IDBCallbacksProxy::create(callbacks), transaction.getIDBTransactionBackendInterface()); > } > > } // namespace WebCore >diff --git a/WebKit/chromium/src/WebIDBObjectStoreImpl.h b/WebKit/chromium/src/WebIDBObjectStoreImpl.h >index a9f1200c9fc4d861d2ef5f79e944219613e64699..76e414b5c3ef53c1f7da80e19ffef29424a47edd 100755 >--- a/WebKit/chromium/src/WebIDBObjectStoreImpl.h >+++ b/WebKit/chromium/src/WebIDBObjectStoreImpl.h >@@ -48,14 +48,14 @@ public: > WebDOMStringList indexNames() const; > > void get(const WebIDBKey& key, WebIDBCallbacks*, const WebIDBTransaction&); >- void put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks*); >- void remove(const WebIDBKey& key, WebIDBCallbacks*); >+ void put(const WebSerializedScriptValue&, const WebIDBKey& key, bool addOnly, WebIDBCallbacks*, const WebIDBTransaction&); >+ void remove(const WebIDBKey& key, WebIDBCallbacks*, const WebIDBTransaction&); > >- void createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks* callbacks); >+ void createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks*, const WebIDBTransaction&); > WebIDBIndex* index(const WebString& name); >- void removeIndex(const WebString& name, WebIDBCallbacks* callbacks); >+ void removeIndex(const WebString& name, WebIDBCallbacks*, const WebIDBTransaction&); > >- void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*); >+ void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&); > > private: > WTF::RefPtr<WebCore::IDBObjectStoreBackendInterface> m_objectStore;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 46823
:
69223
|
69335