mirror of
https://github.com/lexmount/moli.git
synced 2026-10-30 08:07:38 +00:00
fix(indexeddb): preserve first primary keys in reverse unique cursors
Deduplicate the ascending index entries before reversing unique cursor traversal. Previously prevunique chose the last primary key in each duplicate index-key group. Preserve ordinary reverse traversal and cover multiple duplicated index keys in native cursor tests. Update the existing JavaScript cursor and collection regressions to assert the corrected primary-key choice.
This commit is contained in:
@@ -38,12 +38,14 @@ pub fn apply_cursor_direction_by_key<T>(
|
||||
direction: CursorDirection,
|
||||
mut key_for: impl FnMut(&T) -> &Key,
|
||||
) -> Vec<T> {
|
||||
if direction.is_reverse() {
|
||||
entries.reverse();
|
||||
}
|
||||
// Unique index cursors select the lowest primary key for each index key,
|
||||
// including when the distinct index keys are visited in reverse order.
|
||||
if direction.is_unique() {
|
||||
entries.dedup_by(|right, left| key_for(left) == key_for(right));
|
||||
}
|
||||
if direction.is_reverse() {
|
||||
entries.reverse();
|
||||
}
|
||||
entries
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ fn cursor_direction_helpers_reverse_and_deduplicate_by_key() {
|
||||
);
|
||||
assert_eq!(
|
||||
apply_cursor_direction_by_key(entries, CursorDirection::PrevUnique, |entry| &entry.0),
|
||||
vec![(Key::from("b"), 3), (Key::from("a"), 2)]
|
||||
vec![(Key::from("b"), 3), (Key::from("a"), 1)]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1661,3 +1661,25 @@ fn auto_increment_rejects_exhausted_safe_integer_range() {
|
||||
.expect_err("generate_key should fail once the safe integer range is exhausted");
|
||||
assert!(matches!(error, IndexedDbError::Constraint(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reverse_unique_index_cursor_keeps_first_primary_key_for_each_index_key() {
|
||||
let entries = vec![
|
||||
(Key::from("a"), 1),
|
||||
(Key::from("a"), 2),
|
||||
(Key::from("b"), 3),
|
||||
(Key::from("b"), 4),
|
||||
(Key::from("c"), 5),
|
||||
(Key::from("c"), 6),
|
||||
];
|
||||
let actual =
|
||||
apply_cursor_direction_by_key(entries, CursorDirection::PrevUnique, |entry| &entry.0);
|
||||
assert_eq!(
|
||||
actual,
|
||||
vec![
|
||||
(Key::from("c"), 5),
|
||||
(Key::from("b"), 3),
|
||||
(Key::from("a"), 1)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4888,7 +4888,7 @@ fn indexed_db_cursors_support_prev_directions() {
|
||||
.eval_after_selected_page_tasks("String(globalThis.__indexedDbCursorPrevResult)")
|
||||
.expect("indexeddb cursor prev result should be readable");
|
||||
|
||||
assert_eq!(result, "c,b,a|tech:c,news:b");
|
||||
assert_eq!(result, "c,b,a|tech:c,news:a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ promise_test(async () => {
|
||||
);
|
||||
assert_array_equals(
|
||||
await wait_request(index.getAllKeys({ direction: "prevunique" })),
|
||||
[3, 2],
|
||||
[3, 1],
|
||||
"index.getAllKeys() applies options prevunique direction"
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user