зеркало из https://github.com/mozilla/gecko-dev.git
Bug 692669 - 'IndexedDB: remove nsIVariant from IDB* interfaces'. r=sicking.
--HG-- extra : transplant_source : E%E9%F9%B5%FB%88%1E%FA%C1%BE%04%1F%1E%3D%5E%EB%3C%D2%D2c
This commit is contained in:
Родитель
18f25ebd3f
Коммит
09728f7547
|
@ -51,6 +51,13 @@
|
|||
#include "jspubtd.h"
|
||||
#include "nsDOMMemoryReporter.h"
|
||||
|
||||
// Including 'windows.h' will #define GetClassInfo to something else.
|
||||
#ifdef XP_WIN
|
||||
#ifdef GetClassInfo
|
||||
#undef GetClassInfo
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEvent;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
// Only meant to be included in IndexedDB source files, not exported.
|
||||
#include "IndexedDatabase.h"
|
||||
|
||||
#include "Key.h"
|
||||
#include "IDBObjectStore.h"
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include "IDBCursor.h"
|
||||
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
@ -275,8 +273,10 @@ IDBCursor::CreateCommon(IDBRequest* aRequest,
|
|||
IDBCursor::IDBCursor()
|
||||
: mType(OBJECTSTORE),
|
||||
mDirection(nsIIDBCursor::NEXT),
|
||||
mCachedKey(JSVAL_VOID),
|
||||
mCachedPrimaryKey(JSVAL_VOID),
|
||||
mCachedValue(JSVAL_VOID),
|
||||
mHaveCachedKey(false),
|
||||
mHaveCachedPrimaryKey(false),
|
||||
mHaveCachedValue(false),
|
||||
mRooted(false),
|
||||
|
@ -311,27 +311,35 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBCursor)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
NS_ASSERTION(tmp->mHaveCachedKey || JSVAL_IS_VOID(tmp->mCachedKey),
|
||||
"Should have a cached key");
|
||||
NS_ASSERTION(tmp->mHaveCachedPrimaryKey ||
|
||||
JSVAL_IS_VOID(tmp->mCachedPrimaryKey),
|
||||
"Should have a cached primary key");
|
||||
NS_ASSERTION(tmp->mHaveCachedValue || JSVAL_IS_VOID(tmp->mCachedValue),
|
||||
"Should have a cached value");
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedValue)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedValue);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedValue")
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedKey)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedKey);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedKey")
|
||||
}
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedPrimaryKey)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedPrimaryKey);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedPrimaryKey")
|
||||
}
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedValue)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedValue);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedValue")
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor)
|
||||
// Don't unlink mObjectStore, mIndex, or mTransaction!
|
||||
if (tmp->mRooted) {
|
||||
NS_DROP_JS_OBJECTS(tmp, IDBCursor);
|
||||
tmp->mCachedKey = JSVAL_VOID;
|
||||
tmp->mCachedPrimaryKey = JSVAL_VOID;
|
||||
tmp->mCachedValue = JSVAL_VOID;
|
||||
tmp->mHaveCachedKey = false;
|
||||
tmp->mHaveCachedPrimaryKey = false;
|
||||
tmp->mHaveCachedValue = false;
|
||||
tmp->mRooted = false;
|
||||
|
@ -378,43 +386,33 @@ IDBCursor::GetSource(nsISupports** aSource)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBCursor::GetKey(nsIVariant** aKey)
|
||||
IDBCursor::GetKey(JSContext* aCx,
|
||||
jsval* aKey)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (!mCachedKey) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIWritableVariant> variant =
|
||||
do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
NS_ASSERTION(!mKey.IsUnset() || !mHaveValue, "Bad key!");
|
||||
|
||||
NS_ASSERTION(!mKey.IsUnset() || !mHaveValue, "Bad key!");
|
||||
|
||||
if (!mHaveValue) {
|
||||
rv = variant->SetAsVoid();
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = variant->SetAsAString(mKey.StringValue());
|
||||
}
|
||||
else if (mKey.IsInt()) {
|
||||
rv = variant->SetAsInt64(mKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Huh?!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = variant->SetWritable(false);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsIWritableVariant* result;
|
||||
variant.forget(&result);
|
||||
|
||||
mCachedKey = dont_AddRef(static_cast<nsIVariant*>(result));
|
||||
if (!mHaveValue) {
|
||||
*aKey = JSVAL_VOID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIVariant> result(mCachedKey);
|
||||
result.forget(aKey);
|
||||
if (!mHaveCachedKey) {
|
||||
if (!mRooted) {
|
||||
NS_HOLD_JS_OBJECTS(this, IDBCursor);
|
||||
mRooted = true;
|
||||
}
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
nsresult rv = mKey.ToJSVal(aCx, &mCachedKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHaveCachedKey = true;
|
||||
}
|
||||
|
||||
*aKey = mCachedKey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -440,9 +438,9 @@ IDBCursor::GetPrimaryKey(JSContext* aCx,
|
|||
NS_ASSERTION(mType == OBJECTSTORE ? !mKey.IsUnset() :
|
||||
!mObjectKey.IsUnset(), "Bad key!");
|
||||
|
||||
nsresult rv =
|
||||
IDBObjectStore::GetJSValFromKey(mType == OBJECTSTORE ? mKey : mObjectKey,
|
||||
aCx, &mCachedPrimaryKey);
|
||||
const Key& key = mType == OBJECTSTORE ? mKey : mObjectKey;
|
||||
|
||||
nsresult rv = key.ToJSVal(aCx, &mCachedPrimaryKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHaveCachedPrimaryKey = true;
|
||||
|
@ -498,7 +496,7 @@ IDBCursor::Continue(const jsval &aKey,
|
|||
}
|
||||
|
||||
Key key;
|
||||
nsresult rv = IDBObjectStore::GetKeyFromJSVal(aKey, aCx, key);
|
||||
nsresult rv = key.SetFromJSVal(aCx, aKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!key.IsUnset()) {
|
||||
|
@ -588,7 +586,7 @@ IDBCursor::Update(const jsval& aValue,
|
|||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
const Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
|
||||
Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
|
||||
|
||||
if (!mObjectStore->KeyPath().IsEmpty()) {
|
||||
// This has to be an object.
|
||||
|
@ -606,7 +604,7 @@ IDBCursor::Update(const jsval& aValue,
|
|||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
Key key;
|
||||
rv = IDBObjectStore::GetKeyFromJSVal(prop, aCx, key);
|
||||
rv = key.SetFromJSVal(aCx, prop);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -619,7 +617,7 @@ IDBCursor::Update(const jsval& aValue,
|
|||
}
|
||||
|
||||
jsval keyVal;
|
||||
rv = IDBObjectStore::GetJSValFromKey(objectKey, aCx, &keyVal);
|
||||
rv = objectKey.ToJSVal(aCx, &keyVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mObjectStore->Put(aValue, keyVal, aCx, 1, _retval);
|
||||
|
@ -646,10 +644,10 @@ IDBCursor::Delete(JSContext* aCx,
|
|||
NS_ASSERTION(mObjectStore, "This cannot be null!");
|
||||
NS_ASSERTION(!mKey.IsUnset() , "Bad key!");
|
||||
|
||||
const Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
|
||||
Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
|
||||
|
||||
jsval key;
|
||||
nsresult rv = IDBObjectStore::GetJSValFromKey(objectKey, aCx, &key);
|
||||
nsresult rv = objectKey.ToJSVal(aCx, &key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mObjectStore->Delete(key, aCx, _retval);
|
||||
|
@ -688,7 +686,7 @@ ContinueHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -699,11 +697,12 @@ ContinueHelper::GetSuccessResult(JSContext* aCx,
|
|||
jsval* aVal)
|
||||
{
|
||||
// Remove cached stuff from last time.
|
||||
mCursor->mCachedKey = nsnull;
|
||||
mCursor->mCachedValue = JSVAL_VOID;
|
||||
mCursor->mCachedKey = JSVAL_VOID;
|
||||
mCursor->mCachedPrimaryKey = JSVAL_VOID;
|
||||
mCursor->mHaveCachedValue = false;
|
||||
mCursor->mCachedValue = JSVAL_VOID;
|
||||
mCursor->mHaveCachedKey = false;
|
||||
mCursor->mHaveCachedPrimaryKey = false;
|
||||
mCursor->mHaveCachedValue = false;
|
||||
mCursor->mContinueCalled = false;
|
||||
|
||||
if (mKey.IsUnset()) {
|
||||
|
@ -717,7 +716,7 @@ ContinueHelper::GetSuccessResult(JSContext* aCx,
|
|||
// Set new values.
|
||||
mCursor->mKey = mKey;
|
||||
mCursor->mObjectKey = mObjectKey;
|
||||
mCursor->mContinueToKey = Key::UNSETKEY;
|
||||
mCursor->mContinueToKey.Unset();
|
||||
|
||||
mCursor->mCloneBuffer.swap(mCloneBuffer);
|
||||
mCloneBuffer.clear();
|
||||
|
@ -746,31 +745,15 @@ ContinueObjectStoreHelper::BindArgumentsToStatement(
|
|||
mCursor->mKey :
|
||||
mCursor->mContinueToKey;
|
||||
|
||||
if (currentKey.IsString()) {
|
||||
rv = aStatement->BindStringByName(currentKeyName, currentKey.StringValue());
|
||||
}
|
||||
else if (currentKey.IsInt()) {
|
||||
rv = aStatement->BindInt64ByName(currentKeyName, currentKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = currentKey.BindToStatement(aStatement, currentKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Bind range key if it is specified.
|
||||
const Key& rangeKey = mCursor->mRangeKey;
|
||||
|
||||
if (!rangeKey.IsUnset()) {
|
||||
if (rangeKey.IsString()) {
|
||||
rv = aStatement->BindStringByName(rangeKeyName, rangeKey.StringValue());
|
||||
}
|
||||
else if (rangeKey.IsInt()) {
|
||||
rv = aStatement->BindInt64ByName(rangeKeyName, rangeKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = rangeKey.BindToStatement(aStatement, rangeKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -781,20 +764,8 @@ ContinueObjectStoreHelper::GatherResultsFromStatement(
|
|||
mozIStorageStatement* aStatement)
|
||||
{
|
||||
// Figure out what kind of key we have next.
|
||||
PRInt32 keyType;
|
||||
nsresult rv = aStatement->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = aStatement->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = aStatement->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
nsresult rv = mKey.SetFromStatement(aStatement, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetStructuredCloneDataFromStatement(aStatement, 1,
|
||||
mCloneBuffer);
|
||||
|
@ -818,32 +789,14 @@ ContinueIndexHelper::BindArgumentsToStatement(mozIStorageStatement* aStatement)
|
|||
mCursor->mKey :
|
||||
mCursor->mContinueToKey;
|
||||
|
||||
if (currentKey.IsString()) {
|
||||
rv = aStatement->BindStringByName(currentKeyName, currentKey.StringValue());
|
||||
}
|
||||
else if (currentKey.IsInt()) {
|
||||
rv = aStatement->BindInt64ByName(currentKeyName, currentKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = currentKey.BindToStatement(aStatement, currentKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Bind range key if it is specified.
|
||||
if (!mCursor->mRangeKey.IsUnset()) {
|
||||
NS_NAMED_LITERAL_CSTRING(rangeKeyName, "range_key");
|
||||
if (mCursor->mRangeKey.IsString()) {
|
||||
rv = aStatement->BindStringByName(rangeKeyName,
|
||||
mCursor->mRangeKey.StringValue());
|
||||
}
|
||||
else if (mCursor->mRangeKey.IsInt()) {
|
||||
rv = aStatement->BindInt64ByName(rangeKeyName,
|
||||
mCursor->mRangeKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mCursor->mRangeKey.BindToStatement(aStatement, rangeKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Bind object key if duplicates are allowed and we're not continuing to a
|
||||
|
@ -854,18 +807,8 @@ ContinueIndexHelper::BindArgumentsToStatement(mozIStorageStatement* aStatement)
|
|||
NS_ASSERTION(!mCursor->mObjectKey.IsUnset(), "Bad key!");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(objectKeyName, "object_key");
|
||||
if (mCursor->mObjectKey.IsString()) {
|
||||
rv = aStatement->BindStringByName(objectKeyName,
|
||||
mCursor->mObjectKey.StringValue());
|
||||
}
|
||||
else if (mCursor->mObjectKey.IsInt()) {
|
||||
rv = aStatement->BindInt64ByName(objectKeyName,
|
||||
mCursor->mObjectKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mCursor->mObjectKey.BindToStatement(aStatement, objectKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -875,42 +818,11 @@ nsresult
|
|||
ContinueIndexHelper::GatherResultsFromStatement(
|
||||
mozIStorageStatement* aStatement)
|
||||
{
|
||||
PRInt32 keyType;
|
||||
nsresult rv = aStatement->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
nsresult rv = mKey.SetFromStatement(aStatement, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = aStatement->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = aStatement->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
rv = aStatement->GetTypeOfIndex(1, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mObjectKey = aStatement->AsInt64(1);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = aStatement->GetString(1, mObjectKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mObjectKey.SetFromStatement(aStatement, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -919,42 +831,11 @@ nsresult
|
|||
ContinueIndexObjectHelper::GatherResultsFromStatement(
|
||||
mozIStorageStatement* aStatement)
|
||||
{
|
||||
PRInt32 keyType;
|
||||
nsresult rv = aStatement->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
nsresult rv = mKey.SetFromStatement(aStatement, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = aStatement->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = aStatement->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
rv = aStatement->GetTypeOfIndex(1, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mObjectKey = aStatement->AsInt64(1);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = aStatement->GetString(1, mObjectKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mObjectKey.SetFromStatement(aStatement, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetStructuredCloneDataFromStatement(aStatement, 2,
|
||||
mCloneBuffer);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||
#include "mozilla/dom/indexedDB/Key.h"
|
||||
|
||||
#include "nsIIDBCursorWithValue.h"
|
||||
|
||||
|
@ -150,15 +151,13 @@ protected:
|
|||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner;
|
||||
|
||||
// Not cycle-collected, this is guaranteed to be primitive!
|
||||
nsCOMPtr<nsIVariant> mCachedKey;
|
||||
|
||||
Type mType;
|
||||
PRUint16 mDirection;
|
||||
nsCString mContinueQuery;
|
||||
nsCString mContinueToQuery;
|
||||
|
||||
// These are cycle-collected!
|
||||
jsval mCachedKey;
|
||||
jsval mCachedPrimaryKey;
|
||||
jsval mCachedValue;
|
||||
|
||||
|
@ -169,6 +168,7 @@ protected:
|
|||
JSAutoStructuredCloneBuffer mCloneBuffer;
|
||||
Key mContinueToKey;
|
||||
|
||||
bool mHaveCachedKey;
|
||||
bool mHaveCachedPrimaryKey;
|
||||
bool mHaveCachedValue;
|
||||
bool mRooted;
|
||||
|
|
|
@ -127,16 +127,6 @@ private:
|
|||
PRInt64 mObjectStoreId;
|
||||
};
|
||||
|
||||
NS_STACK_CLASS
|
||||
class AutoFree
|
||||
{
|
||||
public:
|
||||
AutoFree(void* aPtr) : mPtr(aPtr) { }
|
||||
~AutoFree() { NS_Free(mPtr); }
|
||||
private:
|
||||
void* mPtr;
|
||||
};
|
||||
|
||||
NS_STACK_CLASS
|
||||
class AutoRemoveObjectStore
|
||||
{
|
||||
|
@ -162,75 +152,6 @@ private:
|
|||
nsString mName;
|
||||
};
|
||||
|
||||
inline
|
||||
nsresult
|
||||
ConvertVariantToStringArray(nsIVariant* aVariant,
|
||||
nsTArray<nsString>& aStringArray)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
PRUint16 type;
|
||||
NS_ASSERTION(NS_SUCCEEDED(aVariant->GetDataType(&type)) &&
|
||||
type == nsIDataType::VTYPE_ARRAY, "Bad arg!");
|
||||
#endif
|
||||
|
||||
PRUint16 valueType;
|
||||
nsIID iid;
|
||||
PRUint32 valueCount;
|
||||
void* rawArray;
|
||||
|
||||
nsresult rv = aVariant->GetAsArray(&valueType, &iid, &valueCount, &rawArray);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AutoFree af(rawArray);
|
||||
|
||||
// Just delete anything that we don't expect and return.
|
||||
if (valueType != nsIDataType::VTYPE_WCHAR_STR) {
|
||||
switch (valueType) {
|
||||
case nsIDataType::VTYPE_ID:
|
||||
case nsIDataType::VTYPE_CHAR_STR: {
|
||||
char** charArray = reinterpret_cast<char**>(rawArray);
|
||||
for (PRUint32 index = 0; index < valueCount; index++) {
|
||||
if (charArray[index]) {
|
||||
NS_Free(charArray[index]);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDataType::VTYPE_INTERFACE:
|
||||
case nsIDataType::VTYPE_INTERFACE_IS: {
|
||||
nsISupports** supportsArray = reinterpret_cast<nsISupports**>(rawArray);
|
||||
for (PRUint32 index = 0; index < valueCount; index++) {
|
||||
NS_IF_RELEASE(supportsArray[index]);
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
// The other types are primitives that do not need to be freed.
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
PRUnichar** strings = reinterpret_cast<PRUnichar**>(rawArray);
|
||||
|
||||
for (PRUint32 index = 0; index < valueCount; index++) {
|
||||
nsString* newString = aStringArray.AppendElement();
|
||||
|
||||
if (!newString) {
|
||||
NS_ERROR("Out of memory?");
|
||||
for (; index < valueCount; index++) {
|
||||
NS_Free(strings[index]);
|
||||
}
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
newString->Adopt(strings[index], -1);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
|
@ -694,9 +615,8 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
||||
IDBDatabase::Transaction(const jsval& aStoreNames,
|
||||
PRUint16 aMode,
|
||||
PRUint32 aTimeout,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBTransaction** _retval)
|
||||
|
@ -711,6 +631,15 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
|||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||
}
|
||||
|
||||
DatabaseInfo* info;
|
||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
||||
NS_ERROR("This should never fail!");
|
||||
}
|
||||
|
||||
if (info->runningVersionChange) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount) {
|
||||
if (aMode != nsIIDBTransaction::READ_WRITE &&
|
||||
aMode != nsIIDBTransaction::READ_ONLY) {
|
||||
|
@ -721,110 +650,102 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
|||
aMode = nsIIDBTransaction::READ_ONLY;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount <= 1) {
|
||||
aTimeout = kDefaultDatabaseTimeoutSeconds;
|
||||
}
|
||||
|
||||
PRUint16 type;
|
||||
nsresult rv = aStoreNames->GetDataType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
DatabaseInfo* info;
|
||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
||||
NS_ERROR("This should never fail!");
|
||||
}
|
||||
|
||||
if (info->runningVersionChange) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsTArray<nsString> storesToOpen;
|
||||
|
||||
switch (type) {
|
||||
case nsIDataType::VTYPE_VOID:
|
||||
case nsIDataType::VTYPE_EMPTY:
|
||||
case nsIDataType::VTYPE_EMPTY_ARRAY: {
|
||||
// Empty, request all object stores
|
||||
if (!info->GetObjectStoreNames(storesToOpen)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
if (!JSVAL_IS_PRIMITIVE(aStoreNames)) {
|
||||
JSObject* obj = JSVAL_TO_OBJECT(aStoreNames);
|
||||
|
||||
// See if this is a JS array.
|
||||
if (JS_IsArrayObject(aCx, obj)) {
|
||||
jsuint length;
|
||||
if (!JS_GetArrayLength(aCx, obj, &length)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
|
||||
// Single name
|
||||
nsString name;
|
||||
rv = aStoreNames->GetAsAString(name);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!info->ContainsStoreName(name)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
|
||||
if (!length) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
|
||||
if (!storesToOpen.AppendElement(name)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
} break;
|
||||
storesToOpen.SetCapacity(length);
|
||||
|
||||
case nsIDataType::VTYPE_ARRAY: {
|
||||
nsTArray<nsString> names;
|
||||
rv = ConvertVariantToStringArray(aStoreNames, names);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
PRUint32 nameCount = names.Length();
|
||||
for (PRUint32 nameIndex = 0; nameIndex < nameCount; nameIndex++) {
|
||||
nsString& name = names[nameIndex];
|
||||
|
||||
if (!info->ContainsStoreName(name)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
|
||||
}
|
||||
|
||||
if (!storesToOpen.AppendElement(name)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
for (jsuint index = 0; index < length; index++) {
|
||||
jsval val;
|
||||
JSString* jsstr;
|
||||
nsDependentJSString str;
|
||||
if (!JS_GetElement(aCx, obj, index, &val) ||
|
||||
!(jsstr = JS_ValueToString(aCx, val)) ||
|
||||
!str.init(aCx, jsstr)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(nameCount == storesToOpen.Length(), "Should have bailed!");
|
||||
} break;
|
||||
|
||||
case nsIDataType::VTYPE_INTERFACE:
|
||||
case nsIDataType::VTYPE_INTERFACE_IS: {
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsID *iid;
|
||||
rv = aStoreNames->GetAsInterface(&iid, getter_AddRefs(supports));
|
||||
storesToOpen.AppendElement(str);
|
||||
}
|
||||
|
||||
NS_ASSERTION(!storesToOpen.IsEmpty(),
|
||||
"Must have something here or else code below will "
|
||||
"misbehave!");
|
||||
}
|
||||
else {
|
||||
// Perhaps some kind of wrapped object?
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
NS_ASSERTION(xpc, "This should never be null!");
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
rv = xpc->GetWrappedNativeOfJSObject(aCx, obj, getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_Free(iid);
|
||||
if (wrapper) {
|
||||
nsISupports* wrappedObject = wrapper->Native();
|
||||
NS_ENSURE_TRUE(wrappedObject, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsCOMPtr<nsIDOMDOMStringList> stringList(do_QueryInterface(supports));
|
||||
if (!stringList) {
|
||||
// We don't support anything other than nsIDOMDOMStringList.
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
// We only accept DOMStringList.
|
||||
nsCOMPtr<nsIDOMDOMStringList> list = do_QueryInterface(wrappedObject);
|
||||
if (list) {
|
||||
PRUint32 length;
|
||||
rv = list->GetLength(&length);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
PRUint32 stringCount;
|
||||
rv = stringList->GetLength(&stringCount);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
if (!length) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
|
||||
for (PRUint32 stringIndex = 0; stringIndex < stringCount; stringIndex++) {
|
||||
nsString name;
|
||||
rv = stringList->Item(stringIndex, name);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
storesToOpen.SetCapacity(length);
|
||||
|
||||
if (!info->ContainsStoreName(name)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
|
||||
}
|
||||
for (PRUint32 index = 0; index < length; index++) {
|
||||
nsString* item = storesToOpen.AppendElement();
|
||||
NS_ASSERTION(item, "This should never fail!");
|
||||
|
||||
if (!storesToOpen.AppendElement(name)) {
|
||||
NS_WARNING("Out of memory?");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
rv = list->Item(index, *item);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
NS_ASSERTION(!storesToOpen.IsEmpty(),
|
||||
"Must have something here or else code below will "
|
||||
"misbehave!");
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
// If our list is empty here then the argument must have been an object that
|
||||
// we don't support or a primitive. Either way we convert to a string.
|
||||
if (storesToOpen.IsEmpty()) {
|
||||
JSString* jsstr;
|
||||
nsDependentJSString str;
|
||||
if (!(jsstr = JS_ValueToString(aCx, aStoreNames)) ||
|
||||
!str.init(aCx, jsstr)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
storesToOpen.AppendElement(str);
|
||||
}
|
||||
|
||||
// Now check to make sure the object store names we collected actually exist.
|
||||
for (PRUint32 index = 0; index < storesToOpen.Length(); index++) {
|
||||
if (!info->ContainsStoreName(storesToOpen[index])) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<IDBTransaction> transaction =
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "AsyncConnectionHelper.h"
|
||||
#include "IDBCursor.h"
|
||||
#include "IDBEvents.h"
|
||||
#include "IDBKeyRange.h"
|
||||
#include "IDBObjectStore.h"
|
||||
#include "IDBTransaction.h"
|
||||
#include "DatabaseInfo.h"
|
||||
|
@ -167,14 +168,10 @@ public:
|
|||
OpenKeyCursorHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBIndex* aIndex,
|
||||
const Key& aLowerKey,
|
||||
const Key& aUpperKey,
|
||||
bool aLowerOpen,
|
||||
bool aUpperOpen,
|
||||
IDBKeyRange* aKeyRange,
|
||||
PRUint16 aDirection)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex),
|
||||
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
|
||||
mUpperOpen(aUpperOpen), mDirection(aDirection)
|
||||
mKeyRange(aKeyRange), mDirection(aDirection)
|
||||
{ }
|
||||
|
||||
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||
|
@ -184,16 +181,14 @@ public:
|
|||
void ReleaseMainThreadObjects()
|
||||
{
|
||||
mIndex = nsnull;
|
||||
mKeyRange = nsnull;
|
||||
AsyncConnectionHelper::ReleaseMainThreadObjects();
|
||||
}
|
||||
|
||||
private:
|
||||
// In-params.
|
||||
nsRefPtr<IDBIndex> mIndex;
|
||||
const Key mLowerKey;
|
||||
const Key mUpperKey;
|
||||
const bool mLowerOpen;
|
||||
const bool mUpperOpen;
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const PRUint16 mDirection;
|
||||
|
||||
// Out-params.
|
||||
|
@ -210,14 +205,10 @@ public:
|
|||
OpenCursorHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBIndex* aIndex,
|
||||
const Key& aLowerKey,
|
||||
const Key& aUpperKey,
|
||||
bool aLowerOpen,
|
||||
bool aUpperOpen,
|
||||
IDBKeyRange* aKeyRange,
|
||||
PRUint16 aDirection)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex),
|
||||
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
|
||||
mUpperOpen(aUpperOpen), mDirection(aDirection)
|
||||
mKeyRange(aKeyRange), mDirection(aDirection)
|
||||
{ }
|
||||
|
||||
~OpenCursorHelper()
|
||||
|
@ -232,16 +223,14 @@ public:
|
|||
void ReleaseMainThreadObjects()
|
||||
{
|
||||
mIndex = nsnull;
|
||||
mKeyRange = nsnull;
|
||||
AsyncConnectionHelper::ReleaseMainThreadObjects();
|
||||
}
|
||||
|
||||
private:
|
||||
// In-params.
|
||||
nsRefPtr<IDBIndex> mIndex;
|
||||
const Key mLowerKey;
|
||||
const Key mUpperKey;
|
||||
const bool mLowerOpen;
|
||||
const bool mUpperOpen;
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const PRUint16 mDirection;
|
||||
|
||||
// Out-params.
|
||||
|
@ -271,7 +260,7 @@ already_AddRefed<IDBIndex>
|
|||
IDBIndex::Create(IDBObjectStore* aObjectStore,
|
||||
const IndexInfo* aIndexInfo)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aObjectStore, "Null pointer!");
|
||||
NS_ASSERTION(aIndexInfo, "Null pointer!");
|
||||
|
||||
|
@ -297,12 +286,12 @@ IDBIndex::IDBIndex()
|
|||
mUnique(false),
|
||||
mAutoIncrement(false)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
IDBIndex::~IDBIndex()
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBIndex)
|
||||
|
@ -333,7 +322,7 @@ DOMCI_DATA(IDBIndex, IDBIndex)
|
|||
NS_IMETHODIMP
|
||||
IDBIndex::GetName(nsAString& aName)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
aName.Assign(mName);
|
||||
return NS_OK;
|
||||
|
@ -342,7 +331,7 @@ IDBIndex::GetName(nsAString& aName)
|
|||
NS_IMETHODIMP
|
||||
IDBIndex::GetStoreName(nsAString& aStoreName)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return mObjectStore->GetName(aStoreName);
|
||||
}
|
||||
|
@ -350,7 +339,7 @@ IDBIndex::GetStoreName(nsAString& aStoreName)
|
|||
NS_IMETHODIMP
|
||||
IDBIndex::GetKeyPath(nsAString& aKeyPath)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
aKeyPath.Assign(mKeyPath);
|
||||
return NS_OK;
|
||||
|
@ -359,7 +348,7 @@ IDBIndex::GetKeyPath(nsAString& aKeyPath)
|
|||
NS_IMETHODIMP
|
||||
IDBIndex::GetUnique(bool* aUnique)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
*aUnique = mUnique;
|
||||
return NS_OK;
|
||||
|
@ -376,10 +365,11 @@ IDBIndex::GetObjectStore(nsIIDBObjectStore** aObjectStore)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::Get(nsIVariant* aKey,
|
||||
IDBIndex::Get(const jsval& aKey,
|
||||
JSContext* aCx,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
IDBTransaction* transaction = mObjectStore->Transaction();
|
||||
if (!transaction->IsOpen()) {
|
||||
|
@ -387,19 +377,16 @@ IDBIndex::Get(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
Key key;
|
||||
nsresult rv = IDBObjectStore::GetKeyFromVariant(aKey, key);
|
||||
nsresult rv = key.SetFromJSVal(aCx, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (key.IsUnset()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<GetHelper> helper = new GetHelper(transaction, request, this, key);
|
||||
nsRefPtr<GetHelper> helper =
|
||||
new GetHelper(transaction, request, this, key);
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
|
@ -408,10 +395,11 @@ IDBIndex::Get(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::GetKey(nsIVariant* aKey,
|
||||
IDBIndex::GetKey(const jsval& aKey,
|
||||
JSContext* aCx,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
IDBTransaction* transaction = mObjectStore->Transaction();
|
||||
if (!transaction->IsOpen()) {
|
||||
|
@ -419,15 +407,11 @@ IDBIndex::GetKey(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
Key key;
|
||||
nsresult rv = IDBObjectStore::GetKeyFromVariant(aKey, key);
|
||||
nsresult rv = key.SetFromJSVal(aCx, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (key.IsUnset()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
|
@ -442,8 +426,9 @@ IDBIndex::GetKey(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::GetAll(nsIVariant* aKey,
|
||||
IDBIndex::GetAll(const jsval& aKey,
|
||||
PRUint32 aLimit,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -454,18 +439,9 @@ IDBIndex::GetAll(nsIVariant* aKey,
|
|||
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
Key key;
|
||||
if (aOptionalArgCount &&
|
||||
NS_FAILED(IDBObjectStore::GetKeyFromVariant(aKey, key))) {
|
||||
PRUint16 type;
|
||||
rv = aKey->GetDataType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (type != nsIDataType::VTYPE_EMPTY) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
if (aOptionalArgCount && NS_FAILED(key.SetFromJSVal(aCx, aKey))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount < 2) {
|
||||
|
@ -478,7 +454,7 @@ IDBIndex::GetAll(nsIVariant* aKey,
|
|||
nsRefPtr<GetAllHelper> helper =
|
||||
new GetAllHelper(transaction, request, this, key, aLimit);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
nsresult rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
request.forget(_retval);
|
||||
|
@ -486,8 +462,9 @@ IDBIndex::GetAll(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::GetAllKeys(nsIVariant* aKey,
|
||||
IDBIndex::GetAllKeys(const jsval& aKey,
|
||||
PRUint32 aLimit,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -501,15 +478,8 @@ IDBIndex::GetAllKeys(nsIVariant* aKey,
|
|||
nsresult rv;
|
||||
|
||||
Key key;
|
||||
if (aOptionalArgCount &&
|
||||
NS_FAILED(IDBObjectStore::GetKeyFromVariant(aKey, key))) {
|
||||
PRUint16 type;
|
||||
rv = aKey->GetDataType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (type != nsIDataType::VTYPE_EMPTY) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
if (aOptionalArgCount && NS_FAILED(key.SetFromJSVal(aCx, aKey))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount < 2) {
|
||||
|
@ -530,8 +500,9 @@ IDBIndex::GetAllKeys(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
IDBIndex::OpenCursor(const jsval& aKey,
|
||||
PRUint16 aDirection,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -543,52 +514,30 @@ IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
Key lowerKey, upperKey;
|
||||
bool lowerOpen = false, upperOpen = false;
|
||||
|
||||
if (aKeyRange) {
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
rv = aKeyRange->GetLower(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aOptionalArgCount) {
|
||||
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetLowerOpen(&lowerOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = aKeyRange->GetUpperOpen(&upperOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<OpenCursorHelper> helper =
|
||||
new OpenCursorHelper(transaction, request, this, lowerKey, upperKey,
|
||||
lowerOpen, upperOpen, aDirection);
|
||||
new OpenCursorHelper(transaction, request, this, keyRange, aDirection);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -598,8 +547,9 @@ IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::OpenKeyCursor(nsIIDBKeyRange* aKeyRange,
|
||||
IDBIndex::OpenKeyCursor(const jsval& aKey,
|
||||
PRUint16 aDirection,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -611,52 +561,30 @@ IDBIndex::OpenKeyCursor(nsIIDBKeyRange* aKeyRange,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
Key lowerKey, upperKey;
|
||||
bool lowerOpen = false, upperOpen = false;
|
||||
|
||||
if (aKeyRange) {
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
rv = aKeyRange->GetLower(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aOptionalArgCount) {
|
||||
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetLowerOpen(&lowerOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = aKeyRange->GetUpperOpen(&upperOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<OpenKeyCursorHelper> helper =
|
||||
new OpenKeyCursorHelper(transaction, request, this, lowerKey, upperKey,
|
||||
lowerOpen, upperOpen, aDirection);
|
||||
new OpenKeyCursorHelper(transaction, request, this, keyRange, aDirection);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -665,6 +593,22 @@ IDBIndex::OpenKeyCursor(nsIIDBKeyRange* aKeyRange,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
NS_IMETHODIMP
|
||||
IDBIndex::Count(const jsval& aKey,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
IDBTransaction* transaction = mObjectStore->Transaction();
|
||||
if (!transaction->IsOpen()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
*/
|
||||
|
||||
nsresult
|
||||
GetKeyHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
{
|
||||
|
@ -683,42 +627,18 @@ GetKeyHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
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, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
|
||||
bool hasResult;
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (hasResult) {
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mKey.SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -729,7 +649,7 @@ GetKeyHelper::GetSuccessResult(JSContext* aCx,
|
|||
jsval* aVal)
|
||||
{
|
||||
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
|
||||
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
|
||||
return mKey.ToJSVal(aCx, aVal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -750,18 +670,10 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
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, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
|
||||
bool hasResult;
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
|
@ -850,48 +762,21 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mKey.IsUnset()) {
|
||||
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, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
if (mKeys.Capacity() == mKeys.Length()) {
|
||||
if (!mKeys.SetCapacity(mKeys.Capacity() * 2)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
mKeys.SetCapacity(mKeys.Capacity() * 2);
|
||||
}
|
||||
|
||||
Key* key = mKeys.AppendElement();
|
||||
NS_ASSERTION(key, "This shouldn't fail!");
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
*key = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, key->ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = key->SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
|
@ -929,7 +814,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
|||
NS_ASSERTION(!key.IsUnset(), "Bad key!");
|
||||
|
||||
jsval value;
|
||||
nsresult rv = IDBObjectStore::GetJSValFromKey(key, aCx, &value);
|
||||
nsresult rv = key.ToJSVal(aCx, &value);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get jsval for key!");
|
||||
return rv;
|
||||
|
@ -1014,16 +899,8 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mKey.IsUnset()) {
|
||||
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, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
|
@ -1096,13 +973,15 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
nsCAutoString keyRangeClause;
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, lowerKeyName, false, !mLowerOpen,
|
||||
keyRangeClause);
|
||||
}
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, upperKeyName, true, !mUpperOpen,
|
||||
keyRangeClause);
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, lowerKeyName, false,
|
||||
!mKeyRange->IsLowerOpen(), keyRangeClause);
|
||||
}
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, upperKeyName, true,
|
||||
!mKeyRange->IsUpperOpen(), keyRangeClause);
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + value;
|
||||
|
@ -1138,30 +1017,15 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
nsresult rv = stmt->BindInt64ByName(id, mIndex->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
if (mLowerKey.IsString()) {
|
||||
rv = stmt->BindStringByName(lowerKeyName, mLowerKey.StringValue());
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (mLowerKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(lowerKeyName, mLowerKey.IntValue());
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
if (mUpperKey.IsString()) {
|
||||
rv = stmt->BindStringByName(upperKeyName, mUpperKey.StringValue());
|
||||
}
|
||||
else if (mUpperKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(upperKeyName, mUpperKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
|
@ -1169,46 +1033,15 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!hasResult) {
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
rv = stmt->GetTypeOfIndex(1, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mObjectKey = stmt->AsInt64(1);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(1, mObjectKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mObjectKey.SetFromStatement(stmt, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now we need to make the query to get the next match.
|
||||
nsCAutoString queryStart = NS_LITERAL_CSTRING("SELECT value, ") + keyColumn +
|
||||
|
@ -1221,9 +1054,10 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mUpperOpen, queryStart);
|
||||
mRangeKey = mUpperKey;
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mKeyRange->IsUpperOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
|
@ -1236,9 +1070,10 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mUpperOpen, queryStart);
|
||||
mRangeKey = mUpperKey;
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mKeyRange->IsUpperOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value > :") +
|
||||
currentKey + directionClause +
|
||||
|
@ -1249,9 +1084,10 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mLowerOpen, queryStart);
|
||||
mRangeKey = mLowerKey;
|
||||
if (mKeyRange && !mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mKeyRange->IsLowerOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
|
@ -1264,9 +1100,10 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mLowerOpen, queryStart);
|
||||
mRangeKey = mLowerKey;
|
||||
if (mKeyRange && !mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mKeyRange->IsLowerOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value < :") +
|
||||
currentKey + directionClause +
|
||||
|
@ -1342,13 +1179,15 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
nsCString keyValue = objectTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
|
||||
|
||||
nsCAutoString keyRangeClause;
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, lowerKeyName, false, !mLowerOpen,
|
||||
keyRangeClause);
|
||||
}
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, upperKeyName, true, !mUpperOpen,
|
||||
keyRangeClause);
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, lowerKeyName, false,
|
||||
!mKeyRange->IsLowerOpen(), keyRangeClause);
|
||||
}
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, upperKeyName, true,
|
||||
!mKeyRange->IsUpperOpen(), keyRangeClause);
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + value;
|
||||
|
@ -1391,30 +1230,15 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
nsresult rv = stmt->BindInt64ByName(id, mIndex->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
if (mLowerKey.IsString()) {
|
||||
rv = stmt->BindStringByName(lowerKeyName, mLowerKey.StringValue());
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (mLowerKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(lowerKeyName, mLowerKey.IntValue());
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
if (mUpperKey.IsString()) {
|
||||
rv = stmt->BindStringByName(upperKeyName, mUpperKey.StringValue());
|
||||
}
|
||||
else if (mUpperKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(upperKeyName, mUpperKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
|
@ -1422,46 +1246,15 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!hasResult) {
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
|
||||
rv = stmt->GetTypeOfIndex(1, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(keyType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
keyType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Bad key type!");
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mObjectKey = stmt->AsInt64(1);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(1, mObjectKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mObjectKey.SetFromStatement(stmt, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetStructuredCloneDataFromStatement(stmt, 2,
|
||||
mCloneBuffer);
|
||||
|
@ -1485,9 +1278,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mUpperOpen, queryStart);
|
||||
mRangeKey = mUpperKey;
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mKeyRange->IsUpperOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
|
@ -1504,9 +1298,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mUpperOpen, queryStart);
|
||||
mRangeKey = mUpperKey;
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, true, !mKeyRange->IsUpperOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" > :") + currentKey +
|
||||
|
@ -1517,9 +1312,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mLowerOpen, queryStart);
|
||||
mRangeKey = mLowerKey;
|
||||
if (mKeyRange && !mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mKeyRange->IsLowerOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
|
@ -1536,9 +1332,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
break;
|
||||
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mLowerOpen, queryStart);
|
||||
mRangeKey = mLowerKey;
|
||||
if (mKeyRange && !mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(value, rangeKey, false, !mKeyRange->IsLowerOpen(),
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" < :") + currentKey +
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "nsIXPConnect.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -54,54 +54,7 @@ USING_INDEXEDDB_NAMESPACE
|
|||
namespace {
|
||||
|
||||
inline
|
||||
JSBool
|
||||
ConvertArguments(JSContext* aCx,
|
||||
uintN aArgc,
|
||||
jsval* aVp,
|
||||
const char* aMethodName,
|
||||
nsTArray<nsCOMPtr<nsIVariant> >& aKeys)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aCx, "Null pointer!");
|
||||
NS_ASSERTION(aVp, "Null pointer!");
|
||||
NS_ASSERTION(aMethodName, "Null pointer!");
|
||||
NS_ASSERTION(aKeys.Capacity(), "Need guaranteed capacity!");
|
||||
NS_ASSERTION(aKeys.IsEmpty(), "Not an empty array!");
|
||||
|
||||
if (aArgc < aKeys.Capacity()) {
|
||||
nsCString num;
|
||||
num.AppendInt(aKeys.Length());
|
||||
JS_ReportErrorNumberUC(aCx, js_GetErrorMessage, nsnull,
|
||||
JSMSG_MORE_ARGS_NEEDED, aMethodName, num.get(),
|
||||
aKeys.Capacity() == 1 ? "" : "s");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
for (uintN i = 0; i < aKeys.Capacity(); i++) {
|
||||
jsval& arg = JS_ARGV(aCx, aVp)[i];
|
||||
if (JSVAL_IS_VOID(arg) || JSVAL_IS_NULL(arg) ||
|
||||
!Key::CanBeConstructedFromJSVal(arg)) {
|
||||
JS_ReportError(aCx, "Argument is not a supported key type.");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
NS_ASSERTION(xpc, "This should never be null!");
|
||||
|
||||
nsCOMPtr<nsIVariant>* key = aKeys.AppendElement();
|
||||
NS_ASSERTION(key, "This should never fail!");
|
||||
|
||||
if (NS_FAILED(xpc->JSValToVariant(aCx, &arg, getter_AddRefs(*key)))) {
|
||||
JS_ReportError(aCx, "Could not convert argument to variant.");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
inline
|
||||
JSBool
|
||||
bool
|
||||
ReturnKeyRange(JSContext* aCx,
|
||||
jsval* aVp,
|
||||
IDBKeyRange* aKeyRange)
|
||||
|
@ -115,24 +68,73 @@ ReturnKeyRange(JSContext* aCx,
|
|||
NS_ASSERTION(xpc, "This should never be null!");
|
||||
|
||||
JSObject* global = JS_GetGlobalForScopeChain(aCx);
|
||||
NS_ENSURE_TRUE(global, JS_FALSE);
|
||||
if (!global) {
|
||||
NS_WARNING("Couldn't get global object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
if (NS_FAILED(xpc->WrapNative(aCx, global, aKeyRange,
|
||||
NS_GET_IID(nsIIDBKeyRange),
|
||||
getter_AddRefs(holder)))) {
|
||||
JS_ReportError(aCx, "Couldn't wrap IDBKeyRange object.");
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject* result;
|
||||
if (NS_FAILED(holder->GetJSObject(&result))) {
|
||||
JS_ReportError(aCx, "Couldn't get JSObject from wrapper.");
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(result));
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
nsresult
|
||||
GetKeyFromJSVal(JSContext* aCx,
|
||||
jsval aVal,
|
||||
Key& aKey,
|
||||
bool aAllowUnset = false)
|
||||
{
|
||||
nsresult rv = aKey.SetFromJSVal(aCx, aVal);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ASSERTION(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB,
|
||||
"Bad error code!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aKey.IsUnset() && !aAllowUnset) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
ThrowException(JSContext* aCx,
|
||||
nsresult aErrorCode)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(aErrorCode), "Not an error code!");
|
||||
if (!JS_IsExceptionPending(aCx)) {
|
||||
nsDOMClassInfo::ThrowJSException(aCx, aErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool
|
||||
GetKeyFromJSValOrThrow(JSContext* aCx,
|
||||
jsval aVal,
|
||||
Key& aKey)
|
||||
{
|
||||
nsresult rv = GetKeyFromJSVal(aCx, aVal, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(aCx, rv);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -142,21 +144,18 @@ MakeOnlyKeyRange(JSContext* aCx,
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIVariant>, 1> keys;
|
||||
if (!ConvertArguments(aCx, aArgc, aVp, "IDBKeyRange.only", keys)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
NS_ASSERTION(keys.Length() == 1, "Didn't set all keys!");
|
||||
|
||||
nsRefPtr<IDBKeyRange> range =
|
||||
IDBKeyRange::Create(keys[0], keys[0], false, false);
|
||||
NS_ASSERTION(range, "Out of memory?");
|
||||
|
||||
if (!ReturnKeyRange(aCx, aVp, range)) {
|
||||
return JS_FALSE;
|
||||
jsval val;
|
||||
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(false, false, true);
|
||||
|
||||
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Lower())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ReturnKeyRange(aCx, aVp, keyRange);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -166,27 +165,19 @@ MakeLowerBoundKeyRange(JSContext* aCx,
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIVariant>, 1> keys;
|
||||
if (!ConvertArguments(aCx, aArgc, aVp, "IDBKeyRange.lowerBound", keys)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
NS_ASSERTION(keys.Length() == 1, "Didn't set all keys!");
|
||||
|
||||
JSBool open = JS_FALSE;
|
||||
if (aArgc > 1 && !JS_ValueToBoolean(aCx, JS_ARGV(aCx, aVp)[1], &open)) {
|
||||
JS_ReportError(aCx, "Couldn't convert argument 2 to boolean.");
|
||||
return JS_FALSE;
|
||||
jsval val;
|
||||
JSBool open = false;
|
||||
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> range =
|
||||
IDBKeyRange::Create(keys[0], nsnull, !!open, true);
|
||||
NS_ASSERTION(range, "Out of memory?");
|
||||
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(open, true, false);
|
||||
|
||||
if (!ReturnKeyRange(aCx, aVp, range)) {
|
||||
return JS_FALSE;
|
||||
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Lower())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReturnKeyRange(aCx, aVp, keyRange);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -196,27 +187,19 @@ MakeUpperBoundKeyRange(JSContext* aCx,
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIVariant>, 1> keys;
|
||||
if (!ConvertArguments(aCx, aArgc, aVp, "IDBKeyRange.upperBound", keys)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
NS_ASSERTION(keys.Length() == 1, "Didn't set all keys!");
|
||||
|
||||
JSBool open = JS_FALSE;
|
||||
if (aArgc > 1 && !JS_ValueToBoolean(aCx, JS_ARGV(aCx, aVp)[1], &open)) {
|
||||
JS_ReportError(aCx, "Couldn't convert argument 2 to boolean.");
|
||||
return JS_FALSE;
|
||||
jsval val;
|
||||
JSBool open = false;
|
||||
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> range =
|
||||
IDBKeyRange::Create(nsnull, keys[0], true, !!open);
|
||||
NS_ASSERTION(range, "Out of memory?");
|
||||
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(true, open, false);
|
||||
|
||||
if (!ReturnKeyRange(aCx, aVp, range)) {
|
||||
return JS_FALSE;
|
||||
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Upper())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReturnKeyRange(aCx, aVp, keyRange);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -226,36 +209,29 @@ MakeBoundKeyRange(JSContext* aCx,
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIVariant>, 2> keys;
|
||||
if (!ConvertArguments(aCx, aArgc, aVp, "IDBKeyRange.bound", keys)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
NS_ASSERTION(keys.Length() == 2, "Didn't set all keys!");
|
||||
|
||||
JSBool lowerOpen = JS_FALSE;
|
||||
if (aArgc > 2 && !JS_ValueToBoolean(aCx, JS_ARGV(aCx, aVp)[2], &lowerOpen)) {
|
||||
JS_ReportError(aCx, "Couldn't convert argument 3 to boolean.");
|
||||
return JS_FALSE;
|
||||
jsval lowerVal, upperVal;
|
||||
JSBool lowerOpen = false, upperOpen = false;
|
||||
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "vv/bb", &lowerVal,
|
||||
&upperVal, &lowerOpen, &upperOpen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSBool upperOpen = JS_FALSE;
|
||||
if (aArgc > 3 && !JS_ValueToBoolean(aCx, JS_ARGV(aCx, aVp)[3], &upperOpen)) {
|
||||
JS_ReportError(aCx, "Couldn't convert argument 3 to boolean.");
|
||||
return JS_FALSE;
|
||||
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(lowerOpen, upperOpen, false);
|
||||
|
||||
if (!GetKeyFromJSValOrThrow(aCx, lowerVal, keyRange->Lower()) ||
|
||||
!GetKeyFromJSValOrThrow(aCx, upperVal, keyRange->Upper())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> range =
|
||||
IDBKeyRange::Create(keys[0], keys[1], lowerOpen, upperOpen);
|
||||
NS_ASSERTION(range, "Out of memory?");
|
||||
|
||||
if (!ReturnKeyRange(aCx, aVp, range)) {
|
||||
return JS_FALSE;
|
||||
if (keyRange->Lower() > keyRange->Upper() ||
|
||||
(keyRange->Lower() == keyRange->Upper() && (lowerOpen || upperOpen))) {
|
||||
ThrowException(aCx, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReturnKeyRange(aCx, aVp, keyRange);
|
||||
}
|
||||
|
||||
|
||||
#define KEYRANGE_FUNCTION_FLAGS (JSPROP_ENUMERATE | JSPROP_PERMANENT)
|
||||
|
||||
const JSFunctionSpec gKeyRangeConstructors[] = {
|
||||
|
@ -285,49 +261,129 @@ IDBKeyRange::DefineConstructors(JSContext* aCx,
|
|||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBKeyRange>
|
||||
IDBKeyRange::Create(nsIVariant* aLower,
|
||||
nsIVariant* aUpper,
|
||||
bool aLowerOpen,
|
||||
bool aUpperOpen)
|
||||
nsresult
|
||||
IDBKeyRange::FromJSVal(JSContext* aCx,
|
||||
const jsval& aVal,
|
||||
IDBKeyRange** aKeyRange)
|
||||
{
|
||||
nsRefPtr<IDBKeyRange> keyRange(new IDBKeyRange());
|
||||
keyRange->mLower = aLower;
|
||||
keyRange->mUpper = aUpper;
|
||||
keyRange->mLowerOpen = aLowerOpen;
|
||||
keyRange->mUpperOpen = aUpperOpen;
|
||||
nsresult rv;
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
|
||||
return keyRange.forget();
|
||||
if (JSVAL_IS_VOID(aVal) || JSVAL_IS_NULL(aVal)) {
|
||||
// undefined and null returns no IDBKeyRange.
|
||||
}
|
||||
else if (JSVAL_IS_PRIMITIVE(aVal)) {
|
||||
// A valid key returns an 'only' IDBKeyRange.
|
||||
keyRange = new IDBKeyRange(false, false, true);
|
||||
|
||||
rv = GetKeyFromJSVal(aCx, aVal, keyRange->Lower());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// An object is not permitted unless it's another IDBKeyRange.
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
NS_ASSERTION(xpc, "This should never be null!");
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
rv = xpc->GetWrappedNativeOfJSObject(aCx, JSVAL_TO_OBJECT(aVal),
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsCOMPtr<nsIIDBKeyRange> iface;
|
||||
if (!wrapper || !(iface = do_QueryInterface(wrapper->Native()))) {
|
||||
// Some random JS object?
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
keyRange = static_cast<IDBKeyRange*>(iface.get());
|
||||
}
|
||||
|
||||
keyRange.forget(aKeyRange);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(IDBKeyRange)
|
||||
NS_IMPL_RELEASE(IDBKeyRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(IDBKeyRange)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIIDBKeyRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBKeyRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBKeyRange)
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedLowerVal)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedLowerVal);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedLowerVal")
|
||||
}
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedUpperVal)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedUpperVal);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedUpperVal")
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBKeyRange)
|
||||
if (tmp->mRooted) {
|
||||
NS_DROP_JS_OBJECTS(tmp, IDBKeyRange);
|
||||
tmp->mCachedLowerVal = JSVAL_VOID;
|
||||
tmp->mCachedUpperVal = JSVAL_VOID;
|
||||
tmp->mHaveCachedLowerVal = false;
|
||||
tmp->mHaveCachedUpperVal = false;
|
||||
tmp->mRooted = false;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBKeyRange)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIDBKeyRange)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBKeyRange)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBKeyRange)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBKeyRange)
|
||||
|
||||
DOMCI_DATA(IDBKeyRange, IDBKeyRange)
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBKeyRange::GetLower(nsIVariant** aLower)
|
||||
IDBKeyRange::GetLower(JSContext* aCx,
|
||||
jsval* aLower)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIVariant> result(mLower);
|
||||
result.forget(aLower);
|
||||
if (!mHaveCachedLowerVal) {
|
||||
if (!mRooted) {
|
||||
NS_HOLD_JS_OBJECTS(this, IDBKeyRange);
|
||||
mRooted = true;
|
||||
}
|
||||
|
||||
nsresult rv = Lower().ToJSVal(aCx, &mCachedLowerVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHaveCachedLowerVal = true;
|
||||
}
|
||||
|
||||
*aLower = mCachedLowerVal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBKeyRange::GetUpper(nsIVariant** aUpper)
|
||||
IDBKeyRange::GetUpper(JSContext* aCx,
|
||||
jsval* aUpper)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIVariant> result(mUpper);
|
||||
result.forget(aUpper);
|
||||
if (!mHaveCachedUpperVal) {
|
||||
if (!mRooted) {
|
||||
NS_HOLD_JS_OBJECTS(this, IDBKeyRange);
|
||||
mRooted = true;
|
||||
}
|
||||
|
||||
nsresult rv = Upper().ToJSVal(aCx, &mCachedUpperVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHaveCachedUpperVal = true;
|
||||
}
|
||||
|
||||
*aUpper = mCachedUpperVal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -336,7 +392,7 @@ IDBKeyRange::GetLowerOpen(bool* aLowerOpen)
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
*aLowerOpen = mLowerOpen ? true : false;
|
||||
*aLowerOpen = mLowerOpen;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -346,6 +402,6 @@ IDBKeyRange::GetUpperOpen(bool* aUpperOpen)
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
*aUpperOpen = mUpperOpen ? true : false;
|
||||
*aUpperOpen = mUpperOpen;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -41,38 +41,78 @@
|
|||
#define mozilla_dom_indexeddb_idbkeyrange_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/Key.h"
|
||||
|
||||
#include "nsIIDBKeyRange.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class IDBKeyRange : public nsIIDBKeyRange
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIIDBKEYRANGE
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBKeyRange)
|
||||
|
||||
static JSBool DefineConstructors(JSContext* aCx,
|
||||
JSObject* aObject);
|
||||
|
||||
static
|
||||
already_AddRefed<IDBKeyRange> Create(nsIVariant* aLower,
|
||||
nsIVariant* aUpper,
|
||||
bool aLowerOpen,
|
||||
bool aUpperOpen);
|
||||
nsresult FromJSVal(JSContext* aCx,
|
||||
const jsval& aVal,
|
||||
IDBKeyRange** aKeyRange);
|
||||
|
||||
protected:
|
||||
IDBKeyRange()
|
||||
: mLowerOpen(false), mUpperOpen(false)
|
||||
IDBKeyRange(bool aLowerOpen, bool aUpperOpen, bool aIsOnly)
|
||||
: mCachedLowerVal(JSVAL_VOID), mCachedUpperVal(JSVAL_VOID),
|
||||
mLowerOpen(aLowerOpen), mUpperOpen(aUpperOpen), mIsOnly(aIsOnly),
|
||||
mHaveCachedLowerVal(false), mHaveCachedUpperVal(false), mRooted(false)
|
||||
{ }
|
||||
|
||||
const Key& Lower() const
|
||||
{
|
||||
return mLower;
|
||||
}
|
||||
|
||||
Key& Lower()
|
||||
{
|
||||
return mLower;
|
||||
}
|
||||
|
||||
const Key& Upper() const
|
||||
{
|
||||
return mIsOnly ? mLower : mUpper;
|
||||
}
|
||||
|
||||
Key& Upper()
|
||||
{
|
||||
return mIsOnly ? mLower : mUpper;
|
||||
}
|
||||
|
||||
bool IsLowerOpen() const
|
||||
{
|
||||
return mLowerOpen;
|
||||
}
|
||||
|
||||
bool IsUpperOpen() const
|
||||
{
|
||||
return mUpperOpen;
|
||||
}
|
||||
|
||||
protected:
|
||||
~IDBKeyRange() { }
|
||||
|
||||
nsCOMPtr<nsIVariant> mLower;
|
||||
nsCOMPtr<nsIVariant> mUpper;
|
||||
Key mLower;
|
||||
Key mUpper;
|
||||
jsval mCachedLowerVal;
|
||||
jsval mCachedUpperVal;
|
||||
bool mLowerOpen;
|
||||
bool mUpperOpen;
|
||||
bool mIsOnly;
|
||||
bool mHaveCachedLowerVal;
|
||||
bool mHaveCachedUpperVal;
|
||||
bool mRooted;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
|
|
@ -40,9 +40,7 @@
|
|||
#include "IDBObjectStore.h"
|
||||
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsclone.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -64,9 +62,6 @@ USING_INDEXEDDB_NAMESPACE
|
|||
|
||||
namespace {
|
||||
|
||||
// This is just to give us some random marker in the byte stream
|
||||
static const PRUint64 kTotallyRandomNumber = LL_INIT(0x286F258B, 0x177D47A9);
|
||||
|
||||
class AddHelper : public AsyncConnectionHelper
|
||||
{
|
||||
public:
|
||||
|
@ -146,7 +141,7 @@ public:
|
|||
protected:
|
||||
// In-params.
|
||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
||||
const Key mKey;
|
||||
Key mKey;
|
||||
|
||||
private:
|
||||
// Out-params.
|
||||
|
@ -196,14 +191,10 @@ public:
|
|||
OpenCursorHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBObjectStore* aObjectStore,
|
||||
const Key& aLowerKey,
|
||||
const Key& aUpperKey,
|
||||
bool aLowerOpen,
|
||||
bool aUpperOpen,
|
||||
IDBKeyRange* aKeyRange,
|
||||
PRUint16 aDirection)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
|
||||
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
|
||||
mUpperOpen(aUpperOpen), mDirection(aDirection)
|
||||
mKeyRange(aKeyRange), mDirection(aDirection)
|
||||
{ }
|
||||
|
||||
~OpenCursorHelper()
|
||||
|
@ -218,6 +209,7 @@ public:
|
|||
void ReleaseMainThreadObjects()
|
||||
{
|
||||
mObjectStore = nsnull;
|
||||
mKeyRange = nsnull;
|
||||
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffer);
|
||||
AsyncConnectionHelper::ReleaseMainThreadObjects();
|
||||
}
|
||||
|
@ -225,10 +217,7 @@ public:
|
|||
private:
|
||||
// In-params.
|
||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
||||
const Key mLowerKey;
|
||||
const Key mUpperKey;
|
||||
const bool mLowerOpen;
|
||||
const bool mUpperOpen;
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const PRUint16 mDirection;
|
||||
|
||||
// Out-params.
|
||||
|
@ -273,8 +262,7 @@ private:
|
|||
nsRefPtr<IDBIndex> mIndex;
|
||||
};
|
||||
|
||||
static const PRUintn BAD_TLS_INDEX = (PRUint32)-1;
|
||||
PRUintn CreateIndexHelper::sTLSIndex = BAD_TLS_INDEX;
|
||||
PRUintn CreateIndexHelper::sTLSIndex = PRUintn(BAD_TLS_INDEX);
|
||||
|
||||
class DeleteIndexHelper : public AsyncConnectionHelper
|
||||
{
|
||||
|
@ -316,14 +304,10 @@ public:
|
|||
GetAllHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBObjectStore* aObjectStore,
|
||||
const Key& aLowerKey,
|
||||
const Key& aUpperKey,
|
||||
const bool aLowerOpen,
|
||||
const bool aUpperOpen,
|
||||
IDBKeyRange* aKeyRange,
|
||||
const PRUint32 aLimit)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
|
||||
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
|
||||
mUpperOpen(aUpperOpen), mLimit(aLimit)
|
||||
mKeyRange(aKeyRange), mLimit(aLimit)
|
||||
{ }
|
||||
|
||||
~GetAllHelper()
|
||||
|
@ -340,6 +324,7 @@ public:
|
|||
void ReleaseMainThreadObjects()
|
||||
{
|
||||
mObjectStore = nsnull;
|
||||
mKeyRange = nsnull;
|
||||
for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) {
|
||||
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffers[index]);
|
||||
}
|
||||
|
@ -349,10 +334,7 @@ public:
|
|||
protected:
|
||||
// In-params.
|
||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
||||
const Key mLowerKey;
|
||||
const Key mUpperKey;
|
||||
const bool mLowerOpen;
|
||||
const bool mUpperOpen;
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const PRUint32 mLimit;
|
||||
|
||||
private:
|
||||
|
@ -414,7 +396,7 @@ GetKeyFromObject(JSContext* aCx,
|
|||
JSBool ok = JS_GetUCProperty(aCx, aObj, keyPathChars, keyPathLen, &key);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsresult rv = IDBObjectStore::GetKeyFromJSVal(key, aCx, aKey);
|
||||
nsresult rv = aKey.SetFromJSVal(aCx, key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -489,107 +471,6 @@ IDBObjectStore::Create(IDBTransaction* aTransaction,
|
|||
return objectStore.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBObjectStore::GetKeyFromVariant(nsIVariant* aKeyVariant,
|
||||
Key& aKey)
|
||||
{
|
||||
if (!aKeyVariant) {
|
||||
aKey = Key::UNSETKEY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint16 type;
|
||||
nsresult rv = aKeyVariant->GetDataType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
// See xpcvariant.cpp, these are the only types we should expect.
|
||||
switch (type) {
|
||||
case nsIDataType::VTYPE_VOID:
|
||||
aKey = Key::UNSETKEY;
|
||||
return NS_OK;
|
||||
|
||||
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
|
||||
rv = aKeyVariant->GetAsAString(aKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return NS_OK;
|
||||
|
||||
case nsIDataType::VTYPE_INT32:
|
||||
case nsIDataType::VTYPE_DOUBLE:
|
||||
rv = aKeyVariant->GetAsInt64(aKey.ToIntPtr());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return NS_OK;
|
||||
|
||||
default:
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Can't get here!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBObjectStore::GetKeyFromJSVal(jsval aKeyVal,
|
||||
JSContext* aCx,
|
||||
Key& aKey)
|
||||
{
|
||||
if (JSVAL_IS_VOID(aKeyVal)) {
|
||||
aKey = Key::UNSETKEY;
|
||||
}
|
||||
else if (JSVAL_IS_STRING(aKeyVal)) {
|
||||
nsDependentJSString depStr;
|
||||
if (!depStr.init(aCx, JSVAL_TO_STRING(aKeyVal))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aKey = depStr;
|
||||
}
|
||||
else if (JSVAL_IS_INT(aKeyVal)) {
|
||||
aKey = JSVAL_TO_INT(aKeyVal);
|
||||
}
|
||||
else if (JSVAL_IS_DOUBLE(aKeyVal)) {
|
||||
aKey = JSVAL_TO_DOUBLE(aKeyVal);
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBObjectStore::GetJSValFromKey(const Key& aKey,
|
||||
JSContext* aCx,
|
||||
jsval* aKeyVal)
|
||||
{
|
||||
if (aKey.IsUnset()) {
|
||||
*aKeyVal = JSVAL_VOID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aKey.IsInt()) {
|
||||
JSBool ok = JS_NewNumberValue(aCx, aKey.IntValue(), aKeyVal);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aKey.IsString()) {
|
||||
const nsString& keyString = aKey.StringValue();
|
||||
JSString* str =
|
||||
JS_NewUCStringCopyN(aCx,
|
||||
reinterpret_cast<const jschar*>(keyString.get()),
|
||||
keyString.Length());
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
*aKeyVal = STRING_TO_JSVAL(str);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
||||
|
@ -614,7 +495,7 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
|||
|
||||
if (JSVAL_IS_PRIMITIVE(clone)) {
|
||||
// This isn't an object, so just leave the key unset.
|
||||
aValue = Key::UNSETKEY;
|
||||
aValue.Unset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -628,11 +509,11 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
|||
JSBool ok = JS_GetUCProperty(aCx, obj, keyPathChars, keyPathLen, &keyVal);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsresult rv = GetKeyFromJSVal(keyVal, aCx, aValue);
|
||||
nsresult rv = aValue.SetFromJSVal(aCx, keyVal);
|
||||
if (NS_FAILED(rv)) {
|
||||
// If the object doesn't have a value that we can use for our index then we
|
||||
// leave it unset.
|
||||
aValue = Key::UNSETKEY;
|
||||
aValue.Unset();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -669,7 +550,7 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
|
|||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
Key value;
|
||||
nsresult rv = GetKeyFromJSVal(keyPathValue, aCx, value);
|
||||
nsresult rv = value.SetFromJSVal(aCx, keyPathValue);
|
||||
if (NS_FAILED(rv) || value.IsUnset()) {
|
||||
// Not a value we can do anything with, ignore it.
|
||||
continue;
|
||||
|
@ -728,17 +609,7 @@ IDBObjectStore::UpdateIndexes(IDBTransaction* aTransaction,
|
|||
|
||||
NS_ASSERTION(!aObjectStoreKey.IsUnset(), "This shouldn't happen!");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(keyValue, "key_value");
|
||||
|
||||
if (aObjectStoreKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(keyValue, aObjectStoreKey.IntValue());
|
||||
}
|
||||
else if (aObjectStoreKey.IsString()) {
|
||||
rv = stmt->BindStringByName(keyValue, aObjectStoreKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
rv = aObjectStoreKey.BindToStatement(stmt, NS_LITERAL_CSTRING("key_value"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool hasResult;
|
||||
|
@ -774,35 +645,15 @@ IDBObjectStore::UpdateIndexes(IDBTransaction* aTransaction,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!updateInfo.info.autoIncrement) {
|
||||
NS_NAMED_LITERAL_CSTRING(objectDataKey, "object_data_key");
|
||||
|
||||
if (aObjectStoreKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(objectDataKey, aObjectStoreKey.IntValue());
|
||||
}
|
||||
else if (aObjectStoreKey.IsString()) {
|
||||
rv = stmt->BindStringByName(objectDataKey,
|
||||
aObjectStoreKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
rv =
|
||||
aObjectStoreKey.BindToStatement(stmt,
|
||||
NS_LITERAL_CSTRING("object_data_key"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
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!");
|
||||
}
|
||||
rv =
|
||||
updateInfo.value.BindToStatementAllowUnset(stmt,
|
||||
NS_LITERAL_CSTRING("value"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
|
@ -901,7 +752,7 @@ SwapBytes(PRUint64 u)
|
|||
((u & 0x00ff000000000000LLU) >> 40) |
|
||||
((u & 0xff00000000000000LLU) >> 56);
|
||||
#else
|
||||
return u;
|
||||
return jsdouble(u);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -910,8 +761,7 @@ IDBObjectStore::ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer,
|
|||
Key& aKey,
|
||||
PRUint64 aOffsetToKeyProp)
|
||||
{
|
||||
NS_ASSERTION(IsAutoIncrement() && KeyPath().IsEmpty() && aKey.IsInt(),
|
||||
"Don't call me!");
|
||||
NS_ASSERTION(IsAutoIncrement() && aKey.IsInteger(), "Don't call me!");
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread");
|
||||
|
||||
// This is a duplicate of the js engine's byte munging here
|
||||
|
@ -920,7 +770,7 @@ IDBObjectStore::ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer,
|
|||
PRUint64 u;
|
||||
} pun;
|
||||
|
||||
pun.d = SwapBytes(aKey.IntValue());
|
||||
pun.d = SwapBytes(aKey.ToInteger());
|
||||
|
||||
memcpy((char*)aBuffer.data() + aOffsetToKeyProp, &pun.u, sizeof(PRUint64));
|
||||
return NS_OK;
|
||||
|
@ -959,7 +809,7 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
|
||||
if (mKeyPath.IsEmpty()) {
|
||||
// Out-of-line keys must be passed in.
|
||||
rv = GetKeyFromJSVal(aKeyVal, aCx, aKey);
|
||||
rv = aKey.SetFromJSVal(aCx, aKeyVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
|
@ -1173,7 +1023,8 @@ IDBObjectStore::GetIndexNames(nsIDOMDOMStringList** aIndexNames)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBObjectStore::Get(nsIVariant* aKey,
|
||||
IDBObjectStore::Get(const jsval& aKey,
|
||||
JSContext* aCx,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
@ -1183,32 +1034,10 @@ IDBObjectStore::Get(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
Key key;
|
||||
nsresult rv = GetKeyFromVariant(aKey, key);
|
||||
nsresult rv = key.SetFromJSVal(aCx, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Check to see if this is a key range.
|
||||
PRUint16 type;
|
||||
rv = aKey->GetDataType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (type != nsIDataType::VTYPE_INTERFACE &&
|
||||
type != nsIDataType::VTYPE_INTERFACE_IS) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
// XXX I hate this API. Move to jsvals, stat.
|
||||
nsID* iid;
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = aKey->GetAsInterface(&iid, getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_Free(iid);
|
||||
|
||||
nsCOMPtr<nsIIDBKeyRange> keyRange = do_QueryInterface(supports);
|
||||
if (!keyRange) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
return GetAll(keyRange, 0, 0, _retval);
|
||||
// Maybe this is a key range.
|
||||
return GetAll(aKey, 0, aCx, 1, _retval);
|
||||
}
|
||||
|
||||
if (key.IsUnset()) {
|
||||
|
@ -1228,8 +1057,9 @@ IDBObjectStore::Get(nsIVariant* aKey,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
|
||||
IDBObjectStore::GetAll(const jsval& aKey,
|
||||
PRUint32 aLimit,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -1239,45 +1069,23 @@ IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
|
|||
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
||||
}
|
||||
|
||||
if (aOptionalArgCount < 2) {
|
||||
aLimit = PR_UINT32_MAX;
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aOptionalArgCount) {
|
||||
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
Key lowerKey, upperKey;
|
||||
bool lowerOpen = false, upperOpen = false;
|
||||
|
||||
if (aKeyRange) {
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
rv = aKeyRange->GetLower(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetLowerOpen(&lowerOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = aKeyRange->GetUpperOpen(&upperOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
if (aOptionalArgCount < 2) {
|
||||
aLimit = PR_UINT32_MAX;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<GetAllHelper> helper =
|
||||
new GetAllHelper(mTransaction, request, this, lowerKey, upperKey, lowerOpen,
|
||||
upperOpen, aLimit);
|
||||
new GetAllHelper(mTransaction, request, this, keyRange, aLimit);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -1326,7 +1134,7 @@ IDBObjectStore::Delete(const jsval& aKey,
|
|||
}
|
||||
|
||||
Key key;
|
||||
nsresult rv = GetKeyFromJSVal(aKey, aCx, key);
|
||||
nsresult rv = key.SetFromJSVal(aCx, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1374,8 +1182,9 @@ IDBObjectStore::Clear(nsIIDBRequest** _retval)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
IDBObjectStore::OpenCursor(const jsval& aKey,
|
||||
PRUint16 aDirection,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
|
@ -1386,52 +1195,30 @@ IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
Key lowerKey, upperKey;
|
||||
bool lowerOpen = false, upperOpen = false;
|
||||
|
||||
if (aKeyRange) {
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
rv = aKeyRange->GetLower(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aOptionalArgCount) {
|
||||
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
rv = aKeyRange->GetLowerOpen(&lowerOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = aKeyRange->GetUpperOpen(&upperOpen);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (aOptionalArgCount >= 2) {
|
||||
if (aDirection != nsIIDBCursor::NEXT &&
|
||||
aDirection != nsIIDBCursor::NEXT_NO_DUPLICATE &&
|
||||
aDirection != nsIIDBCursor::PREV &&
|
||||
aDirection != nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<OpenCursorHelper> helper =
|
||||
new OpenCursorHelper(mTransaction, request, this, lowerKey, upperKey,
|
||||
lowerOpen, upperOpen, aDirection);
|
||||
new OpenCursorHelper(mTransaction, request, this, keyRange, aDirection);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -1673,6 +1460,21 @@ IDBObjectStore::DeleteIndex(const nsAString& aName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
NS_IMETHODIMP
|
||||
IDBObjectStore::Count(jsval aKey,
|
||||
JSContext* aCx,
|
||||
PRUint8 aOptionalArgCount,
|
||||
nsIIDBRequest** _retval)
|
||||
{
|
||||
if (!mTransaction->IsOpen()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
*/
|
||||
|
||||
nsresult
|
||||
AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
{
|
||||
|
@ -1708,18 +1510,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), osid);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(id, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(id, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("id"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool hasResult;
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
|
@ -1744,16 +1536,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
if (!autoIncrement || mayOverwrite) {
|
||||
NS_ASSERTION(!mKey.IsUnset(), "This shouldn't happen!");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(keyValue, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(keyValue, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, keyValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
const PRUint8* buffer = reinterpret_cast<const PRUint8*>(mCloneBuffer.data());
|
||||
|
@ -1780,16 +1564,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
NS_ASSERTION(!mKey.IsUnset(), "This shouldn't happen!");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(keyValue, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(keyValue, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, keyValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->BindBlobByName(NS_LITERAL_CSTRING("data"), buffer,
|
||||
bufferLength);
|
||||
|
@ -1806,16 +1582,20 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
// If we are supposed to generate a key, get the new id.
|
||||
if (autoIncrement && !mOverwrite) {
|
||||
#ifdef DEBUG
|
||||
PRInt64 oldKey = unsetKey ? 0 : mKey.IntValue();
|
||||
PRInt64 oldKey = unsetKey ? 0 : mKey.ToInteger();
|
||||
#endif
|
||||
|
||||
rv = aConnection->GetLastInsertRowID(mKey.ToIntPtr());
|
||||
PRInt64 newIntKey;
|
||||
rv = aConnection->GetLastInsertRowID(&newIntKey);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = mKey.SetFromInteger(newIntKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(mKey.IsInt(), "Bad key value!");
|
||||
NS_ASSERTION(mKey.IsInteger(), "Bad key value!");
|
||||
if (!unsetKey) {
|
||||
NS_ASSERTION(mKey.IntValue() == oldKey, "Something went haywire!");
|
||||
NS_ASSERTION(mKey.ToInteger() == oldKey, "Something went haywire!");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1839,8 +1619,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), osid);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = stmt->BindInt64ByName(keyValue, mKey.IntValue());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, keyValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
buffer = reinterpret_cast<const PRUint8*>(mCloneBuffer.data());
|
||||
bufferLength = mCloneBuffer.nbytes();
|
||||
|
@ -1856,7 +1636,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
// Update our indexes if needed.
|
||||
if (!mIndexUpdateInfo.IsEmpty()) {
|
||||
PRInt64 objectDataId = autoIncrement ? mKey.IntValue() : LL_MININT;
|
||||
PRInt64 objectDataId = autoIncrement ? mKey.ToInteger() : LL_MININT;
|
||||
rv = IDBObjectStore::UpdateIndexes(mTransaction, osid, mKey,
|
||||
autoIncrement, mOverwrite,
|
||||
objectDataId, mIndexUpdateInfo);
|
||||
|
@ -1877,7 +1657,7 @@ AddHelper::GetSuccessResult(JSContext* aCx,
|
|||
|
||||
mCloneBuffer.clear();
|
||||
|
||||
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
|
||||
return mKey.ToJSVal(aCx, aVal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1897,18 +1677,8 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
NS_ASSERTION(!mKey.IsUnset(), "Must have a key here!");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(id, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(id, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("id"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Search for it!
|
||||
bool hasResult;
|
||||
|
@ -1953,18 +1723,8 @@ DeleteHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
|
||||
NS_ASSERTION(!mKey.IsUnset(), "Must have a key here!");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(key_value, "key_value");
|
||||
|
||||
if (mKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(key_value, mKey.IntValue());
|
||||
}
|
||||
else if (mKey.IsString()) {
|
||||
rv = stmt->BindStringByName(key_value, mKey.StringValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("key_value"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -1977,7 +1737,7 @@ DeleteHelper::GetSuccessResult(JSContext* aCx,
|
|||
jsval* aVal)
|
||||
{
|
||||
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
|
||||
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
|
||||
return mKey.ToJSVal(aCx, aVal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -2031,13 +1791,15 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_NAMED_LITERAL_CSTRING(upperKeyName, "upper_key");
|
||||
|
||||
nsCAutoString keyRangeClause;
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(keyColumn, lowerKeyName, false, !mLowerOpen,
|
||||
keyRangeClause);
|
||||
}
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(keyColumn, upperKeyName, true, !mUpperOpen,
|
||||
keyRangeClause);
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(keyColumn, lowerKeyName, false,
|
||||
!mKeyRange->IsLowerOpen(), keyRangeClause);
|
||||
}
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(keyColumn, upperKeyName, true,
|
||||
!mKeyRange->IsUpperOpen(), keyRangeClause);
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + keyColumn;
|
||||
|
@ -2070,30 +1832,15 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
nsresult rv = stmt->BindInt64ByName(id, mObjectStore->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
if (mLowerKey.IsString()) {
|
||||
rv = stmt->BindStringByName(lowerKeyName, mLowerKey.StringValue());
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (mLowerKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(lowerKeyName, mLowerKey.IntValue());
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
if (mUpperKey.IsString()) {
|
||||
rv = stmt->BindStringByName(upperKeyName, mUpperKey.StringValue());
|
||||
}
|
||||
else if (mUpperKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(upperKeyName, mUpperKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
|
@ -2101,24 +1848,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!hasResult) {
|
||||
mKey = Key::UNSETKEY;
|
||||
mKey.Unset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(0, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
mKey = stmt->AsInt64(0);
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
rv = stmt->GetString(0, mKey.ToString());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
rv = mKey.SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStore::GetStructuredCloneDataFromStatement(stmt, 1,
|
||||
mCloneBuffer);
|
||||
|
@ -2138,12 +1873,13 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
keyRangeClause);
|
||||
AppendConditionClause(keyColumn, currentKey, false, true,
|
||||
continueToKeyRangeClause);
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
AppendConditionClause(keyColumn, rangeKey, true, !mUpperOpen,
|
||||
keyRangeClause);
|
||||
AppendConditionClause(keyColumn, rangeKey, true, !mUpperOpen,
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
AppendConditionClause(keyColumn, rangeKey, true,
|
||||
!mKeyRange->IsUpperOpen(), keyRangeClause);
|
||||
AppendConditionClause(keyColumn, rangeKey, true,
|
||||
!mKeyRange->IsUpperOpen(),
|
||||
continueToKeyRangeClause);
|
||||
mRangeKey = mUpperKey;
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2152,12 +1888,13 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
AppendConditionClause(keyColumn, currentKey, true, false, keyRangeClause);
|
||||
AppendConditionClause(keyColumn, currentKey, true, true,
|
||||
continueToKeyRangeClause);
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
AppendConditionClause(keyColumn, rangeKey, false, !mLowerOpen,
|
||||
keyRangeClause);
|
||||
AppendConditionClause(keyColumn, rangeKey, false, !mLowerOpen,
|
||||
if (mKeyRange && !mKeyRange->Lower().IsUnset()) {
|
||||
AppendConditionClause(keyColumn, rangeKey, false,
|
||||
!mKeyRange->IsLowerOpen(), keyRangeClause);
|
||||
AppendConditionClause(keyColumn, rangeKey, false,
|
||||
!mKeyRange->IsLowerOpen(),
|
||||
continueToKeyRangeClause);
|
||||
mRangeKey = mLowerKey;
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2392,24 +2129,13 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
|
|||
if (!mIndex->IsAutoIncrement()) {
|
||||
NS_NAMED_LITERAL_CSTRING(objectDataKey, "object_data_key");
|
||||
|
||||
PRInt32 keyType;
|
||||
rv = stmt->GetTypeOfIndex(2, &keyType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
Key key;
|
||||
rv = key.SetFromStatement(stmt, 2);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (keyType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
rv = insertStmt->BindInt64ByName(objectDataKey, stmt->AsInt64(2));
|
||||
}
|
||||
else if (keyType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
nsString stringKey;
|
||||
rv = stmt->GetString(2, stringKey);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
rv = insertStmt->BindStringByName(objectDataKey, stringKey);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad SQLite type!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv =
|
||||
key.BindToStatement(insertStmt, NS_LITERAL_CSTRING("object_data_key"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
const PRUint8* data;
|
||||
|
@ -2432,24 +2158,16 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
|
|||
Key key;
|
||||
rv = IDBObjectStore::GetKeyPathValueFromStructuredData(data, dataLength,
|
||||
mIndex->KeyPath(),
|
||||
tlsEntry->Context(), key);
|
||||
tlsEntry->Context(),
|
||||
key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (key.IsUnset()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
if (key.IsInt()) {
|
||||
rv = insertStmt->BindInt64ByName(value, key.IntValue());
|
||||
}
|
||||
else if (key.IsString()) {
|
||||
rv = insertStmt->BindStringByName(value, key.StringValue());
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
rv = key.BindToStatement(insertStmt, NS_LITERAL_CSTRING("value"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = insertStmt->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -2502,26 +2220,28 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
NS_NAMED_LITERAL_CSTRING(upperKeyName, "upper_key");
|
||||
|
||||
nsCAutoString keyRangeClause;
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
keyRangeClause = NS_LITERAL_CSTRING(" AND ") + keyColumn;
|
||||
if (mLowerOpen) {
|
||||
keyRangeClause.AppendLiteral(" > :");
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
keyRangeClause = NS_LITERAL_CSTRING(" AND ") + keyColumn;
|
||||
if (mKeyRange->IsLowerOpen()) {
|
||||
keyRangeClause.AppendLiteral(" > :");
|
||||
}
|
||||
else {
|
||||
keyRangeClause.AppendLiteral(" >= :");
|
||||
}
|
||||
keyRangeClause.Append(lowerKeyName);
|
||||
}
|
||||
else {
|
||||
keyRangeClause.AppendLiteral(" >= :");
|
||||
}
|
||||
keyRangeClause.Append(lowerKeyName);
|
||||
}
|
||||
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
keyRangeClause += NS_LITERAL_CSTRING(" AND ") + keyColumn;
|
||||
if (mUpperOpen) {
|
||||
keyRangeClause.AppendLiteral(" < :");
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
keyRangeClause += NS_LITERAL_CSTRING(" AND ") + keyColumn;
|
||||
if (mKeyRange->IsUpperOpen()) {
|
||||
keyRangeClause.AppendLiteral(" < :");
|
||||
}
|
||||
else {
|
||||
keyRangeClause.AppendLiteral(" <= :");
|
||||
}
|
||||
keyRangeClause.Append(upperKeyName);
|
||||
}
|
||||
else {
|
||||
keyRangeClause.AppendLiteral(" <= :");
|
||||
}
|
||||
keyRangeClause.Append(upperKeyName);
|
||||
}
|
||||
|
||||
nsCAutoString limitClause;
|
||||
|
@ -2535,10 +2255,7 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
keyRangeClause + NS_LITERAL_CSTRING(" ORDER BY ") +
|
||||
keyColumn + NS_LITERAL_CSTRING(" ASC") + limitClause;
|
||||
|
||||
if (!mCloneBuffers.SetCapacity(50)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
mCloneBuffers.SetCapacity(50);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -2548,30 +2265,15 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!mLowerKey.IsUnset()) {
|
||||
if (mLowerKey.IsString()) {
|
||||
rv = stmt->BindStringByName(lowerKeyName, mLowerKey.StringValue());
|
||||
if (mKeyRange) {
|
||||
if (!mKeyRange->Lower().IsUnset()) {
|
||||
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (mLowerKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(lowerKeyName, mLowerKey.IntValue());
|
||||
if (!mKeyRange->Upper().IsUnset()) {
|
||||
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (!mUpperKey.IsUnset()) {
|
||||
if (mUpperKey.IsString()) {
|
||||
rv = stmt->BindStringByName(upperKeyName, mUpperKey.StringValue());
|
||||
}
|
||||
else if (mUpperKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(upperKeyName, mUpperKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
#include "mozilla/dom/indexedDB/Key.h"
|
||||
|
||||
#include "nsIIDBObjectStore.h"
|
||||
#include "nsIIDBTransaction.h"
|
||||
|
@ -55,6 +54,7 @@ class nsPIDOMWindow;
|
|||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class AsyncConnectionHelper;
|
||||
class Key;
|
||||
|
||||
struct ObjectStoreInfo;
|
||||
struct IndexInfo;
|
||||
|
@ -72,20 +72,6 @@ public:
|
|||
Create(IDBTransaction* aTransaction,
|
||||
const ObjectStoreInfo* aInfo);
|
||||
|
||||
static nsresult
|
||||
GetKeyFromVariant(nsIVariant* aKeyVariant,
|
||||
Key& aKey);
|
||||
|
||||
static nsresult
|
||||
GetKeyFromJSVal(jsval aKeyVal,
|
||||
JSContext* aCx,
|
||||
Key& aKey);
|
||||
|
||||
static nsresult
|
||||
GetJSValFromKey(const Key& aKey,
|
||||
JSContext* aCx,
|
||||
jsval* aKeyVal);
|
||||
|
||||
static nsresult
|
||||
GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
||||
PRUint32 aDataLength,
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "IDBRequest.h"
|
||||
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
|
|
@ -42,70 +42,45 @@
|
|||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
|
||||
#include "mozIStorageStatement.h"
|
||||
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCQuickStubs.h"
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class Key
|
||||
{
|
||||
public:
|
||||
enum Type { UNSETKEY, STRINGKEY, INTKEY };
|
||||
|
||||
Key()
|
||||
: mType(UNSETKEY), mInt(0)
|
||||
{ }
|
||||
|
||||
Key(const Key& aOther)
|
||||
{
|
||||
*this = aOther;
|
||||
}
|
||||
|
||||
Key& operator=(const Key& aOther)
|
||||
{
|
||||
if (this != &aOther) {
|
||||
mType = aOther.mType;
|
||||
mString = aOther.mString;
|
||||
mInt = aOther.mInt;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Key& operator=(Type aType)
|
||||
{
|
||||
NS_ASSERTION(aType == UNSETKEY ,
|
||||
"Use one of the other operators to assign your value!");
|
||||
mType = aType;
|
||||
mString.Truncate();
|
||||
mInt = 0;
|
||||
return *this;
|
||||
Unset();
|
||||
}
|
||||
|
||||
Key& operator=(const nsAString& aString)
|
||||
{
|
||||
mType = STRINGKEY;
|
||||
mString = aString;
|
||||
mInt = 0;
|
||||
SetFromString(aString);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Key& operator=(PRInt64 aInt)
|
||||
{
|
||||
mType = INTKEY;
|
||||
mString.Truncate();
|
||||
mInt = aInt;
|
||||
SetFromInteger(aInt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Key& aOther) const
|
||||
{
|
||||
NS_ASSERTION(mType != KEYTYPE_VOID && aOther.mType != KEYTYPE_VOID,
|
||||
"Don't compare unset keys!");
|
||||
|
||||
if (mType == aOther.mType) {
|
||||
switch (mType) {
|
||||
case UNSETKEY:
|
||||
return true;
|
||||
case KEYTYPE_STRING:
|
||||
return ToString() == aOther.ToString();
|
||||
|
||||
case STRINGKEY:
|
||||
return mString == aOther.mString;
|
||||
|
||||
case INTKEY:
|
||||
return mInt == aOther.mInt;
|
||||
case KEYTYPE_INTEGER:
|
||||
return ToInteger() == aOther.ToInteger();
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Unknown type!");
|
||||
|
@ -121,30 +96,24 @@ public:
|
|||
|
||||
bool operator<(const Key& aOther) const
|
||||
{
|
||||
NS_ASSERTION(mType != KEYTYPE_VOID && aOther.mType != KEYTYPE_VOID,
|
||||
"Don't compare unset keys!");
|
||||
|
||||
switch (mType) {
|
||||
case UNSETKEY:
|
||||
if (aOther.mType == UNSETKEY) {
|
||||
case KEYTYPE_STRING: {
|
||||
if (aOther.mType == KEYTYPE_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
NS_ASSERTION(aOther.mType == KEYTYPE_STRING, "Unknown type!");
|
||||
return ToString() < aOther.ToString();
|
||||
}
|
||||
|
||||
case STRINGKEY:
|
||||
if (aOther.mType == UNSETKEY ||
|
||||
aOther.mType == INTKEY) {
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(aOther.mType == STRINGKEY, "Unknown type!");
|
||||
return mString < aOther.mString;
|
||||
|
||||
case INTKEY:
|
||||
if (aOther.mType == UNSETKEY) {
|
||||
return false;
|
||||
}
|
||||
if (aOther.mType == STRINGKEY) {
|
||||
case KEYTYPE_INTEGER:
|
||||
if (aOther.mType == KEYTYPE_STRING) {
|
||||
return true;
|
||||
}
|
||||
NS_ASSERTION(aOther.mType == INTKEY, "Unknown type!");
|
||||
return mInt < aOther.mInt;
|
||||
NS_ASSERTION(aOther.mType == KEYTYPE_INTEGER, "Unknown type!");
|
||||
return ToInteger() < aOther.ToInteger();
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Unknown type!");
|
||||
|
@ -167,42 +136,187 @@ public:
|
|||
return (*this == aOther || !(*this < aOther));
|
||||
}
|
||||
|
||||
bool IsUnset() const { return mType == UNSETKEY; }
|
||||
bool IsString() const { return mType == STRINGKEY; }
|
||||
bool IsInt() const { return mType == INTKEY; }
|
||||
|
||||
const nsString& StringValue() const {
|
||||
NS_ASSERTION(IsString(), "Wrong type!");
|
||||
return mString;
|
||||
void
|
||||
Unset()
|
||||
{
|
||||
mType = KEYTYPE_VOID;
|
||||
mStringKey.SetIsVoid(true);
|
||||
mIntKey = 0;
|
||||
}
|
||||
|
||||
PRInt64 IntValue() const {
|
||||
NS_ASSERTION(IsInt(), "Wrong type!");
|
||||
return mInt;
|
||||
bool IsUnset() const { return mType == KEYTYPE_VOID; }
|
||||
bool IsString() const { return mType == KEYTYPE_STRING; }
|
||||
bool IsInteger() const { return mType == KEYTYPE_INTEGER; }
|
||||
|
||||
nsresult SetFromString(const nsAString& aString)
|
||||
{
|
||||
mType = KEYTYPE_STRING;
|
||||
mStringKey = aString;
|
||||
mIntKey = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAString& ToString() {
|
||||
mType = STRINGKEY;
|
||||
mInt = 0;
|
||||
return mString;
|
||||
nsresult SetFromInteger(PRInt64 aInt)
|
||||
{
|
||||
mType = KEYTYPE_INTEGER;
|
||||
mStringKey.SetIsVoid(true);
|
||||
mIntKey = aInt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt64* ToIntPtr() {
|
||||
mType = INTKEY;
|
||||
mString.Truncate();
|
||||
return &mInt;
|
||||
nsresult SetFromJSVal(JSContext* aCx,
|
||||
jsval aVal)
|
||||
{
|
||||
if (JSVAL_IS_STRING(aVal)) {
|
||||
jsval tempRoot = JSVAL_VOID;
|
||||
SetFromString(xpc_qsAString(aCx, aVal, &tempRoot));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_INT(aVal)) {
|
||||
SetFromInteger(JSVAL_TO_INT(aVal));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_DOUBLE(aVal)) {
|
||||
jsdouble doubleActual = JSVAL_TO_DOUBLE(aVal);
|
||||
int64 doubleAsInt = static_cast<int64>(doubleActual);
|
||||
if (doubleActual == doubleAsInt) {
|
||||
SetFromInteger(doubleAsInt);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (JSVAL_IS_NULL(aVal) || JSVAL_IS_VOID(aVal)) {
|
||||
Unset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
||||
nsresult ToJSVal(JSContext* aCx,
|
||||
jsval* aVal) const
|
||||
{
|
||||
if (IsString()) {
|
||||
if (!xpc_qsStringToJsval(aCx, nsString(ToString()), aVal)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
else if (IsInteger()) {
|
||||
if (!JS_NewNumberValue(aCx, static_cast<jsdouble>(ToInteger()), aVal)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
else if (IsUnset()) {
|
||||
*aVal = JSVAL_VOID;
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Unknown key type!");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt64 ToInteger() const
|
||||
{
|
||||
NS_ASSERTION(IsInteger(), "Don't call me!");
|
||||
return mIntKey;
|
||||
}
|
||||
|
||||
const nsAString& ToString() const
|
||||
{
|
||||
NS_ASSERTION(IsString(), "Don't call me!");
|
||||
return mStringKey;
|
||||
}
|
||||
|
||||
nsresult BindToStatement(mozIStorageStatement* aStatement,
|
||||
const nsACString& aParamName) const
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (IsString()) {
|
||||
rv = aStatement->BindStringByName(aParamName, ToString());
|
||||
}
|
||||
else if (IsInteger()) {
|
||||
rv = aStatement->BindInt64ByName(aParamName, ToInteger());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult BindToStatementAllowUnset(mozIStorageStatement* aStatement,
|
||||
const nsACString& aParamName) const
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (IsUnset()) {
|
||||
rv = aStatement->BindStringByName(aParamName, EmptyString());
|
||||
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
return BindToStatement(aStatement, aParamName);
|
||||
}
|
||||
|
||||
nsresult SetFromStatement(mozIStorageStatement* aStatement,
|
||||
PRUint32 aIndex)
|
||||
{
|
||||
PRInt32 columnType;
|
||||
nsresult rv = aStatement->GetTypeOfIndex(aIndex, &columnType);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
NS_ASSERTION(columnType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
|
||||
columnType == mozIStorageStatement::VALUE_TYPE_TEXT,
|
||||
"Unsupported column type!");
|
||||
|
||||
return SetFromStatement(aStatement, aIndex, columnType);
|
||||
}
|
||||
|
||||
nsresult SetFromStatement(mozIStorageStatement* aStatement,
|
||||
PRUint32 aIndex,
|
||||
PRInt32 aColumnType)
|
||||
{
|
||||
if (aColumnType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
|
||||
return SetFromInteger(aStatement->AsInt64(aIndex));
|
||||
}
|
||||
|
||||
if (aColumnType == mozIStorageStatement::VALUE_TYPE_TEXT) {
|
||||
nsString keyString;
|
||||
nsresult rv = aStatement->GetString(aIndex, keyString);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
return SetFromString(keyString);
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unsupported column type!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
static
|
||||
JSBool CanBeConstructedFromJSVal(jsval aVal) {
|
||||
return JSVAL_IS_VOID(aVal) || JSVAL_IS_NULL(aVal) || JSVAL_IS_INT(aVal) ||
|
||||
JSVAL_IS_DOUBLE(aVal) || JSVAL_IS_STRING(aVal);
|
||||
bool CanBeConstructedFromJSVal(jsval aVal)
|
||||
{
|
||||
return JSVAL_IS_INT(aVal) || JSVAL_IS_DOUBLE(aVal) || JSVAL_IS_STRING(aVal);
|
||||
}
|
||||
|
||||
private:
|
||||
// Wish we could use JSType here but we will end up supporting types like Date
|
||||
// which JSType can't really identify. Rolling our own for now.
|
||||
enum Type {
|
||||
KEYTYPE_VOID,
|
||||
KEYTYPE_STRING,
|
||||
KEYTYPE_INTEGER
|
||||
};
|
||||
|
||||
// Type of value in mJSVal.
|
||||
Type mType;
|
||||
nsString mString;
|
||||
PRInt64 mInt;
|
||||
|
||||
// The string if mType is KEYTYPE_STRING, otherwise a void string.
|
||||
nsString mStringKey;
|
||||
|
||||
// The integer value if mType is KEYTYPE_INTEGER, otherwise 0.
|
||||
int64 mIntKey;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
|
|
@ -93,6 +93,7 @@ LOCAL_INCLUDES = \
|
|||
-I$(topsrcdir)/dom/src/storage \
|
||||
-I$(topsrcdir)/content/base/src \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
-I$(topsrcdir)/js/xpconnect/src \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -D_IMPL_NS_LAYOUT
|
||||
|
|
|
@ -40,14 +40,13 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIIDBRequest;
|
||||
interface nsIVariant;
|
||||
|
||||
/**
|
||||
* IDBCursor interface. See
|
||||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(adee4085-68cd-4568-9d74-e3d32b6dc5c5)]
|
||||
[scriptable, builtinclass, uuid(462a3607-b2d6-4f4b-9dd7-8ca0b26d3414)]
|
||||
interface nsIIDBCursor : nsISupports
|
||||
{
|
||||
const unsigned short NEXT = 0;
|
||||
|
@ -58,7 +57,8 @@ interface nsIIDBCursor : nsISupports
|
|||
|
||||
readonly attribute nsISupports source;
|
||||
|
||||
readonly attribute nsIVariant key;
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval key;
|
||||
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval primaryKey;
|
||||
|
|
|
@ -39,16 +39,12 @@
|
|||
|
||||
#include "nsIIDBCursor.idl"
|
||||
|
||||
%{C++
|
||||
#include "jsapi.h"
|
||||
%}
|
||||
|
||||
/**
|
||||
* IDBCursor interface. See
|
||||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(b6b7e08a-4379-4441-a176-447c5c96df69)]
|
||||
[scriptable, builtinclass, uuid(b6b7e08a-4379-4441-a176-447c5c96df69)]
|
||||
interface nsIIDBCursorWithValue : nsIIDBCursor
|
||||
{
|
||||
[implicit_jscontext]
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIVariant;
|
||||
interface nsIIDBObjectStore;
|
||||
interface nsIIDBRequest;
|
||||
interface nsIIDBTransaction;
|
||||
|
@ -51,7 +50,7 @@ interface nsIDOMEventListener;
|
|||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, uuid(ac14faa5-261c-4a84-9616-a700fd606f83)]
|
||||
[scriptable, builtinclass, uuid(ddc9dd43-704f-45da-bb91-20f4b3103117)]
|
||||
interface nsIIDBDatabase : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
@ -78,9 +77,8 @@ interface nsIIDBDatabase : nsISupports
|
|||
|
||||
[optional_argc, implicit_jscontext]
|
||||
nsIIDBTransaction
|
||||
transaction(in nsIVariant storeNames, // js array of strings
|
||||
[optional /* READ_ONLY */] in unsigned short mode,
|
||||
[optional /* 5000ms */] in unsigned long timeout);
|
||||
transaction(in jsval storeNames, // js array of strings
|
||||
[optional /* READ_ONLY */] in unsigned short mode);
|
||||
|
||||
void
|
||||
close();
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(7aad2542-a5cb-4a57-b20c-c7d16b8582ab)]
|
||||
[scriptable, builtinclass, uuid(7aad2542-a5cb-4a57-b20c-c7d16b8582ab)]
|
||||
interface nsIIDBDatabaseException : nsISupports
|
||||
{
|
||||
// const unsigned short NO_ERR = 0;
|
||||
|
|
|
@ -42,14 +42,13 @@
|
|||
|
||||
interface nsIIDBKeyRange;
|
||||
interface nsIIDBOpenDBRequest;
|
||||
interface nsIVariant;
|
||||
|
||||
/**
|
||||
* Interface that defines the indexedDB property on a window. See
|
||||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, uuid(d2889b8f-662a-42d3-8a8f-ac5179b9d5b0)]
|
||||
[scriptable, builtinclass, uuid(d2889b8f-662a-42d3-8a8f-ac5179b9d5b0)]
|
||||
interface nsIIDBFactory : nsISupports
|
||||
{
|
||||
[implicit_jscontext, optional_argc]
|
||||
|
|
|
@ -39,17 +39,15 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIIDBKeyRange;
|
||||
interface nsIIDBObjectStore;
|
||||
interface nsIIDBRequest;
|
||||
interface nsIVariant;
|
||||
|
||||
/**
|
||||
* IDBIndex interface. See
|
||||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBIndex for more
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(9df1ac24-06cf-47d1-9159-3b3d65975b80)]
|
||||
[scriptable, builtinclass, uuid(1da60889-3db4-4f66-9fd7-b78c1e7969b7)]
|
||||
interface nsIIDBIndex : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
@ -62,29 +60,38 @@ interface nsIIDBIndex : nsISupports
|
|||
|
||||
readonly attribute nsIIDBObjectStore objectStore;
|
||||
|
||||
[implicit_jscontext]
|
||||
nsIIDBRequest
|
||||
get(in nsIVariant key);
|
||||
get(in jsval key);
|
||||
|
||||
[implicit_jscontext]
|
||||
nsIIDBRequest
|
||||
getKey(in nsIVariant key);
|
||||
getKey(in jsval key);
|
||||
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
getAll([optional /* null */] in nsIVariant key,
|
||||
getAll([optional /* null */] in jsval key,
|
||||
[optional /* unlimited */] in unsigned long limit);
|
||||
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
getAllKeys([optional /* null */] in nsIVariant key,
|
||||
getAllKeys([optional /* null */] in jsval key,
|
||||
[optional /* unlimited */] in unsigned long limit);
|
||||
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
openCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
openCursor([optional /* null */] in jsval key,
|
||||
[optional /* nsIIDBCursor::NEXT */] in unsigned short direction);
|
||||
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
openKeyCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
openKeyCursor([optional /* null */] in jsval key,
|
||||
[optional /* nsIIDBCursor::NEXT */] in unsigned short direction);
|
||||
|
||||
/*
|
||||
// Accepts null, a key value, or a nsIIDBKeyRange object.
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
count([optional] in jsval key);
|
||||
*/
|
||||
};
|
||||
|
|
|
@ -39,18 +39,20 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIVariant;
|
||||
|
||||
/**
|
||||
* IDBKeyRange interface. See
|
||||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBKeyRange for more
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(a1505e41-7e48-4542-9fa5-3f2c98233567)]
|
||||
[scriptable, builtinclass, uuid(8aeb8660-76b3-4651-b8c2-9894ae6dfe68)]
|
||||
interface nsIIDBKeyRange : nsISupports
|
||||
{
|
||||
readonly attribute nsIVariant lower;
|
||||
readonly attribute nsIVariant upper;
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval lower;
|
||||
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval upper;
|
||||
|
||||
readonly attribute boolean lowerOpen;
|
||||
readonly attribute boolean upperOpen;
|
||||
};
|
||||
|
|
|
@ -43,7 +43,6 @@ interface nsIIDBIndex;
|
|||
interface nsIIDBKeyRange;
|
||||
interface nsIIDBRequest;
|
||||
interface nsIIDBTransaction;
|
||||
interface nsIVariant;
|
||||
interface nsIDOMDOMStringList;
|
||||
|
||||
/**
|
||||
|
@ -51,7 +50,7 @@ interface nsIDOMDOMStringList;
|
|||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, uuid(6a65dc92-66e3-407a-a370-590a6c54664a)]
|
||||
[scriptable, builtinclass, uuid(d25dff2f-81ad-4531-bcbe-e85c8a19f11a)]
|
||||
interface nsIIDBObjectStore : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
@ -63,13 +62,14 @@ interface nsIIDBObjectStore : nsISupports
|
|||
readonly attribute nsIIDBTransaction transaction;
|
||||
|
||||
// Success fires IDBTransactionEvent, result == value for key
|
||||
[implicit_jscontext]
|
||||
nsIIDBRequest
|
||||
get(in nsIVariant key);
|
||||
get(in jsval key);
|
||||
|
||||
// Success fires IDBTransactionEvent, result == array of values for given keys
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
getAll([optional /* null */] in nsIIDBKeyRange key,
|
||||
getAll([optional /* null */] in jsval key,
|
||||
[optional /* unlimited */] in unsigned long limit);
|
||||
|
||||
// Success fires IDBTransactionEvent, result == key
|
||||
|
@ -95,9 +95,9 @@ interface nsIIDBObjectStore : nsISupports
|
|||
|
||||
// Success fires IDBTransactionEvent, result == IDBCursor or result == null if
|
||||
// no match.
|
||||
[optional_argc]
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
openCursor([optional /* null */] in nsIIDBKeyRange range,
|
||||
openCursor([optional /* null */] in jsval range,
|
||||
[optional /* NEXT */] in unsigned short direction);
|
||||
|
||||
/**
|
||||
|
@ -118,4 +118,11 @@ interface nsIIDBObjectStore : nsISupports
|
|||
|
||||
void
|
||||
deleteIndex(in AString name);
|
||||
|
||||
/*
|
||||
// Accepts null, a key value, or a nsIIDBKeyRange object.
|
||||
[implicit_jscontext, optional_argc]
|
||||
nsIIDBRequest
|
||||
count([optional] in jsval key);
|
||||
*/
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ interface nsIDOMEventListener;
|
|||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, uuid(91010fbe-1dfb-435d-852e-288d2804c0a7)]
|
||||
[scriptable, builtinclass, uuid(91010fbe-1dfb-435d-852e-288d2804c0a7)]
|
||||
interface nsIIDBOpenDBRequest : nsISupports
|
||||
{
|
||||
attribute nsIDOMEventListener onblocked;
|
||||
|
|
|
@ -48,7 +48,7 @@ interface nsIIDBTransaction;
|
|||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(a1e4a0ff-e0b2-431c-89cf-43b078189e27)]
|
||||
[scriptable, builtinclass, uuid(a1e4a0ff-e0b2-431c-89cf-43b078189e27)]
|
||||
interface nsIIDBRequest : nsISupports
|
||||
{
|
||||
const unsigned short LOADING = 1;
|
||||
|
|
|
@ -50,7 +50,7 @@ interface nsIDOMDOMStringList;
|
|||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransaction
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, uuid(13e551a1-1a58-42ec-b0bd-7102ec0f64d6)]
|
||||
[scriptable, builtinclass, uuid(13e551a1-1a58-42ec-b0bd-7102ec0f64d6)]
|
||||
interface nsIIDBTransaction : nsISupports
|
||||
{
|
||||
readonly attribute nsIIDBDatabase db;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include "nsIDOMEvent.idl"
|
||||
|
||||
[scriptable, uuid(2c5159dc-7d71-4fc6-a3b3-884ed7586456)]
|
||||
[scriptable, builtinclass, uuid(2c5159dc-7d71-4fc6-a3b3-884ed7586456)]
|
||||
interface nsIIDBVersionChangeEvent : nsIDOMEvent
|
||||
{
|
||||
readonly attribute unsigned long long oldVersion;
|
||||
|
|
|
@ -51,7 +51,7 @@ interface nsIIndexedDatabaseUsageCallback : nsISupports
|
|||
in unsigned long long aUsage);
|
||||
};
|
||||
|
||||
[scriptable, uuid(415f5684-6c84-4a8b-b777-d01f5df778f2)]
|
||||
[scriptable, builtinclass, uuid(415f5684-6c84-4a8b-b777-d01f5df778f2)]
|
||||
interface nsIIndexedDatabaseManager : nsISupports
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
request.onsuccess = continueToNextStep;
|
||||
yield;
|
||||
|
||||
transaction = db.transaction("foo");
|
||||
transaction = db.transaction(db.objectStoreNames);
|
||||
|
||||
let objectStore3 = transaction.objectStore("foo");
|
||||
let objectStore4 = transaction.objectStore("foo");
|
||||
|
|
|
@ -52,11 +52,7 @@
|
|||
class nsAutoJSValHolder
|
||||
{
|
||||
public:
|
||||
|
||||
nsAutoJSValHolder()
|
||||
: mRt(NULL)
|
||||
, mVal(JSVAL_NULL)
|
||||
, mHeld(JS_FALSE)
|
||||
nsAutoJSValHolder() : mVal(JSVAL_NULL), mRt(nsnull)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
@ -68,10 +64,28 @@ public:
|
|||
Release();
|
||||
}
|
||||
|
||||
nsAutoJSValHolder(const nsAutoJSValHolder& aOther) {
|
||||
*this = aOther;
|
||||
}
|
||||
|
||||
nsAutoJSValHolder& operator=(const nsAutoJSValHolder& aOther) {
|
||||
if (this != &aOther) {
|
||||
if (aOther.IsHeld()) {
|
||||
// XXX No error handling here...
|
||||
this->Hold(aOther.mRt);
|
||||
}
|
||||
else {
|
||||
this->Release();
|
||||
}
|
||||
*this = static_cast<jsval>(aOther);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hold by rooting on the context's runtime.
|
||||
*/
|
||||
JSBool Hold(JSContext* aCx) {
|
||||
bool Hold(JSContext* aCx) {
|
||||
return Hold(JS_GetRuntime(aCx));
|
||||
}
|
||||
|
||||
|
@ -79,16 +93,18 @@ public:
|
|||
* Hold by rooting on the runtime.
|
||||
* Note that mVal may be JSVAL_NULL, which is not a problem.
|
||||
*/
|
||||
JSBool Hold(JSRuntime* aRt) {
|
||||
if (!mHeld) {
|
||||
if (js_AddRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
|
||||
mRt = aRt;
|
||||
mHeld = JS_TRUE;
|
||||
} else {
|
||||
Release(); // out of memory
|
||||
}
|
||||
bool Hold(JSRuntime* aRt) {
|
||||
// Do we really care about different runtimes?
|
||||
if (mRt && aRt != mRt) {
|
||||
js_RemoveRoot(mRt, &mVal);
|
||||
mRt = nsnull;
|
||||
}
|
||||
return mHeld;
|
||||
|
||||
if (!mRt && js_AddRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
|
||||
mRt = aRt;
|
||||
}
|
||||
|
||||
return !!mRt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,17 +112,14 @@ public:
|
|||
* the original jsval.
|
||||
*/
|
||||
jsval Release() {
|
||||
NS_ASSERTION(!mHeld || mRt, "Bad!");
|
||||
|
||||
jsval oldval = mVal;
|
||||
|
||||
if (mHeld) {
|
||||
if (mRt) {
|
||||
js_RemoveRoot(mRt, &mVal); // infallible
|
||||
mHeld = JS_FALSE;
|
||||
mRt = nsnull;
|
||||
}
|
||||
|
||||
mVal = JSVAL_NULL;
|
||||
mRt = NULL;
|
||||
|
||||
return oldval;
|
||||
}
|
||||
|
@ -114,8 +127,8 @@ public:
|
|||
/**
|
||||
* Determine if Hold has been called.
|
||||
*/
|
||||
JSBool IsHeld() {
|
||||
return mHeld;
|
||||
bool IsHeld() const {
|
||||
return !!mRt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,7 +137,7 @@ public:
|
|||
JSObject* ToJSObject() const {
|
||||
return JSVAL_IS_OBJECT(mVal)
|
||||
? JSVAL_TO_OBJECT(mVal)
|
||||
: NULL;
|
||||
: nsnull;
|
||||
}
|
||||
|
||||
jsval* ToJSValPtr() {
|
||||
|
@ -137,18 +150,13 @@ public:
|
|||
operator jsval() const { return mVal; }
|
||||
|
||||
nsAutoJSValHolder &operator=(JSObject* aOther) {
|
||||
#ifdef DEBUG
|
||||
if (aOther) {
|
||||
NS_ASSERTION(mHeld, "Not rooted!");
|
||||
}
|
||||
#endif
|
||||
return *this = OBJECT_TO_JSVAL(aOther);
|
||||
}
|
||||
|
||||
nsAutoJSValHolder &operator=(jsval aOther) {
|
||||
#ifdef DEBUG
|
||||
if (JSVAL_IS_OBJECT(aOther) && JSVAL_TO_OBJECT(aOther)) {
|
||||
NS_ASSERTION(mHeld, "Not rooted!");
|
||||
if (JSVAL_IS_GCTHING(aOther) && !JSVAL_IS_NULL(aOther)) {
|
||||
NS_ASSERTION(IsHeld(), "Not rooted!");
|
||||
}
|
||||
#endif
|
||||
mVal = aOther;
|
||||
|
@ -156,9 +164,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
JSRuntime* mRt;
|
||||
jsval mVal;
|
||||
JSBool mHeld;
|
||||
JSRuntime* mRt;
|
||||
};
|
||||
|
||||
#endif /* __NSAUTOJSVALHOLDER_H__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче