Я не могу сбрасывать свой код, но в сортировках и фильтрациях применительно к курсорам нет ничего сложного.
Общий подход такой - курсор хранит в себе первичный ключ опорной записи, направление отображения, режим сортировки и текущий набор фильтров. На каждую страницу у вас может быть много курсоров. Я с каждой страницей возвращаю
- курсор на первую страницу (не содержит первичного ключа, направление "вперед", + текущие фильтры и сортировка),
- курсор на следующую страницу (первичный ключ последней записи на странице + остально),
- курсор на предыдущую страницу (первичный ключ первой записи на странице + остальное),
- и курсор на последнюю страницу (не содержит первичного ключа, направление "назад", + текущие фильтры и сортировка).
Чтобы вычислить курсор, вы сначала сортируете и фильтруете по вашим предпочтениям (главное, чтобы сортировка была стабильной), затем извлекаете все, что находится после первичного ключа опорной записи (если направление "вперед"), или то, что находится до (если направление "назад").
Если у вас "первые 5 страниц и последние 5 страниц", то это не имеет значения. Для начальной навигации у вас будет оффсет, потому что человек, который перематывается на "5 страницу с конца" и так не знает, что он хочет (и что получит). Затем, когда навигация произошла, для связного перемещения у вас уже будут курсоры.