Backout eb32aca6d54d, b5c0bfd03fcf and 5675bf2c7930 (bug 692669 and bug 692669) for failing to build on all platforms

This commit is contained in:
Ed Morley 2011-11-03 01:57:48 +00:00
Родитель f8c31947fd
Коммит f643cfb775
30 изменённых файлов: 1525 добавлений и 1660 удалений

Просмотреть файл

@ -51,13 +51,6 @@
#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,7 +43,6 @@
// Only meant to be included in IndexedDB source files, not exported.
#include "IndexedDatabase.h"
#include "Key.h"
#include "IDBObjectStore.h"
BEGIN_INDEXEDDB_NAMESPACE

Просмотреть файл

@ -39,6 +39,8 @@
#include "IDBCursor.h"
#include "nsIVariant.h"
#include "jscntxt.h"
#include "mozilla/storage.h"
#include "nsComponentManagerUtils.h"
@ -273,10 +275,8 @@ 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,35 +311,27 @@ 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->mCachedKey)) {
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedKey);
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedKey")
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->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;
@ -386,33 +378,43 @@ IDBCursor::GetSource(nsISupports** aSource)
}
NS_IMETHODIMP
IDBCursor::GetKey(JSContext* aCx,
jsval* aKey)
IDBCursor::GetKey(nsIVariant** aKey)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!mKey.IsUnset() || !mHaveValue, "Bad key!");
if (!mCachedKey) {
nsresult rv;
nsCOMPtr<nsIWritableVariant> variant =
do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mHaveValue) {
*aKey = JSVAL_VOID;
return NS_OK;
}
NS_ASSERTION(!mKey.IsUnset() || !mHaveValue, "Bad key!");
if (!mHaveCachedKey) {
if (!mRooted) {
NS_HOLD_JS_OBJECTS(this, IDBCursor);
mRooted = true;
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);
JSAutoRequest ar(aCx);
rv = variant->SetWritable(false);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsresult rv = mKey.ToJSVal(aCx, &mCachedKey);
NS_ENSURE_SUCCESS(rv, rv);
nsIWritableVariant* result;
variant.forget(&result);
mHaveCachedKey = true;
mCachedKey = dont_AddRef(static_cast<nsIVariant*>(result));
}
*aKey = mCachedKey;
nsCOMPtr<nsIVariant> result(mCachedKey);
result.forget(aKey);
return NS_OK;
}
@ -438,9 +440,9 @@ IDBCursor::GetPrimaryKey(JSContext* aCx,
NS_ASSERTION(mType == OBJECTSTORE ? !mKey.IsUnset() :
!mObjectKey.IsUnset(), "Bad key!");
const Key& key = mType == OBJECTSTORE ? mKey : mObjectKey;
nsresult rv = key.ToJSVal(aCx, &mCachedPrimaryKey);
nsresult rv =
IDBObjectStore::GetJSValFromKey(mType == OBJECTSTORE ? mKey : mObjectKey,
aCx, &mCachedPrimaryKey);
NS_ENSURE_SUCCESS(rv, rv);
mHaveCachedPrimaryKey = true;
@ -496,7 +498,7 @@ IDBCursor::Continue(const jsval &aKey,
}
Key key;
nsresult rv = key.SetFromJSVal(aCx, aKey);
nsresult rv = IDBObjectStore::GetKeyFromJSVal(aKey, aCx, key);
NS_ENSURE_SUCCESS(rv, rv);
if (!key.IsUnset()) {
@ -586,7 +588,7 @@ IDBCursor::Update(const jsval& aValue,
JSAutoRequest ar(aCx);
Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
const Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
if (!mObjectStore->KeyPath().IsEmpty()) {
// This has to be an object.
@ -604,7 +606,7 @@ IDBCursor::Update(const jsval& aValue,
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
Key key;
rv = key.SetFromJSVal(aCx, prop);
rv = IDBObjectStore::GetKeyFromJSVal(prop, aCx, key);
if (NS_FAILED(rv)) {
return rv;
}
@ -617,7 +619,7 @@ IDBCursor::Update(const jsval& aValue,
}
jsval keyVal;
rv = objectKey.ToJSVal(aCx, &keyVal);
rv = IDBObjectStore::GetJSValFromKey(objectKey, aCx, &keyVal);
NS_ENSURE_SUCCESS(rv, rv);
return mObjectStore->Put(aValue, keyVal, aCx, 1, _retval);
@ -644,10 +646,10 @@ IDBCursor::Delete(JSContext* aCx,
NS_ASSERTION(mObjectStore, "This cannot be null!");
NS_ASSERTION(!mKey.IsUnset() , "Bad key!");
Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
const Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
jsval key;
nsresult rv = objectKey.ToJSVal(aCx, &key);
nsresult rv = IDBObjectStore::GetJSValFromKey(objectKey, aCx, &key);
NS_ENSURE_SUCCESS(rv, rv);
return mObjectStore->Delete(key, aCx, _retval);
@ -686,7 +688,7 @@ ContinueHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else {
mKey.Unset();
mKey = Key::UNSETKEY;
}
return NS_OK;
@ -697,12 +699,11 @@ ContinueHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
// Remove cached stuff from last time.
mCursor->mCachedKey = JSVAL_VOID;
mCursor->mCachedPrimaryKey = JSVAL_VOID;
mCursor->mCachedKey = nsnull;
mCursor->mCachedValue = JSVAL_VOID;
mCursor->mHaveCachedKey = false;
mCursor->mHaveCachedPrimaryKey = false;
mCursor->mCachedPrimaryKey = JSVAL_VOID;
mCursor->mHaveCachedValue = false;
mCursor->mHaveCachedPrimaryKey = false;
mCursor->mContinueCalled = false;
if (mKey.IsUnset()) {
@ -716,7 +717,7 @@ ContinueHelper::GetSuccessResult(JSContext* aCx,
// Set new values.
mCursor->mKey = mKey;
mCursor->mObjectKey = mObjectKey;
mCursor->mContinueToKey.Unset();
mCursor->mContinueToKey = Key::UNSETKEY;
mCursor->mCloneBuffer.swap(mCloneBuffer);
mCloneBuffer.clear();
@ -745,15 +746,31 @@ ContinueObjectStoreHelper::BindArgumentsToStatement(
mCursor->mKey :
mCursor->mContinueToKey;
rv = currentKey.BindToStatement(aStatement, currentKeyName);
NS_ENSURE_SUCCESS(rv, rv);
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);
// Bind range key if it is specified.
const Key& rangeKey = mCursor->mRangeKey;
if (!rangeKey.IsUnset()) {
rv = rangeKey.BindToStatement(aStatement, rangeKeyName);
NS_ENSURE_SUCCESS(rv, rv);
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);
}
return NS_OK;
@ -764,8 +781,20 @@ ContinueObjectStoreHelper::GatherResultsFromStatement(
mozIStorageStatement* aStatement)
{
// Figure out what kind of key we have next.
nsresult rv = mKey.SetFromStatement(aStatement, 0);
NS_ENSURE_SUCCESS(rv, rv);
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!");
}
rv = IDBObjectStore::GetStructuredCloneDataFromStatement(aStatement, 1,
mCloneBuffer);
@ -789,14 +818,32 @@ ContinueIndexHelper::BindArgumentsToStatement(mozIStorageStatement* aStatement)
mCursor->mKey :
mCursor->mContinueToKey;
rv = currentKey.BindToStatement(aStatement, currentKeyName);
NS_ENSURE_SUCCESS(rv, rv);
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);
// Bind range key if it is specified.
if (!mCursor->mRangeKey.IsUnset()) {
NS_NAMED_LITERAL_CSTRING(rangeKeyName, "range_key");
rv = mCursor->mRangeKey.BindToStatement(aStatement, rangeKeyName);
NS_ENSURE_SUCCESS(rv, rv);
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);
}
// Bind object key if duplicates are allowed and we're not continuing to a
@ -807,8 +854,18 @@ ContinueIndexHelper::BindArgumentsToStatement(mozIStorageStatement* aStatement)
NS_ASSERTION(!mCursor->mObjectKey.IsUnset(), "Bad key!");
NS_NAMED_LITERAL_CSTRING(objectKeyName, "object_key");
rv = mCursor->mObjectKey.BindToStatement(aStatement, objectKeyName);
NS_ENSURE_SUCCESS(rv, rv);
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);
}
return NS_OK;
@ -818,11 +875,42 @@ nsresult
ContinueIndexHelper::GatherResultsFromStatement(
mozIStorageStatement* aStatement)
{
nsresult rv = mKey.SetFromStatement(aStatement, 0);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 keyType;
nsresult rv = aStatement->GetTypeOfIndex(0, &keyType);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = mObjectKey.SetFromStatement(aStatement, 1);
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!");
}
return NS_OK;
}
@ -831,11 +919,42 @@ nsresult
ContinueIndexObjectHelper::GatherResultsFromStatement(
mozIStorageStatement* aStatement)
{
nsresult rv = mKey.SetFromStatement(aStatement, 0);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 keyType;
nsresult rv = aStatement->GetTypeOfIndex(0, &keyType);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = mObjectKey.SetFromStatement(aStatement, 1);
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 = IDBObjectStore::GetStructuredCloneDataFromStatement(aStatement, 2,
mCloneBuffer);

Просмотреть файл

@ -42,7 +42,6 @@
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/Key.h"
#include "nsIIDBCursorWithValue.h"
@ -151,13 +150,15 @@ 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;
@ -168,7 +169,6 @@ protected:
JSAutoStructuredCloneBuffer mCloneBuffer;
Key mContinueToKey;
bool mHaveCachedKey;
bool mHaveCachedPrimaryKey;
bool mHaveCachedValue;
bool mRooted;

Просмотреть файл

@ -127,6 +127,16 @@ 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
{
@ -152,6 +162,75 @@ 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
@ -615,8 +694,9 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName)
}
NS_IMETHODIMP
IDBDatabase::Transaction(const jsval& aStoreNames,
IDBDatabase::Transaction(nsIVariant* aStoreNames,
PRUint16 aMode,
PRUint32 aTimeout,
JSContext* aCx,
PRUint8 aOptionalArgCount,
nsIIDBTransaction** _retval)
@ -631,15 +711,6 @@ IDBDatabase::Transaction(const jsval& 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) {
@ -650,102 +721,110 @@ IDBDatabase::Transaction(const jsval& aStoreNames,
aMode = nsIIDBTransaction::READ_ONLY;
}
nsresult rv;
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;
}
nsTArray<nsString> storesToOpen;
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)) {
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?");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
} break;
if (!length) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
storesToOpen.SetCapacity(length);
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;
}
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));
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 (wrapper) {
nsISupports* wrappedObject = wrapper->Native();
NS_ENSURE_TRUE(wrappedObject, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!info->ContainsStoreName(name)) {
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_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);
if (!storesToOpen.AppendElement(name)) {
NS_WARNING("Out of memory?");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
} break;
if (!length) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
case nsIDataType::VTYPE_ARRAY: {
nsTArray<nsString> names;
rv = ConvertVariantToStringArray(aStoreNames, names);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
storesToOpen.SetCapacity(length);
PRUint32 nameCount = names.Length();
for (PRUint32 nameIndex = 0; nameIndex < nameCount; nameIndex++) {
nsString& name = names[nameIndex];
for (PRUint32 index = 0; index < length; index++) {
nsString* item = storesToOpen.AppendElement();
NS_ASSERTION(item, "This should never fail!");
if (!info->ContainsStoreName(name)) {
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_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!");
if (!storesToOpen.AppendElement(name)) {
NS_WARNING("Out of memory?");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
}
}
NS_ASSERTION(nameCount == storesToOpen.Length(), "Should have bailed!");
} break;
// 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;
}
case nsIDataType::VTYPE_INTERFACE:
case nsIDataType::VTYPE_INTERFACE_IS: {
nsCOMPtr<nsISupports> supports;
nsID *iid;
rv = aStoreNames->GetAsInterface(&iid, getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
storesToOpen.AppendElement(str);
}
NS_Free(iid);
// 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;
}
nsCOMPtr<nsIDOMDOMStringList> stringList(do_QueryInterface(supports));
if (!stringList) {
// We don't support anything other than nsIDOMDOMStringList.
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
}
PRUint32 stringCount;
rv = stringList->GetLength(&stringCount);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_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);
if (!info->ContainsStoreName(name)) {
return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
}
if (!storesToOpen.AppendElement(name)) {
NS_WARNING("Out of memory?");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
} break;
default:
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
}
nsRefPtr<IDBTransaction> transaction =

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -42,7 +42,7 @@
#include "nsIXPConnect.h"
#include "jscntxt.h"
#include "nsDOMClassInfo.h"
#include "nsDOMClassInfoID.h"
#include "nsJSUtils.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
@ -54,7 +54,54 @@ USING_INDEXEDDB_NAMESPACE
namespace {
inline
bool
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
ReturnKeyRange(JSContext* aCx,
jsval* aVp,
IDBKeyRange* aKeyRange)
@ -68,73 +115,24 @@ ReturnKeyRange(JSContext* aCx,
NS_ASSERTION(xpc, "This should never be null!");
JSObject* global = JS_GetGlobalForScopeChain(aCx);
if (!global) {
NS_WARNING("Couldn't get global object!");
return false;
}
NS_ENSURE_TRUE(global, JS_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 false;
return JS_FALSE;
}
JSObject* result;
if (NS_FAILED(holder->GetJSObject(&result))) {
JS_ReportError(aCx, "Couldn't get JSObject from wrapper.");
return false;
return JS_FALSE;
}
JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(result));
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;
return JS_TRUE;
}
JSBool
@ -144,18 +142,21 @@ MakeOnlyKeyRange(JSContext* aCx,
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
jsval val;
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &val)) {
return false;
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;
}
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(false, false, true);
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Lower())) {
return false;
}
return ReturnKeyRange(aCx, aVp, keyRange);
return JS_TRUE;
}
JSBool
@ -165,19 +166,27 @@ MakeLowerBoundKeyRange(JSContext* aCx,
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
jsval val;
JSBool open = false;
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
return false;
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;
}
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(open, true, false);
nsRefPtr<IDBKeyRange> range =
IDBKeyRange::Create(keys[0], nsnull, !!open, true);
NS_ASSERTION(range, "Out of memory?");
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Lower())) {
return false;
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return ReturnKeyRange(aCx, aVp, keyRange);
return JS_TRUE;
}
JSBool
@ -187,19 +196,27 @@ MakeUpperBoundKeyRange(JSContext* aCx,
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
jsval val;
JSBool open = false;
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
return false;
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;
}
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(true, open, false);
nsRefPtr<IDBKeyRange> range =
IDBKeyRange::Create(nsnull, keys[0], true, !!open);
NS_ASSERTION(range, "Out of memory?");
if (!GetKeyFromJSValOrThrow(aCx, val, keyRange->Upper())) {
return false;
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return ReturnKeyRange(aCx, aVp, keyRange);
return JS_TRUE;
}
JSBool
@ -209,29 +226,36 @@ MakeBoundKeyRange(JSContext* aCx,
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
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;
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;
}
nsRefPtr<IDBKeyRange> keyRange = new IDBKeyRange(lowerOpen, upperOpen, false);
if (!GetKeyFromJSValOrThrow(aCx, lowerVal, keyRange->Lower()) ||
!GetKeyFromJSValOrThrow(aCx, upperVal, keyRange->Upper())) {
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;
}
if (keyRange->Lower() > keyRange->Upper() ||
(keyRange->Lower() == keyRange->Upper() && (lowerOpen || upperOpen))) {
ThrowException(aCx, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
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;
}
return ReturnKeyRange(aCx, aVp, keyRange);
return JS_TRUE;
}
#define KEYRANGE_FUNCTION_FLAGS (JSPROP_ENUMERATE | JSPROP_PERMANENT)
const JSFunctionSpec gKeyRangeConstructors[] = {
@ -261,129 +285,49 @@ IDBKeyRange::DefineConstructors(JSContext* aCx,
}
// static
nsresult
IDBKeyRange::FromJSVal(JSContext* aCx,
const jsval& aVal,
IDBKeyRange** aKeyRange)
already_AddRefed<IDBKeyRange>
IDBKeyRange::Create(nsIVariant* aLower,
nsIVariant* aUpper,
bool aLowerOpen,
bool aUpperOpen)
{
nsresult rv;
nsRefPtr<IDBKeyRange> keyRange;
nsRefPtr<IDBKeyRange> keyRange(new IDBKeyRange());
keyRange->mLower = aLower;
keyRange->mUpper = aUpper;
keyRange->mLowerOpen = aLowerOpen;
keyRange->mUpperOpen = aUpperOpen;
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;
return keyRange.forget();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
NS_IMPL_ADDREF(IDBKeyRange)
NS_IMPL_RELEASE(IDBKeyRange)
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_BEGIN(IDBKeyRange)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIIDBKeyRange)
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(JSContext* aCx,
jsval* aLower)
IDBKeyRange::GetLower(nsIVariant** aLower)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
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;
nsCOMPtr<nsIVariant> result(mLower);
result.forget(aLower);
return NS_OK;
}
NS_IMETHODIMP
IDBKeyRange::GetUpper(JSContext* aCx,
jsval* aUpper)
IDBKeyRange::GetUpper(nsIVariant** aUpper)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
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;
nsCOMPtr<nsIVariant> result(mUpper);
result.forget(aUpper);
return NS_OK;
}
@ -392,7 +336,7 @@ IDBKeyRange::GetLowerOpen(bool* aLowerOpen)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
*aLowerOpen = mLowerOpen;
*aLowerOpen = mLowerOpen ? true : false;
return NS_OK;
}
@ -402,6 +346,6 @@ IDBKeyRange::GetUpperOpen(bool* aUpperOpen)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
*aUpperOpen = mUpperOpen;
*aUpperOpen = mUpperOpen ? true : false;
return NS_OK;
}

Просмотреть файл

@ -41,78 +41,38 @@
#define mozilla_dom_indexeddb_idbkeyrange_h__
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
#include "mozilla/dom/indexedDB/Key.h"
#include "nsIIDBKeyRange.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIVariant.h"
BEGIN_INDEXEDDB_NAMESPACE
class IDBKeyRange : public nsIIDBKeyRange
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_ISUPPORTS
NS_DECL_NSIIDBKEYRANGE
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBKeyRange)
static JSBool DefineConstructors(JSContext* aCx,
JSObject* aObject);
static
nsresult FromJSVal(JSContext* aCx,
const jsval& aVal,
IDBKeyRange** aKeyRange);
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;
}
already_AddRefed<IDBKeyRange> Create(nsIVariant* aLower,
nsIVariant* aUpper,
bool aLowerOpen,
bool aUpperOpen);
protected:
IDBKeyRange()
: mLowerOpen(false), mUpperOpen(false)
{ }
~IDBKeyRange() { }
Key mLower;
Key mUpper;
jsval mCachedLowerVal;
jsval mCachedUpperVal;
nsCOMPtr<nsIVariant> mLower;
nsCOMPtr<nsIVariant> mUpper;
bool mLowerOpen;
bool mUpperOpen;
bool mIsOnly;
bool mHaveCachedLowerVal;
bool mHaveCachedUpperVal;
bool mRooted;
};
END_INDEXEDDB_NAMESPACE

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -42,6 +42,7 @@
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/indexedDB/Key.h"
#include "nsIIDBObjectStore.h"
#include "nsIIDBTransaction.h"
@ -54,7 +55,6 @@ class nsPIDOMWindow;
BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
class Key;
struct ObjectStoreInfo;
struct IndexInfo;
@ -72,6 +72,20 @@ 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,6 +41,7 @@
#include "IDBRequest.h"
#include "nsIScriptContext.h"
#include "nsIVariant.h"
#include "nsComponentManagerUtils.h"
#include "nsDOMClassInfoID.h"

Просмотреть файл

@ -42,45 +42,70 @@
#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)
{
Unset();
*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;
}
Key& operator=(const nsAString& aString)
{
SetFromString(aString);
mType = STRINGKEY;
mString = aString;
mInt = 0;
return *this;
}
Key& operator=(PRInt64 aInt)
{
SetFromInteger(aInt);
mType = INTKEY;
mString.Truncate();
mInt = 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 KEYTYPE_STRING:
return ToString() == aOther.ToString();
case UNSETKEY:
return true;
case KEYTYPE_INTEGER:
return ToInteger() == aOther.ToInteger();
case STRINGKEY:
return mString == aOther.mString;
case INTKEY:
return mInt == aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
@ -96,24 +121,30 @@ public:
bool operator<(const Key& aOther) const
{
NS_ASSERTION(mType != KEYTYPE_VOID && aOther.mType != KEYTYPE_VOID,
"Don't compare unset keys!");
switch (mType) {
case KEYTYPE_STRING: {
if (aOther.mType == KEYTYPE_INTEGER) {
case UNSETKEY:
if (aOther.mType == UNSETKEY) {
return false;
}
NS_ASSERTION(aOther.mType == KEYTYPE_STRING, "Unknown type!");
return ToString() < aOther.ToString();
}
return true;
case KEYTYPE_INTEGER:
if (aOther.mType == KEYTYPE_STRING) {
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) {
return true;
}
NS_ASSERTION(aOther.mType == KEYTYPE_INTEGER, "Unknown type!");
return ToInteger() < aOther.ToInteger();
NS_ASSERTION(aOther.mType == INTKEY, "Unknown type!");
return mInt < aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
@ -136,188 +167,42 @@ public:
return (*this == aOther || !(*this < aOther));
}
void
Unset()
{
mType = KEYTYPE_VOID;
mStringKey.SetIsVoid(true);
mIntKey = 0;
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;
}
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;
PRInt64 IntValue() const {
NS_ASSERTION(IsInt(), "Wrong type!");
return mInt;
}
nsresult SetFromInteger(PRInt64 aInt)
{
mType = KEYTYPE_INTEGER;
mStringKey.SetIsVoid(true);
mIntKey = aInt;
return NS_OK;
nsAString& ToString() {
mType = STRINGKEY;
mInt = 0;
return mString;
}
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()) {
nsString stringKey = ToString();
if (!xpc_qsStringToJsval(aCx, stringKey, 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;
PRInt64* ToIntPtr() {
mType = INTKEY;
mString.Truncate();
return &mInt;
}
static
bool CanBeConstructedFromJSVal(jsval aVal)
{
return JSVAL_IS_INT(aVal) || JSVAL_IS_DOUBLE(aVal) || JSVAL_IS_STRING(aVal);
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);
}
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;
// 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;
nsString mString;
PRInt64 mInt;
};
END_INDEXEDDB_NAMESPACE

Просмотреть файл

@ -93,7 +93,6 @@ 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,13 +40,14 @@
#include "nsISupports.idl"
interface nsIIDBRequest;
interface nsIVariant;
/**
* IDBCursor interface. See
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
* information.
*/
[scriptable, builtinclass, uuid(462a3607-b2d6-4f4b-9dd7-8ca0b26d3414)]
[scriptable, uuid(adee4085-68cd-4568-9d74-e3d32b6dc5c5)]
interface nsIIDBCursor : nsISupports
{
const unsigned short NEXT = 0;
@ -57,8 +58,7 @@ interface nsIIDBCursor : nsISupports
readonly attribute nsISupports source;
[implicit_jscontext]
readonly attribute jsval key;
readonly attribute nsIVariant key;
[implicit_jscontext]
readonly attribute jsval primaryKey;

Просмотреть файл

@ -39,12 +39,16 @@
#include "nsIIDBCursor.idl"
%{C++
#include "jsapi.h"
%}
/**
* IDBCursor interface. See
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
* information.
*/
[scriptable, builtinclass, uuid(b6b7e08a-4379-4441-a176-447c5c96df69)]
[scriptable, uuid(b6b7e08a-4379-4441-a176-447c5c96df69)]
interface nsIIDBCursorWithValue : nsIIDBCursor
{
[implicit_jscontext]

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsISupports.idl"
interface nsIVariant;
interface nsIIDBObjectStore;
interface nsIIDBRequest;
interface nsIIDBTransaction;
@ -50,7 +51,7 @@ interface nsIDOMEventListener;
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
* for more information.
*/
[scriptable, builtinclass, uuid(ddc9dd43-704f-45da-bb91-20f4b3103117)]
[scriptable, uuid(ac14faa5-261c-4a84-9616-a700fd606f83)]
interface nsIIDBDatabase : nsISupports
{
readonly attribute DOMString name;
@ -77,8 +78,9 @@ interface nsIIDBDatabase : nsISupports
[optional_argc, implicit_jscontext]
nsIIDBTransaction
transaction(in jsval storeNames, // js array of strings
[optional /* READ_ONLY */] in unsigned short mode);
transaction(in nsIVariant storeNames, // js array of strings
[optional /* READ_ONLY */] in unsigned short mode,
[optional /* 5000ms */] in unsigned long timeout);
void
close();

Просмотреть файл

@ -39,7 +39,7 @@
#include "nsISupports.idl"
[scriptable, builtinclass, uuid(7aad2542-a5cb-4a57-b20c-c7d16b8582ab)]
[scriptable, uuid(7aad2542-a5cb-4a57-b20c-c7d16b8582ab)]
interface nsIIDBDatabaseException : nsISupports
{
// const unsigned short NO_ERR = 0;

Просмотреть файл

@ -42,13 +42,14 @@
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, builtinclass, uuid(d2889b8f-662a-42d3-8a8f-ac5179b9d5b0)]
[scriptable, uuid(d2889b8f-662a-42d3-8a8f-ac5179b9d5b0)]
interface nsIIDBFactory : nsISupports
{
[implicit_jscontext, optional_argc]

Просмотреть файл

@ -39,15 +39,17 @@
#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, builtinclass, uuid(1da60889-3db4-4f66-9fd7-b78c1e7969b7)]
[scriptable, uuid(9df1ac24-06cf-47d1-9159-3b3d65975b80)]
interface nsIIDBIndex : nsISupports
{
readonly attribute DOMString name;
@ -60,36 +62,29 @@ interface nsIIDBIndex : nsISupports
readonly attribute nsIIDBObjectStore objectStore;
[implicit_jscontext]
nsIIDBRequest
get(in jsval key);
get(in nsIVariant key);
[implicit_jscontext]
nsIIDBRequest
getKey(in jsval key);
getKey(in nsIVariant key);
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
getAll([optional /* null */] in jsval key,
getAll([optional /* null */] in nsIVariant key,
[optional /* unlimited */] in unsigned long limit);
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
getAllKeys([optional /* null */] in jsval key,
getAllKeys([optional /* null */] in nsIVariant key,
[optional /* unlimited */] in unsigned long limit);
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
openCursor([optional /* null */] in jsval key,
openCursor([optional /* null */] in nsIIDBKeyRange range,
[optional /* nsIIDBCursor::NEXT */] in unsigned short direction);
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
openKeyCursor([optional /* null */] in jsval key,
openKeyCursor([optional /* null */] in nsIIDBKeyRange range,
[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,20 +39,18 @@
#include "nsISupports.idl"
interface nsIVariant;
/**
* IDBKeyRange interface. See
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBKeyRange for more
* information.
*/
[scriptable, builtinclass, uuid(8aeb8660-76b3-4651-b8c2-9894ae6dfe68)]
[scriptable, uuid(a1505e41-7e48-4542-9fa5-3f2c98233567)]
interface nsIIDBKeyRange : nsISupports
{
[implicit_jscontext]
readonly attribute jsval lower;
[implicit_jscontext]
readonly attribute jsval upper;
readonly attribute nsIVariant lower;
readonly attribute nsIVariant upper;
readonly attribute boolean lowerOpen;
readonly attribute boolean upperOpen;
};

Просмотреть файл

@ -43,6 +43,7 @@ interface nsIIDBIndex;
interface nsIIDBKeyRange;
interface nsIIDBRequest;
interface nsIIDBTransaction;
interface nsIVariant;
interface nsIDOMDOMStringList;
/**
@ -50,7 +51,7 @@ interface nsIDOMDOMStringList;
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
* for more information.
*/
[scriptable, builtinclass, uuid(d25dff2f-81ad-4531-bcbe-e85c8a19f11a)]
[scriptable, uuid(6a65dc92-66e3-407a-a370-590a6c54664a)]
interface nsIIDBObjectStore : nsISupports
{
readonly attribute DOMString name;
@ -62,14 +63,13 @@ interface nsIIDBObjectStore : nsISupports
readonly attribute nsIIDBTransaction transaction;
// Success fires IDBTransactionEvent, result == value for key
[implicit_jscontext]
nsIIDBRequest
get(in jsval key);
get(in nsIVariant key);
// Success fires IDBTransactionEvent, result == array of values for given keys
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
getAll([optional /* null */] in jsval key,
getAll([optional /* null */] in nsIIDBKeyRange 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.
[implicit_jscontext, optional_argc]
[optional_argc]
nsIIDBRequest
openCursor([optional /* null */] in jsval range,
openCursor([optional /* null */] in nsIIDBKeyRange range,
[optional /* NEXT */] in unsigned short direction);
/**
@ -118,9 +118,4 @@ 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, builtinclass, uuid(91010fbe-1dfb-435d-852e-288d2804c0a7)]
[scriptable, 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, builtinclass, uuid(a1e4a0ff-e0b2-431c-89cf-43b078189e27)]
[scriptable, 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, builtinclass, uuid(13e551a1-1a58-42ec-b0bd-7102ec0f64d6)]
[scriptable, uuid(13e551a1-1a58-42ec-b0bd-7102ec0f64d6)]
interface nsIIDBTransaction : nsISupports
{
readonly attribute nsIIDBDatabase db;

Просмотреть файл

@ -39,7 +39,7 @@
#include "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(2c5159dc-7d71-4fc6-a3b3-884ed7586456)]
[scriptable, 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, builtinclass, uuid(415f5684-6c84-4a8b-b777-d01f5df778f2)]
[scriptable, uuid(415f5684-6c84-4a8b-b777-d01f5df778f2)]
interface nsIIndexedDatabaseManager : nsISupports
{
/**

Просмотреть файл

@ -57,7 +57,6 @@ TEST_FILES = \
test_bad_keypath.html \
test_bfcache.html \
test_clear.html \
test_count.html \
test_create_index.html \
test_create_index_with_integer_keys.html \
test_create_objectStore.html \

Просмотреть файл

@ -1,366 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
const objectStoreName = "People";
const objectStoreData = [
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
{ key: "237-23-7738", value: { name: "Mel", height: 66, weight: {} } },
{ key: "237-23-7739", value: { name: "Tom", height: 62, weight: 130 } }
];
const indexData = {
name: "weight",
keyPath: "weight",
options: { unique: false }
};
const weightSort = [1, 0, 3, 7, 4, 2];
let request = mozIndexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.onerror = errorHandler;
let objectStore = db.createObjectStore(objectStoreName, { });
objectStore.createIndex(indexData.name, indexData.keyPath,
indexData.options);
for each (let data in objectStoreData) {
objectStore.add(data.value, data.key);
}
event = yield;
is(event.type, "success", "Got correct event type");
objectStore = db.transaction(db.objectStoreNames)
.objectStore(objectStoreName);
objectStore.count().onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length,
"Correct number of object store entries for all keys");
objectStore.count(null).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length,
"Correct number of object store entries for null key");
objectStore.count(objectStoreData[2].key).onsuccess =
grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of object store entries for single existing key");
objectStore.count("foo").onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of object store entries for single non-existing key");
let keyRange = IDBKeyRange.only(objectStoreData[2].key);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of object store entries for existing only keyRange");
keyRange = IDBKeyRange.only("foo");
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of object store entries for non-existing only keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length - 2,
"Correct number of object store entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key, true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length - 3,
"Correct number of object store entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound("foo");
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of object store entries for lowerBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, false);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 3,
"Correct number of object store entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 2,
"Correct number of object store entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound("foo", true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length,
"Correct number of object store entries for upperBound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
objectStoreData[objectStoreData.length - 1].key);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length,
"Correct number of object store entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
objectStoreData[objectStoreData.length - 1].key,
true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length - 1,
"Correct number of object store entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
objectStoreData[objectStoreData.length - 1].key,
true, true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length - 2,
"Correct number of object store entries for bound keyRange");
keyRange = IDBKeyRange.bound("foo", "foopy", true, true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of object store entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[0].key, "foo", true, true);
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, objectStoreData.length - 1,
"Correct number of object store entries for bound keyRange");
let index = objectStore.index(indexData.name);
index.count().onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for no key");
index.count(objectStoreData[7].value.weight).onsuccess =
grabEventAndContinueHandler;
event = yield;
is(event.target.result, 2,
"Correct number of index entries for duplicate key");
index.count(objectStoreData[0].value.weight).onsuccess =
grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of index entries for single key");
keyRange = IDBKeyRange.only(objectStoreData[0].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of index entries for only existing keyRange");
keyRange = IDBKeyRange.only("foo");
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of index entries for only non-existing keyRange");
keyRange = IDBKeyRange.only(objectStoreData[7].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 2,
"Correct number of index entries for only duplicate keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[1]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 1,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight - 1);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 1,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight + 1,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of index entries for lowerBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 1,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 1,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 1,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.upperBound("foo");
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for upperBound keyRange");
keyRange = IDBKeyRange.bound("foo", "foopy");
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, 0,
"Correct number of index entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
objectStoreData[weightSort[weightSort.length - 1]].value.weight);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length,
"Correct number of index entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
objectStoreData[weightSort[weightSort.length - 1]].value.weight,
true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 1,
"Correct number of index entries for bound keyRange");
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
objectStoreData[weightSort[weightSort.length - 1]].value.weight,
true, true);
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result, weightSort.length - 2,
"Correct number of index entries for bound keyRange");
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

Просмотреть файл

@ -31,7 +31,7 @@
request.onsuccess = continueToNextStep;
yield;
transaction = db.transaction(db.objectStoreNames);
transaction = db.transaction("foo");
let objectStore3 = transaction.objectStore("foo");
let objectStore4 = transaction.objectStore("foo");

Просмотреть файл

@ -52,7 +52,11 @@
class nsAutoJSValHolder
{
public:
nsAutoJSValHolder() : mVal(JSVAL_NULL), mRt(nsnull)
nsAutoJSValHolder()
: mRt(NULL)
, mVal(JSVAL_NULL)
, mHeld(JS_FALSE)
{
// nothing to do
}
@ -64,28 +68,10 @@ 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.
*/
bool Hold(JSContext* aCx) {
JSBool Hold(JSContext* aCx) {
return Hold(JS_GetRuntime(aCx));
}
@ -93,18 +79,16 @@ public:
* Hold by rooting on the runtime.
* Note that mVal may be JSVAL_NULL, which is not a problem.
*/
bool Hold(JSRuntime* aRt) {
// Do we really care about different runtimes?
if (mRt && aRt != mRt) {
js_RemoveRoot(mRt, &mVal);
mRt = nsnull;
JSBool Hold(JSRuntime* aRt) {
if (!mHeld) {
if (js_AddRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
mRt = aRt;
mHeld = JS_TRUE;
} else {
Release(); // out of memory
}
}
if (!mRt && js_AddRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
mRt = aRt;
}
return !!mRt;
return mHeld;
}
/**
@ -112,14 +96,17 @@ public:
* the original jsval.
*/
jsval Release() {
NS_ASSERTION(!mHeld || mRt, "Bad!");
jsval oldval = mVal;
if (mRt) {
if (mHeld) {
js_RemoveRoot(mRt, &mVal); // infallible
mRt = nsnull;
mHeld = JS_FALSE;
}
mVal = JSVAL_NULL;
mRt = NULL;
return oldval;
}
@ -127,8 +114,8 @@ public:
/**
* Determine if Hold has been called.
*/
bool IsHeld() const {
return !!mRt;
JSBool IsHeld() {
return mHeld;
}
/**
@ -137,7 +124,7 @@ public:
JSObject* ToJSObject() const {
return JSVAL_IS_OBJECT(mVal)
? JSVAL_TO_OBJECT(mVal)
: nsnull;
: NULL;
}
jsval* ToJSValPtr() {
@ -150,13 +137,18 @@ 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_GCTHING(aOther) && !JSVAL_IS_NULL(aOther)) {
NS_ASSERTION(IsHeld(), "Not rooted!");
if (JSVAL_IS_OBJECT(aOther) && JSVAL_TO_OBJECT(aOther)) {
NS_ASSERTION(mHeld, "Not rooted!");
}
#endif
mVal = aOther;
@ -164,8 +156,9 @@ public:
}
private:
jsval mVal;
JSRuntime* mRt;
jsval mVal;
JSBool mHeld;
};
#endif /* __NSAUTOJSVALHOLDER_H__ */