forked from mirrors/gecko-dev
		
	This patch replaces four functions of the name AssignWithConversion which
are essentially wrappers around CopyASCIItoUTF16 and LossyCopyUTF16toASCII
with direct calls to the latter two functions.  The replaced functions are:
  void nsCString::AssignWithConversion( const nsAString& aData )
  void nsString::AssignWithConversion( const nsACString& aData )
  void nsTString_CharT::AssignWithConversion(
                            const incompatible_char_type* aData,
                            int32_t aLength = -1);
The last of the three exists inside the double-included nsTString* world and
so describes two functions, giving four in total.
This has two advantages:
* it removes code
* at the call points, it makes clear (from the replacement name) which
  conversion is being carried out.  The generic name "AssignWithConversion"
  doesn't make that obvious -- one had to infer it from the types.
The patch also removes two commented out lines from
editor/composer/nsComposerCommands.cpp, that appear to be related.  They are
at top level, where they would never have compiled.  They look like
leftovers from some previous change.
--HG--
extra : rebase_source : fb47bf450771c3c9ee3341dd14520f5da69ec4f5
		
	
			
		
			
				
	
	
		
			680 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			680 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* 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/. */
 | 
						|
 | 
						|
#include "IDBIndex.h"
 | 
						|
 | 
						|
#include "FileInfo.h"
 | 
						|
#include "IDBCursor.h"
 | 
						|
#include "IDBEvents.h"
 | 
						|
#include "IDBKeyRange.h"
 | 
						|
#include "IDBObjectStore.h"
 | 
						|
#include "IDBRequest.h"
 | 
						|
#include "IDBTransaction.h"
 | 
						|
#include "IndexedDatabase.h"
 | 
						|
#include "IndexedDatabaseInlines.h"
 | 
						|
#include "mozilla/ErrorResult.h"
 | 
						|
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
 | 
						|
#include "ProfilerHelpers.h"
 | 
						|
#include "ReportInternalError.h"
 | 
						|
 | 
						|
// Include this last to avoid path problems on Windows.
 | 
						|
#include "ActorsChild.h"
 | 
						|
 | 
						|
namespace mozilla {
 | 
						|
namespace dom {
 | 
						|
 | 
						|
using namespace mozilla::dom::indexedDB;
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
already_AddRefed<IDBRequest>
 | 
						|
GenerateRequest(JSContext* aCx, IDBIndex* aIndex)
 | 
						|
{
 | 
						|
  MOZ_ASSERT(aIndex);
 | 
						|
  aIndex->AssertIsOnOwningThread();
 | 
						|
 | 
						|
  IDBTransaction* transaction = aIndex->ObjectStore()->Transaction();
 | 
						|
 | 
						|
  RefPtr<IDBRequest> request =
 | 
						|
    IDBRequest::Create(aCx, aIndex, transaction->Database(), transaction);
 | 
						|
  MOZ_ASSERT(request);
 | 
						|
 | 
						|
  return request.forget();
 | 
						|
}
 | 
						|
 | 
						|
} // namespace
 | 
						|
 | 
						|
IDBIndex::IDBIndex(IDBObjectStore* aObjectStore, const IndexMetadata* aMetadata)
 | 
						|
  : mObjectStore(aObjectStore)
 | 
						|
  , mCachedKeyPath(JS::UndefinedValue())
 | 
						|
  , mMetadata(aMetadata)
 | 
						|
  , mId(aMetadata->id())
 | 
						|
  , mRooted(false)
 | 
						|
{
 | 
						|
  MOZ_ASSERT(aObjectStore);
 | 
						|
  aObjectStore->AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(aMetadata);
 | 
						|
}
 | 
						|
 | 
						|
IDBIndex::~IDBIndex()
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (mRooted) {
 | 
						|
    mCachedKeyPath.setUndefined();
 | 
						|
    mozilla::DropJSObjects(this);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
already_AddRefed<IDBIndex>
 | 
						|
IDBIndex::Create(IDBObjectStore* aObjectStore,
 | 
						|
                 const IndexMetadata& aMetadata)
 | 
						|
{
 | 
						|
  MOZ_ASSERT(aObjectStore);
 | 
						|
  aObjectStore->AssertIsOnOwningThread();
 | 
						|
 | 
						|
  RefPtr<IDBIndex> index = new IDBIndex(aObjectStore, &aMetadata);
 | 
						|
 | 
						|
  return index.forget();
 | 
						|
}
 | 
						|
 | 
						|
#ifdef DEBUG
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::AssertIsOnOwningThread() const
 | 
						|
{
 | 
						|
  MOZ_ASSERT(mObjectStore);
 | 
						|
  mObjectStore->AssertIsOnOwningThread();
 | 
						|
}
 | 
						|
 | 
						|
#endif // DEBUG
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::RefreshMetadata(bool aMayDelete)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT_IF(mDeletedMetadata, mMetadata == mDeletedMetadata);
 | 
						|
 | 
						|
  const nsTArray<IndexMetadata>& indexes = mObjectStore->Spec().indexes();
 | 
						|
 | 
						|
  bool found = false;
 | 
						|
 | 
						|
  for (uint32_t count = indexes.Length(), index = 0;
 | 
						|
       index < count;
 | 
						|
       index++) {
 | 
						|
    const IndexMetadata& metadata = indexes[index];
 | 
						|
 | 
						|
    if (metadata.id() == Id()) {
 | 
						|
      mMetadata = &metadata;
 | 
						|
 | 
						|
      found = true;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  MOZ_ASSERT_IF(!aMayDelete && !mDeletedMetadata, found);
 | 
						|
 | 
						|
  if (found) {
 | 
						|
    MOZ_ASSERT(mMetadata != mDeletedMetadata);
 | 
						|
    mDeletedMetadata = nullptr;
 | 
						|
  } else {
 | 
						|
    NoteDeletion();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::NoteDeletion()
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
  MOZ_ASSERT(Id() == mMetadata->id());
 | 
						|
 | 
						|
  if (mDeletedMetadata) {
 | 
						|
    MOZ_ASSERT(mMetadata == mDeletedMetadata);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  mDeletedMetadata = new IndexMetadata(*mMetadata);
 | 
						|
 | 
						|
  mMetadata = mDeletedMetadata;
 | 
						|
}
 | 
						|
 | 
						|
const nsString&
 | 
						|
IDBIndex::Name() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->name();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::SetName(const nsAString& aName, ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  IDBTransaction* transaction = mObjectStore->Transaction();
 | 
						|
 | 
						|
  if (transaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
 | 
						|
      mDeletedMetadata) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!transaction->IsOpen()) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (aName == mMetadata->name()) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Cache logging string of this index before renaming.
 | 
						|
  const LoggingString loggingOldIndex(this);
 | 
						|
 | 
						|
  const int64_t indexId = Id();
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
    transaction->Database()->RenameIndex(mObjectStore->Id(),
 | 
						|
                                         indexId,
 | 
						|
                                         aName);
 | 
						|
 | 
						|
  if (NS_FAILED(rv)) {
 | 
						|
    aRv.Throw(rv);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // 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]: "
 | 
						|
                 "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                 "rename(%s)",
 | 
						|
               "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.rename()",
 | 
						|
               IDB_LOG_ID_STRING(),
 | 
						|
               transaction->LoggingSerialNumber(),
 | 
						|
               requestSerialNumber,
 | 
						|
               IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
               IDB_LOG_STRINGIFY(transaction),
 | 
						|
               IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
               loggingOldIndex.get(),
 | 
						|
               IDB_LOG_STRINGIFY(this));
 | 
						|
 | 
						|
  transaction->RenameIndex(mObjectStore, indexId, aName);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
IDBIndex::Unique() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->unique();
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
IDBIndex::MultiEntry() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->multiEntry();
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
IDBIndex::LocaleAware() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->locale().IsEmpty();
 | 
						|
}
 | 
						|
 | 
						|
const indexedDB::KeyPath&
 | 
						|
IDBIndex::GetKeyPath() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->keyPath();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::GetLocale(nsString& aLocale) const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  if (mMetadata->locale().IsEmpty()) {
 | 
						|
    SetDOMStringToNull(aLocale);
 | 
						|
  } else {
 | 
						|
    CopyASCIItoUTF16(mMetadata->locale(), aLocale);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const nsCString&
 | 
						|
IDBIndex::Locale() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->locale();
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
IDBIndex::IsAutoLocale() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
  MOZ_ASSERT(mMetadata);
 | 
						|
 | 
						|
  return mMetadata->autoLocale();
 | 
						|
}
 | 
						|
 | 
						|
nsPIDOMWindowInner*
 | 
						|
IDBIndex::GetParentObject() const
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  return mObjectStore->GetParentObject();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
IDBIndex::GetKeyPath(JSContext* aCx,
 | 
						|
                     JS::MutableHandle<JS::Value> aResult,
 | 
						|
                     ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (!mCachedKeyPath.isUndefined()) {
 | 
						|
    MOZ_ASSERT(mRooted);
 | 
						|
    aResult.set(mCachedKeyPath);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  MOZ_ASSERT(!mRooted);
 | 
						|
 | 
						|
  aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
 | 
						|
  if (NS_WARN_IF(aRv.Failed())) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mCachedKeyPath.isGCThing()) {
 | 
						|
    mozilla::HoldJSObjects(this);
 | 
						|
    mRooted = true;
 | 
						|
  }
 | 
						|
 | 
						|
  aResult.set(mCachedKeyPath);
 | 
						|
}
 | 
						|
 | 
						|
already_AddRefed<IDBRequest>
 | 
						|
IDBIndex::GetInternal(bool aKeyOnly,
 | 
						|
                      JSContext* aCx,
 | 
						|
                      JS::Handle<JS::Value> aKey,
 | 
						|
                      ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (mDeletedMetadata) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  IDBTransaction* transaction = mObjectStore->Transaction();
 | 
						|
  if (!transaction->IsOpen()) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBKeyRange> keyRange;
 | 
						|
  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
 | 
						|
  if (NS_WARN_IF(aRv.Failed())) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!keyRange) {
 | 
						|
    // Must specify a key or keyRange for get() and getKey().
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  const int64_t objectStoreId = mObjectStore->Id();
 | 
						|
  const int64_t indexId = Id();
 | 
						|
 | 
						|
  SerializedKeyRange serializedKeyRange;
 | 
						|
  keyRange->ToSerialized(serializedKeyRange);
 | 
						|
 | 
						|
  RequestParams params;
 | 
						|
 | 
						|
  if (aKeyOnly) {
 | 
						|
    params = IndexGetKeyParams(objectStoreId, indexId, serializedKeyRange);
 | 
						|
  } else {
 | 
						|
    params = IndexGetParams(objectStoreId, indexId, serializedKeyRange);
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBRequest> request = GenerateRequest(aCx, this);
 | 
						|
  MOZ_ASSERT(request);
 | 
						|
 | 
						|
  if (aKeyOnly) {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "getKey(%s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getKey()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange));
 | 
						|
  } else {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "get(%s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.get()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange));
 | 
						|
  }
 | 
						|
 | 
						|
  transaction->StartRequest(request, params);
 | 
						|
 | 
						|
  return request.forget();
 | 
						|
}
 | 
						|
 | 
						|
already_AddRefed<IDBRequest>
 | 
						|
IDBIndex::GetAllInternal(bool aKeysOnly,
 | 
						|
                         JSContext* aCx,
 | 
						|
                         JS::Handle<JS::Value> aKey,
 | 
						|
                         const Optional<uint32_t>& aLimit,
 | 
						|
                         ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (mDeletedMetadata) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  IDBTransaction* transaction = mObjectStore->Transaction();
 | 
						|
  if (!transaction->IsOpen()) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBKeyRange> keyRange;
 | 
						|
  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
 | 
						|
  if (NS_WARN_IF(aRv.Failed())) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  const int64_t objectStoreId = mObjectStore->Id();
 | 
						|
  const int64_t indexId = Id();
 | 
						|
 | 
						|
  OptionalKeyRange optionalKeyRange;
 | 
						|
  if (keyRange) {
 | 
						|
    SerializedKeyRange serializedKeyRange;
 | 
						|
    keyRange->ToSerialized(serializedKeyRange);
 | 
						|
    optionalKeyRange = serializedKeyRange;
 | 
						|
  } else {
 | 
						|
    optionalKeyRange = void_t();
 | 
						|
  }
 | 
						|
 | 
						|
  const uint32_t limit = aLimit.WasPassed() ? aLimit.Value() : 0;
 | 
						|
 | 
						|
  RequestParams params;
 | 
						|
  if (aKeysOnly) {
 | 
						|
    params = IndexGetAllKeysParams(objectStoreId, indexId, optionalKeyRange,
 | 
						|
                                   limit);
 | 
						|
  } else {
 | 
						|
    params = IndexGetAllParams(objectStoreId, indexId, optionalKeyRange, limit);
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBRequest> request = GenerateRequest(aCx, this);
 | 
						|
  MOZ_ASSERT(request);
 | 
						|
 | 
						|
  if (aKeysOnly) {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "getAllKeys(%s, %s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getAllKeys()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange),
 | 
						|
                 IDB_LOG_STRINGIFY(aLimit));
 | 
						|
  } else {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "getAll(%s, %s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getAll()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange),
 | 
						|
                 IDB_LOG_STRINGIFY(aLimit));
 | 
						|
  }
 | 
						|
 | 
						|
  transaction->StartRequest(request, params);
 | 
						|
 | 
						|
  return request.forget();
 | 
						|
}
 | 
						|
 | 
						|
already_AddRefed<IDBRequest>
 | 
						|
IDBIndex::OpenCursorInternal(bool aKeysOnly,
 | 
						|
                             JSContext* aCx,
 | 
						|
                             JS::Handle<JS::Value> aRange,
 | 
						|
                             IDBCursorDirection aDirection,
 | 
						|
                             ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (mDeletedMetadata) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  IDBTransaction* transaction = mObjectStore->Transaction();
 | 
						|
  if (!transaction->IsOpen()) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBKeyRange> keyRange;
 | 
						|
  aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
 | 
						|
  if (NS_WARN_IF(aRv.Failed())) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  int64_t objectStoreId = mObjectStore->Id();
 | 
						|
  int64_t indexId = Id();
 | 
						|
 | 
						|
  OptionalKeyRange optionalKeyRange;
 | 
						|
 | 
						|
  if (keyRange) {
 | 
						|
    SerializedKeyRange serializedKeyRange;
 | 
						|
    keyRange->ToSerialized(serializedKeyRange);
 | 
						|
 | 
						|
    optionalKeyRange = Move(serializedKeyRange);
 | 
						|
  } else {
 | 
						|
    optionalKeyRange = void_t();
 | 
						|
  }
 | 
						|
 | 
						|
  IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);
 | 
						|
 | 
						|
  OpenCursorParams params;
 | 
						|
  if (aKeysOnly) {
 | 
						|
    IndexOpenKeyCursorParams openParams;
 | 
						|
    openParams.objectStoreId() = objectStoreId;
 | 
						|
    openParams.indexId() = indexId;
 | 
						|
    openParams.optionalKeyRange() = Move(optionalKeyRange);
 | 
						|
    openParams.direction() = direction;
 | 
						|
 | 
						|
    params = Move(openParams);
 | 
						|
  } else {
 | 
						|
    IndexOpenCursorParams openParams;
 | 
						|
    openParams.objectStoreId() = objectStoreId;
 | 
						|
    openParams.indexId() = indexId;
 | 
						|
    openParams.optionalKeyRange() = Move(optionalKeyRange);
 | 
						|
    openParams.direction() = direction;
 | 
						|
 | 
						|
    params = Move(openParams);
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBRequest> request = GenerateRequest(aCx, this);
 | 
						|
  MOZ_ASSERT(request);
 | 
						|
 | 
						|
  if (aKeysOnly) {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "openKeyCursor(%s, %s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.openKeyCursor()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange),
 | 
						|
                 IDB_LOG_STRINGIFY(direction));
 | 
						|
  } else {
 | 
						|
    IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                   "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                   "openCursor(%s, %s)",
 | 
						|
                 "IndexedDB %s: C T[%lld] R[%llu]: "
 | 
						|
                   "IDBObjectStore.openKeyCursor()",
 | 
						|
                 IDB_LOG_ID_STRING(),
 | 
						|
                 transaction->LoggingSerialNumber(),
 | 
						|
                 request->LoggingSerialNumber(),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
                 IDB_LOG_STRINGIFY(transaction),
 | 
						|
                 IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
                 IDB_LOG_STRINGIFY(this),
 | 
						|
                 IDB_LOG_STRINGIFY(keyRange),
 | 
						|
                 IDB_LOG_STRINGIFY(direction));
 | 
						|
  }
 | 
						|
 | 
						|
  BackgroundCursorChild* actor =
 | 
						|
    new BackgroundCursorChild(request, this, direction);
 | 
						|
 | 
						|
  mObjectStore->Transaction()->OpenCursor(actor, params);
 | 
						|
 | 
						|
  return request.forget();
 | 
						|
}
 | 
						|
 | 
						|
already_AddRefed<IDBRequest>
 | 
						|
IDBIndex::Count(JSContext* aCx,
 | 
						|
                JS::Handle<JS::Value> aKey,
 | 
						|
                ErrorResult& aRv)
 | 
						|
{
 | 
						|
  AssertIsOnOwningThread();
 | 
						|
 | 
						|
  if (mDeletedMetadata) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  IDBTransaction* transaction = mObjectStore->Transaction();
 | 
						|
  if (!transaction->IsOpen()) {
 | 
						|
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBKeyRange> keyRange;
 | 
						|
  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
 | 
						|
  if (aRv.Failed()) {
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  IndexCountParams params;
 | 
						|
  params.objectStoreId() = mObjectStore->Id();
 | 
						|
  params.indexId() = Id();
 | 
						|
 | 
						|
  if (keyRange) {
 | 
						|
    SerializedKeyRange serializedKeyRange;
 | 
						|
    keyRange->ToSerialized(serializedKeyRange);
 | 
						|
    params.optionalKeyRange() = serializedKeyRange;
 | 
						|
  } else {
 | 
						|
    params.optionalKeyRange() = void_t();
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<IDBRequest> request = GenerateRequest(aCx, this);
 | 
						|
  MOZ_ASSERT(request);
 | 
						|
 | 
						|
  IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
 | 
						|
                 "database(%s).transaction(%s).objectStore(%s).index(%s)."
 | 
						|
                 "count(%s)",
 | 
						|
               "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.count()",
 | 
						|
               IDB_LOG_ID_STRING(),
 | 
						|
               transaction->LoggingSerialNumber(),
 | 
						|
               request->LoggingSerialNumber(),
 | 
						|
               IDB_LOG_STRINGIFY(transaction->Database()),
 | 
						|
               IDB_LOG_STRINGIFY(transaction),
 | 
						|
               IDB_LOG_STRINGIFY(mObjectStore),
 | 
						|
               IDB_LOG_STRINGIFY(this),
 | 
						|
               IDB_LOG_STRINGIFY(keyRange));
 | 
						|
 | 
						|
  transaction->StartRequest(request, params);
 | 
						|
 | 
						|
  return request.forget();
 | 
						|
}
 | 
						|
 | 
						|
NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBIndex)
 | 
						|
NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBIndex)
 | 
						|
 | 
						|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBIndex)
 | 
						|
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
 | 
						|
  NS_INTERFACE_MAP_ENTRY(nsISupports)
 | 
						|
NS_INTERFACE_MAP_END
 | 
						|
 | 
						|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBIndex)
 | 
						|
 | 
						|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBIndex)
 | 
						|
  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 | 
						|
  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedKeyPath)
 | 
						|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
 | 
						|
 | 
						|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBIndex)
 | 
						|
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectStore)
 | 
						|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 | 
						|
 | 
						|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBIndex)
 | 
						|
  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 | 
						|
 | 
						|
  // Don't unlink mObjectStore!
 | 
						|
 | 
						|
  tmp->mCachedKeyPath.setUndefined();
 | 
						|
 | 
						|
  if (tmp->mRooted) {
 | 
						|
    mozilla::DropJSObjects(tmp);
 | 
						|
    tmp->mRooted = false;
 | 
						|
  }
 | 
						|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 | 
						|
 | 
						|
JSObject*
 | 
						|
IDBIndex::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 | 
						|
{
 | 
						|
  return IDBIndexBinding::Wrap(aCx, this, aGivenProto);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace dom
 | 
						|
} // namespace mozilla
 |