Use items_available in API response instead of retrieving all items.
[arvados.git] / apps / workbench / app / models / arvados_resource_list.rb
1 class ArvadosResourceList
2   include Enumerable
3
4   def initialize(resource_class)
5     @resource_class = resource_class
6   end
7
8   def eager(bool=true)
9     @eager = bool
10     self
11   end
12
13   def limit(max_results)
14     @limit = max_results
15     self
16   end
17
18   def order(orderby_spec)
19     @orderby_spec = orderby_spec
20     self
21   end
22
23   def where(cond)
24     cond = cond.dup
25     cond.keys.each do |uuid_key|
26       if cond[uuid_key] and (cond[uuid_key].is_a? Array or
27                              cond[uuid_key].is_a? ArvadosBase)
28         # Coerce cond[uuid_key] to an array of uuid strings.  This
29         # allows caller the convenience of passing an array of real
30         # objects and uuids in cond[uuid_key].
31         if !cond[uuid_key].is_a? Array
32           cond[uuid_key] = [cond[uuid_key]]
33         end
34         cond[uuid_key] = cond[uuid_key].collect do |item|
35           if item.is_a? ArvadosBase
36             item.uuid
37           else
38             item
39           end
40         end
41       end
42     end
43     cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
44       if cond[kind_key].is_a? Class
45         cond = cond.merge({ kind_key => 'arvados#' + $arvados_api_client.class_kind(cond[kind_key]) })
46       end
47     end
48     api_params = {
49       _method: 'GET',
50       where: cond
51     }
52     api_params[:eager] = '1' if @eager
53     api_params[:limit] = @limit if @limit
54     api_params[:order] = @orderby_spec if @orderby_spec
55     res = $arvados_api_client.api @resource_class, '', api_params
56     @results = $arvados_api_client.unpack_api_response res
57     self
58   end
59
60   def results
61     self.where({}) if !@results
62     @results
63   end
64
65   def all
66     where({})
67   end
68
69   def each(&block)
70     results.each do |m|
71       block.call m
72     end
73     self
74   end
75
76   def first
77     results.first
78   end
79
80   def last
81     results.last
82   end
83
84   def [](*x)
85     results.send('[]', *x)
86   end
87
88   def |(x)
89     if x.is_a? Hash
90       self.to_hash | x
91     else
92       results | x.to_ary
93     end
94   end
95
96   def to_ary
97     results
98   end
99
100   def to_hash
101     Hash[results.collect { |x| [x.uuid, x] }]
102   end
103
104   def empty?
105     results.empty?
106   end
107
108   def items_available
109     results.items_available if results.respond_to? :items_available
110   end
111 end