mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-28 11:28:38 +00:00
Implement NEXT_NO_DUPLICATE and PREV_NO_DUPLICATE for index cursors
This commit is contained in:
parent
1e7079f23f
commit
258defbdbe
@ -477,12 +477,6 @@ IDBIndexRequest::OpenCursor(nsIIDBKeyRange* aKeyRange,
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
if (aDirection == nsIIDBCursor::NEXT_NO_DUPLICATE ||
|
||||
aDirection == nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aPreload) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -550,12 +544,6 @@ IDBIndexRequest::OpenObjectCursor(nsIIDBKeyRange* aKeyRange,
|
||||
aDirection = nsIIDBCursor::NEXT;
|
||||
}
|
||||
|
||||
if (aDirection == nsIIDBCursor::NEXT_NO_DUPLICATE ||
|
||||
aDirection == nsIIDBCursor::PREV_NO_DUPLICATE) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aPreload) {
|
||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -1019,13 +1007,30 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
keyRangeClause.Append(rightKeyName);
|
||||
}
|
||||
|
||||
nsCString groupClause;
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
case nsIIDBCursor::PREV:
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
groupClause = NS_LITERAL_CSTRING(" GROUP BY value");
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Unknown direction!");
|
||||
}
|
||||
|
||||
nsCString directionClause;
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
directionClause = NS_LITERAL_CSTRING("DESC");
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
directionClause = NS_LITERAL_CSTRING("ASC");
|
||||
break;
|
||||
|
||||
@ -1036,8 +1041,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsCString query = NS_LITERAL_CSTRING("SELECT value, ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(" FROM ") + table +
|
||||
NS_LITERAL_CSTRING(" WHERE index_id = :") + indexId +
|
||||
keyRangeClause + NS_LITERAL_CSTRING(" ORDER BY value ") +
|
||||
directionClause;
|
||||
keyRangeClause + groupClause +
|
||||
NS_LITERAL_CSTRING(" ORDER BY value ") + directionClause;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
|
||||
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
@ -1210,13 +1215,31 @@ OpenObjectCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
keyRangeClause.Append(rightKeyName);
|
||||
}
|
||||
|
||||
nsCString groupClause;
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
case nsIIDBCursor::PREV:
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
groupClause = NS_LITERAL_CSTRING(" GROUP BY ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + value;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Unknown direction!");
|
||||
}
|
||||
|
||||
nsCString directionClause;
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
directionClause = NS_LITERAL_CSTRING(" DESC");
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
directionClause = NS_LITERAL_CSTRING(" ASC");
|
||||
break;
|
||||
|
||||
@ -1224,18 +1247,19 @@ OpenObjectCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_NOTREACHED("Unknown direction!");
|
||||
}
|
||||
|
||||
nsCAutoString query = NS_LITERAL_CSTRING("SELECT ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + value +
|
||||
NS_LITERAL_CSTRING(",") + objectTable +
|
||||
NS_LITERAL_CSTRING(".") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".object_data_id = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexId +
|
||||
NS_LITERAL_CSTRING("= :") + indexId + keyRangeClause +
|
||||
NS_LITERAL_CSTRING(" ORDER BY ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + value + directionClause;
|
||||
nsCString query = NS_LITERAL_CSTRING("SELECT ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + value +
|
||||
NS_LITERAL_CSTRING(",") + objectTable +
|
||||
NS_LITERAL_CSTRING(".") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".object_data_id = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexId +
|
||||
NS_LITERAL_CSTRING("= :") + indexId + keyRangeClause +
|
||||
groupClause + NS_LITERAL_CSTRING(" ORDER BY ") +
|
||||
indexTable + NS_LITERAL_CSTRING(".") + value +
|
||||
directionClause;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
|
||||
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||
|
@ -18,6 +18,10 @@
|
||||
const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
|
||||
const NEXT = Components.interfaces.nsIIDBCursor.NEXT;
|
||||
const PREV = Components.interfaces.nsIIDBCursor.PREV;
|
||||
const NEXT_NO_DUPLICATE =
|
||||
Components.interfaces.nsIIDBCursor.NEXT_NO_DUPLICATE;
|
||||
const PREV_NO_DUPLICATE =
|
||||
Components.interfaces.nsIIDBCursor.PREV_NO_DUPLICATE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
@ -56,6 +60,15 @@
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
const objectStoreDataHeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = moz_indexedDB.open(name, description);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
@ -775,6 +788,184 @@
|
||||
|
||||
is(keyIndex, 0, "Saw all the expected keys");
|
||||
|
||||
// Test NEXT_NO_DUPLICATE
|
||||
keyIndex = 3;
|
||||
keyRange = moz_indexedDB.makeSingleKeyRange(65);
|
||||
|
||||
request = objectStore.index("height").openCursor(keyRange, NEXT);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataHeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 4;
|
||||
keyRange = moz_indexedDB.makeSingleKeyRange(65);
|
||||
|
||||
request = objectStore.index("height").openCursor(keyRange,
|
||||
NEXT_NO_DUPLICATE);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataHeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 5;
|
||||
|
||||
request = objectStore.index("height").openCursor(null,
|
||||
PREV_NO_DUPLICATE);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value, objectStoreDataHeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
if (keyIndex == 4) {
|
||||
keyIndex--;
|
||||
}
|
||||
keyIndex--;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, -1, "Saw all the expected keys");
|
||||
|
||||
// Test NEXT_NO_DUPLICATE
|
||||
keyIndex = 3;
|
||||
keyRange = moz_indexedDB.makeSingleKeyRange(65);
|
||||
|
||||
request = objectStore.index("height").openObjectCursor(keyRange, NEXT);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
|
||||
"Correct name");
|
||||
is(cursor.value.height,
|
||||
objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct height");
|
||||
if ("weight" in cursor.value) {
|
||||
is(cursor.value.weight,
|
||||
objectStoreDataHeightSort[keyIndex].value.weight,
|
||||
"Correct weight");
|
||||
}
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 4;
|
||||
keyRange = moz_indexedDB.makeSingleKeyRange(65);
|
||||
|
||||
request = objectStore.index("height").openObjectCursor(keyRange,
|
||||
NEXT_NO_DUPLICATE);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
|
||||
"Correct name");
|
||||
is(cursor.value.height,
|
||||
objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct height");
|
||||
if ("weight" in cursor.value) {
|
||||
is(cursor.value.weight,
|
||||
objectStoreDataHeightSort[keyIndex].value.weight,
|
||||
"Correct weight");
|
||||
}
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, 5, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 5;
|
||||
|
||||
request = objectStore.index("height").openObjectCursor(null,
|
||||
PREV_NO_DUPLICATE);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct key");
|
||||
is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
|
||||
"Correct name");
|
||||
is(cursor.value.height,
|
||||
objectStoreDataHeightSort[keyIndex].value.height,
|
||||
"Correct height");
|
||||
if ("weight" in cursor.value) {
|
||||
is(cursor.value.weight,
|
||||
objectStoreDataHeightSort[keyIndex].value.weight,
|
||||
"Correct weight");
|
||||
}
|
||||
|
||||
cursor.continue();
|
||||
if (keyIndex == 4) {
|
||||
keyIndex--;
|
||||
}
|
||||
keyIndex--;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(keyIndex, -1, "Saw all the expected keys");
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user