Merge branch 'origin-3442-no-reuse-job-when-output-unreadable' refs #3442
[arvados.git] / services / api / app / controllers / arvados / v1 / groups_controller.rb
1 class Arvados::V1::GroupsController < ApplicationController
2
3   def self._contents_requires_parameters
4     _index_requires_parameters.
5       merge({
6               uuid: {
7                 type: 'string', required: false, default: nil
8               },
9               include_linked: {
10                 type: 'boolean', required: false, default: false
11               },
12             })
13   end
14
15   def render_404_if_no_object
16     if params[:action] == 'contents' and !params[:uuid]
17       # OK!
18       @object = nil
19     else
20       super
21     end
22   end
23
24   def contents
25     # Set @objects:
26     load_searchable_objects(owner_uuid: @object.andand.uuid,
27                             include_linked: params[:include_linked])
28     sql = 'link_class=? and head_uuid in (?)'
29     sql_params = ['name', @objects.collect(&:uuid)]
30     if @object
31       sql += ' and tail_uuid=?'
32       sql_params << @object.uuid
33     end
34     @links = Link.where sql, *sql_params
35     @object_list = {
36       :kind  => "arvados#objectList",
37       :etag => "",
38       :self_link => "",
39       :links => @links.as_api_response(nil),
40       :offset => @offset,
41       :limit => @limit,
42       :items_available => @items_available,
43       :items => @objects.as_api_response(nil)
44     }
45     render json: @object_list
46   end
47
48   protected
49
50   def load_searchable_objects opts
51     all_objects = []
52     @items_available = 0
53
54     # Trick apply_where_limit_order_params into applying suitable
55     # per-table values. *_all are the real ones we'll apply to the
56     # aggregate set.
57     limit_all = @limit
58     offset_all = @offset
59     @orders = []
60
61     [Group,
62      Job, PipelineInstance, PipelineTemplate,
63      Collection,
64      Human, Specimen, Trait].each do |klass|
65       @objects = klass.readable_by(*@read_users)
66       if klass == Group
67         @objects = @objects.where('group_class in (?)', ['project', 'folder'])
68       end
69       if opts[:owner_uuid]
70         conds = []
71         cond_params = []
72         conds << "#{klass.table_name}.owner_uuid = ?"
73         cond_params << opts[:owner_uuid]
74         if opts[:include_linked]
75           haslink = "#{klass.table_name}.uuid IN (SELECT head_uuid FROM links WHERE link_class=#{klass.sanitize 'name'}"
76           haslink += " AND links.tail_uuid=#{klass.sanitize opts[:owner_uuid]}"
77           haslink += ")"
78           conds << haslink
79         end
80         if conds.any?
81           cond_sql = '(' + conds.join(') OR (') + ')'
82           @objects = @objects.where(cond_sql, *cond_params)
83         end
84       end
85
86       @objects = @objects.order("#{klass.table_name}.uuid")
87       @limit = limit_all - all_objects.count
88       apply_where_limit_order_params
89       klass_items_available = @objects.
90         except(:limit).except(:offset).
91         count(:id, distinct: true)
92       @items_available += klass_items_available
93       @offset = [@offset - klass_items_available, 0].max
94
95       all_objects += @objects.to_a
96     end
97
98     @objects = all_objects
99     @limit = limit_all
100     @offset = offset_all
101   end
102
103 end