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-92558-20120731160255.patch (text/plain), 34.87 KB, created by
David Grogan
on 2012-07-31 16:03:12 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
David Grogan
Created:
2012-07-31 16:03:12 PDT
Size:
34.87 KB
patch
obsolete
>Subversion Revision: 123817 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8a5cc3491212a2bec28503ae128ef21fbbeb461d..d623b28adb3549b503650f623ffcdfd1af5460b0 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,90 @@ >+2012-07-31 David Grogan <dgrogan@chromium.org> >+ >+ IndexedDB: Core upgradeneeded logic >+ https://bugs.webkit.org/show_bug.cgi?id=92558 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This is the backend webkit logic needed for integer versions. The rest >+ is in https://bugs.webkit.org/show_bug.cgi?id=89505. >+ >+ I tried to make use of the existing processPendingCalls and added two >+ more queues, pendingOpenWithVersionCalls and >+ pendingSecondHalfOpenWithVersionCalls. The "second half" refers to >+ how there are two events that need to be fired in response to an >+ open-with-version call. The "second half" queue holds the open >+ requests that should immediately follow the caller's upgradeneeded >+ handler. >+ >+ No new tests, there are so many they are in their own patch - >+ https://bugs.webkit.org/show_bug.cgi?id=92560 >+ >+ * Modules/indexeddb/IDBBackingStore.h: >+ (IDBBackingStore): >+ * Modules/indexeddb/IDBCallbacks.h: >+ (WebCore::IDBCallbacks::onBlocked): >+ (WebCore::IDBCallbacks::onUpgradeNeeded): >+ * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: >+ (IDBDatabaseBackendImpl::PendingOpenCall): >+ (IDBDatabaseBackendImpl::PendingOpenWithVersionCall): >+ (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::create): >+ (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::callbacks): >+ (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::version): >+ (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::PendingOpenWithVersionCall): >+ (WebCore): >+ (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl): >+ (WebCore::IDBDatabaseBackendImpl::openInternal): >+ (WebCore::IDBDatabaseBackendImpl::metadata): >+ (WebCore::IDBDatabaseBackendImpl::setVersion): >+ (WebCore::IDBDatabaseBackendImpl::setIntVersionInternal): >+ (WebCore::IDBDatabaseBackendImpl::transactionFinished): >+ (WebCore::IDBDatabaseBackendImpl::transactionFinishedAndEventsFired): >+ When an upgradeneeded event is fired in response to an >+ open-with-version call, the version change transaction must receive its >+ complete event before processPendingCalls fires a success event at >+ IDBOpenDBRequest. In the future this should probably be changed >+ instead to transactionFinishedAndAbortFired and >+ transactionFinishedAndCompleteFired so that we'll know to fire a >+ success or error event at IDBOpenDBRequest. Currently, instead of >+ firing error when there's an abort, we don't fire anything. >+ (WebCore::IDBDatabaseBackendImpl::processPendingCalls): >+ Now that this is called after a connection is opened, we unfortunately >+ lose the invariant that there is only one existing connection when this >+ is called, but nothing inside there actually relied on that. >+ Additionally, the secondHalfOpen calls only ever need to be serviced >+ in one place: right after a version change transaction completes, so >+ it could be moved out of here. >+ (WebCore::IDBDatabaseBackendImpl::registerFrontendCallbacks): >+ Now that setVersion and deleteDatabase calls are queued up behind >+ secondHalfOpen calls, we have to service those queues when >+ secondHalfOpen calls complete, which is here. >+ (WebCore::IDBDatabaseBackendImpl::runIntVersionChangeTransaction): >+ (WebCore::IDBDatabaseBackendImpl::openConnectionWithVersion): >+ (WebCore::IDBDatabaseBackendImpl::deleteDatabase): >+ (WebCore::IDBDatabaseBackendImpl::close): >+ * Modules/indexeddb/IDBDatabaseBackendImpl.h: >+ (IDBDatabaseBackendImpl): >+ * Modules/indexeddb/IDBDatabaseCallbacks.h: >+ (WebCore::IDBDatabaseCallbacks::onVersionChange): >+ * Modules/indexeddb/IDBFactoryBackendImpl.cpp: >+ (WebCore::IDBFactoryBackendImpl::open): >+ This is refactored some so that the call to openConection{WithVersion} >+ happens once, at the end. >+ * Modules/indexeddb/IDBLevelDBBackingStore.cpp: >+ (WebCore::IDBLevelDBBackingStore::getIDBDatabaseMetaData): >+ (WebCore::IDBLevelDBBackingStore::createIDBDatabaseMetaData): >+ (WebCore::IDBLevelDBBackingStore::updateIDBDatabaseIntVersion): >+ (WebCore): >+ (WebCore::IDBLevelDBBackingStore::deleteDatabase): >+ * Modules/indexeddb/IDBLevelDBBackingStore.h: >+ (IDBLevelDBBackingStore): >+ * Modules/indexeddb/IDBTransactionBackendImpl.cpp: >+ (WebCore::IDBTransactionBackendImpl::commit): >+ See above comments about transactionFinishedAndEventsFired. I tried >+ moving the call to transactionFinished after the events were fired but >+ that failed some asserts. But fixing those asserts is still an >+ alternative to splitting up transactionFinished as is done here. >+ > 2012-07-26 Nayan Kumar K <nayankk@motorola.com> > > [WebGL] Initial size of canvas can be larger than MAX_VIEWPORT_DIMS. >diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog >index 1d704740c7fadd861998dae88538e62a741516ed..fe1b0ca00fddb3bf0ccbde2cec2633e6722de6b7 100644 >--- a/Source/WebKit/chromium/ChangeLog >+++ b/Source/WebKit/chromium/ChangeLog >@@ -1,3 +1,16 @@ >+2012-07-31 David Grogan <dgrogan@chromium.org> >+ >+ IndexedDB: Core upgradeneeded logic >+ https://bugs.webkit.org/show_bug.cgi?id=92558 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update overridden methods to match new signatures. >+ >+ * tests/IDBAbortOnCorruptTest.cpp: >+ (WebCore::FailingBackingStore::createIDBDatabaseMetaData): >+ * tests/IDBFakeBackingStore.h: >+ > 2012-07-26 Sheriff Bot <webkit.review.bot@gmail.com> > > Unreviewed, rolling out r123799. >diff --git a/Source/WebCore/Modules/indexeddb/IDBBackingStore.h b/Source/WebCore/Modules/indexeddb/IDBBackingStore.h >index 78a9f667add130e63e3c0746d4a703b489546bd7..444f2235f2a49b2be4e8882e2e97cd1a980fe94d 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBBackingStore.h >+++ b/Source/WebCore/Modules/indexeddb/IDBBackingStore.h >@@ -47,8 +47,9 @@ public: > virtual ~IDBBackingStore() {}; > > virtual void getDatabaseNames(Vector<String>& foundNames) = 0; >- virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) = 0; >- virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId) = 0; >+ virtual bool getIDBDatabaseMetaData(const String& name, String& foundStringVersion, int64_t& foundIntVersion, int64_t& foundId) = 0; >+ virtual bool createIDBDatabaseMetaData(const String& name, const String& stringVersion, const int64_t intVersion, int64_t& rowId) = 0; >+ virtual bool updateIDBDatabaseIntVersion(int64_t rowId, int64_t intVersion) = 0; > virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version) = 0; > virtual bool deleteDatabase(const String& name) = 0; > >diff --git a/Source/WebCore/Modules/indexeddb/IDBCallbacks.h b/Source/WebCore/Modules/indexeddb/IDBCallbacks.h >index 853ffc72d260391fcc43664d573fc5dae302dc0f..2a6afef38315be65b26628e56886dba32ac53645 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCallbacks.h >+++ b/Source/WebCore/Modules/indexeddb/IDBCallbacks.h >@@ -59,7 +59,9 @@ public: > virtual void onSuccess(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, const IDBKeyPath&) = 0; > virtual void onSuccessWithContinuation() = 0; > virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >& keys, const Vector<RefPtr<IDBKey> >& primaryKeys, const Vector<RefPtr<SerializedScriptValue> >& values) = 0; >- virtual void onBlocked() = 0; >+ virtual void onBlocked() { ASSERT_NOT_REACHED(); } >+ virtual void onBlocked(int64_t existingVersion) { ASSERT_NOT_REACHED(); } >+ virtual void onUpgradeNeeded(int64_t oldVersion, PassRefPtr<IDBTransactionBackendInterface>, PassRefPtr<IDBDatabaseBackendInterface>) { ASSERT_NOT_REACHED(); } > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >index e45147d5c0b0b62b33d3f3ccd63a617fb5b8b98e..93d21f3eb4a0b244eefcb655fa80ff9d28da4772 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp >@@ -52,9 +52,29 @@ private: > : m_callbacks(callbacks) > { > } >+ > RefPtr<IDBCallbacks> m_callbacks; > }; > >+class IDBDatabaseBackendImpl::PendingOpenWithVersionCall : public RefCounted<PendingOpenWithVersionCall> { >+public: >+ static PassRefPtr<PendingOpenWithVersionCall> create(PassRefPtr<IDBCallbacks> callbacks, int64_t version) >+ { >+ return adoptRef(new PendingOpenWithVersionCall(callbacks, version)); >+ } >+ PassRefPtr<IDBCallbacks> callbacks() { return m_callbacks; } >+ int64_t version() { return m_version; } >+ >+private: >+ PendingOpenWithVersionCall(PassRefPtr<IDBCallbacks> callbacks, int64_t version) >+ : m_callbacks(callbacks) >+ , m_version(version) >+ { >+ } >+ RefPtr<IDBCallbacks> m_callbacks; >+ int64_t m_version; >+}; >+ > class IDBDatabaseBackendImpl::PendingDeleteCall : public RefCounted<PendingDeleteCall> { > public: > static PassRefPtr<PendingDeleteCall> create(PassRefPtr<IDBCallbacks> callbacks) >@@ -106,6 +126,7 @@ IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingSto > , m_id(InvalidId) > , m_name(name) > , m_version("") >+ , m_intVersion(IDBDatabaseMetadata::NoIntVersion) > , m_identifier(uniqueIdentifier) > , m_factory(factory) > , m_transactionCoordinator(coordinator) >@@ -116,13 +137,13 @@ IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingSto > > bool IDBDatabaseBackendImpl::openInternal() > { >- bool success = m_backingStore->getIDBDatabaseMetaData(m_name, m_version, m_id); >- ASSERT(success == (m_id != InvalidId)); >+ bool success = m_backingStore->getIDBDatabaseMetaData(m_name, m_version, m_intVersion, m_id); >+ ASSERT_WITH_MESSAGE(success == (m_id != InvalidId), "success = %s, m_id = %"PRId64, success ? "true" : "false", m_id); > if (success) { > loadObjectStores(); > return true; > } >- return m_backingStore->createIDBDatabaseMetaData(m_name, m_version, m_id); >+ return m_backingStore->createIDBDatabaseMetaData(m_name, m_version, m_intVersion, m_id); > } > > IDBDatabaseBackendImpl::~IDBDatabaseBackendImpl() >@@ -136,7 +157,7 @@ PassRefPtr<IDBBackingStore> IDBDatabaseBackendImpl::backingStore() const > > IDBDatabaseMetadata IDBDatabaseBackendImpl::metadata() const > { >- IDBDatabaseMetadata metadata(m_name, m_version, IDBDatabaseMetadata::NoIntVersion); >+ IDBDatabaseMetadata metadata(m_name, m_version, m_intVersion); > for (ObjectStoreMap::const_iterator it = m_objectStores.begin(); it != m_objectStores.end(); ++it) > metadata.objectStores.set(it->first, it->second->metadata()); > return metadata; >@@ -214,6 +235,10 @@ void IDBDatabaseBackendImpl::setVersion(const String& version, PassRefPtr<IDBCal > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR, "Connection was closed before set version transaction was created")); > return; > } >+ if (m_intVersion != IDBDatabaseMetadata::NoIntVersion) { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, String::format("You can't use the setVersion function if you've already set the version through an open call. The current integer version is %"PRId64, m_intVersion))); >+ return; >+ } > for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { > if (*it != databaseCallbacks) > (*it)->onVersionChange(version); >@@ -259,6 +284,20 @@ void IDBDatabaseBackendImpl::setVersionInternal(ScriptExecutionContext*, PassRef > callbacks->onSuccess(PassRefPtr<IDBTransactionBackendInterface>(transaction)); > } > >+void IDBDatabaseBackendImpl::setIntVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) >+{ >+ int64_t databaseId = database->id(); >+ int64_t oldVersion = database->m_intVersion; >+ ASSERT(version > oldVersion); >+ database->m_intVersion = version; >+ if (!database->m_backingStore->updateIDBDatabaseIntVersion(databaseId, database->m_intVersion)) { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage.")); >+ transaction->abort(); >+ return; >+ } >+ callbacks->onUpgradeNeeded(oldVersion, transaction, database); >+} >+ > void IDBDatabaseBackendImpl::transactionStarted(PassRefPtr<IDBTransactionBackendImpl> prpTransaction) > { > RefPtr<IDBTransactionBackendImpl> transaction = prpTransaction; >@@ -276,6 +315,16 @@ void IDBDatabaseBackendImpl::transactionFinished(PassRefPtr<IDBTransactionBacken > if (transaction->mode() == IDBTransaction::VERSION_CHANGE) { > ASSERT(transaction.get() == m_runningVersionChangeTransaction.get()); > m_runningVersionChangeTransaction.clear(); >+ } >+} >+ >+void IDBDatabaseBackendImpl::transactionFinishedAndEventsFired(PassRefPtr<IDBTransactionBackendImpl> prpTransaction) >+{ >+ RefPtr<IDBTransactionBackendImpl> transaction = prpTransaction; >+ if (transaction->mode() == IDBTransaction::VERSION_CHANGE) { >+ // If this was an open-with-version call, there should be a "second >+ // half" open call waiting for us in processPendingCalls. >+ // When we no longer support setVersion, we can assert such a thing. > processPendingCalls(); > } > } >@@ -287,7 +336,15 @@ int32_t IDBDatabaseBackendImpl::connectionCount() > > void IDBDatabaseBackendImpl::processPendingCalls() > { >- ASSERT(connectionCount() <= 1); >+ ASSERT(m_pendingSecondHalfOpenWithVersionCalls.size() <= 1); >+ while (!m_pendingSecondHalfOpenWithVersionCalls.isEmpty()) { >+ RefPtr<PendingOpenWithVersionCall> pendingOpenWithVersionCall = m_pendingSecondHalfOpenWithVersionCalls.takeFirst(); >+ ASSERT(pendingOpenWithVersionCall->version() == m_intVersion); >+ ASSERT(m_id != InvalidId); >+ ++m_pendingConnectionCount; >+ pendingOpenWithVersionCall->callbacks()->onSuccess(this); >+ return; >+ } > > // Pending calls may be requeued or aborted > Deque<RefPtr<PendingSetVersionCall> > pendingSetVersionCalls; >@@ -325,6 +382,13 @@ void IDBDatabaseBackendImpl::processPendingCalls() > if (m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty() || !m_pendingDeleteCalls.isEmpty()) > return; > >+ Deque<RefPtr<PendingOpenWithVersionCall> > pendingOpenWithVersionCalls; >+ m_pendingOpenWithVersionCalls.swap(pendingOpenWithVersionCalls); >+ while (!pendingOpenWithVersionCalls.isEmpty()) { >+ RefPtr<PendingOpenWithVersionCall> pendingOpenWithVersionCall = pendingOpenWithVersionCalls.takeFirst(); >+ openConnectionWithVersion(pendingOpenWithVersionCall->callbacks(), pendingOpenWithVersionCall->version()); >+ } >+ > // Given the check above, it appears that calls cannot be requeued by > // openConnection, but use a different queue for iteration to be safe. > Deque<RefPtr<PendingOpenCall> > pendingOpenCalls; >@@ -356,6 +420,10 @@ void IDBDatabaseBackendImpl::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCal > ASSERT(m_pendingConnectionCount); > --m_pendingConnectionCount; > m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks)); >+ // Now that we give max priority to open calls that follow upgradeneeded >+ // events, something has to trigger the rest of the queues being serviced >+ // when those open calls are finished. >+ processPendingCalls(); > } > > void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks) >@@ -373,6 +441,73 @@ void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks) > } > } > >+void IDBDatabaseBackendImpl::runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks> prpCallbacks) >+{ >+ ASSERT_NOT_REACHED(); >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ ASSERT(callbacks); >+ for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { >+ // Note that some connections might close in the versionchange event >+ // handler for some other connection, after which its own versionchange >+ // event should not be fired. The backend doesn't worry about this, we >+ // just queue up a version change event for every connection. The >+ // frontend takes care to only dispatch to open connections. >+ (*it)->onVersionChange(m_intVersion, requestedVersion); >+ } >+ // The spec dictates we wait until all the version change events are >+ // delivered and then check m_databaseCallbacks.empty() before proceeding >+ // or firing a blocked event, but instead we should be consistent with how >+ // the old setVersion (incorrectly) did it: >+ // https://bugs.webkit.org/show_bug.cgi?id=71130 >+ if (connectionCount() > 0) >+ callbacks->onBlocked(m_intVersion); >+ // FIXME: Figure out how to test m_runningVersionChangeTransaction. >+ if (m_runningVersionChangeTransaction || connectionCount() > 0) { >+ m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, requestedVersion)); >+ return; >+ } >+ RefPtr<DOMStringList> objectStoreNames = DOMStringList::create(); >+ ExceptionCode ec = 0; >+ RefPtr<IDBTransactionBackendInterface> transactionInterface = transaction(objectStoreNames.get(), IDBTransaction::VERSION_CHANGE, ec); >+ RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionInterface.get()); >+ ASSERT(!ec); >+ >+ RefPtr<IDBDatabaseBackendImpl> database = this; >+ if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::setIntVersionInternal, database, requestedVersion, callbacks, transaction), >+ createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version))) { >+ ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; >+ } >+ m_pendingSecondHalfOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, requestedVersion)); >+} >+ >+void IDBDatabaseBackendImpl::openConnectionWithVersion(PassRefPtr<IDBCallbacks> prpCallbacks, int64_t version) >+{ >+ RefPtr<IDBCallbacks> callbacks = prpCallbacks; >+ if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()) { >+ m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, version)); >+ return; >+ } >+ if (m_id == InvalidId) { >+ if (openInternal()) >+ ASSERT(m_intVersion == IDBDatabaseMetadata::NoIntVersion); >+ else { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); >+ return; >+ } >+ } >+ if (version > m_intVersion) { >+ runIntVersionChangeTransaction(version, callbacks); >+ return; >+ } >+ if (version < m_intVersion) { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::VER_ERR, String::format("The requested version (%"PRId64") is less than the existing version (%"PRId64").", version, m_intVersion))); >+ return; >+ } >+ ASSERT(version == m_intVersion); >+ ++m_pendingConnectionCount; >+ callbacks->onSuccess(this); >+} >+ > void IDBDatabaseBackendImpl::deleteDatabase(PassRefPtr<IDBCallbacks> prpCallbacks) > { > if (m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()) { >@@ -388,17 +523,19 @@ void IDBDatabaseBackendImpl::deleteDatabase(PassRefPtr<IDBCallbacks> prpCallback > // FIXME: Only fire onBlocked if there are open connections after the > // VersionChangeEvents are received, not just set up to fire. > // https://bugs.webkit.org/show_bug.cgi?id=71130 >- if (!m_databaseCallbacksSet.isEmpty()) { >+ if (connectionCount() >= 1) { > m_pendingDeleteCalls.append(PendingDeleteCall::create(callbacks)); > callbacks->onBlocked(); > return; > } >+ ASSERT(m_backingStore); > if (!m_backingStore->deleteDatabase(m_name)) { > callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); > return; > } > m_version = ""; > m_id = InvalidId; >+ m_intVersion = IDBDatabaseMetadata::NoIntVersion; > m_objectStores.clear(); > callbacks->onSuccess(SerializedScriptValue::nullValue()); > } >@@ -411,12 +548,17 @@ void IDBDatabaseBackendImpl::close(PassRefPtr<IDBDatabaseCallbacks> prpCallbacks > if (connectionCount() > 1) > return; > >+ TransactionSet transactions(m_transactions); > processPendingCalls(); > >- if (!connectionCount()) { >- TransactionSet transactions(m_transactions); >+ ASSERT(m_transactions.size() - transactions.size() <= 1); >+ // FIXME: Instead of relying on transactions.size(), make connectionCount >+ // aware of in-flight upgradeneeded events as well as in-flight success >+ // events. >+ if (!connectionCount() && !m_pendingDeleteCalls.size() && m_transactions.size() == transactions.size()) { > for (TransactionSet::const_iterator it = transactions.begin(); it != transactions.end(); ++it) > (*it)->abort(); >+ > ASSERT(m_transactions.isEmpty()); > > m_backingStore.clear(); >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h >index 805eb617fb3214d0bbb2575f32bf895a45f10d1d..220de51133f77d1c14ecb333892f2dc6b60eb836 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h >@@ -57,6 +57,7 @@ public: > > void registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks>); > void openConnection(PassRefPtr<IDBCallbacks>); >+ void openConnectionWithVersion(PassRefPtr<IDBCallbacks>, int64_t version); > void deleteDatabase(PassRefPtr<IDBCallbacks>); > > // IDBDatabaseBackendInterface >@@ -71,11 +72,13 @@ public: > IDBTransactionCoordinator* transactionCoordinator() const { return m_transactionCoordinator.get(); } > void transactionStarted(PassRefPtr<IDBTransactionBackendImpl>); > void transactionFinished(PassRefPtr<IDBTransactionBackendImpl>); >+ void transactionFinishedAndEventsFired(PassRefPtr<IDBTransactionBackendImpl>); > > private: > IDBDatabaseBackendImpl(const String& name, IDBBackingStore* database, IDBTransactionCoordinator*, IDBFactoryBackendImpl*, const String& uniqueIdentifier); > > bool openInternal(); >+ void runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks>); > void loadObjectStores(); > int32_t connectionCount(); > void processPendingCalls(); >@@ -83,6 +86,7 @@ private: > static void createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBTransactionBackendImpl>); > static void deleteObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBTransactionBackendImpl>); > static void setVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendImpl>); >+ static void setIntVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, int64_t version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>); > > // These are used as setVersion transaction abort tasks. > static void removeObjectStoreFromMap(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>); >@@ -93,6 +97,7 @@ private: > int64_t m_id; > String m_name; > String m_version; >+ int64_t m_intVersion; > > String m_identifier; > // This might not need to be a RefPtr since the factory's lifetime is that of the page group, but it's better to be conservitive than sorry. >@@ -113,6 +118,10 @@ private: > class PendingOpenCall; > Deque<RefPtr<PendingOpenCall> > m_pendingOpenCalls; > >+ class PendingOpenWithVersionCall; >+ Deque<RefPtr<PendingOpenWithVersionCall> > m_pendingOpenWithVersionCalls; >+ Deque<RefPtr<PendingOpenWithVersionCall> > m_pendingSecondHalfOpenWithVersionCalls; >+ > class PendingDeleteCall; > Deque<RefPtr<PendingDeleteCall> > m_pendingDeleteCalls; > >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacks.h b/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacks.h >index b3f244f516b6987ea119cbf7019b7b54375f12bf..16a9ea6c508b0d92b61e4997c5430132a6d2acaa 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacks.h >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacks.h >@@ -38,6 +38,7 @@ public: > virtual ~IDBDatabaseCallbacks() { } > > virtual void onVersionChange(const String& version) = 0; >+ virtual void onVersionChange(int64_t currentVersion, int64_t requestedVersion) { ASSERT_NOT_REACHED(); } > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp >index dfb1457a306daa7a568c21af6efa34546ce3ff46..b9518d54518d0104c796cd0da7a4622a7f037383 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp >@@ -35,6 +35,7 @@ > #include "IDBDatabaseException.h" > #include "IDBLevelDBBackingStore.h" > #include "IDBTransactionCoordinator.h" >+#include "SecurityOrigin.h" > #include <wtf/Threading.h> > #include <wtf/UnusedParam.h> > >@@ -151,30 +152,32 @@ PassRefPtr<IDBBackingStore> IDBFactoryBackendImpl::openBackingStore(PassRefPtr<S > > void IDBFactoryBackendImpl::open(const String& name, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> prpSecurityOrigin, ScriptExecutionContext*, const String& dataDirectory) > { >+ // FIXME: Make this a parameter and plumb through from javascript. >+ int64_t version = IDBDatabaseMetadata::NoIntVersion; > RefPtr<SecurityOrigin> securityOrigin = prpSecurityOrigin; > const String uniqueIdentifier = computeUniqueIdentifier(name, securityOrigin.get()); > >+ RefPtr<IDBDatabaseBackendImpl> databaseBackend; > IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier); >- if (it != m_databaseBackendMap.end()) { >- // If it's already been opened, we have to wait for any pending >- // setVersion calls to complete. >- it->second->openConnection(callbacks); >- return; >- } >- >- // FIXME: Everything from now on should be done on another thread. >- RefPtr<IDBBackingStore> backingStore = openBackingStore(securityOrigin, dataDirectory); >- if (!backingStore) { >- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); >- return; >- } >- >- RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, backingStore.get(), m_transactionCoordinator.get(), this, uniqueIdentifier); >- if (databaseBackend) { >- m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get()); >- databaseBackend->openConnection(callbacks); >+ if (it == m_databaseBackendMap.end()) { >+ RefPtr<IDBBackingStore> backingStore = openBackingStore(securityOrigin, dataDirectory); >+ if (!backingStore) { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); >+ return; >+ } >+ databaseBackend = IDBDatabaseBackendImpl::create(name, backingStore.get(), m_transactionCoordinator.get(), this, uniqueIdentifier); >+ if (databaseBackend) >+ m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get()); >+ else { >+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); >+ return; >+ } > } else >- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); >+ databaseBackend = it->second; >+ if (version == IDBDatabaseMetadata::NoIntVersion) >+ databaseBackend->openConnection(callbacks); >+ else >+ databaseBackend->openConnectionWithVersion(callbacks, version); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp >index 32e2f681579409a0908d29a1872c0cdc56b89ef9..0c46413abe0bbec480ca10d7e259c93bb6afcf13 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp >@@ -234,7 +234,7 @@ void IDBLevelDBBackingStore::getDatabaseNames(Vector<String>& foundNames) > } > } > >-bool IDBLevelDBBackingStore::getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) >+bool IDBLevelDBBackingStore::getIDBDatabaseMetaData(const String& name, String& foundStringVersion, int64_t& foundIntVersion, int64_t& foundId) > { > const Vector<char> key = DatabaseNameKey::encode(m_identifier, name); > >@@ -242,7 +242,7 @@ bool IDBLevelDBBackingStore::getIDBDatabaseMetaData(const String& name, String& > if (!ok) > return false; > >- ok = getString(m_db.get(), DatabaseMetaDataKey::encode(foundId, DatabaseMetaDataKey::UserVersion), foundVersion); >+ ok = getString(m_db.get(), DatabaseMetaDataKey::encode(foundId, DatabaseMetaDataKey::UserVersion), foundStringVersion); > if (!ok) > return false; > >@@ -264,7 +264,7 @@ static int64_t getNewDatabaseId(LevelDBDatabase* db) > return databaseId; > } > >-bool IDBLevelDBBackingStore::createIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId) >+bool IDBLevelDBBackingStore::createIDBDatabaseMetaData(const String& name, const String& version, int64_t intVersion, int64_t& rowId) > { > rowId = getNewDatabaseId(m_db.get()); > if (rowId < 0) >@@ -278,6 +278,12 @@ bool IDBLevelDBBackingStore::createIDBDatabaseMetaData(const String& name, const > return true; > } > >+bool IDBLevelDBBackingStore::updateIDBDatabaseIntVersion(int64_t rowId, int64_t intVersion) >+{ >+ // FIXME: Make this actually do something. (first cut is in http://wkb.ug/89505) >+ return true; >+} >+ > bool IDBLevelDBBackingStore::updateIDBDatabaseMetaData(int64_t rowId, const String& version) > { > ASSERT(m_currentTransaction); >@@ -305,7 +311,8 @@ bool IDBLevelDBBackingStore::deleteDatabase(const String& name) > > int64_t databaseId; > String version; >- if (!getIDBDatabaseMetaData(name, version, databaseId)) { >+ int64_t intVersion; >+ if (!getIDBDatabaseMetaData(name, version, intVersion, databaseId)) { > transaction->rollback(); > return true; > } >diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h >index c5a9e2ee309e8ca3fd7f70f0aa2bb80cec046b2e..673ca9c15ae3c6dad4597e174db27eea61ed9f70 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h >+++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h >@@ -45,9 +45,10 @@ public: > virtual ~IDBLevelDBBackingStore(); > > virtual void getDatabaseNames(Vector<String>& foundNames); >- virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId); >- virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId); >+ virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundIntVersion, int64_t& foundId); >+ virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t intVersion, int64_t& rowId); > virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version); >+ virtual bool updateIDBDatabaseIntVersion(int64_t rowId, int64_t intVersion); > virtual bool deleteDatabase(const String& name); > > virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags); >diff --git a/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp >index 70f3367abfbc1a04a9feca1cab4e4330dd637341..1bbd23b56bba0f9e6ef34499deb806b3c08470ef 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp >@@ -227,6 +227,8 @@ void IDBTransactionBackendImpl::commit() > else > m_callbacks->onAbort(); > >+ m_database->transactionFinishedAndEventsFired(this); >+ > m_database = 0; > } > >diff --git a/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp b/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp >index d9e3d697b197c7406f63baeb483931b4eac95085..91df126a5fb8fb67bc6eaac51d947e9da41d09a6 100644 >--- a/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp >+++ b/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp >@@ -74,7 +74,7 @@ public: > { > return adoptRef(new FailingBackingStore); > } >- virtual bool createIDBDatabaseMetaData(const String&, const String&, int64_t&) >+ virtual bool createIDBDatabaseMetaData(const String&, const String&, int64_t, int64_t&) > { > return false; > } >diff --git a/Source/WebKit/chromium/tests/IDBFakeBackingStore.h b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h >index 08405ce0ab58c96fc296c3f0f8a14ff69d65ba18..5e231a929bd43742b32795b3943fa8e21a6a8249 100644 >--- a/Source/WebKit/chromium/tests/IDBFakeBackingStore.h >+++ b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h >@@ -33,9 +33,10 @@ namespace WebCore { > class IDBFakeBackingStore : public IDBBackingStore { > public: > virtual void getDatabaseNames(Vector<String>& foundNames) OVERRIDE { } >- virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) OVERRIDE { return false; } >- virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId) OVERRIDE { return true; } >+ virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundIntVersion, int64_t& foundId) OVERRIDE { return false; } >+ virtual bool createIDBDatabaseMetaData(const String& name, const String& version, const int64_t intVersion, int64_t& rowId) OVERRIDE { return true; } > virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version) OVERRIDE { return false; } >+ virtual bool updateIDBDatabaseIntVersion(int64_t rowId, int64_t version) OVERRIDE { return false; } > virtual bool deleteDatabase(const String& name) OVERRIDE { return false; } > > virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) OVERRIDE { }
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 92558
:
155071
|
155080
|
155096
|
155404
|
155659
|
155701
|
155914
|
156200
|
156451