class Jamf::Pager

an object that performs a paged query for a pageable resource, possibly sorted and filtered. One of these is returned by class method .pager class method of CollectionResources the .change_log_pager method of ChangeLog resources

Constants

DEFAULT_PAGE_SIZE
MAX_PAGE_SIZE
MIN_PAGE_SIZE

Constants

PAGE_SIZE_RANGE

Attributes

cnx[R]

@return [Jamf::Connection] The Connection object used for the query

filter[R]

@return [String, nil] The optional filter parameter for the query

last_fetched_page[R]

@return [nil, Integer] The most recent page number fetched by fetch_next_page,

or nil if it hasn't been called yet.
list_path[R]

@return [String] The Resource URL path that provides the paged query results

next_page[R]

@return [Integer] The page which will be returned when fetch_next_page is called

page_size[R]

@return [Integer] How many items to return per page

query_path[R]

@return [] The full r#source URL, with page_size, sort, and filter, but

without the 'page' parameter
sort[R]

@return [String, nil] The optional sort parameter for the query,

total_count[R]

@return [Integer, nil] How many items are there in total? NOTE: this does

not apply any given filter, which might reduce the number of items
returned by a pager.
total_pages[R]

@return [Integer, nil] How many pages needed to retrieve the total_count?

nil if using a filter, since that may return fewer than the total count.

Public Class Methods

all_pages(list_path:, sort: nil, filter: nil, instantiate: nil, cnx: Jamf.cnx) click to toggle source

Return all results from a pageable list path.

Pageable resources are always returned in pages, usually defaulting to 100 items per page, but the max allowed page size is 2000. If there are more than 2000 items, we must loop through the pages to get them all.

This method is used to get all pages of data from a giving path, automatically looping through the pages and collecting the data to be returned in a single Array. It uses a Pager object to do that, but the Pager itself is transient, only the resulting Array is returned.

@param list_path [String] The Resource URL path that provides the paged

query results

@param sort [String ] The optional sort parameter for the query

@param filter [String] The optional RSQL filter parameter for the query

@param instantiate [Class] Instantiate the results as the given class by

passing the raw JSON data to the class' .new method. WARNING: Be sure the
data returned from the API is appropriate for instantiating this class.

@param cnx [Jamf::Connection] The API connection to use, default: Jamf.cnx

@return [Array<Hash,Jamf::OAPIObject>] All of the pages of data, returned as one array,

optionally instantiated into a subclass of Jamf::OAPIObject.
   # File lib/jamf/api/jamf_pro/other_classes/pager.rb
75 def self.all_pages(list_path:, sort: nil, filter: nil, instantiate: nil, cnx: Jamf.cnx)
76   sort &&= Jamf::Sortable.parse_url_sort_param(sort)
77   filter &&= Jamf::Filterable.parse_url_filter_param(filter)
78 
79   pager = new(
80     page_size: MAX_PAGE_SIZE,
81     list_path: list_path,
82     sort: sort,
83     filter: filter,
84     instantiate: instantiate,
85     cnx: cnx
86   )
87 
88   fetched_page = pager.fetch_next_page
89   data = fetched_page
90   until fetched_page.empty?
91     fetched_page = pager.fetch_next_page
92     data += fetched_page
93   end
94   data
95 end
new(list_path:, page_size: DEFAULT_PAGE_SIZE, sort: nil, filter: nil, instantiate: nil, cnx: Jamf.cnx) click to toggle source

@param list_path [String] The Resource URL path that provides the paged

query results

@param page_size [Integer] How many items to return per page

@param sort [String ] The optional sort parameter for the query

@param filter [String] The optional RSQL filter parameter for the query

@param instantiate [Class] Instantiate the results as the given class by

passing the raw JSON data to the class' .new method

@param cnx [Jamf::Connection] The Connection object used for the query.

Defaults to the Default connection
    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
154 def initialize(list_path:, page_size: DEFAULT_PAGE_SIZE, sort: nil, filter: nil, instantiate: nil, cnx: Jamf.cnx)
155   validate_page_size(page_size)
156 
157   @cnx = cnx
158   @list_path = list_path
159   @sort = Jamf::Sortable.parse_url_sort_param(sort)
160   @filter = Jamf::Filterable.parse_url_filter_param(filter)
161   @page_size ||= DEFAULT_PAGE_SIZE
162   @instantiate = instantiate
163 
164   # start with page 0, the first page
165   # This will be incremented and appended to the query path each time we call
166   # next_page
167   @next_page = 0
168 
169   @query_path = "#{@list_path}?page-size=#{@page_size}#{@sort}#{@filter}"
170 
171   # get one item which will contain the total count
172   @total_count = cnx.jp_get("#{@list_path}?page-size=1&page=0#{@filter}")[:totalCount]
173   # can't know total pages of filtered query
174   @total_pages = @filter ? nil : (@total_count / @page_size.to_f).ceil
175 end

Public Instance Methods

fetch_next_page() click to toggle source

@return [Array] The next page of the collection, i.e. whichever page is

indicated in the next_page attribute.
    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
180 def fetch_next_page
181   page @next_page, increment_next: true
182 end
page(page_number, increment_next: false) click to toggle source

Retrieve an arbitrary page of the result.

IMPORTANT: In the Jamf Pro API, page numbers are zero-based! The first page is 0, the second is 1, and so on. Asking for page 27 will give you the 28th page of results

If increment_next is true, then subsequent calls to fetch_next_page will continue from whatever page number was requested.

When increment_next is false (the default), the sequence of pages returned by next_page is unchanged, regardless of which page you return here.

@param number [Integer, Symbol] Which page to retrieve.

The Symbols :first and :last will work as expected. Otherwise, the
zero-based page number is needed. Will return an empty array if greater
than the total number of pages in the query result

@param increment_next [Boolean] should the next_page value be reset to the

page number plus 1? This makes #fetch_next_page continue from this one.

@return [Array] The desired page of the result, containing up to page_size

items. Will be empty if the page is greater than the total available.
    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
217 def page(page_number, increment_next: false)
218   page_number = 0 if page_number == :first
219   if page_number == :last
220     raise Jamf::UnsupportedError, 'Cannot use :last with filtered queries' if @filter
221 
222     page_number = (@total_pages - 1)
223   end
224 
225   validate_page_number page_number
226 
227   data = @cnx.jp_get "#{@query_path}&page=#{page_number}"
228   data = data[:results]
229   data.map! { |r| @instantiate.new r } if @instantiate
230 
231   if increment_next
232     @last_fetched_page = page_number
233     @next_page = (page_number + 1)
234   end
235 
236   data
237 end
reset(to_page = 0) click to toggle source

Reset the pager to start at a specific page (by default, the beginning) so that fetch_next_page will start from there the next time it’s called.

    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
186 def reset(to_page = 0)
187   to_page = 0 if to_page == :first
188   raise ArgumentError, 'Page number must be an Integer 0 or higher' if !to_page.is_a?(Integer) || to_page.negative?
189 
190   @next_page = to_page
191 end

Private Instance Methods

validate_page_number(page_number) click to toggle source

ensure valid page_number

@param page [Integer] the page number requested, must be >= 0

@return [void]

    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
258 def validate_page_number(page_number)
259   return if page_number.is_a?(Integer) && page_number >= 0
260 
261   raise ArgumentError, 'Page number must be an Integer 0 or higher'
262 end
validate_page_size(page_size) click to toggle source

ensure valid page_size

@param page_size [Integer] the page_size to be validated, must be in range

@return [void]

    # File lib/jamf/api/jamf_pro/other_classes/pager.rb
245 def validate_page_size(page_size)
246   return if page_size.is_a?(Integer) && PAGE_SIZE_RANGE.cover?(page_size)
247 
248   raise ArgumentError, "page_size must be an Integer from #{MIN_PAGE_SIZE} to #{MAX_PAGE_SIZE}"
249 end