2010-06-23 12:46:08 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2010-06-28 09:46:21 -07:00
|
|
|
#include "IDBTransaction.h"
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
#include "BackgroundChildImpl.h"
|
|
|
|
#include "IDBDatabase.h"
|
|
|
|
#include "IDBEvents.h"
|
|
|
|
#include "IDBObjectStore.h"
|
|
|
|
#include "IDBRequest.h"
|
|
|
|
#include "mozilla/ErrorResult.h"
|
2014-09-17 16:36:01 -07:00
|
|
|
#include "mozilla/EventDispatcher.h"
|
2014-09-26 16:21:57 -07:00
|
|
|
#include "mozilla/dom/DOMError.h"
|
|
|
|
#include "mozilla/dom/DOMStringList.h"
|
|
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
|
|
|
#include "nsIAppShell.h"
|
|
|
|
#include "nsIDOMFile.h"
|
2010-08-26 13:57:25 -07:00
|
|
|
#include "nsPIDOMWindow.h"
|
2014-09-26 16:21:57 -07:00
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "nsTHashtable.h"
|
2012-04-06 13:40:10 -07:00
|
|
|
#include "nsWidgetsCID.h"
|
2013-03-15 23:58:50 -07:00
|
|
|
#include "ProfilerHelpers.h"
|
2014-01-27 16:37:05 -08:00
|
|
|
#include "ReportInternalError.h"
|
2012-06-01 10:21:12 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// Include this last to avoid path problems on Windows.
|
|
|
|
#include "ActorsChild.h"
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
namespace indexedDB {
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
using namespace mozilla::ipc;
|
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
namespace {
|
|
|
|
|
2012-04-06 13:40:10 -07:00
|
|
|
NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
} // anonymous namespace
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::IDBTransaction(IDBDatabase* aDatabase,
|
|
|
|
const nsTArray<nsString>& aObjectStoreNames,
|
|
|
|
Mode aMode)
|
|
|
|
: IDBWrapperCache(aDatabase)
|
|
|
|
, mDatabase(aDatabase)
|
|
|
|
, mObjectStoreNames(aObjectStoreNames)
|
2014-10-15 21:56:52 -07:00
|
|
|
, mLoggingSerialNumber(0)
|
2014-09-26 16:21:57 -07:00
|
|
|
, mNextObjectStoreId(0)
|
|
|
|
, mNextIndexId(0)
|
|
|
|
, mAbortCode(NS_OK)
|
|
|
|
, mPendingRequestCount(0)
|
2014-11-13 18:20:38 -08:00
|
|
|
, mLineNo(0)
|
2014-09-26 16:21:57 -07:00
|
|
|
, mReadyState(IDBTransaction::INITIAL)
|
|
|
|
, mMode(aMode)
|
|
|
|
, mCreating(false)
|
|
|
|
, mAbortedByScript(false)
|
|
|
|
#ifdef DEBUG
|
|
|
|
, mSentCommitOrAbort(false)
|
|
|
|
, mFiredCompleteOrAbort(false)
|
|
|
|
#endif
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(aDatabase);
|
|
|
|
aDatabase->AssertIsOnOwningThread();
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mBackgroundActor.mNormalBackgroundActor = nullptr;
|
2011-11-18 07:21:04 -08:00
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
BackgroundChildImpl::ThreadLocal* threadLocal =
|
|
|
|
BackgroundChildImpl::GetThreadLocalForCurrentThread();
|
|
|
|
MOZ_ASSERT(threadLocal);
|
2014-09-26 16:21:57 -07:00
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
|
|
|
|
MOZ_ASSERT(idbThreadLocal);
|
|
|
|
|
|
|
|
const_cast<int64_t&>(mLoggingSerialNumber) =
|
|
|
|
idbThreadLocal->NextTransactionSN(aMode);
|
2011-11-18 07:21:04 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (!aObjectStoreNames.IsEmpty()) {
|
|
|
|
nsTArray<nsString> sortedNames(aObjectStoreNames);
|
|
|
|
sortedNames.Sort();
|
|
|
|
|
|
|
|
const uint32_t count = sortedNames.Length();
|
|
|
|
MOZ_ASSERT(count == aObjectStoreNames.Length());
|
|
|
|
|
|
|
|
// Make sure the array is properly sorted.
|
|
|
|
for (uint32_t index = 0; index < count; index++) {
|
|
|
|
MOZ_ASSERT(aObjectStoreNames[index] == sortedNames[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure there are no duplicates in our objectStore names.
|
|
|
|
for (uint32_t index = 0; index < count - 1; index++) {
|
|
|
|
MOZ_ASSERT(sortedNames[index] != sortedNames[index + 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-18 07:21:04 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::~IDBTransaction()
|
2011-11-18 07:21:04 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(!mPendingRequestCount);
|
|
|
|
MOZ_ASSERT(!mCreating);
|
|
|
|
MOZ_ASSERT(mSentCommitOrAbort);
|
|
|
|
MOZ_ASSERT_IF(mMode == VERSION_CHANGE &&
|
|
|
|
mBackgroundActor.mVersionChangeBackgroundActor,
|
|
|
|
mFiredCompleteOrAbort);
|
|
|
|
MOZ_ASSERT_IF(mMode != VERSION_CHANGE &&
|
|
|
|
mBackgroundActor.mNormalBackgroundActor,
|
|
|
|
mFiredCompleteOrAbort);
|
2011-11-18 07:21:04 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mDatabase->UnregisterTransaction(this);
|
2011-11-18 07:21:04 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == VERSION_CHANGE) {
|
2014-10-15 21:56:52 -07:00
|
|
|
if (auto* actor = mBackgroundActor.mVersionChangeBackgroundActor) {
|
|
|
|
actor->SendDeleteMeInternal();
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(!mBackgroundActor.mVersionChangeBackgroundActor,
|
|
|
|
"SendDeleteMeInternal should have cleared!");
|
|
|
|
}
|
2014-10-15 21:56:52 -07:00
|
|
|
} else if (auto* actor = mBackgroundActor.mNormalBackgroundActor) {
|
|
|
|
actor->SendDeleteMeInternal();
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor,
|
|
|
|
"SendDeleteMeInternal should have cleared!");
|
|
|
|
}
|
|
|
|
}
|
2010-06-23 12:46:08 -07:00
|
|
|
|
|
|
|
// static
|
2010-06-28 09:46:21 -07:00
|
|
|
already_AddRefed<IDBTransaction>
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::CreateVersionChange(
|
|
|
|
IDBDatabase* aDatabase,
|
|
|
|
BackgroundVersionChangeTransactionChild* aActor,
|
2014-11-13 18:20:38 -08:00
|
|
|
IDBOpenDBRequest* aOpenRequest,
|
2014-09-26 16:21:57 -07:00
|
|
|
int64_t aNextObjectStoreId,
|
|
|
|
int64_t aNextIndexId)
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(aDatabase);
|
|
|
|
aDatabase->AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aActor);
|
2014-11-13 18:20:38 -08:00
|
|
|
MOZ_ASSERT(aOpenRequest);
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(aNextObjectStoreId > 0);
|
|
|
|
MOZ_ASSERT(aNextIndexId > 0);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsTArray<nsString> emptyObjectStoreNames;
|
2014-05-29 13:07:35 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsRefPtr<IDBTransaction> transaction =
|
|
|
|
new IDBTransaction(aDatabase, emptyObjectStoreNames, VERSION_CHANGE);
|
2014-11-13 18:20:38 -08:00
|
|
|
aOpenRequest->GetCallerLocation(transaction->mFilename,
|
|
|
|
&transaction->mLineNo);
|
2012-06-01 10:21:12 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
transaction->SetScriptOwner(aDatabase->GetScriptOwner());
|
|
|
|
transaction->mBackgroundActor.mVersionChangeBackgroundActor = aActor;
|
|
|
|
transaction->mNextObjectStoreId = aNextObjectStoreId;
|
|
|
|
transaction->mNextIndexId = aNextIndexId;
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// XXX Fix!
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "This won't work on non-main threads!");
|
2012-06-01 10:21:12 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
|
|
|
|
if (NS_WARN_IF(!appShell) ||
|
|
|
|
NS_WARN_IF(NS_FAILED(appShell->RunBeforeNextEvent(transaction)))) {
|
|
|
|
return nullptr;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
transaction->mCreating = true;
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
aDatabase->RegisterTransaction(transaction);
|
2010-11-18 14:19:19 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return transaction.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
already_AddRefed<IDBTransaction>
|
|
|
|
IDBTransaction::Create(IDBDatabase* aDatabase,
|
|
|
|
const nsTArray<nsString>& aObjectStoreNames,
|
|
|
|
Mode aMode)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aDatabase);
|
|
|
|
aDatabase->AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(!aObjectStoreNames.IsEmpty());
|
|
|
|
MOZ_ASSERT(aMode == READ_ONLY || aMode == READ_WRITE);
|
2010-11-18 14:19:19 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsRefPtr<IDBTransaction> transaction =
|
|
|
|
new IDBTransaction(aDatabase, aObjectStoreNames, aMode);
|
2014-11-13 18:20:38 -08:00
|
|
|
IDBRequest::CaptureCaller(transaction->mFilename, &transaction->mLineNo);
|
2010-11-15 13:49:49 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
transaction->SetScriptOwner(aDatabase->GetScriptOwner());
|
2011-11-18 07:21:04 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// XXX Fix!
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "This won't work on non-main threads!");
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
|
|
|
|
if (NS_WARN_IF(!appShell) ||
|
|
|
|
NS_WARN_IF(NS_FAILED(appShell->RunBeforeNextEvent(transaction)))) {
|
|
|
|
return nullptr;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
transaction->mCreating = true;
|
|
|
|
|
|
|
|
aDatabase->RegisterTransaction(transaction);
|
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
return transaction.forget();
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// static
|
|
|
|
IDBTransaction*
|
|
|
|
IDBTransaction::GetCurrent()
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
using namespace mozilla::ipc;
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(BackgroundChild::GetForCurrentThread());
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
BackgroundChildImpl::ThreadLocal* threadLocal =
|
|
|
|
BackgroundChildImpl::GetThreadLocalForCurrentThread();
|
|
|
|
MOZ_ASSERT(threadLocal);
|
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
|
|
|
|
MOZ_ASSERT(idbThreadLocal);
|
|
|
|
|
|
|
|
return idbThreadLocal->GetCurrentTransaction();
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
|
2012-11-09 19:29:07 -08:00
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::AssertIsOnOwningThread() const
|
2012-11-09 19:29:07 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(mDatabase);
|
|
|
|
mDatabase->AssertIsOnOwningThread();
|
2012-11-09 19:29:07 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
#endif // DEBUG
|
|
|
|
|
2011-12-04 09:39:01 -08:00
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor)
|
2011-12-04 09:39:01 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aBackgroundActor);
|
|
|
|
MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor);
|
|
|
|
MOZ_ASSERT(mMode != VERSION_CHANGE);
|
|
|
|
|
|
|
|
mBackgroundActor.mNormalBackgroundActor = aBackgroundActor;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2011-12-16 16:40:47 -08:00
|
|
|
|
2014-09-17 16:36:01 -07:00
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::StartRequest(BackgroundRequestChild* aBackgroundActor,
|
|
|
|
const RequestParams& aParams)
|
2014-09-17 16:36:01 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aBackgroundActor);
|
|
|
|
MOZ_ASSERT(aParams.type() != RequestParams::T__None);
|
2011-12-16 16:40:47 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == VERSION_CHANGE) {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendPBackgroundIDBRequestConstructor(aBackgroundActor, aParams);
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
|
|
|
|
|
|
|
|
mBackgroundActor.mNormalBackgroundActor->
|
|
|
|
SendPBackgroundIDBRequestConstructor(aBackgroundActor, aParams);
|
2011-12-04 09:39:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-20 09:10:56 -07:00
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::OpenCursor(BackgroundCursorChild* aBackgroundActor,
|
|
|
|
const OpenCursorParams& aParams)
|
2011-10-20 09:10:56 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aBackgroundActor);
|
|
|
|
MOZ_ASSERT(aParams.type() != OpenCursorParams::T__None);
|
2011-10-20 09:10:56 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == VERSION_CHANGE) {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
2010-10-19 17:46:37 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
|
2012-06-19 18:50:39 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mBackgroundActor.mNormalBackgroundActor->
|
|
|
|
SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
|
2012-06-01 10:21:12 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// Balanced in BackgroundCursorChild::RecvResponse().
|
|
|
|
OnNewRequest();
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::RefreshSpec(bool aMayDelete)
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2014-01-31 10:53:37 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
for (uint32_t count = mObjectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
mObjectStores[index]->RefreshSpec(aMayDelete);
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
for (uint32_t count = mDeletedObjectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
mDeletedObjectStores[index]->RefreshSpec(false);
|
|
|
|
}
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::OnNewRequest()
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2010-10-19 10:58:52 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (!mPendingRequestCount) {
|
|
|
|
MOZ_ASSERT(INITIAL == mReadyState);
|
|
|
|
mReadyState = LOADING;
|
2014-01-31 10:53:37 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
++mPendingRequestCount;
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::OnRequestFinished()
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(mPendingRequestCount);
|
2014-01-31 10:53:37 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
--mPendingRequestCount;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (!mPendingRequestCount && !mDatabase->IsInvalidated()) {
|
|
|
|
mReadyState = COMMITTING;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (NS_SUCCEEDED(mAbortCode)) {
|
|
|
|
SendCommit();
|
|
|
|
} else {
|
|
|
|
SendAbort(mAbortCode);
|
|
|
|
}
|
2014-01-31 10:53:37 -08:00
|
|
|
}
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::SendCommit()
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(mAbortCode));
|
|
|
|
MOZ_ASSERT(IsFinished());
|
|
|
|
MOZ_ASSERT(!mSentCommitOrAbort);
|
2014-10-15 21:56:52 -07:00
|
|
|
MOZ_ASSERT(!mPendingRequestCount);
|
|
|
|
|
|
|
|
// Don't do this in the macro because we always need to increment the serial
|
|
|
|
// number to keep in sync with the parent.
|
|
|
|
const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
|
|
|
|
|
|
|
|
IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: "
|
|
|
|
"All requests complete, committing transaction",
|
|
|
|
"IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction commit",
|
|
|
|
IDB_LOG_ID_STRING(),
|
|
|
|
LoggingSerialNumber(),
|
|
|
|
requestSerialNumber);
|
2013-03-15 23:58:50 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == VERSION_CHANGE) {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
mBackgroundActor.mVersionChangeBackgroundActor->SendCommit();
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
|
|
|
|
mBackgroundActor.mNormalBackgroundActor->SendCommit();
|
2010-09-10 12:12:11 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
mSentCommitOrAbort = true;
|
|
|
|
#endif
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::SendAbort(nsresult aResultCode)
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(NS_FAILED(aResultCode));
|
|
|
|
MOZ_ASSERT(IsFinished());
|
|
|
|
MOZ_ASSERT(!mSentCommitOrAbort);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
// Don't do this in the macro because we always need to increment the serial
|
|
|
|
// number to keep in sync with the parent.
|
|
|
|
const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
|
|
|
|
|
|
|
|
IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: "
|
|
|
|
"Aborting transaction with result 0x%x",
|
|
|
|
"IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction abort (0x%x)",
|
|
|
|
IDB_LOG_ID_STRING(),
|
|
|
|
LoggingSerialNumber(),
|
|
|
|
requestSerialNumber,
|
|
|
|
aResultCode);
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == VERSION_CHANGE) {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
mBackgroundActor.mVersionChangeBackgroundActor->SendAbort(aResultCode);
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
|
|
|
|
mBackgroundActor.mNormalBackgroundActor->SendAbort(aResultCode);
|
|
|
|
}
|
2010-06-23 12:46:08 -07:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2014-09-26 16:21:57 -07:00
|
|
|
mSentCommitOrAbort = true;
|
2010-06-23 12:46:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2010-12-15 13:21:17 -08:00
|
|
|
IDBTransaction::IsOpen() const
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2010-11-15 13:49:49 -08:00
|
|
|
|
|
|
|
// If we haven't started anything then we're open.
|
2012-03-12 21:44:45 -07:00
|
|
|
if (mReadyState == IDBTransaction::INITIAL) {
|
2010-11-15 13:49:49 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we've already started then we need to check to see if we still have the
|
|
|
|
// mCreating flag set. If we do (i.e. we haven't returned to the event loop
|
|
|
|
// from the time we were created) then we are open. Otherwise check the
|
|
|
|
// currently running transaction to see if it's the same. We only allow other
|
|
|
|
// requests to be made if this transaction is currently running.
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mReadyState == IDBTransaction::LOADING &&
|
|
|
|
(mCreating || GetCurrent() == this)) {
|
|
|
|
return true;
|
2010-11-15 13:49:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2010-06-23 12:46:08 -07:00
|
|
|
}
|
|
|
|
|
2014-11-13 18:20:38 -08:00
|
|
|
void
|
|
|
|
IDBTransaction::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo) const
|
|
|
|
{
|
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aLineNo);
|
|
|
|
|
|
|
|
aFilename = mFilename;
|
|
|
|
*aLineNo = mLineNo;
|
|
|
|
}
|
|
|
|
|
2010-11-10 15:25:40 -08:00
|
|
|
already_AddRefed<IDBObjectStore>
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::CreateObjectStore(const ObjectStoreSpec& aSpec)
|
2010-11-10 15:25:40 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aSpec.metadata().id());
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
MOZ_ASSERT(IsOpen());
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
{
|
|
|
|
const nsString& name = aSpec.metadata().name();
|
|
|
|
|
|
|
|
for (uint32_t count = mObjectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
MOZ_ASSERT(mObjectStores[index]->Name() != name);
|
2010-11-10 15:25:40 -08:00
|
|
|
}
|
|
|
|
}
|
2014-09-26 16:21:57 -07:00
|
|
|
#endif
|
2010-11-10 15:25:40 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendCreateObjectStore(aSpec.metadata()));
|
2010-11-10 15:25:40 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsRefPtr<IDBObjectStore> objectStore = IDBObjectStore::Create(this, aSpec);
|
|
|
|
MOZ_ASSERT(objectStore);
|
2010-11-10 15:25:40 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mObjectStores.AppendElement(objectStore);
|
|
|
|
|
|
|
|
return objectStore.forget();
|
2010-11-10 15:25:40 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::DeleteObjectStore(int64_t aObjectStoreId)
|
2012-06-03 09:33:52 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aObjectStoreId);
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
MOZ_ASSERT(IsOpen());
|
|
|
|
|
|
|
|
MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendDeleteObjectStore(aObjectStoreId));
|
|
|
|
|
|
|
|
for (uint32_t count = mObjectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
nsRefPtr<IDBObjectStore>& objectStore = mObjectStores[index];
|
|
|
|
|
|
|
|
if (objectStore->Id() == aObjectStoreId) {
|
|
|
|
objectStore->NoteDeletion();
|
|
|
|
|
|
|
|
nsRefPtr<IDBObjectStore>* deletedObjectStore =
|
|
|
|
mDeletedObjectStores.AppendElement();
|
|
|
|
deletedObjectStore->swap(mObjectStores[index]);
|
|
|
|
|
|
|
|
mObjectStores.RemoveElementAt(index);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-06-03 09:33:52 -07:00
|
|
|
}
|
|
|
|
|
2011-12-15 23:34:24 -08:00
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::CreateIndex(IDBObjectStore* aObjectStore,
|
|
|
|
const IndexMetadata& aMetadata)
|
2011-12-15 23:34:24 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aObjectStore);
|
|
|
|
MOZ_ASSERT(aMetadata.id());
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
MOZ_ASSERT(IsOpen());
|
|
|
|
|
|
|
|
MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendCreateIndex(aObjectStore->Id(), aMetadata));
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::DeleteIndex(IDBObjectStore* aObjectStore,
|
|
|
|
int64_t aIndexId)
|
2011-12-15 23:34:24 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aObjectStore);
|
|
|
|
MOZ_ASSERT(aIndexId);
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
|
|
|
MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
|
|
|
|
MOZ_ASSERT(IsOpen());
|
|
|
|
|
|
|
|
MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
|
|
|
|
SendDeleteIndex(aObjectStore->Id(), aIndexId));
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
2012-06-29 09:48:34 -07:00
|
|
|
IDBTransaction::AbortInternal(nsresult aAbortCode,
|
2013-05-18 10:52:06 -07:00
|
|
|
already_AddRefed<DOMError> aError)
|
2012-06-01 10:21:12 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(NS_FAILED(aAbortCode));
|
2012-06-01 10:21:12 -07:00
|
|
|
|
2013-05-18 10:52:06 -07:00
|
|
|
nsRefPtr<DOMError> error = aError;
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2012-06-26 08:09:25 -07:00
|
|
|
if (IsFinished()) {
|
2014-09-26 16:21:57 -07:00
|
|
|
// Already finished, nothing to do here.
|
|
|
|
return;
|
2012-06-01 10:21:12 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
const bool isVersionChange = mMode == VERSION_CHANGE;
|
|
|
|
const bool isInvalidated = mDatabase->IsInvalidated();
|
|
|
|
bool needToSendAbort = mReadyState == INITIAL && !isInvalidated;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (isInvalidated) {
|
2014-10-15 21:56:52 -07:00
|
|
|
#ifdef DEBUG
|
2014-09-26 16:21:57 -07:00
|
|
|
mSentCommitOrAbort = true;
|
|
|
|
#endif
|
2014-10-15 21:56:52 -07:00
|
|
|
// Increment the serial number counter here to account for the aborted
|
|
|
|
// transaction and keep the parent in sync.
|
|
|
|
IDBRequest::NextSerialNumber();
|
|
|
|
}
|
2012-06-01 10:21:12 -07:00
|
|
|
|
|
|
|
mAbortCode = aAbortCode;
|
2014-09-26 16:21:57 -07:00
|
|
|
mReadyState = DONE;
|
2012-06-29 09:48:34 -07:00
|
|
|
mError = error.forget();
|
2012-06-01 10:21:12 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (isVersionChange) {
|
2012-06-29 09:48:34 -07:00
|
|
|
// If a version change transaction is aborted, we must revert the world
|
2014-09-26 16:21:57 -07:00
|
|
|
// back to its previous state unless we're being invalidated after the
|
|
|
|
// transaction already completed.
|
|
|
|
if (!isInvalidated) {
|
|
|
|
mDatabase->RevertToPreviousState();
|
|
|
|
}
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
const nsTArray<ObjectStoreSpec>& specArray =
|
|
|
|
mDatabase->Spec()->objectStores();
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (specArray.IsEmpty()) {
|
|
|
|
mObjectStores.Clear();
|
|
|
|
mDeletedObjectStores.Clear();
|
|
|
|
} else {
|
|
|
|
nsTHashtable<nsUint64HashKey> validIds(specArray.Length());
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
for (uint32_t specCount = specArray.Length(), specIndex = 0;
|
|
|
|
specIndex < specCount;
|
|
|
|
specIndex++) {
|
|
|
|
const int64_t objectStoreId = specArray[specIndex].metadata().id();
|
|
|
|
MOZ_ASSERT(objectStoreId);
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
validIds.PutEntry(uint64_t(objectStoreId));
|
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
for (uint32_t objCount = mObjectStores.Length(), objIndex = 0;
|
|
|
|
objIndex < objCount;
|
|
|
|
/* incremented conditionally */) {
|
|
|
|
const int64_t objectStoreId = mObjectStores[objIndex]->Id();
|
|
|
|
MOZ_ASSERT(objectStoreId);
|
|
|
|
|
|
|
|
if (validIds.Contains(uint64_t(objectStoreId))) {
|
|
|
|
objIndex++;
|
|
|
|
} else {
|
|
|
|
mObjectStores.RemoveElementAt(objIndex);
|
|
|
|
objCount--;
|
|
|
|
}
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (!mDeletedObjectStores.IsEmpty()) {
|
|
|
|
for (uint32_t objCount = mDeletedObjectStores.Length(), objIndex = 0;
|
|
|
|
objIndex < objCount;
|
|
|
|
objIndex++) {
|
|
|
|
const int64_t objectStoreId = mDeletedObjectStores[objIndex]->Id();
|
|
|
|
MOZ_ASSERT(objectStoreId);
|
|
|
|
|
|
|
|
if (validIds.Contains(uint64_t(objectStoreId))) {
|
|
|
|
nsRefPtr<IDBObjectStore>* objectStore =
|
|
|
|
mObjectStores.AppendElement();
|
|
|
|
objectStore->swap(mDeletedObjectStores[objIndex]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mDeletedObjectStores.Clear();
|
|
|
|
}
|
2012-06-29 09:48:34 -07:00
|
|
|
}
|
2012-06-01 10:21:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fire the abort event if there are no outstanding requests. Otherwise the
|
|
|
|
// abort event will be fired when all outstanding requests finish.
|
2014-09-26 16:21:57 -07:00
|
|
|
if (needToSendAbort) {
|
|
|
|
SendAbort(aAbortCode);
|
2012-06-01 10:21:12 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (isVersionChange) {
|
|
|
|
mDatabase->Close();
|
|
|
|
}
|
2012-06-01 10:21:12 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
2012-06-25 12:15:17 -07:00
|
|
|
IDBTransaction::Abort(IDBRequest* aRequest)
|
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(aRequest);
|
2012-06-25 12:15:17 -07:00
|
|
|
|
2013-05-18 10:52:06 -07:00
|
|
|
ErrorResult rv;
|
|
|
|
nsRefPtr<DOMError> error = aRequest->GetError(rv);
|
2012-06-29 09:48:34 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
AbortInternal(aRequest->GetErrorCode(), error.forget());
|
2012-06-29 09:48:34 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
2012-06-29 09:48:34 -07:00
|
|
|
IDBTransaction::Abort(nsresult aErrorCode)
|
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2012-06-25 12:15:17 -07:00
|
|
|
|
2013-05-18 10:52:06 -07:00
|
|
|
nsRefPtr<DOMError> error = new DOMError(GetOwner(), aErrorCode);
|
2014-09-26 16:21:57 -07:00
|
|
|
AbortInternal(aErrorCode, error.forget());
|
2012-06-25 12:15:17 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::Abort(ErrorResult& aRv)
|
2014-09-17 16:36:01 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2011-10-20 09:10:56 -07:00
|
|
|
|
2014-09-17 16:36:01 -07:00
|
|
|
if (IsFinished()) {
|
2014-09-26 16:21:57 -07:00
|
|
|
aRv = NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
|
|
|
return;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2011-12-16 16:40:47 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
MOZ_ASSERT(!mAbortedByScript);
|
|
|
|
mAbortedByScript = true;
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
void
|
|
|
|
IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult)
|
2012-08-24 11:51:33 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(!mFiredCompleteOrAbort);
|
2012-08-24 11:51:33 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mReadyState = DONE;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2014-09-26 16:21:57 -07:00
|
|
|
mFiredCompleteOrAbort = true;
|
2014-09-17 16:36:01 -07:00
|
|
|
#endif
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsCOMPtr<nsIDOMEvent> event;
|
|
|
|
if (NS_SUCCEEDED(aResult)) {
|
|
|
|
event = CreateGenericEvent(this,
|
|
|
|
nsDependentString(kCompleteEventType),
|
|
|
|
eDoesNotBubble,
|
|
|
|
eNotCancelable);
|
|
|
|
} else {
|
|
|
|
if (!mError && !mAbortedByScript) {
|
|
|
|
mError = new DOMError(GetOwner(), aResult);
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
event = CreateGenericEvent(this,
|
|
|
|
nsDependentString(kAbortEventType),
|
|
|
|
eDoesBubble,
|
|
|
|
eNotCancelable);
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (NS_WARN_IF(!event)) {
|
|
|
|
return;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
|
|
|
|
2014-10-15 21:56:52 -07:00
|
|
|
if (NS_SUCCEEDED(mAbortCode)) {
|
|
|
|
IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld]: "
|
|
|
|
"Firing 'complete' event",
|
|
|
|
"IndexedDB %s: C T[%lld]: IDBTransaction 'complete' event",
|
|
|
|
IDB_LOG_ID_STRING(),
|
|
|
|
mLoggingSerialNumber);
|
|
|
|
} else {
|
|
|
|
IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld]: "
|
|
|
|
"Firing 'abort' event with error 0x%x",
|
|
|
|
"IndexedDB %s: C T[%lld]: IDBTransaction 'abort' event (0x%x)",
|
|
|
|
IDB_LOG_ID_STRING(),
|
|
|
|
mLoggingSerialNumber,
|
|
|
|
mAbortCode);
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
bool dummy;
|
|
|
|
if (NS_FAILED(DispatchEvent(event, &dummy))) {
|
|
|
|
NS_WARNING("DispatchEvent failed!");
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mDatabase->DelayedMaybeExpireFileActors();
|
2012-08-24 11:51:33 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
int64_t
|
|
|
|
IDBTransaction::NextObjectStoreId()
|
2012-08-24 11:51:33 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
2012-08-24 11:51:33 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return mNextObjectStoreId++;
|
2012-08-24 11:51:33 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
int64_t
|
|
|
|
IDBTransaction::NextIndexId()
|
2012-08-24 11:51:33 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
MOZ_ASSERT(VERSION_CHANGE == mMode);
|
2012-08-24 11:51:33 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return mNextIndexId++;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsPIDOMWindow*
|
|
|
|
IDBTransaction::GetParentObject() const
|
2014-09-17 16:36:01 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return mDatabase->GetParentObject();
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransactionMode
|
|
|
|
IDBTransaction::GetMode(ErrorResult& aRv) const
|
2014-09-13 09:12:19 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
switch (mMode) {
|
|
|
|
case READ_ONLY:
|
|
|
|
return IDBTransactionMode::Readonly;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
case READ_WRITE:
|
|
|
|
return IDBTransactionMode::Readwrite;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
case VERSION_CHANGE:
|
|
|
|
return IDBTransactionMode::Versionchange;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
case MODE_INVALID:
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("Bad mode!");
|
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
DOMError*
|
|
|
|
IDBTransaction::GetError() const
|
2014-09-17 16:36:01 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return mError;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
already_AddRefed<DOMStringList>
|
|
|
|
IDBTransaction::ObjectStoreNames()
|
2014-09-17 16:36:01 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (mMode == IDBTransaction::VERSION_CHANGE) {
|
|
|
|
return mDatabase->ObjectStoreNames();
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsRefPtr<DOMStringList> list = new DOMStringList();
|
|
|
|
list->StringArray() = mObjectStoreNames;
|
|
|
|
return list.forget();
|
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
already_AddRefed<IDBObjectStore>
|
|
|
|
IDBTransaction::ObjectStore(const nsAString& aName, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (IsFinished()) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
const ObjectStoreSpec* spec = nullptr;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (IDBTransaction::VERSION_CHANGE == mMode ||
|
|
|
|
mObjectStoreNames.Contains(aName)) {
|
|
|
|
const nsTArray<ObjectStoreSpec>& objectStores =
|
|
|
|
mDatabase->Spec()->objectStores();
|
|
|
|
|
|
|
|
for (uint32_t count = objectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
const ObjectStoreSpec& objectStore = objectStores[index];
|
|
|
|
if (objectStore.metadata().name() == aName) {
|
|
|
|
spec = &objectStore;
|
2014-09-17 16:36:01 -07:00
|
|
|
break;
|
2014-09-26 16:21:57 -07:00
|
|
|
}
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (!spec) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
|
|
|
|
return nullptr;
|
2012-08-24 11:51:33 -07:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
const int64_t desiredId = spec->metadata().id();
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
nsRefPtr<IDBObjectStore> objectStore;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
for (uint32_t count = mObjectStores.Length(), index = 0;
|
|
|
|
index < count;
|
|
|
|
index++) {
|
|
|
|
nsRefPtr<IDBObjectStore>& existingObjectStore = mObjectStores[index];
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (existingObjectStore->Id() == desiredId) {
|
|
|
|
objectStore = existingObjectStore;
|
|
|
|
break;
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
if (!objectStore) {
|
|
|
|
objectStore = IDBObjectStore::Create(this, *spec);
|
|
|
|
MOZ_ASSERT(objectStore);
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
mObjectStores.AppendElement(objectStore);
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2014-01-31 10:53:37 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return objectStore.forget();
|
2014-09-17 16:36:01 -07:00
|
|
|
}
|
2014-01-31 10:53:37 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache)
|
2014-09-13 09:12:19 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
|
|
|
|
NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
|
|
|
|
IDBWrapperCache)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDatabase)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectStores)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeletedObjectStores)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
|
|
|
|
// Don't unlink mDatabase!
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObjectStores)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeletedObjectStores)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
JSObject*
|
|
|
|
IDBTransaction::WrapObject(JSContext* aCx)
|
2011-12-15 23:34:24 -08:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2011-12-15 23:34:24 -08:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
return IDBTransactionBinding::Wrap(aCx, this);
|
2014-09-13 09:12:19 -07:00
|
|
|
}
|
2012-08-24 11:51:33 -07:00
|
|
|
|
2014-09-17 16:36:01 -07:00
|
|
|
nsresult
|
2014-09-26 16:21:57 -07:00
|
|
|
IDBTransaction::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
2014-09-13 09:12:19 -07:00
|
|
|
{
|
2014-09-26 16:21:57 -07:00
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
aVisitor.mCanHandle = true;
|
|
|
|
aVisitor.mParentTarget = mDatabase;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
IDBTransaction::Run()
|
|
|
|
{
|
|
|
|
AssertIsOnOwningThread();
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// We're back at the event loop, no longer newborn.
|
|
|
|
mCreating = false;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
// Maybe commit if there were no requests generated.
|
|
|
|
if (mReadyState == IDBTransaction::INITIAL) {
|
|
|
|
mReadyState = DONE;
|
2014-09-17 16:36:01 -07:00
|
|
|
|
2014-09-26 16:21:57 -07:00
|
|
|
SendCommit();
|
2011-12-15 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-09-26 16:21:57 -07:00
|
|
|
|
|
|
|
} // namespace indexedDB
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|