@@ -197,63 +197,67 @@ def _cursor_paginated_query(
197197 asc (self ._model_pk ())
198198 )
199199
200- # TODO: Use window functions
201- if not is_before_cursor :
202- previous_query = stmt .where (
203- getattr (self ._model , cursor_reference .column ) <= cursor_reference .value
204- )
205- previous_query = (
206- self ._filter_order_by (
207- previous_query , [(cursor_reference .column , SortDirection .DESC )]
208- )
209- .limit (1 )
210- .subquery ("previous" ) # type: ignore
200+ previous_query = self ._cursor_pagination_previous_item_query (
201+ stmt , cursor_reference , is_before_cursor
202+ ).subquery ("previous" )
203+
204+ page_query = self ._cursor_pagination_slice_query (
205+ stmt , cursor_reference , forward_limit , is_before_cursor
206+ ).subquery ("slice" )
207+
208+ query = select (
209+ aliased (
210+ self ._model ,
211+ select (previous_query )
212+ .union_all (select (page_query ))
213+ .order_by (cursor_reference .column )
214+ .subquery ("cursor_pagination" ), # type: ignore
211215 )
216+ )
217+ return query
212218
219+ def _cursor_pagination_slice_query (
220+ self ,
221+ stmt : Select ,
222+ cursor_reference : CursorReference ,
223+ forward_limit : int ,
224+ is_before_cursor : bool ,
225+ ):
226+ if not is_before_cursor :
213227 page_query = stmt .where (
214228 getattr (self ._model , cursor_reference .column ) > cursor_reference .value
215229 )
216- page_query = (
217- self ._filter_order_by (
218- page_query , [(cursor_reference .column , SortDirection .ASC )]
219- )
220- .limit (forward_limit )
221- .subquery ("page" ) # type: ignore
230+ page_query = self ._filter_order_by (
231+ page_query , [(cursor_reference .column , SortDirection .ASC )]
222232 )
223233 else :
224- previous_query = stmt .where (
225- getattr (self ._model , cursor_reference .column ) >= cursor_reference .value
226- )
227- previous_query = (
228- self ._filter_order_by (
229- previous_query , [(cursor_reference .column , SortDirection .ASC )]
230- )
231- .limit (1 )
232- .subquery ("previous" ) # type: ignore
233- )
234-
235234 page_query = stmt .where (
236235 getattr (self ._model , cursor_reference .column ) < cursor_reference .value
237236 )
238- page_query = (
239- self ._filter_order_by (
240- page_query , [(cursor_reference .column , SortDirection .DESC )]
241- )
242- .limit (forward_limit )
243- .subquery ("page" ) # type: ignore
237+ page_query = self ._filter_order_by (
238+ page_query , [(cursor_reference .column , SortDirection .DESC )]
244239 )
240+ return page_query .limit (forward_limit )
245241
246- query = select (
247- aliased (
248- self ._model ,
249- select (previous_query )
250- .union (select (page_query ))
251- .order_by (cursor_reference .column )
252- .subquery (), # type: ignore
242+ def _cursor_pagination_previous_item_query (
243+ self , stmt : Select , cursor_reference : CursorReference , is_before_cursor : bool
244+ ) -> Select :
245+ if not is_before_cursor :
246+ previous_query = stmt .where (
247+ getattr (self ._model , cursor_reference .column ) <= cursor_reference .value
248+ )
249+ previous_query = self ._filter_order_by (
250+ previous_query , [(cursor_reference .column , SortDirection .DESC )]
251+ )
252+ else :
253+ previous_query = stmt .where (
254+ getattr (self ._model , cursor_reference .column ) >= cursor_reference .value
255+ )
256+ previous_query = self ._filter_order_by (
257+ previous_query , [(cursor_reference .column , SortDirection .ASC )]
253258 )
254- )
255259
256- return query
260+ return previous_query . limit ( 1 )
257261
258262 def _sanitised_query_limit (self , limit ):
259263 return max (min (limit , self ._max_query_limit ), 0 )
0 commit comments