Merge branch 'master' into origin-2035-arv-mount-tags-folders
[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               include_linked: {
7                 type: 'boolean', required: false, default: false
8               },
9             })
10   end
11
12   def contents
13     all_objects = []
14     all_available = 0
15
16     # Trick apply_where_limit_order_params into applying suitable
17     # per-table values. *_all are the real ones we'll apply to the
18     # aggregate set.
19     limit_all = @limit
20     offset_all = @offset
21     @orders = []
22
23     ArvadosModel.descendants.reject(&:abstract_class?).sort_by(&:to_s).
24       each do |klass|
25       case klass.to_s
26         # We might expect klass==Link etc. here, but we would be
27         # disappointed: when Rails reloads model classes, we get two
28         # distinct classes called Link which do not equal each
29         # other. But we can still rely on klass.to_s to be "Link".
30       when 'ApiClientAuthorization', 'UserAgreement', 'Link'
31         # Do not want.
32       else
33         @objects = klass.readable_by(*@read_users)
34         cond_sql = "#{klass.table_name}.owner_uuid = ?"
35         cond_params = [@object.uuid]
36         if params[:include_linked]
37           cond_sql += " OR #{klass.table_name}.uuid IN (SELECT head_uuid FROM links WHERE link_class=#{klass.sanitize 'name'} AND links.tail_uuid=#{klass.sanitize @object.uuid})"
38         end
39         @objects = @objects.where(cond_sql, *cond_params).order("#{klass.table_name}.uuid")
40         @limit = limit_all - all_objects.count
41         apply_where_limit_order_params
42         items_available = @objects.
43           except(:limit).except(:offset).
44           count(:id, distinct: true)
45         all_available += items_available
46         @offset = [@offset - items_available, 0].max
47
48         all_objects += @objects.to_a
49       end
50     end
51     @objects = all_objects || []
52     @links = Link.where('link_class=? and tail_uuid=?'\
53                         ' and head_uuid in (?)',
54                         'name',
55                         @object.uuid,
56                         @objects.collect(&:uuid))
57     @object_list = {
58       :kind  => "arvados#objectList",
59       :etag => "",
60       :self_link => "",
61       :links => @links.as_api_response(nil),
62       :offset => offset_all,
63       :limit => limit_all,
64       :items_available => all_available,
65       :items => @objects.as_api_response(nil)
66     }
67     render json: @object_list
68   end
69
70 end