attr_accessor :attribute_sortkey
def self.uuid_infix_object_kind
- @@uuid_infix_object_kind ||= {
- '4zz18' => 'arvados#collection',
- 'tpzed' => 'arvados#user',
- 'ozdt8' => 'arvados#api_client',
- '8i9sb' => 'arvados#job',
- 'o0j2j' => 'arvados#link',
- '57u5n' => 'arvados#log',
- 'j58dm' => 'arvados#specimen',
- 'p5p6p' => 'arvados#pipeline_template',
- 'mxsvm' => 'arvados#pipeline_template', # legacy Pipeline objects
- 'd1hrv' => 'arvados#pipeline_instance',
- 'uo14g' => 'arvados#pipeline_instance', # legacy PipelineInstance objects
- 'j7d0g' => 'arvados#group',
- 'ldvyl' => 'arvados#group' # only needed for legacy Project objects
- }
+ @@uuid_infix_object_kind ||=
+ begin
+ infix_kind = {}
+ $arvados_api_client.discovery[:schemas].each do |name, schema|
+ if schema[:uuidPrefix]
+ infix_kind[schema[:uuidPrefix]] =
+ 'arvados#' + name.to_s.camelcase(:lower)
+ end
+ end
+
+ # Recognize obsolete types.
+ infix_kind.
+ merge('mxsvm' => 'arvados#pipelineTemplate', # Pipeline
+ 'uo14g' => 'arvados#pipelineInstance', # PipelineInvocation
+ 'ldvyl' => 'arvados#group') # Project
+ end
end
def initialize(*args)
super(*args)
@attribute_sortkey ||= {
'id' => nil,
- 'uuid' => '000',
- 'owner_uuid' => '001',
- 'created_at' => '002',
- 'modified_at' => '003',
- 'modified_by_user_uuid' => '004',
- 'modified_by_client_uuid' => '005',
- 'name' => '050',
- 'tail_kind' => '100',
- 'tail_uuid' => '100',
- 'head_kind' => '101',
- 'head_uuid' => '101',
- 'info' => 'zzz-000',
- 'updated_at' => 'zzz-999'
+ 'name' => '000',
+ 'owner_uuid' => '002',
+ 'event_type' => '100',
+ 'link_class' => '100',
+ 'group_class' => '100',
+ 'tail_uuid' => '101',
+ 'head_uuid' => '102',
+ 'object_uuid' => '102',
+ 'summary' => '104',
+ 'description' => '104',
+ 'properties' => '150',
+ 'info' => '150',
+ 'created_at' => '200',
+ 'modified_at' => '201',
+ 'modified_by_user_uuid' => '202',
+ 'modified_by_client_uuid' => '203',
+ 'uuid' => '999',
}
end
return @columns unless @columns.nil?
@columns = []
@attribute_info ||= {}
- return @columns if $arvados_api_client.arvados_schema[self.to_s.to_sym].nil?
- $arvados_api_client.arvados_schema[self.to_s.to_sym].each do |coldef|
- k = coldef[:name].to_sym
- if coldef[:type] == coldef[:type].downcase
- @columns << column(k, coldef[:type].to_sym)
+ schema = $arvados_api_client.discovery[:schemas][self.to_s.to_sym]
+ return @columns if schema.nil?
+ schema[:properties].each do |k, coldef|
+ case k
+ when :etag, :kind
+ attr_reader k
else
- @columns << column(k, :text)
- serialize k, coldef[:type].constantize
+ if coldef[:type] == coldef[:type].downcase
+ # boolean, integer, etc.
+ @columns << column(k, coldef[:type].to_sym)
+ else
+ # Hash, Array
+ @columns << column(k, :text)
+ serialize k, coldef[:type].constantize
+ end
+ attr_accessible k
+ @attribute_info[k] = coldef
end
- attr_accessible k
- @attribute_info[k] = coldef
end
- attr_reader :etag
- attr_reader :kind
@columns
end
+
def self.column(name, sql_type = nil, default = nil, null = true)
ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
end
+
def self.attribute_info
self.columns
@attribute_info
end
- def self.find(uuid)
+
+ def self.find(uuid, opts={})
if uuid.class != String or uuid.length < 27 then
raise 'argument to find() must be a uuid string. Acceptable formats: warehouse locator or string with format xxxxx-xxxxx-xxxxxxxxxxxxxxx'
end
- new.private_reload(uuid)
+
+ if self == ArvadosBase
+ # Determine type from uuid and defer to the appropriate subclass.
+ return resource_class_for_uuid(uuid).find(uuid, opts)
+ end
+
+ # Only do one lookup on the API side per {class, uuid, workbench
+ # request} unless {cache: false} is given via opts.
+ cache_key = "request_#{Thread.current.object_id}_#{self.to_s}_#{uuid}"
+ if opts[:cache] == false
+ Rails.cache.write cache_key, $arvados_api_client.api(self, '/' + uuid)
+ end
+ hash = Rails.cache.fetch cache_key do
+ $arvados_api_client.api(self, '/' + uuid)
+ end
+ new.private_reload(hash)
end
+
def self.order(*args)
ArvadosResourceList.new(self).order(*args)
end
+
+ def self.filter(*args)
+ ArvadosResourceList.new(self).filter(*args)
+ end
+
def self.where(*args)
ArvadosResourceList.new(self).where(*args)
end
+
def self.limit(*args)
ArvadosResourceList.new(self).limit(*args)
end
+
def self.eager(*args)
ArvadosResourceList.new(self).eager(*args)
end
+
def self.all(*args)
ArvadosResourceList.new(self).all(*args)
end
+
def save
obdata = {}
self.class.columns.each do |col|
@etag = resp[:etag]
@kind = resp[:kind]
- # these attrs can be modified by "save" -- we should update our copies
- %w(uuid owner_uuid created_at
- modified_at modified_by_user_uuid modified_by_client_uuid
- ).each do |attr|
+ # attributes can be modified during "save" -- we should update our copies
+ resp.keys.each do |attr|
if self.respond_to? "#{attr}=".to_sym
- self.send(attr + '=', resp[attr.to_sym])
+ self.send(attr.to_s + '=', resp[attr.to_sym])
end
end
+ @new_record = false
+
self
end
+
def save!
self.save or raise Exception.new("Save failed")
end
true
end
end
-
+
def links(*args)
o = {}
o.merge!(args.pop) if args[-1].is_a? Hash
o[:link_class] ||= args.shift
o[:name] ||= args.shift
- o[:head_kind] ||= args.shift
- o[:tail_kind] = self.kind
o[:tail_uuid] = self.uuid
if all_links
return all_links.select do |m|
@links = $arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
@links = $arvados_api_client.unpack_api_response(@links)
end
+
def all_links
return @all_links if @all_links
res = $arvados_api_client.api Link, '', {
}
@all_links = $arvados_api_client.unpack_api_response(res)
end
+
def reload
private_reload(self.uuid)
end
+
def private_reload(uuid_or_hash)
raise "No such object" if !uuid_or_hash
if uuid_or_hash.is_a? Hash
end
end
@all_links = nil
+ @new_record = false
self
end
+
+ def to_param
+ uuid
+ end
+
def dup
super.forget_uuid!
end
}
end
+ def class_for_display
+ self.class.to_s
+ end
+
def self.creatable?
current_user
end
def editable?
(current_user and current_user.is_active and
(current_user.is_admin or
- current_user.uuid == self.owner_uuid))
+ current_user.uuid == self.owner_uuid or
+ new_record?))
end
def attribute_editable?(attr)
elsif "uuid owner_uuid".index(attr.to_s) or current_user.is_admin
current_user.is_admin
else
- current_user.uuid == self.owner_uuid or current_user.uuid == self.uuid
+ current_user.uuid == self.owner_uuid or
+ current_user.uuid == self.uuid or
+ new_record?
end
end
end
def friendly_link_name
- if self.class.column_names.include? 'name'
- self.name
- end
+ (name if self.respond_to? :name) || uuid
+ end
+
+ def content_summary
+ self.class_for_display
+ end
+
+ def selection_label
+ friendly_link_name
end
protected