mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-19 09:30:44 +00:00
Implement index.openCursor
This commit is contained in:
parent
3f04112c9c
commit
d5f3eada6f
@ -54,6 +54,7 @@
|
||||
|
||||
#include "AsyncConnectionHelper.h"
|
||||
#include "IDBEvents.h"
|
||||
#include "IDBIndexRequest.h"
|
||||
#include "IDBObjectStoreRequest.h"
|
||||
#include "IDBTransactionRequest.h"
|
||||
#include "Savepoint.h"
|
||||
@ -139,24 +140,95 @@ IDBCursorRequest::Create(IDBRequest* aRequest,
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyValuePair>& aData)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aRequest, "Null pointer!");
|
||||
NS_ASSERTION(aTransaction, "Null pointer!");
|
||||
NS_ASSERTION(aObjectStore, "Null pointer!");
|
||||
|
||||
nsRefPtr<IDBCursorRequest> cursor(new IDBCursorRequest());
|
||||
cursor->mRequest = aRequest;
|
||||
cursor->mTransaction = aTransaction;
|
||||
nsRefPtr<IDBCursorRequest> cursor =
|
||||
IDBCursorRequest::CreateCommon(aRequest, aTransaction, aDirection);
|
||||
|
||||
cursor->mObjectStore = aObjectStore;
|
||||
cursor->mDirection = aDirection;
|
||||
|
||||
if (!cursor->mData.SwapElements(aData)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
return nsnull;
|
||||
}
|
||||
NS_ASSERTION(!cursor->mData.IsEmpty(), "Should ever have an empty set!");
|
||||
NS_ASSERTION(!cursor->mData.IsEmpty(), "Should never have an empty set!");
|
||||
|
||||
cursor->mDataIndex = cursor->mData.Length() - 1;
|
||||
cursor->mType = OBJECTSTORE;
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
IDBCursorRequest::Create(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
IDBIndexRequest* aIndex,
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyKeyPair>& aData)
|
||||
{
|
||||
NS_ASSERTION(aIndex, "Null pointer!");
|
||||
|
||||
nsRefPtr<IDBCursorRequest> cursor =
|
||||
IDBCursorRequest::CreateCommon(aRequest, aTransaction, aDirection);
|
||||
|
||||
cursor->mObjectStore = aIndex->ObjectStore();
|
||||
cursor->mIndex = aIndex;
|
||||
|
||||
if (!cursor->mKeyData.SwapElements(aData)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
return nsnull;
|
||||
}
|
||||
NS_ASSERTION(!cursor->mKeyData.IsEmpty(), "Should never have an empty set!");
|
||||
|
||||
cursor->mDataIndex = cursor->mKeyData.Length() - 1;
|
||||
cursor->mType = INDEX;
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
IDBCursorRequest::Create(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
IDBIndexRequest* aIndex,
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyValuePair>& aData)
|
||||
{
|
||||
NS_ASSERTION(aIndex, "Null pointer!");
|
||||
|
||||
nsRefPtr<IDBCursorRequest> cursor =
|
||||
IDBCursorRequest::CreateCommon(aRequest, aTransaction, aDirection);
|
||||
|
||||
cursor->mObjectStore = aIndex->ObjectStore();
|
||||
cursor->mIndex = aIndex;
|
||||
|
||||
if (!cursor->mData.SwapElements(aData)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
return nsnull;
|
||||
}
|
||||
NS_ASSERTION(!cursor->mData.IsEmpty(), "Should never have an empty set!");
|
||||
|
||||
cursor->mDataIndex = cursor->mData.Length() - 1;
|
||||
cursor->mType = INDEXOBJECT;
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
IDBCursorRequest::CreateCommon(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
PRUint16 aDirection)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aRequest, "Null pointer!");
|
||||
NS_ASSERTION(aTransaction, "Null pointer!");
|
||||
|
||||
nsRefPtr<IDBCursorRequest> cursor(new IDBCursorRequest());
|
||||
cursor->mRequest = aRequest;
|
||||
cursor->mTransaction = aTransaction;
|
||||
cursor->mDirection = aDirection;
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
@ -166,7 +238,8 @@ IDBCursorRequest::IDBCursorRequest()
|
||||
mCachedValue(JSVAL_VOID),
|
||||
mHaveCachedValue(false),
|
||||
mJSRuntime(nsnull),
|
||||
mDataIndex(0)
|
||||
mDataIndex(0),
|
||||
mType(OBJECTSTORE)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
@ -212,7 +285,9 @@ IDBCursorRequest::GetKey(nsIVariant** aKey)
|
||||
do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const Key& key = mData[mDataIndex].key;
|
||||
const Key& key = mType == INDEX ?
|
||||
mKeyData[mDataIndex].key :
|
||||
mData[mDataIndex].key;
|
||||
NS_ASSERTION(!key.IsUnset() && !key.IsNull(), "Bad key!");
|
||||
|
||||
if (key.IsString()) {
|
||||
@ -242,17 +317,49 @@ IDBCursorRequest::GetKey(nsIVariant** aKey)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBCursorRequest::GetValue(nsIVariant** /* aValue */)
|
||||
IDBCursorRequest::GetValue(nsIVariant** aValue)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (mType == INDEX) {
|
||||
nsCOMPtr<nsIWritableVariant> variant =
|
||||
do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
if (!variant) {
|
||||
NS_ERROR("Couldn't create variant!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const Key& value = mKeyData[mDataIndex].value;
|
||||
NS_ASSERTION(!value.IsUnset() && !value.IsNull(), "Bad key!");
|
||||
if (value.IsInt()) {
|
||||
rv = variant->SetAsInt64(value.IntValue());
|
||||
}
|
||||
else if (value.IsString()) {
|
||||
rv = variant->SetAsAString(value.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = variant->SetWritable(PR_FALSE);;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIWritableVariant* result;
|
||||
variant.forget(&result);
|
||||
*aValue = result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("Using a slow path for GetValue! Fix this now!");
|
||||
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
NS_ENSURE_TRUE(xpc, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAXPCNativeCallContext* cc;
|
||||
nsresult rv = xpc->GetCurrentNativeCallContext(&cc);
|
||||
rv = xpc->GetCurrentNativeCallContext(&cc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(cc, NS_ERROR_UNEXPECTED);
|
||||
|
||||
@ -271,7 +378,7 @@ IDBCursorRequest::GetValue(nsIVariant** /* aValue */)
|
||||
JSRuntime* rt = JS_GetRuntime(cx);
|
||||
|
||||
JSBool ok = JS_AddNamedRootRT(rt, &mCachedValue,
|
||||
"IDBCursorRequest::mCachedValue");
|
||||
"IDBCursorRequest::mCachedValue");
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
mJSRuntime = rt;
|
||||
@ -313,6 +420,11 @@ IDBCursorRequest::Continue(nsIVariant* aKey,
|
||||
}
|
||||
}
|
||||
|
||||
if (mType != OBJECTSTORE && !key.IsUnset()) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
||||
NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE);
|
||||
|
||||
@ -333,6 +445,11 @@ IDBCursorRequest::Update(nsIVariant* aValue,
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mType != OBJECTSTORE) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!mObjectStore->TransactionIsOpen()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -475,6 +592,11 @@ IDBCursorRequest::Remove(nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mType != OBJECTSTORE) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!mObjectStore->TransactionIsOpen()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -630,7 +752,12 @@ ContinueRunnable::Run()
|
||||
mCursor->mCachedValue = JSVAL_VOID;
|
||||
mCursor->mHaveCachedValue = false;
|
||||
|
||||
mCursor->mData.RemoveElementAt(mCursor->mDataIndex);
|
||||
if (mCursor->mType == IDBCursorRequest::INDEX) {
|
||||
mCursor->mKeyData.RemoveElementAt(mCursor->mDataIndex);
|
||||
}
|
||||
else {
|
||||
mCursor->mData.RemoveElementAt(mCursor->mDataIndex);
|
||||
}
|
||||
if (mCursor->mDataIndex) {
|
||||
mCursor->mDataIndex--;
|
||||
}
|
||||
@ -642,7 +769,11 @@ ContinueRunnable::Run()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mCursor->mData.IsEmpty()) {
|
||||
PRBool empty = mCursor->mType == IDBCursorRequest::INDEX ?
|
||||
mCursor->mKeyData.IsEmpty() :
|
||||
mCursor->mData.IsEmpty();
|
||||
|
||||
if (empty) {
|
||||
rv = variant->SetAsEmpty();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -650,6 +781,11 @@ ContinueRunnable::Run()
|
||||
if (!mKey.IsUnset()) {
|
||||
NS_ASSERTION(!mKey.IsNull(), "Huh?!");
|
||||
|
||||
if (mCursor->mType != IDBCursorRequest::OBJECTSTORE) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_WARNING("Using a slow O(n) search for continue(key), do something "
|
||||
"smarter!");
|
||||
|
||||
|
@ -49,6 +49,7 @@ class nsIRunnable;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class IDBIndexRequest;
|
||||
class IDBRequest;
|
||||
class IDBObjectStoreRequest;
|
||||
class IDBTransactionRequest;
|
||||
@ -59,6 +60,12 @@ struct KeyValuePair
|
||||
nsString value;
|
||||
};
|
||||
|
||||
struct KeyKeyPair
|
||||
{
|
||||
Key key;
|
||||
Key value;
|
||||
};
|
||||
|
||||
class ContinueRunnable;
|
||||
|
||||
class IDBCursorRequest : public IDBRequest::Generator,
|
||||
@ -79,14 +86,43 @@ public:
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyValuePair>& aData);
|
||||
|
||||
|
||||
static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
Create(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
IDBIndexRequest* aIndex,
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyKeyPair>& aData);
|
||||
|
||||
static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
Create(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
IDBIndexRequest* aIndex,
|
||||
PRUint16 aDirection,
|
||||
nsTArray<KeyValuePair>& aData);
|
||||
|
||||
enum Type
|
||||
{
|
||||
OBJECTSTORE = 0,
|
||||
INDEX,
|
||||
INDEXOBJECT
|
||||
};
|
||||
|
||||
protected:
|
||||
IDBCursorRequest();
|
||||
~IDBCursorRequest();
|
||||
|
||||
static
|
||||
already_AddRefed<IDBCursorRequest>
|
||||
CreateCommon(IDBRequest* aRequest,
|
||||
IDBTransactionRequest* aTransaction,
|
||||
PRUint16 aDirection);
|
||||
|
||||
nsRefPtr<IDBRequest> mRequest;
|
||||
nsRefPtr<IDBTransactionRequest> mTransaction;
|
||||
nsRefPtr<IDBObjectStoreRequest> mObjectStore;
|
||||
nsRefPtr<IDBIndexRequest> mIndex;
|
||||
|
||||
PRUint16 mDirection;
|
||||
|
||||
@ -96,7 +132,10 @@ protected:
|
||||
JSRuntime* mJSRuntime;
|
||||
|
||||
PRUint32 mDataIndex;
|
||||
|
||||
Type mType;
|
||||
nsTArray<KeyValuePair> mData;
|
||||
nsTArray<KeyKeyPair> mKeyData;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
@ -41,12 +41,14 @@
|
||||
#include "IDBIndexRequest.h"
|
||||
|
||||
#include "nsIIDBDatabaseException.h"
|
||||
#include "nsIIDBKeyRange.h"
|
||||
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Storage.h"
|
||||
|
||||
#include "AsyncConnectionHelper.h"
|
||||
#include "IDBCursorRequest.h"
|
||||
#include "IDBEvents.h"
|
||||
#include "IDBObjectStoreRequest.h"
|
||||
#include "IDBTransactionRequest.h"
|
||||
@ -61,11 +63,11 @@ class GetHelper : public AsyncConnectionHelper
|
||||
public:
|
||||
GetHelper(IDBTransactionRequest* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
const nsAString& aValue,
|
||||
const Key& aKey,
|
||||
PRInt64 aId,
|
||||
bool aUnique,
|
||||
bool aAutoIncrement)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mValue(aValue), mId(aId),
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mKey(aKey), mId(aId),
|
||||
mUnique(aUnique), mAutoIncrement(aAutoIncrement)
|
||||
{ }
|
||||
|
||||
@ -74,14 +76,10 @@ public:
|
||||
|
||||
protected:
|
||||
// In-params.
|
||||
nsString mValue;
|
||||
Key mKey;
|
||||
const PRInt64 mId;
|
||||
const bool mUnique;
|
||||
const bool mAutoIncrement;
|
||||
|
||||
private:
|
||||
// Out-params.
|
||||
Key mKey;
|
||||
};
|
||||
|
||||
class GetObjectHelper : public GetHelper
|
||||
@ -89,19 +87,58 @@ class GetObjectHelper : public GetHelper
|
||||
public:
|
||||
GetObjectHelper(IDBTransactionRequest* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
const nsAString& aValue,
|
||||
const Key& aKey,
|
||||
PRInt64 aId,
|
||||
bool aUnique,
|
||||
bool aAutoIncrement)
|
||||
: GetHelper(aTransaction, aRequest, aValue, aId, aUnique, aAutoIncrement)
|
||||
: GetHelper(aTransaction, aRequest, aKey, aId, aUnique, aAutoIncrement)
|
||||
{ }
|
||||
|
||||
PRUint16 DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||
PRUint16 OnSuccess(nsIDOMEventTarget* aTarget);
|
||||
|
||||
private:
|
||||
nsString mValue;
|
||||
};
|
||||
|
||||
// Remove once XPIDL can handle jsvals
|
||||
class OpenCursorHelper : public AsyncConnectionHelper
|
||||
{
|
||||
public:
|
||||
OpenCursorHelper(IDBTransactionRequest* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBIndexRequest* aIndex,
|
||||
PRInt64 aId,
|
||||
bool aUnique,
|
||||
bool aAutoIncrement,
|
||||
const Key& aLeftKey,
|
||||
const Key& aRightKey,
|
||||
PRUint16 aKeyRangeFlags,
|
||||
PRUint16 aDirection,
|
||||
PRBool aPreload)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex), mId(aId),
|
||||
mUnique(aUnique), mAutoIncrement(aAutoIncrement), mLeftKey(aLeftKey),
|
||||
mRightKey(aRightKey), mKeyRangeFlags(aKeyRangeFlags),
|
||||
mDirection(aDirection), mPreload(aPreload)
|
||||
{ }
|
||||
|
||||
PRUint16 DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||
PRUint16 GetSuccessResult(nsIWritableVariant* aResult);
|
||||
|
||||
private:
|
||||
// In-params.
|
||||
nsRefPtr<IDBIndexRequest> mIndex;
|
||||
const PRInt64 mId;
|
||||
const bool mUnique;
|
||||
const bool mAutoIncrement;
|
||||
const Key mLeftKey;
|
||||
const Key mRightKey;
|
||||
const PRUint16 mKeyRangeFlags;
|
||||
const PRUint16 mDirection;
|
||||
const PRBool mPreload;
|
||||
|
||||
// Out-params.
|
||||
nsTArray<KeyKeyPair> mData;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@ -191,10 +228,66 @@ IDBIndexRequest::GetUnique(PRBool* aUnique)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIIDBIndexRequest
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndexRequest::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
PRUint16 aDirection,
|
||||
PRBool aPreload,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (!mObjectStore->TransactionIsOpen()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (aKeyRange) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
if (aDirection != nsIIDBCursor::NEXT) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aPreload) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest();
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<OpenCursorHelper> helper =
|
||||
new OpenCursorHelper(mObjectStore->Transaction(), request, this, mId,
|
||||
mUnique, mAutoIncrement, Key(), Key(), 0, aDirection,
|
||||
aPreload);
|
||||
|
||||
nsresult rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndexRequest::OpenObjectCursor(nsIIDBKeyRange* aRange,
|
||||
PRUint16 aDirection,
|
||||
PRBool aPreload,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
@ -202,35 +295,29 @@ IDBIndexRequest::OpenObjectCursor(nsIIDBKeyRange* aRange,
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndexRequest::OpenCursor(nsIIDBKeyRange* aRange,
|
||||
PRUint16 aDirection,
|
||||
PRBool aPreload,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndexRequest::GetObject(nsIVariant* /* aKey */,
|
||||
IDBIndexRequest::GetObject(nsIVariant* aKey,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_WARNING("Using a slow path for Get! Fix this now!");
|
||||
|
||||
nsString jsonValue;
|
||||
nsresult rv = IDBObjectStoreRequest::GetJSONFromArg0(jsonValue);
|
||||
Key key;
|
||||
nsresult rv = IDBObjectStoreRequest::GetKeyFromVariant(aKey, key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (key.IsUnset() || key.IsNull()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest();
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<GetObjectHelper> helper =
|
||||
new GetObjectHelper(mObjectStore->Transaction(), request, jsonValue, mId,
|
||||
mUnique, mAutoIncrement);
|
||||
new GetObjectHelper(mObjectStore->Transaction(), request, key, mId, mUnique,
|
||||
mAutoIncrement);
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -239,22 +326,26 @@ IDBIndexRequest::GetObject(nsIVariant* /* aKey */,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndexRequest::Get(nsIVariant* /* aKey */,
|
||||
IDBIndexRequest::Get(nsIVariant* aKey,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_WARNING("Using a slow path for Get! Fix this now!");
|
||||
|
||||
nsString jsonValue;
|
||||
nsresult rv = IDBObjectStoreRequest::GetJSONFromArg0(jsonValue);
|
||||
Key key;
|
||||
nsresult rv = IDBObjectStoreRequest::GetKeyFromVariant(aKey, key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (key.IsUnset() || key.IsNull()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest();
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<GetHelper> helper =
|
||||
new GetHelper(mObjectStore->Transaction(), request, jsonValue, mId, mUnique,
|
||||
new GetHelper(mObjectStore->Transaction(), request, key, mId, mUnique,
|
||||
mAutoIncrement);
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -277,9 +368,21 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"), mId);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("value"), mValue);
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(value, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(value, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
mKey = Key::UNSETKEY;
|
||||
|
||||
PRBool hasResult;
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
@ -300,6 +403,9 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
rv = stmt->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -339,9 +445,21 @@ GetObjectHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"), mId);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("value"), mValue);
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(value, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(value, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
mKey = Key::UNSETKEY;
|
||||
|
||||
PRBool hasResult;
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
@ -368,3 +486,124 @@ GetObjectHelper::OnSuccess(nsIDOMEventTarget* aTarget)
|
||||
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
|
||||
return OK;
|
||||
}
|
||||
|
||||
PRUint16
|
||||
OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
{
|
||||
NS_ASSERTION(aConnection, "Passed a null connection!");
|
||||
|
||||
nsCString table;
|
||||
nsCString keyColumn;
|
||||
|
||||
if (mAutoIncrement) {
|
||||
keyColumn.AssignLiteral("ai_object_data_id");
|
||||
if (mUnique) {
|
||||
table.AssignLiteral("unique_ai_index_data");
|
||||
}
|
||||
else {
|
||||
table.AssignLiteral("ai_index_data");
|
||||
}
|
||||
}
|
||||
else {
|
||||
keyColumn.AssignLiteral("object_data_key");
|
||||
if (mUnique) {
|
||||
table.AssignLiteral("unique_index_data");
|
||||
}
|
||||
else {
|
||||
table.AssignLiteral("index_data");
|
||||
}
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
|
||||
|
||||
nsCAutoString query("SELECT value, ");
|
||||
query.Append(keyColumn);
|
||||
query.AppendLiteral(" FROM ");
|
||||
query.Append(table);
|
||||
query.AppendLiteral(" WHERE index_id = :");
|
||||
query.Append(indexId);
|
||||
query.AppendLiteral(" ORDER BY value DESC");
|
||||
|
||||
if (!mData.SetCapacity(50)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
nsresult rv = aConnection->CreateStatement(query, getter_AddRefs(stmt));
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
rv = stmt->BindInt64ByName(indexId, mId);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
PRBool hasResult;
|
||||
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
if (mData.Capacity() == mData.Length()) {
|
||||
if (!mData.SetCapacity(mData.Capacity() * 2)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
KeyKeyPair* pair = mData.AppendElement();
|
||||
NS_ASSERTION(pair, "Shouldn't fail if SetCapacity succeeded!");
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
pair->key = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, pair->key.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
rv = stmt->GetTypeOfIndex(1, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
pair->value = stmt->AsInt64(1);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(1, pair->value.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
PRUint16
|
||||
OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
||||
{
|
||||
if (mData.IsEmpty()) {
|
||||
aResult->SetAsEmpty();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBCursorRequest> cursor =
|
||||
IDBCursorRequest::Create(mRequest, mTransaction, mIndex, mDirection,
|
||||
mData);
|
||||
NS_ENSURE_TRUE(cursor, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
aResult->SetAsISupports(static_cast<IDBRequest::Generator*>(cursor));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -61,6 +61,11 @@ public:
|
||||
Create(IDBObjectStoreRequest* aObjectStore,
|
||||
const IndexInfo* aIndexInfo);
|
||||
|
||||
IDBObjectStoreRequest* ObjectStore()
|
||||
{
|
||||
return mObjectStore;
|
||||
}
|
||||
|
||||
protected:
|
||||
IDBIndexRequest();
|
||||
~IDBIndexRequest();
|
||||
|
@ -71,7 +71,7 @@ BEGIN_INDEXEDDB_NAMESPACE
|
||||
struct IndexUpdateInfo
|
||||
{
|
||||
IndexInfo info;
|
||||
nsString value;
|
||||
Key value;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
@ -411,7 +411,7 @@ nsresult
|
||||
IDBObjectStoreRequest::GetKeyPathValueFromJSON(const nsAString& aJSON,
|
||||
const nsAString& aKeyPath,
|
||||
JSContext** aCx,
|
||||
nsAString& aValue)
|
||||
Key& aValue)
|
||||
{
|
||||
NS_ASSERTION(!aJSON.IsEmpty(), "Empty JSON!");
|
||||
NS_ASSERTION(!aKeyPath.IsEmpty(), "Empty keyPath!");
|
||||
@ -443,8 +443,31 @@ IDBObjectStoreRequest::GetKeyPathValueFromJSON(const nsAString& aJSON,
|
||||
value.addr());
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
rv = json->EncodeFromJSVal(value.addr(), *aCx, aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (JSVAL_IS_VOID(value.value())) {
|
||||
// Not sure what to do if the object doesn't have a value for our index...
|
||||
aValue = Key::UNSETKEY;
|
||||
}
|
||||
else if (JSVAL_IS_INT(value.value())) {
|
||||
aValue = JSVAL_TO_INT(value.value());
|
||||
}
|
||||
else if (JSVAL_IS_DOUBLE(value.value())) {
|
||||
aValue = *JSVAL_TO_DOUBLE(value.value());
|
||||
}
|
||||
else if (JSVAL_IS_STRING(value.value())) {
|
||||
JSString* str = JSVAL_TO_STRING(value.value());
|
||||
size_t len = JS_GetStringLength(str);
|
||||
if (len) {
|
||||
const PRUnichar* chars =
|
||||
reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
|
||||
aValue = nsDependentString(chars, len);
|
||||
}
|
||||
else {
|
||||
aValue = EmptyString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -561,8 +584,6 @@ IDBObjectStoreRequest::GetAddInfo(/* jsval aValue, */
|
||||
cloneObj = JSVAL_TO_OBJECT(clone.value());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIJSON> json(new nsJSON());
|
||||
|
||||
for (PRUint32 indexesIndex = 0; indexesIndex < indexesCount; indexesIndex++) {
|
||||
const IndexInfo& indexInfo = objectStoreInfo->indexes[indexesIndex];
|
||||
|
||||
@ -575,14 +596,32 @@ IDBObjectStoreRequest::GetAddInfo(/* jsval aValue, */
|
||||
&keyPathValue);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
nsString value;
|
||||
Key value;
|
||||
if (JSVAL_IS_VOID(keyPathValue)) {
|
||||
// Not sure what to do if the object doesn't have a value for our index...
|
||||
NS_WARNING("Using an empty string for an index match failure!");
|
||||
// No value here, continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_INT(keyPathValue)) {
|
||||
value = JSVAL_TO_INT(keyPathValue);
|
||||
}
|
||||
else if (JSVAL_IS_DOUBLE(keyPathValue)) {
|
||||
value = *JSVAL_TO_DOUBLE(keyPathValue);
|
||||
}
|
||||
else if (JSVAL_IS_STRING(keyPathValue)) {
|
||||
JSString* str = JSVAL_TO_STRING(keyPathValue);
|
||||
size_t len = JS_GetStringLength(str);
|
||||
if (len) {
|
||||
const PRUnichar* chars =
|
||||
reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
|
||||
value = nsDependentString(chars, len);
|
||||
}
|
||||
else {
|
||||
value = EmptyString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = json->EncodeFromJSVal(&keyPathValue, cx, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
|
||||
@ -592,6 +631,7 @@ IDBObjectStoreRequest::GetAddInfo(/* jsval aValue, */
|
||||
updateInfo->value = value;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIJSON> json(new nsJSON());
|
||||
rv = json->EncodeFromJSVal(clone.addr(), cx, aJSON);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -923,6 +963,11 @@ IDBObjectStoreRequest::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
if (aDirection != nsIIDBCursor::NEXT) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aPreload) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -1383,7 +1428,20 @@ AddHelper::UpdateIndexes(mozIStorageConnection* aConnection,
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("value"), updateInfo.value);
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
if (updateInfo.value.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(value, updateInfo.value.IntValue());
|
||||
}
|
||||
else if (updateInfo.value.IsString()) {
|
||||
rv = stmt->BindStringByName(value, updateInfo.value.StringValue());
|
||||
}
|
||||
else if (updateInfo.value.IsUnset()) {
|
||||
rv = stmt->BindStringByName(value, updateInfo.value.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
@ -1630,6 +1688,9 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
rv = stmt->GetString(0, pair->key.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
@ -1768,14 +1829,28 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
|
||||
rv = stmt->GetString(1, json);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
nsString value;
|
||||
Key key;
|
||||
JSContext* cx = nsnull;
|
||||
rv = IDBObjectStoreRequest::GetKeyPathValueFromJSON(json, mKeyPath, &cx,
|
||||
value);
|
||||
key);
|
||||
// XXX this should be a constraint error maybe?
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
rv = insertStmt->BindStringByName(NS_LITERAL_CSTRING("value"), value);
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
if (key.IsUnset()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key.IsInt()) {
|
||||
rv = insertStmt->BindInt64ByName(value, key.IntValue());
|
||||
}
|
||||
else if (key.IsString()) {
|
||||
rv = insertStmt->BindStringByName(value, key.StringValue());
|
||||
}
|
||||
else {
|
||||
return nsIIDBDatabaseException::CONSTRAINT_ERR;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
rv = insertStmt->Execute();
|
||||
|
@ -230,7 +230,7 @@ public:
|
||||
GetKeyPathValueFromJSON(const nsAString& aJSON,
|
||||
const nsAString& aKeyPath,
|
||||
JSContext** aCx,
|
||||
nsAString& aValue);
|
||||
Key& aValue);
|
||||
|
||||
bool TransactionIsOpen() const
|
||||
{
|
||||
|
@ -203,7 +203,7 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value TEXT NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
@ -226,7 +226,7 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value TEXT NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
@ -243,7 +243,7 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value TEXT NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
@ -265,7 +265,7 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value TEXT NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
|
@ -51,17 +51,19 @@ interface nsIVariant;
|
||||
[scriptable, uuid(8c21dfc3-62fa-470e-bc92-7d115b0fac97)]
|
||||
interface nsIIDBIndexRequest : nsIIDBIndex
|
||||
{
|
||||
[optional_argc]
|
||||
nsIIDBRequest
|
||||
openCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
[optional /* nsIIDBCursor::NEXT */] in unsigned short direction,
|
||||
[optional /* false */] in boolean preload);
|
||||
|
||||
[optional_argc]
|
||||
nsIIDBRequest
|
||||
openObjectCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
[optional /* nsIIDBCursor::NEXT */]
|
||||
in unsigned short direction,
|
||||
[optional /* false */] in boolean preload);
|
||||
|
||||
nsIIDBRequest
|
||||
openCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
[optional /* nsIIDBCursor::NEXT */] in unsigned short direction,
|
||||
[optional /* false */] in boolean preload);
|
||||
|
||||
nsIIDBRequest
|
||||
getObject(in nsIVariant key);
|
||||
|
||||
|
@ -37,6 +37,23 @@
|
||||
{ name: "weight", keyPath: "weight", unique: false }
|
||||
];
|
||||
|
||||
const objectStoreDataNameSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, description);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
@ -117,6 +134,64 @@
|
||||
is(event.result.height, 60, "Correct height returned!");
|
||||
is(event.result.weight, 120, "Correct weight returned!");
|
||||
|
||||
let keyIndex = 0;
|
||||
|
||||
request = objectStore.index("name").openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
let ok = cursor.continue();
|
||||
is(ok, true, "Correct return from continue");
|
||||
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.index("weight").openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataWeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
let ok = cursor.continue();
|
||||
is(ok, true, "Correct return from continue");
|
||||
|
||||
is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataWeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, objectStoreData.length - 1, "Saw all the expected keys");
|
||||
|
||||
objectStore = db.objectStore(objectStoreName, READ_WRITE);
|
||||
request = objectStore.add({ name: "Bob", height: 62, weight: 170 },
|
||||
"237-23-7738");
|
||||
|
@ -494,8 +494,8 @@ members = [
|
||||
'-nsIIDBCursorRequest.continue',
|
||||
'-nsIIDBCursorRequest.value',
|
||||
'-nsIIDBCursorRequest.update',
|
||||
'-nsIIDBIndexRequest.get',
|
||||
'-nsIIDBIndexRequest.getObject',
|
||||
'-nsIIDBIndexRequest.openCursor',
|
||||
'-nsIIDBIndexRequest.openObjectCursor'
|
||||
]
|
||||
|
||||
# Most interfaces can be found by searching the includePath; to find
|
||||
|
Loading…
x
Reference in New Issue
Block a user