Bug 607122 - 'IndexedDB: IDBKeyRange cleanup'. r=sicking, a=blocking+

This commit is contained in:
Ben Turner 2010-11-10 15:26:00 -08:00
Родитель 6f6dc4e252
Коммит d891e8880c
14 изменённых файлов: 682 добавлений и 498 удалений

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

@ -6145,6 +6145,12 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
NS_ENSURE_SUCCESS(rv, rv);
}
// Special case for |IDBKeyRange| which gets funny "static" functions.
if (primary_iid->Equals(NS_GET_IID(nsIIDBKeyRange)) &&
!indexedDB::IDBKeyRange::DefineConstructors(cx, class_obj)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIInterfaceInfoManager>
iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);

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

@ -501,27 +501,6 @@ CreateDatabaseConnection(const nsACString& aASCIIOrigin,
return NS_OK;
}
inline
nsresult
ValidateVariantForKey(nsIVariant* aVariant)
{
PRUint16 type;
nsresult rv = aVariant->GetDataType(&type);
NS_ENSURE_SUCCESS(rv, rv);
switch (type) {
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
case nsIDataType::VTYPE_INT32:
case nsIDataType::VTYPE_DOUBLE:
break;
default:
return NS_ERROR_INVALID_ARG;
}
return NS_OK;
}
} // anonyomous namespace
// static
@ -881,106 +860,6 @@ IDBFactory::Open(const nsAString& aName,
return NS_OK;
}
NS_IMETHODIMP
IDBFactory::MakeSingleKeyRange(nsIVariant* aValue,
nsIIDBKeyRange** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = ValidateVariantForKey(aValue);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsRefPtr<IDBKeyRange> range =
IDBKeyRange::Create(aValue, aValue, PRUint16(nsIIDBKeyRange::LEFT_BOUND |
nsIIDBKeyRange::RIGHT_BOUND));
NS_ASSERTION(range, "Out of memory?");
range.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
IDBFactory::MakeLeftBoundKeyRange(nsIVariant* aBound,
PRBool aOpen,
nsIIDBKeyRange** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = ValidateVariantForKey(aBound);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
PRUint16 flags = aOpen ?
PRUint16(nsIIDBKeyRange::LEFT_OPEN) :
PRUint16(nsIIDBKeyRange::LEFT_BOUND);
nsRefPtr<IDBKeyRange> range = IDBKeyRange::Create(aBound, nsnull, flags);
NS_ASSERTION(range, "Out of memory?");
range.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
IDBFactory::MakeRightBoundKeyRange(nsIVariant* aBound,
PRBool aOpen,
nsIIDBKeyRange** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = ValidateVariantForKey(aBound);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
PRUint16 flags = aOpen ?
PRUint16(nsIIDBKeyRange::RIGHT_OPEN) :
PRUint16(nsIIDBKeyRange::RIGHT_BOUND);
nsRefPtr<IDBKeyRange> range = IDBKeyRange::Create(nsnull, aBound, flags);
NS_ASSERTION(range, "Out of memory?");
range.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
IDBFactory::MakeBoundKeyRange(nsIVariant* aLeft,
nsIVariant* aRight,
PRBool aOpenLeft,
PRBool aOpenRight,
nsIIDBKeyRange **_retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = ValidateVariantForKey(aLeft);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
rv = ValidateVariantForKey(aRight);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
PRUint16 flags = aOpenLeft ?
PRUint16(nsIIDBKeyRange::LEFT_OPEN) :
PRUint16(nsIIDBKeyRange::LEFT_BOUND);
flags |= aOpenRight ?
PRUint16(nsIIDBKeyRange::RIGHT_OPEN) :
PRUint16(nsIIDBKeyRange::RIGHT_BOUND);
nsRefPtr<IDBKeyRange> range = IDBKeyRange::Create(aLeft, aRight, flags);
NS_ASSERTION(range, "Out of memory?");
range.forget(_retval);
return NS_OK;
}
nsresult
OpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{

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

@ -143,13 +143,14 @@ public:
OpenCursorHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aLeftKey,
const Key& aRightKey,
PRUint16 aKeyRangeFlags,
const Key& aLowerKey,
const Key& aUpperKey,
PRBool aLowerOpen,
PRBool aUpperOpen,
PRUint16 aDirection)
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex),
mLeftKey(aLeftKey), mRightKey(aRightKey), mKeyRangeFlags(aKeyRangeFlags),
mDirection(aDirection)
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
mUpperOpen(aUpperOpen), mDirection(aDirection)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -164,9 +165,10 @@ public:
private:
// In-params.
nsRefPtr<IDBIndex> mIndex;
const Key mLeftKey;
const Key mRightKey;
const PRUint16 mKeyRangeFlags;
const Key mLowerKey;
const Key mUpperKey;
const PRPackedBool mLowerOpen;
const PRPackedBool mUpperOpen;
const PRUint16 mDirection;
// Out-params.
@ -179,13 +181,14 @@ public:
OpenObjectCursorHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aLeftKey,
const Key& aRightKey,
PRUint16 aKeyRangeFlags,
const Key& aLowerKey,
const Key& aUpperKey,
PRBool aLowerOpen,
PRBool aUpperOpen,
PRUint16 aDirection)
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex),
mLeftKey(aLeftKey), mRightKey(aRightKey), mKeyRangeFlags(aKeyRangeFlags),
mDirection(aDirection)
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
mUpperOpen(aUpperOpen), mDirection(aDirection)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -200,9 +203,10 @@ public:
private:
// In-params.
nsRefPtr<IDBIndex> mIndex;
const Key mLeftKey;
const Key mRightKey;
const PRUint16 mKeyRangeFlags;
const Key mLowerKey;
const Key mUpperKey;
const PRPackedBool mLowerOpen;
const PRPackedBool mUpperOpen;
const PRUint16 mDirection;
// Out-params.
@ -477,24 +481,27 @@ IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
}
nsresult rv;
Key leftKey, rightKey;
PRUint16 keyRangeFlags = 0;
Key lowerKey, upperKey;
PRBool lowerOpen = PR_FALSE, upperOpen = PR_FALSE;
if (aKeyRange) {
rv = aKeyRange->GetFlags(&keyRangeFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIVariant> variant;
rv = aKeyRange->GetLeft(getter_AddRefs(variant));
rv = aKeyRange->GetLower(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = IDBObjectStore::GetKeyFromVariant(variant, leftKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = aKeyRange->GetRight(getter_AddRefs(variant));
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = IDBObjectStore::GetKeyFromVariant(variant, rightKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
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);
}
@ -514,8 +521,8 @@ IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<OpenCursorHelper> helper =
new OpenCursorHelper(transaction, request, this, leftKey, rightKey,
keyRangeFlags, aDirection);
new OpenCursorHelper(transaction, request, this, lowerKey, upperKey,
lowerOpen, upperOpen, aDirection);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -538,24 +545,27 @@ IDBIndex::OpenObjectCursor(nsIIDBKeyRange* aKeyRange,
}
nsresult rv;
Key leftKey, rightKey;
PRUint16 keyRangeFlags = 0;
Key lowerKey, upperKey;
PRBool lowerOpen = PR_FALSE, upperOpen = PR_FALSE;
if (aKeyRange) {
rv = aKeyRange->GetFlags(&keyRangeFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIVariant> variant;
rv = aKeyRange->GetLeft(getter_AddRefs(variant));
rv = aKeyRange->GetLower(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = IDBObjectStore::GetKeyFromVariant(variant, leftKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = aKeyRange->GetRight(getter_AddRefs(variant));
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = IDBObjectStore::GetKeyFromVariant(variant, rightKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
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);
}
@ -575,8 +585,8 @@ IDBIndex::OpenObjectCursor(nsIIDBKeyRange* aKeyRange,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<OpenObjectCursorHelper> helper =
new OpenObjectCursorHelper(transaction, request, this, leftKey, rightKey,
keyRangeFlags, aDirection);
new OpenObjectCursorHelper(transaction, request, this, lowerKey, upperKey,
lowerOpen, upperOpen, aDirection);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1008,25 +1018,23 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_NAMED_LITERAL_CSTRING(rightKeyName, "right_key");
nsCAutoString keyRangeClause;
if (!mLeftKey.IsUnset()) {
if (!mLowerKey.IsUnset()) {
keyRangeClause = NS_LITERAL_CSTRING(" AND value");
if (mKeyRangeFlags & nsIIDBKeyRange::LEFT_OPEN) {
if (mLowerOpen) {
keyRangeClause.AppendLiteral(" > :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::LEFT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" >= :");
}
keyRangeClause.Append(leftKeyName);
}
if (!mRightKey.IsUnset()) {
if (!mUpperKey.IsUnset()) {
keyRangeClause.AppendLiteral(" AND value");
if (mKeyRangeFlags & nsIIDBKeyRange::RIGHT_OPEN) {
if (mUpperOpen) {
keyRangeClause.AppendLiteral(" < :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::RIGHT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" <= :");
}
keyRangeClause.Append(rightKeyName);
@ -1077,12 +1085,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mLeftKey.IsUnset()) {
if (mLeftKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLeftKey.StringValue());
if (!mLowerKey.IsUnset()) {
if (mLowerKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLowerKey.StringValue());
}
else if (mLeftKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLeftKey.IntValue());
else if (mLowerKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLowerKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -1090,12 +1098,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
if (!mRightKey.IsUnset()) {
if (mRightKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mRightKey.StringValue());
if (!mUpperKey.IsUnset()) {
if (mUpperKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mUpperKey.StringValue());
}
else if (mRightKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mRightKey.IntValue());
else if (mUpperKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mUpperKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -1215,25 +1223,23 @@ OpenObjectCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_NAMED_LITERAL_CSTRING(data, "data");
nsCAutoString keyRangeClause;
if (!mLeftKey.IsUnset()) {
if (!mLowerKey.IsUnset()) {
keyRangeClause = NS_LITERAL_CSTRING(" AND value");
if (mKeyRangeFlags & nsIIDBKeyRange::LEFT_OPEN) {
if (mLowerOpen) {
keyRangeClause.AppendLiteral(" > :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::LEFT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" >= :");
}
keyRangeClause.Append(leftKeyName);
}
if (!mRightKey.IsUnset()) {
if (!mUpperKey.IsUnset()) {
keyRangeClause += NS_LITERAL_CSTRING(" AND value");
if (mKeyRangeFlags & nsIIDBKeyRange::RIGHT_OPEN) {
if (mUpperOpen) {
keyRangeClause.AppendLiteral(" < :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::RIGHT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" <= :");
}
keyRangeClause.Append(rightKeyName);
@ -1294,12 +1300,12 @@ OpenObjectCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mLeftKey.IsUnset()) {
if (mLeftKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLeftKey.StringValue());
if (!mLowerKey.IsUnset()) {
if (mLowerKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLowerKey.StringValue());
}
else if (mLeftKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLeftKey.IntValue());
else if (mLowerKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLowerKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -1307,12 +1313,12 @@ OpenObjectCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
if (!mRightKey.IsUnset()) {
if (mRightKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mRightKey.StringValue());
if (!mUpperKey.IsUnset()) {
if (mUpperKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mUpperKey.StringValue());
}
else if (mRightKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mRightKey.IntValue());
else if (mUpperKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mUpperKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");

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

@ -39,21 +39,262 @@
#include "IDBKeyRange.h"
#include "nsIXPConnect.h"
#include "jscntxt.h"
#include "nsDOMClassInfo.h"
#include "nsJSUtils.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
#include "Key.h"
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 (!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)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aCx, "Null pointer!");
NS_ASSERTION(aVp, "Null pointer!");
NS_ASSERTION(aKeyRange, "Null pointer!");
nsIXPConnect* xpc = nsContentUtils::XPConnect();
NS_ASSERTION(xpc, "This should never be null!");
JSObject* global = JS_GetGlobalForObject(aCx, JS_GetScopeChain(aCx));
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 JS_FALSE;
}
JSObject* result;
if (NS_FAILED(holder->GetJSObject(&result))) {
JS_ReportError(aCx, "Couldn't get JSObject from wrapper.");
return JS_FALSE;
}
JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(result));
return JS_TRUE;
}
JSBool
MakeOnlyKeyRange(JSContext* aCx,
uintN aArgc,
jsval* aVp)
{
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], PR_FALSE, PR_FALSE);
NS_ASSERTION(range, "Out of memory?");
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return JS_TRUE;
}
JSBool
MakeLowerBoundKeyRange(JSContext* aCx,
uintN aArgc,
jsval* aVp)
{
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;
}
nsRefPtr<IDBKeyRange> range =
IDBKeyRange::Create(keys[0], nsnull, !!open, PR_TRUE);
NS_ASSERTION(range, "Out of memory?");
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return JS_TRUE;
}
JSBool
MakeUpperBoundKeyRange(JSContext* aCx,
uintN aArgc,
jsval* aVp)
{
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;
}
nsRefPtr<IDBKeyRange> range =
IDBKeyRange::Create(nsnull, keys[0], PR_TRUE, !!open);
NS_ASSERTION(range, "Out of memory?");
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return JS_TRUE;
}
JSBool
MakeBoundKeyRange(JSContext* aCx,
uintN aArgc,
jsval* aVp)
{
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;
}
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> range =
IDBKeyRange::Create(keys[0], keys[1], lowerOpen, upperOpen);
NS_ASSERTION(range, "Out of memory?");
if (!ReturnKeyRange(aCx, aVp, range)) {
return JS_FALSE;
}
return JS_TRUE;
}
#define KEYRANGE_FUNCTION_FLAGS (JSPROP_ENUMERATE | JSPROP_PERMANENT)
const JSFunctionSpec gKeyRangeConstructors[] = {
JS_FN("only", MakeOnlyKeyRange, 1, KEYRANGE_FUNCTION_FLAGS),
JS_FN("lowerBound", MakeLowerBoundKeyRange, 1, KEYRANGE_FUNCTION_FLAGS),
JS_FN("upperBound", MakeUpperBoundKeyRange, 1, KEYRANGE_FUNCTION_FLAGS),
JS_FN("bound", MakeBoundKeyRange, 2, KEYRANGE_FUNCTION_FLAGS),
JS_FS_END
};
#undef KEYRANGE_FUNCTION_FLAGS
} // anonymous namespace
// static
JSBool
IDBKeyRange::DefineConstructors(JSContext* aCx,
JSObject* aObject)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aCx, "Null pointer!");
NS_ASSERTION(aObject, "Null pointer!");
// Add the constructor methods for key ranges.
return JS_DefineFunctions(aCx, aObject,
const_cast<JSFunctionSpec*>(gKeyRangeConstructors));
}
// static
already_AddRefed<IDBKeyRange>
IDBKeyRange::Create(nsIVariant* aLeft,
nsIVariant* aRight,
PRUint16 aFlags)
IDBKeyRange::Create(nsIVariant* aLower,
nsIVariant* aUpper,
PRBool aLowerOpen,
PRBool aUpperOpen)
{
nsRefPtr<IDBKeyRange> keyRange(new IDBKeyRange());
keyRange->mLeft = aLeft;
keyRange->mRight = aRight;
keyRange->mFlags = aFlags;
keyRange->mLower = aLower;
keyRange->mUpper = aUpper;
keyRange->mLowerOpen = aLowerOpen;
keyRange->mUpperOpen = aUpperOpen;
return keyRange.forget();
}
@ -70,30 +311,40 @@ NS_INTERFACE_MAP_END
DOMCI_DATA(IDBKeyRange, IDBKeyRange)
NS_IMETHODIMP
IDBKeyRange::GetFlags(PRUint16* aFlags)
IDBKeyRange::GetLower(nsIVariant** aLower)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
*aFlags = mFlags;
nsCOMPtr<nsIVariant> result(mLower);
result.forget(aLower);
return NS_OK;
}
NS_IMETHODIMP
IDBKeyRange::GetLeft(nsIVariant** aLeft)
IDBKeyRange::GetUpper(nsIVariant** aUpper)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIVariant> result(mLeft);
result.forget(aLeft);
nsCOMPtr<nsIVariant> result(mUpper);
result.forget(aUpper);
return NS_OK;
}
NS_IMETHODIMP
IDBKeyRange::GetRight(nsIVariant** aRight)
IDBKeyRange::GetLowerOpen(PRBool* aLowerOpen)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIVariant> result(mRight);
result.forget(aRight);
*aLowerOpen = mLowerOpen ? PR_TRUE : PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
IDBKeyRange::GetUpperOpen(PRBool* aUpperOpen)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
*aUpperOpen = mUpperOpen ? PR_TRUE : PR_FALSE;
return NS_OK;
}

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

@ -47,31 +47,32 @@
BEGIN_INDEXEDDB_NAMESPACE
class IDBFactory;
class IDBKeyRange : public nsIIDBKeyRange
{
friend class IDBFactory;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIDBKEYRANGE
protected:
static
already_AddRefed<IDBKeyRange> Create(nsIVariant* aLeft,
nsIVariant* aRight,
PRUint16 aFlags);
static JSBool DefineConstructors(JSContext* aCx,
JSObject* aObject);
static
already_AddRefed<IDBKeyRange> Create(nsIVariant* aLower,
nsIVariant* aUpper,
PRBool aLowerOpen,
PRBool aUpperOpen);
protected:
IDBKeyRange()
: mFlags(0)
: mLowerOpen(PR_FALSE), mUpperOpen(PR_FALSE)
{ }
~IDBKeyRange() { }
nsCOMPtr<nsIVariant> mLeft;
nsCOMPtr<nsIVariant> mRight;
PRUint16 mFlags;
nsCOMPtr<nsIVariant> mLower;
nsCOMPtr<nsIVariant> mUpper;
PRPackedBool mLowerOpen;
PRPackedBool mUpperOpen;
};
END_INDEXEDDB_NAMESPACE

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

@ -177,13 +177,14 @@ public:
OpenCursorHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBObjectStore* aObjectStore,
const Key& aLeftKey,
const Key& aRightKey,
PRUint16 aKeyRangeFlags,
const Key& aLowerKey,
const Key& aUpperKey,
PRBool aLowerOpen,
PRBool aUpperOpen,
PRUint16 aDirection)
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
mLeftKey(aLeftKey), mRightKey(aRightKey), mKeyRangeFlags(aKeyRangeFlags),
mDirection(aDirection)
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
mUpperOpen(aUpperOpen), mDirection(aDirection)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -198,9 +199,10 @@ public:
private:
// In-params.
nsRefPtr<IDBObjectStore> mObjectStore;
const Key mLeftKey;
const Key mRightKey;
const PRUint16 mKeyRangeFlags;
const Key mLowerKey;
const Key mUpperKey;
const PRPackedBool mLowerOpen;
const PRPackedBool mUpperOpen;
const PRUint16 mDirection;
// Out-params.
@ -267,13 +269,14 @@ public:
GetAllHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBObjectStore* aObjectStore,
const Key& aLeftKey,
const Key& aRightKey,
const PRUint16 aKeyRangeFlags,
const Key& aLowerKey,
const Key& aUpperKey,
const PRBool aLowerOpen,
const PRBool aUpperOpen,
const PRUint32 aLimit)
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
mLeftKey(aLeftKey), mRightKey(aRightKey), mKeyRangeFlags(aKeyRangeFlags),
mLimit(aLimit)
mLowerKey(aLowerKey), mUpperKey(aUpperKey), mLowerOpen(aLowerOpen),
mUpperOpen(aUpperOpen), mLimit(aLimit)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -288,9 +291,10 @@ public:
protected:
// In-params.
nsRefPtr<IDBObjectStore> mObjectStore;
const Key mLeftKey;
const Key mRightKey;
const PRUint16 mKeyRangeFlags;
const Key mLowerKey;
const Key mUpperKey;
const PRPackedBool mLowerOpen;
const PRPackedBool mUpperOpen;
const PRUint32 mLimit;
private:
@ -952,25 +956,28 @@ IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
aLimit = PR_UINT32_MAX;
}
Key leftKey, rightKey;
PRUint16 keyRangeFlags = 0;
nsresult rv;
Key lowerKey, upperKey;
PRBool lowerOpen = PR_FALSE, upperOpen = PR_FALSE;
if (aKeyRange) {
rv = aKeyRange->GetFlags(&keyRangeFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIVariant> variant;
rv = aKeyRange->GetLeft(getter_AddRefs(variant));
rv = aKeyRange->GetLower(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = GetKeyFromVariant(variant, leftKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = aKeyRange->GetRight(getter_AddRefs(variant));
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = GetKeyFromVariant(variant, rightKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
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);
}
@ -978,8 +985,8 @@ IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetAllHelper> helper =
new GetAllHelper(mTransaction, request, this, leftKey, rightKey,
keyRangeFlags, aLimit);
new GetAllHelper(mTransaction, request, this, lowerKey, upperKey, lowerOpen,
upperOpen, aLimit);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1148,25 +1155,27 @@ IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
}
nsresult rv;
Key leftKey, rightKey;
PRUint16 keyRangeFlags = 0;
Key lowerKey, upperKey;
PRBool lowerOpen = PR_FALSE, upperOpen = PR_FALSE;
if (aKeyRange) {
rv = aKeyRange->GetFlags(&keyRangeFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIVariant> variant;
rv = aKeyRange->GetLeft(getter_AddRefs(variant));
rv = aKeyRange->GetLower(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = GetKeyFromVariant(variant, leftKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, lowerKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = aKeyRange->GetRight(getter_AddRefs(variant));
rv = aKeyRange->GetUpper(getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = GetKeyFromVariant(variant, rightKey);
rv = IDBObjectStore::GetKeyFromVariant(variant, upperKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
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);
}
@ -1186,8 +1195,8 @@ IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<OpenCursorHelper> helper =
new OpenCursorHelper(mTransaction, request, this, leftKey, rightKey,
keyRangeFlags, aDirection);
new OpenCursorHelper(mTransaction, request, this, lowerKey, upperKey,
lowerOpen, upperOpen, aDirection);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1818,25 +1827,23 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_NAMED_LITERAL_CSTRING(rightKeyName, "right_key");
nsCAutoString keyRangeClause;
if (!mLeftKey.IsUnset()) {
if (!mLowerKey.IsUnset()) {
keyRangeClause = NS_LITERAL_CSTRING(" AND ") + keyColumn;
if (mKeyRangeFlags & nsIIDBKeyRange::LEFT_OPEN) {
if (mLowerOpen) {
keyRangeClause.AppendLiteral(" > :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::LEFT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" >= :");
}
keyRangeClause.Append(leftKeyName);
}
if (!mRightKey.IsUnset()) {
if (!mUpperKey.IsUnset()) {
keyRangeClause += NS_LITERAL_CSTRING(" AND ") + keyColumn;
if (mKeyRangeFlags & nsIIDBKeyRange::RIGHT_OPEN) {
if (mUpperOpen) {
keyRangeClause.AppendLiteral(" < :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::RIGHT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" <= :");
}
keyRangeClause.Append(rightKeyName);
@ -1877,12 +1884,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mLeftKey.IsUnset()) {
if (mLeftKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLeftKey.StringValue());
if (!mLowerKey.IsUnset()) {
if (mLowerKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLowerKey.StringValue());
}
else if (mLeftKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLeftKey.IntValue());
else if (mLowerKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLowerKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -1890,12 +1897,12 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
if (!mRightKey.IsUnset()) {
if (mRightKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mRightKey.StringValue());
if (!mUpperKey.IsUnset()) {
if (mUpperKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mUpperKey.StringValue());
}
else if (mRightKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mRightKey.IntValue());
else if (mUpperKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mUpperKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -2184,25 +2191,23 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_NAMED_LITERAL_CSTRING(rightKeyName, "right_key");
nsCAutoString keyRangeClause;
if (!mLeftKey.IsUnset()) {
if (!mLowerKey.IsUnset()) {
keyRangeClause = NS_LITERAL_CSTRING(" AND ") + keyColumn;
if (mKeyRangeFlags & nsIIDBKeyRange::LEFT_OPEN) {
if (mLowerOpen) {
keyRangeClause.AppendLiteral(" > :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::LEFT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" >= :");
}
keyRangeClause.Append(leftKeyName);
}
if (!mRightKey.IsUnset()) {
if (!mUpperKey.IsUnset()) {
keyRangeClause += NS_LITERAL_CSTRING(" AND ") + keyColumn;
if (mKeyRangeFlags & nsIIDBKeyRange::RIGHT_OPEN) {
if (mUpperOpen) {
keyRangeClause.AppendLiteral(" < :");
}
else {
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::RIGHT_BOUND, "Bad flags!");
keyRangeClause.AppendLiteral(" <= :");
}
keyRangeClause.Append(rightKeyName);
@ -2232,12 +2237,12 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mLeftKey.IsUnset()) {
if (mLeftKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLeftKey.StringValue());
if (!mLowerKey.IsUnset()) {
if (mLowerKey.IsString()) {
rv = stmt->BindStringByName(leftKeyName, mLowerKey.StringValue());
}
else if (mLeftKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLeftKey.IntValue());
else if (mLowerKey.IsInt()) {
rv = stmt->BindInt64ByName(leftKeyName, mLowerKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");
@ -2245,12 +2250,12 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
if (!mRightKey.IsUnset()) {
if (mRightKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mRightKey.StringValue());
if (!mUpperKey.IsUnset()) {
if (mUpperKey.IsString()) {
rv = stmt->BindStringByName(rightKeyName, mUpperKey.StringValue());
}
else if (mRightKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mRightKey.IntValue());
else if (mUpperKey.IsInt()) {
rv = stmt->BindInt64ByName(rightKeyName, mUpperKey.IntValue());
}
else {
NS_NOTREACHED("Bad key!");

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

@ -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"
@ -56,162 +57,6 @@ struct ObjectStoreInfo;
struct IndexInfo;
struct IndexUpdateInfo;
class Key
{
public:
enum Type { UNSETKEY, NULLKEY, 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 || aType == NULLKEY,
"Use one of the other operators to assign your value!");
mType = aType;
mString.Truncate();
mInt = 0;
return *this;
}
Key& operator=(const nsAString& aString)
{
mType = STRINGKEY;
mString = aString;
mInt = 0;
return *this;
}
Key& operator=(PRInt64 aInt)
{
mType = INTKEY;
mString.Truncate();
mInt = aInt;
return *this;
}
bool operator==(const Key& aOther) const
{
if (mType == aOther.mType) {
switch (mType) {
case UNSETKEY:
case NULLKEY:
return true;
case STRINGKEY:
return mString == aOther.mString;
case INTKEY:
return mInt == aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
}
}
return false;
}
bool operator!=(const Key& aOther) const
{
return !(*this == aOther);
}
bool operator<(const Key& aOther) const
{
switch (mType) {
case UNSETKEY:
if (aOther.mType == UNSETKEY) {
return false;
}
return true;
case NULLKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY) {
return false;
}
return true;
case STRINGKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY ||
aOther.mType == INTKEY) {
return false;
}
NS_ASSERTION(aOther.mType == STRINGKEY, "Unknown type!");
return mString < aOther.mString;
case INTKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY) {
return false;
}
if (aOther.mType == STRINGKEY) {
return true;
}
NS_ASSERTION(aOther.mType == INTKEY, "Unknown type!");
return mInt < aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
}
return false;
}
bool operator>(const Key& aOther) const
{
return !(*this == aOther || *this < aOther);
}
bool IsUnset() const { return mType == UNSETKEY; }
bool IsNull() const { return mType == NULLKEY; }
bool IsString() const { return mType == STRINGKEY; }
bool IsInt() const { return mType == INTKEY; }
const nsString& StringValue() const {
NS_ASSERTION(IsString(), "Wrong type!");
return mString;
}
PRInt64 IntValue() const {
NS_ASSERTION(IsInt(), "Wrong type!");
return mInt;
}
nsAString& ToString() {
mType = STRINGKEY;
mInt = 0;
return mString;
}
PRInt64* ToIntPtr() {
mType = INTKEY;
mString.Truncate();
return &mInt;
}
private:
Type mType;
nsString mString;
PRInt64 mInt;
};
class IDBObjectStore : public nsDOMEventTargetHelper,
public nsIIDBObjectStore
{

211
dom/indexedDB/Key.h Normal file
Просмотреть файл

@ -0,0 +1,211 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Indexed Database.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Turner <bent.mozilla@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_dom_indexeddb_key_h__
#define mozilla_dom_indexeddb_key_h__
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
BEGIN_INDEXEDDB_NAMESPACE
class Key
{
public:
enum Type { UNSETKEY, NULLKEY, 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 || aType == NULLKEY,
"Use one of the other operators to assign your value!");
mType = aType;
mString.Truncate();
mInt = 0;
return *this;
}
Key& operator=(const nsAString& aString)
{
mType = STRINGKEY;
mString = aString;
mInt = 0;
return *this;
}
Key& operator=(PRInt64 aInt)
{
mType = INTKEY;
mString.Truncate();
mInt = aInt;
return *this;
}
bool operator==(const Key& aOther) const
{
if (mType == aOther.mType) {
switch (mType) {
case UNSETKEY:
case NULLKEY:
return true;
case STRINGKEY:
return mString == aOther.mString;
case INTKEY:
return mInt == aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
}
}
return false;
}
bool operator!=(const Key& aOther) const
{
return !(*this == aOther);
}
bool operator<(const Key& aOther) const
{
switch (mType) {
case UNSETKEY:
if (aOther.mType == UNSETKEY) {
return false;
}
return true;
case NULLKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY) {
return false;
}
return true;
case STRINGKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY ||
aOther.mType == INTKEY) {
return false;
}
NS_ASSERTION(aOther.mType == STRINGKEY, "Unknown type!");
return mString < aOther.mString;
case INTKEY:
if (aOther.mType == UNSETKEY ||
aOther.mType == NULLKEY) {
return false;
}
if (aOther.mType == STRINGKEY) {
return true;
}
NS_ASSERTION(aOther.mType == INTKEY, "Unknown type!");
return mInt < aOther.mInt;
default:
NS_NOTREACHED("Unknown type!");
}
return false;
}
bool operator>(const Key& aOther) const
{
return !(*this == aOther || *this < aOther);
}
bool IsUnset() const { return mType == UNSETKEY; }
bool IsNull() const { return mType == NULLKEY; }
bool IsString() const { return mType == STRINGKEY; }
bool IsInt() const { return mType == INTKEY; }
const nsString& StringValue() const {
NS_ASSERTION(IsString(), "Wrong type!");
return mString;
}
PRInt64 IntValue() const {
NS_ASSERTION(IsInt(), "Wrong type!");
return mInt;
}
nsAString& ToString() {
mType = STRINGKEY;
mInt = 0;
return mString;
}
PRInt64* ToIntPtr() {
mType = INTKEY;
mString.Truncate();
return &mInt;
}
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);
}
private:
Type mType;
nsString mString;
PRInt64 mInt;
};
END_INDEXEDDB_NAMESPACE
#endif /* mozilla_dom_indexeddb_key_h__ */

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

@ -82,6 +82,7 @@ EXPORTS_mozilla/dom/indexedDB = \
IndexedDatabase.h \
IndexedDatabaseManager.h \
IDBFactory.h \
Key.h \
LazyIdleThread.h \
$(NULL)

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

@ -53,27 +53,10 @@ interface nsIVariant;
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
* for more information.
*/
[scriptable, uuid(ee8c8813-e91a-494f-88f1-9f3e7de50466)]
[scriptable, uuid(137d17a5-fac5-4788-87b5-bc3806d7cfaf)]
interface nsIIDBFactory : nsISupports
{
[implicit_jscontext]
nsIIDBRequest
open(in AString name);
nsIIDBKeyRange
makeSingleKeyRange(in nsIVariant value);
nsIIDBKeyRange
makeLeftBoundKeyRange(in nsIVariant bound,
[optional /* false */] in boolean open);
nsIIDBKeyRange
makeRightBoundKeyRange(in nsIVariant bound,
[optional /* false */] in boolean open);
nsIIDBKeyRange
makeBoundKeyRange(in nsIVariant left,
in nsIVariant right,
[optional /* false */] in boolean openLeft,
[optional /* false */] in boolean openRight);
};

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

@ -46,15 +46,11 @@ interface nsIVariant;
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBKeyRange for more
* information.
*/
[scriptable, uuid(8e6b05f4-2358-420b-a6fd-03416543ed18)]
[scriptable, uuid(a1505e41-7e48-4542-9fa5-3f2c98233567)]
interface nsIIDBKeyRange : nsISupports
{
const unsigned short LEFT_OPEN = 1 << 1;
const unsigned short RIGHT_OPEN = 1 << 2;
const unsigned short LEFT_BOUND = 1 << 3;
const unsigned short RIGHT_BOUND = 1 << 4;
readonly attribute unsigned short flags;
readonly attribute nsIVariant left;
readonly attribute nsIVariant right;
readonly attribute nsIVariant lower;
readonly attribute nsIVariant upper;
readonly attribute boolean lowerOpen;
readonly attribute boolean upperOpen;
};

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

@ -121,7 +121,7 @@
keyIndex = 4;
let range = moz_indexedDB.makeBoundKeyRange(2000, "q");
let range = IDBKeyRange.bound(2000, "q");
request = objectStore.openCursor(range);
request.onerror = errorHandler;
request.onsuccess = function (event) {

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

@ -77,7 +77,7 @@
is(event.result[i], values[i], "Same value");
}
let keyRange = moz_indexedDB.makeBoundKeyRange(1, 9);
let keyRange = IDBKeyRange.bound(1, 9);
request = db.transaction("foo").objectStore("foo").getAll(keyRange);
request.onerror = errorHandler;
@ -91,7 +91,7 @@
is(event.result[i], values[i], "Same value");
}
keyRange = moz_indexedDB.makeBoundKeyRange(4, 7);
keyRange = IDBKeyRange.bound(4, 7);
request = db.transaction("foo").objectStore("foo").getAll(keyRange);
request.onerror = errorHandler;
@ -105,7 +105,7 @@
is(event.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = moz_indexedDB.makeBoundKeyRange(4, 7);
keyRange = IDBKeyRange.bound(4, 7);
request = db.transaction("foo").objectStore("foo").getAll(keyRange, 2);
request.onerror = errorHandler;
@ -119,7 +119,7 @@
is(event.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = moz_indexedDB.makeBoundKeyRange(4, 7);
keyRange = IDBKeyRange.bound(4, 7);
request = db.transaction("foo").objectStore("foo").getAll(keyRange, 50);
request.onerror = errorHandler;
@ -133,7 +133,7 @@
is(event.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = moz_indexedDB.makeBoundKeyRange(4, 7);
keyRange = IDBKeyRange.bound(4, 7);
request = db.transaction("foo").objectStore("foo").getAll(keyRange, 0);
request.onerror = errorHandler;
@ -143,7 +143,7 @@
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 0, "Correct length");
keyRange = moz_indexedDB.makeBoundKeyRange(4, 7, true, true);
keyRange = IDBKeyRange.bound(4, 7, true, true);
request = db.transaction("foo").objectStore("foo").getAll(keyRange);
request.onerror = errorHandler;

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

@ -243,7 +243,7 @@
is(keyIndex, -1, "Saw all the expected keys");
keyIndex = 1;
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron");
let keyRange = IDBKeyRange.bound("Bob", "Ron");
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -267,7 +267,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 2;
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true);
let keyRange = IDBKeyRange.bound("Bob", "Ron", true);
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -291,7 +291,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 1;
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", false, true);
let keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -315,7 +315,7 @@
is(keyIndex, 4, "Saw all the expected keys");
keyIndex = 2;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true, true);
keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -339,7 +339,7 @@
is(keyIndex, 4, "Saw all the expected keys");
keyIndex = 1;
keyRange = moz_indexedDB.makeLeftBoundKeyRange("Bob");
keyRange = IDBKeyRange.lowerBound("Bob");
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -363,7 +363,7 @@
is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
keyIndex = 2;
keyRange = moz_indexedDB.makeLeftBoundKeyRange("Bob", true);
keyRange = IDBKeyRange.lowerBound("Bob", true);
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -387,7 +387,7 @@
is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
keyIndex = 0;
keyRange = moz_indexedDB.makeRightBoundKeyRange("Joe");
keyRange = IDBKeyRange.upperBound("Joe");
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -411,7 +411,7 @@
is(keyIndex, 3, "Saw all the expected keys");
keyIndex = 0;
keyRange = moz_indexedDB.makeRightBoundKeyRange("Joe", true);
keyRange = IDBKeyRange.upperBound("Joe", true);
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -435,7 +435,7 @@
is(keyIndex, 2, "Saw all the expected keys");
keyIndex = 3;
keyRange = moz_indexedDB.makeSingleKeyRange("Pat");
keyRange = IDBKeyRange.only("Pat");
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
@ -551,7 +551,7 @@
is(keyIndex, -1, "Saw all the expected keys");
keyIndex = 1;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron");
keyRange = IDBKeyRange.bound("Bob", "Ron");
request = objectStore.index("name").openObjectCursor(keyRange);
request.onerror = errorHandler;
@ -598,7 +598,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 2;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true);
keyRange = IDBKeyRange.bound("Bob", "Ron", true);
request = objectStore.index("name").openObjectCursor(keyRange);
request.onerror = errorHandler;
@ -645,7 +645,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 1;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", false, true);
keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
request = objectStore.index("name").openObjectCursor(keyRange);
request.onerror = errorHandler;
@ -692,7 +692,7 @@
is(keyIndex, 4, "Saw all the expected keys");
keyIndex = 2;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true, true);
keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
request = objectStore.index("name").openObjectCursor(keyRange);
request.onerror = errorHandler;
@ -739,7 +739,7 @@
is(keyIndex, 4, "Saw all the expected keys");
keyIndex = 4;
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron");
keyRange = IDBKeyRange.bound("Bob", "Ron");
request = objectStore.index("name").openObjectCursor(keyRange, PREV);
request.onerror = errorHandler;
@ -787,7 +787,7 @@
// Test NEXT_NO_DUPLICATE
keyIndex = 3;
keyRange = moz_indexedDB.makeSingleKeyRange(65);
keyRange = IDBKeyRange.only(65);
request = objectStore.index("height").openCursor(keyRange, NEXT);
request.onerror = errorHandler;
@ -811,7 +811,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 4;
keyRange = moz_indexedDB.makeSingleKeyRange(65);
keyRange = IDBKeyRange.only(65);
request = objectStore.index("height").openCursor(keyRange,
NEXT_NO_DUPLICATE);
@ -864,7 +864,7 @@
// Test NEXT_NO_DUPLICATE
keyIndex = 3;
keyRange = moz_indexedDB.makeSingleKeyRange(65);
keyRange = IDBKeyRange.only(65);
request = objectStore.index("height").openObjectCursor(keyRange, NEXT);
request.onerror = errorHandler;
@ -896,7 +896,7 @@
is(keyIndex, 5, "Saw all the expected keys");
keyIndex = 4;
keyRange = moz_indexedDB.makeSingleKeyRange(65);
keyRange = IDBKeyRange.only(65);
request = objectStore.index("height").openObjectCursor(keyRange,
NEXT_NO_DUPLICATE);