Merge branch 'master' into 3052-crunch-log-stdout
[arvados.git] / apps / workbench / app / models / arvados_resource_list.rb
index b1c15617878d5f15fb796db3767d7cb02c6bf1d8..1a3c6b7e3c8e55036306743843f31839489c4da3 100644 (file)
@@ -1,7 +1,8 @@
 class ArvadosResourceList
+  include ArvadosApiClientHelper
   include Enumerable
 
-  def initialize(resource_class)
+  def initialize resource_class=nil
     @resource_class = resource_class
   end
 
@@ -15,11 +16,33 @@ class ArvadosResourceList
     self
   end
 
+  def offset(skip)
+    @offset = skip
+    self
+  end
+
   def order(orderby_spec)
     @orderby_spec = orderby_spec
     self
   end
 
+  def select(columns=nil)
+    # If no column arguments were given, invoke Enumerable#select.
+    if columns.nil?
+      super()
+    else
+      @select ||= []
+      @select += columns
+      self
+    end
+  end
+
+  def filter _filters
+    @filters ||= []
+    @filters += _filters
+    self
+  end
+
   def where(cond)
     cond = cond.dup
     cond.keys.each do |uuid_key|
@@ -42,7 +65,7 @@ class ArvadosResourceList
     end
     cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
       if cond[kind_key].is_a? Class
-        cond = cond.merge({ kind_key => 'arvados#' + $arvados_api_client.class_kind(cond[kind_key]) })
+        cond = cond.merge({ kind_key => 'arvados#' + arvados_api_client.class_kind(cond[kind_key]) })
       end
     end
     api_params = {
@@ -51,9 +74,12 @@ class ArvadosResourceList
     }
     api_params[:eager] = '1' if @eager
     api_params[:limit] = @limit if @limit
+    api_params[:offset] = @offset if @offset
+    api_params[:select] = @select if @select
     api_params[:order] = @orderby_spec if @orderby_spec
-    res = $arvados_api_client.api @resource_class, '', api_params
-    @results = $arvados_api_client.unpack_api_response res
+    api_params[:filters] = @filters if @filters
+    res = arvados_api_client.api @resource_class, '', api_params
+    @results = arvados_api_client.unpack_api_response res
     self
   end
 
@@ -62,6 +88,10 @@ class ArvadosResourceList
     @results
   end
 
+  def results=(r)
+    @results = r
+  end
+
   def all
     where({})
   end
@@ -73,6 +103,12 @@ class ArvadosResourceList
     self
   end
 
+  def collect
+    results.collect do |m|
+      yield m
+    end
+  end
+
   def first
     results.first
   end
@@ -104,4 +140,51 @@ class ArvadosResourceList
   def empty?
     results.empty?
   end
+
+  def items_available
+    results.items_available if results.respond_to? :items_available
+  end
+
+  def result_limit
+    results.limit if results.respond_to? :limit
+  end
+
+  def result_offset
+    results.offset if results.respond_to? :offset
+  end
+
+  def result_links
+    results.links if results.respond_to? :links
+  end
+
+  # Return links provided with API response that point to the
+  # specified object, and have the specified link_class. If link_class
+  # is false or omitted, return all links pointing to the specified
+  # object.
+  def links_for item_or_uuid, link_class=false
+    return [] if !result_links
+    unless @links_for_uuid
+      @links_for_uuid = {}
+      result_links.each do |link|
+        if link.respond_to? :head_uuid
+          @links_for_uuid[link.head_uuid] ||= []
+          @links_for_uuid[link.head_uuid] << link
+        end
+      end
+    end
+    if item_or_uuid.respond_to? :uuid
+      uuid = item_or_uuid.uuid
+    else
+      uuid = item_or_uuid
+    end
+    (@links_for_uuid[uuid] || []).select do |link|
+      link_class == false or link.link_class == link_class
+    end
+  end
+
+  # Note: this arbitrarily chooses one of (possibly) multiple names.
+  def name_for item_or_uuid
+    links_for(item_or_uuid, 'name').first.andand.name
+  end
+
 end