mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-01 05:43:46 +00:00
Add keyrange support for index cursors
This commit is contained in:
parent
4a719c39a8
commit
d1b409e700
@ -241,9 +241,26 @@ IDBIndexRequest::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
Key leftKey, rightKey;
|
||||
PRUint16 keyRangeFlags = 0;
|
||||
|
||||
if (aKeyRange) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
rv = aKeyRange->GetFlags(&keyRangeFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
rv = aKeyRange->GetLeft(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStoreRequest::GetKeyFromVariant(variant, leftKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aKeyRange->GetRight(getter_AddRefs(variant));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = IDBObjectStoreRequest::GetKeyFromVariant(variant, rightKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (aOptionalArgCount >= 2) {
|
||||
@ -274,10 +291,10 @@ IDBIndexRequest::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
|
||||
nsRefPtr<OpenCursorHelper> helper =
|
||||
new OpenCursorHelper(mObjectStore->Transaction(), request, this, mId,
|
||||
mUnique, mAutoIncrement, Key(), Key(), 0, aDirection,
|
||||
aPreload);
|
||||
mUnique, mAutoIncrement, leftKey, rightKey,
|
||||
keyRangeFlags, aDirection, aPreload);
|
||||
|
||||
nsresult rv = helper->DispatchToTransactionPool();
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
request.forget(_retval);
|
||||
@ -516,6 +533,33 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
|
||||
NS_NAMED_LITERAL_CSTRING(leftKeyName, "left_key");
|
||||
NS_NAMED_LITERAL_CSTRING(rightKeyName, "right_key");
|
||||
|
||||
nsCAutoString keyRangeClause;
|
||||
if (!mLeftKey.IsUnset()) {
|
||||
keyRangeClause.AppendLiteral(" AND value");
|
||||
if (mKeyRangeFlags & nsIIDBKeyRange::LEFT_OPEN) {
|
||||
keyRangeClause.AppendLiteral(" > :");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::LEFT_BOUND, "Bad flags!");
|
||||
keyRangeClause.AppendLiteral(" >= :");
|
||||
}
|
||||
keyRangeClause.Append(leftKeyName);
|
||||
}
|
||||
|
||||
if (!mRightKey.IsUnset()) {
|
||||
keyRangeClause.AppendLiteral(" AND value");
|
||||
if (mKeyRangeFlags & nsIIDBKeyRange::RIGHT_OPEN) {
|
||||
keyRangeClause.AppendLiteral(" < :");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(mKeyRangeFlags & nsIIDBKeyRange::RIGHT_BOUND, "Bad flags!");
|
||||
keyRangeClause.AppendLiteral(" <= :");
|
||||
}
|
||||
keyRangeClause.Append(rightKeyName);
|
||||
}
|
||||
|
||||
nsCAutoString query("SELECT value, ");
|
||||
query.Append(keyColumn);
|
||||
@ -523,6 +567,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
query.Append(table);
|
||||
query.AppendLiteral(" WHERE index_id = :");
|
||||
query.Append(indexId);
|
||||
query.Append(keyRangeClause);
|
||||
query.AppendLiteral(" ORDER BY value ");
|
||||
|
||||
switch (mDirection) {
|
||||
@ -551,6 +596,32 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsresult rv = stmt->BindInt64ByName(indexId, mId);
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
||||
if (!mLeftKey.IsUnset()) {
|
||||
if (mLeftKey.IsString()) {
|
||||
rv = stmt->BindStringByName(leftKeyName, mLeftKey.StringValue());
|
||||
}
|
||||
else if (mLeftKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(leftKeyName, mLeftKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
if (!mRightKey.IsUnset()) {
|
||||
if (mRightKey.IsString()) {
|
||||
rv = stmt->BindStringByName(rightKeyName, mRightKey.StringValue());
|
||||
}
|
||||
else if (mRightKey.IsInt()) {
|
||||
rv = stmt->BindInt64ByName(rightKeyName, mRightKey.IntValue());
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Bad key!");
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
PRBool hasResult;
|
||||
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
if (mData.Capacity() == mData.Length()) {
|
||||
@ -620,5 +691,7 @@ OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
||||
|
||||
aResult->SetAsISupports(static_cast<IDBRequest::Generator*>(cursor));
|
||||
|
||||
mIndex = nsnull;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ protected:
|
||||
PRUint16 aFlags);
|
||||
|
||||
IDBKeyRange()
|
||||
: mFlags(nsIIDBKeyRange::SINGLE)
|
||||
: mFlags(0)
|
||||
{ }
|
||||
|
||||
~IDBKeyRange() { }
|
||||
|
@ -181,7 +181,7 @@ public:
|
||||
|
||||
private:
|
||||
// In-params.
|
||||
const nsRefPtr<IDBObjectStoreRequest> mObjectStore;
|
||||
nsRefPtr<IDBObjectStoreRequest> mObjectStore;
|
||||
const Key mLeftKey;
|
||||
const Key mRightKey;
|
||||
const PRUint16 mKeyRangeFlags;
|
||||
@ -1460,7 +1460,9 @@ AddHelper::UpdateIndexes(mozIStorageConnection* aConnection,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1754,6 +1756,8 @@ OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
||||
|
||||
aResult->SetAsISupports(static_cast<IDBRequest::Generator*>(cursor));
|
||||
|
||||
mObjectStore = nsnull;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -566,7 +566,8 @@ IndexedDatabaseRequest::MakeSingleKeyRange(nsIVariant* aValue,
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> range =
|
||||
IDBKeyRange::Create(aValue, aValue, PRUint16(nsIIDBKeyRange::SINGLE));
|
||||
IDBKeyRange::Create(aValue, aValue, PRUint16(nsIIDBKeyRange::LEFT_BOUND |
|
||||
nsIIDBKeyRange::RIGHT_BOUND));
|
||||
NS_ASSERTION(range, "Out of memory?");
|
||||
|
||||
range.forget(_retval);
|
||||
|
@ -49,7 +49,6 @@ interface nsIVariant;
|
||||
[scriptable, uuid(8e6b05f4-2358-420b-a6fd-03416543ed18)]
|
||||
interface nsIIDBKeyRange : nsISupports
|
||||
{
|
||||
const unsigned short SINGLE = 0;
|
||||
const unsigned short LEFT_OPEN = 1 << 1;
|
||||
const unsigned short RIGHT_OPEN = 1 << 2;
|
||||
const unsigned short LEFT_BOUND = 1 << 3;
|
||||
|
@ -232,6 +232,222 @@
|
||||
|
||||
is(keyIndex, -1, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 1;
|
||||
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron");
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 2;
|
||||
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true);
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 1;
|
||||
let keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", false, true);
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 4, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 2;
|
||||
keyRange = moz_indexedDB.makeBoundKeyRange("Bob", "Ron", true, true);
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 4, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 1;
|
||||
keyRange = moz_indexedDB.makeLeftBoundKeyRange("Bob");
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 2;
|
||||
keyRange = moz_indexedDB.makeLeftBoundKeyRange("Bob", true);
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
keyRange = moz_indexedDB.makeRightBoundKeyRange("Joe");
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 3, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
keyRange = moz_indexedDB.makeRightBoundKeyRange("Joe", true);
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 2, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 3;
|
||||
keyRange = moz_indexedDB.makeSingleKeyRange("Pat");
|
||||
|
||||
request = objectStore.index("name").openCursor(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataNameSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 4, "Saw all the expected keys");
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user