Module: Sdp::Pagination
- Defined in:
- lib/sdp/pagination.rb
Overview
Lazy enumeration over SDP list endpoints.
Two modes, keyed on whether the caller pinned a page:
-
No :page in the query — auto-paginate. The enumerator fetches the first page on first consumption and follows meta.hasMore, requesting the next page only when iteration runs past the rows already fetched (so ‘enum.take(3)` against a 20-row first page performs exactly one request). Filters are re-sent on every page request.
-
Explicit :page — single page. The enumerator yields exactly that page’s rows and never fetches another, even when meta.hasMore is true.
:pageSize is clamped client-side to MAX_PAGE_SIZE — SDP rejects larger values, and a clamped request is more useful than a guaranteed 400.
Non-paginated list endpoints (GET /v1/wallets at v0.28) flow through the same helper: their meta carries no hasMore, so enumeration stops after a single fetch — and they pick up auto-pagination for free if SDP paginates them in a later version.
Constant Summary collapse
- MAX_PAGE_SIZE =
SDP’s pageSize ceiling (v0.28)
100- MAX_PAGES =
defensive ceiling; empty-page + hasMore guards are the primary stop
10_000
Class Method Summary collapse
-
.enumerate(client, path, query = {}, &mapper) ⇒ Object
client — anything exposing #get(path, query:) → Client::Response query — wire-shaped (camelCase keys), nils allowed (compacted here) mapper — called once per page with the Response; returns that page’s rows.
Class Method Details
.enumerate(client, path, query = {}, &mapper) ⇒ Object
client — anything exposing #get(path, query:) → Client::Response query — wire-shaped (camelCase keys), nils allowed (compacted here) mapper — called once per page with the Response; returns that page’s rows
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/sdp/pagination.rb', line 30 def self.enumerate(client, path, query = {}, &mapper) query = query.compact query[:pageSize] = [ query[:pageSize].to_i, MAX_PAGE_SIZE ].min if query.key?(:pageSize) single_page = query.key?(:page) Enumerator.new do |yielder| page = query[:page] loop do request_query = page ? query.merge(page: page) : query response = client.get(path, query: request_query) rows = mapper.call(response) rows.each { |row| yielder << row } break if single_page = response. || {} # An empty page also stops: hasMore with zero rows would loop forever. break if rows.empty? || ![:has_more] # Advance a LOCAL counter the client owns; ignore meta[:page] so a # server that echoes the wrong page number cannot cause an infinite # loop or a TypeError (string "1" + 1). page = (page || 1) + 1 break if page > MAX_PAGES end end end |