1 class ArvadosResourceList
2 include ArvadosApiClientHelper
5 def initialize resource_class=nil
6 @resource_class = resource_class
7 @fetch_multiple_pages = true
15 def limit(max_results)
25 def order(orderby_spec)
26 @orderby_spec = orderby_spec
30 def select(columns=nil)
31 # If no column arguments were given, invoke Enumerable#select.
49 @cond.keys.each do |uuid_key|
50 if @cond[uuid_key] and (@cond[uuid_key].is_a? Array or
51 @cond[uuid_key].is_a? ArvadosBase)
52 # Coerce cond[uuid_key] to an array of uuid strings. This
53 # allows caller the convenience of passing an array of real
54 # objects and uuids in cond[uuid_key].
55 if !@cond[uuid_key].is_a? Array
56 @cond[uuid_key] = [@cond[uuid_key]]
58 @cond[uuid_key] = @cond[uuid_key].collect do |item|
59 if item.is_a? ArvadosBase
67 @cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
68 if @cond[kind_key].is_a? Class
69 @cond = @cond.merge({ kind_key => 'arvados#' + arvados_api_client.class_kind(@cond[kind_key]) })
75 def fetch_multiple_pages(f)
76 @fetch_multiple_pages = f
92 @items_available = r.items_available if r.respond_to? :items_available
93 @result_limit = r.limit if r.respond_to? :limit
94 @result_offset = r.offset if r.respond_to? :offset
95 @result_links = r.links if r.respond_to? :links
112 api_params[:where] = @cond if @cond
113 api_params[:eager] = '1' if @eager
114 api_params[:limit] = @limit if @limit
115 api_params[:select] = @select if @select
116 api_params[:order] = @orderby_spec if @orderby_spec
117 api_params[:filters] = @filters if @filters
127 if @limit.is_a? Integer
128 items_to_get = @limit
130 items_to_get = 1000000000
134 api_params[:offset] = offset
136 res = arvados_api_client.api @resource_class, '', api_params
137 items = arvados_api_client.unpack_api_response res
139 if items.nil? or items.size == 0
143 @items_available = items.items_available if items.respond_to? :items_available
144 @result_limit = items.limit
145 @result_offset = items.offset
146 @result_links = items.links if items.respond_to? :links
148 item_count += items.size
150 if items.respond_to? :items_available and
151 (@limit.nil? or (@limit.is_a? Integer and @limit > items.items_available))
152 items_to_get = items.items_available
155 offset = items.offset + items.size
159 end while @fetch_multiple_pages and item_count < items_to_get
167 self.each_page do |items|
181 results.send('[]', *x)
193 Hash[self.collect { |x| [x.uuid, x] }]
216 # Return links provided with API response that point to the
217 # specified object, and have the specified link_class. If link_class
218 # is false or omitted, return all links pointing to the specified
220 def links_for item_or_uuid, link_class=false
221 return [] if !result_links
222 unless @links_for_uuid
224 result_links.each do |link|
225 if link.respond_to? :head_uuid
226 @links_for_uuid[link.head_uuid] ||= []
227 @links_for_uuid[link.head_uuid] << link
231 if item_or_uuid.respond_to? :uuid
232 uuid = item_or_uuid.uuid
236 (@links_for_uuid[uuid] || []).select do |link|
237 link_class == false or link.link_class == link_class
241 # Note: this arbitrarily chooses one of (possibly) multiple names.
242 def name_for item_or_uuid
243 links_for(item_or_uuid, 'name').first.andand.name