Class: InterMine::Metadata::ClassDescriptor
- Inherits:
-
Object
- Object
- InterMine::Metadata::ClassDescriptor
- Includes:
- SetHashKey
- Defined in:
- lib/intermine/model.rb
Overview
A class representing a table in the InterMine data model
A class descriptor represents a logical abstraction of a table in the InterMine model, and contains information about the columns in the table and the other tables that are referenced by this table.
It can be used to construct queries directly, when obtained from a webservice.
cld = service.model.table('Gene')
cld.where(:symbol => 'zen').each_row {|row| puts row}
:include:contact_header.rdoc
Instance Attribute Summary collapse
-
#fields ⇒ Object
readonly
The Hash containing the fields of this model.
-
#model ⇒ Object
readonly
The InterMine Model.
Instance Method Summary collapse
-
#attributes ⇒ Object
call-seq: attributes => Array.
-
#get_field(name) ⇒ Object
(also: #field)
call-seq: get_field(name) => FieldDescriptor.
-
#has_field?(name) ⇒ Boolean
call-seq: has_field?(name) => bool.
-
#initialize(opts, model) ⇒ ClassDescriptor
constructor
ClassDescriptors are constructed automatically when the model itself is parsed.
-
#inspect ⇒ Object
Return a fuller string representation.
-
#new_query ⇒ Object
(also: #query)
call-seq: new_query => PathQuery::Query.
-
#select(*cols) ⇒ Object
call-seq: select(*columns) => PathQuery::Query.
-
#subclass_of?(other) ⇒ Boolean
call-seq: subclass_of?(other) => bool.
-
#to_class ⇒ Object
call-seq: to_class => Class.
-
#to_module ⇒ Object
call-seq: to_module => Module.
-
#to_s ⇒ Object
Returns a human readable string.
-
#where(*args) ⇒ Object
call-seq: where(*constraints) => PathQuery::Query.
Methods included from SetHashKey
Constructor Details
#initialize(opts, model) ⇒ ClassDescriptor
ClassDescriptors are constructed automatically when the model itself is parsed. They should not be constructed on their own.
Arguments:
opts
-
A Hash containing the information to initialise this ClassDescriptor.
model
-
The model this ClassDescriptor belongs to.
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/intermine/model.rb', line 349 def initialize(opts, model) @model = model @fields = {} @klass = nil @module = nil field_types = { "attributes" => AttributeDescriptor, "references" => ReferenceDescriptor, "collections" => CollectionDescriptor } opts.each do |k,v| if (field_types.has_key?(k)) v.each do |name, field| @fields[name] = field_types[k].new(field, model) end else set_key_value(k, v) end end end |
Instance Attribute Details
#fields ⇒ Object (readonly)
The Hash containing the fields of this model
340 341 342 |
# File 'lib/intermine/model.rb', line 340 def fields @fields end |
#model ⇒ Object (readonly)
The InterMine Model
337 338 339 |
# File 'lib/intermine/model.rb', line 337 def model @model end |
Instance Method Details
#attributes ⇒ Object
call-seq:
attributes => Array[AttributeDescriptor]
Returns an Array of all fields in the current table that represent attributes (ie. columns that can hold values, rather than references to other tables.)
The array returned will be sorted in alphabetical order by field-name.
452 453 454 455 456 457 |
# File 'lib/intermine/model.rb', line 452 def attributes return @fields. select {|_, v| v.is_a?(AttributeDescriptor)}. sort {|(k0, _), (k1, _)| k0 <=> k1}. map {|(_, v)| v} end |
#get_field(name) ⇒ Object Also known as: field
call-seq:
get_field(name) => FieldDescriptor
Returns the field of the given name if it exists in the referenced table.
428 429 430 |
# File 'lib/intermine/model.rb', line 428 def get_field(name) return @fields[name] end |
#has_field?(name) ⇒ Boolean
call-seq:
has_field?(name) => bool
Returns true if the table has a field of the given name.
439 440 441 |
# File 'lib/intermine/model.rb', line 439 def has_field?(name) return @fields.has_key?(name) end |
#inspect ⇒ Object
Return a fuller string representation.
465 466 467 |
# File 'lib/intermine/model.rb', line 465 def inspect return "<#{self.class.name}:#{self.object_id} #{to_s}>" end |
#new_query ⇒ Object Also known as: query
380 381 382 383 |
# File 'lib/intermine/model.rb', line 380 def new_query q = @model.service.new_query(self.name) return q end |
#select(*cols) ⇒ Object
call-seq:
select(*columns) => PathQuery::Query
Construct a new query on this table in the originating service with given columns selected for output.
query = model.table('Gene').select(:symbol, :name, "organism.name", "alleles.*")
query.each_result do |gene|
puts "#{gene.symbol} (#{gene.organism.name}): #{gene.alleles.size} Alleles"
end
399 400 401 402 403 |
# File 'lib/intermine/model.rb', line 399 def select(*cols) q = new_query q.add_views(cols) return q end |
#subclass_of?(other) ⇒ Boolean
call-seq:
subclass_of?(other) => bool
Returns true if the class this ClassDescriptor describes is a subclass of the class the other element evaluates to. The other may be a ClassDescriptor, or a Path, or a String describing a path.
model.table('Gene').subclass_of?(model.table('SequenceFeature'))
>>> true
model.table('Gene').subclass_of?(model.table('Protein'))
>>> false
482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'lib/intermine/model.rb', line 482 def subclass_of?(other) path = Path.new(other, @model) if @extends.include? path.end_type return true else @extends.each do |x| superCls = @model.get_cd(x) if superCls.subclass_of?(path) return true end end end return false end |
#to_class ⇒ Object
call-seq:
to_class => Class
Returns a Class that can be used to instantiate new objects representing rows of data in the InterMine database.
614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'lib/intermine/model.rb', line 614 def to_class if @klass.nil? mod = to_module kls = Class.new(InterMineObject) cd = self kls.class_eval do include mod @__cd__ = cd end @klass = kls end return @klass end |
#to_module ⇒ Object
call-seq:
to_module => Module
Produces a module containing the logic this ClassDescriptor represents, suitable for including into a class definition.
The use of modules enables multiple inheritance, which is supported in the InterMine data model, to be represented in the classes instantiated in the client.
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
# File 'lib/intermine/model.rb', line 507 def to_module if @module.nil? nums = Model::FLOAT_TYPES ints = Model::INT_TYPES bools = Model::BOOL_TYPES supers = @extends.map { |x| @model.get_cd(x).to_module } klass = Module.new fd_names = @fields.values.map { |x| x.name } attr_names = @fields.values.select { |x| x.is_a?(AttributeDescriptor)}.map {|x| x.name} klass.class_eval do include *supers attr_reader *attr_names end @fields.values.each do |fd| if fd.is_a?(CollectionDescriptor) klass.class_eval do define_method("add" + fd.name.capitalize) do |*vals| type = fd.referencedType instance_var = instance_variable_get("@" + fd.name) instance_var ||= [] vals.each do |item| if item.is_a?(Hash) item = type.model.make_new(type.name, item) end if !item.is_a?(type) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be #{type.name}s" end instance_var << item end instance_variable_set("@" + fd.name, instance_var) end end end if fd.is_a?(ReferenceDescriptor) klass.class_eval do define_method(fd.name) do if instance_variable_get("@" + fd.name).nil? q = __cd__.select(fd.name + ".*").where(:id => objectId) instance_var = q.results.first[fd.name] instance_variable_set("@" + fd.name, instance_var) end return instance_variable_get("@" + fd.name) end end end klass.class_eval do define_method(fd.name + "=") do |val| if fd.is_a?(AttributeDescriptor) type = fd.dataType if nums.include?(type) if !val.is_a?(Numeric) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be numeric" end elsif ints.include?(type) if !val.is_a?(Integer) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be integers" end elsif bools.include?(type) if !val.is_a?(TrueClass) && !val.is_a?(FalseClass) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be booleans" end end instance_variable_set("@" + fd.name, val) else type = fd.referencedType if fd.is_a?(CollectionDescriptor) instance_var = [] val.each do |item| if item.is_a?(Hash) item = type.model.make_new(type.name, item) end if !item.is_a?(type) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be #{type.name}s" end instance_var << item end instance_variable_set("@" + fd.name, instance_var) else if val.is_a?(Hash) val = type.model.make_new(type.name, val) end if !val.is_a?(type) raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be #{type.name}s" end instance_variable_set("@" + fd.name, val) end end end end end @module = klass end return @module end |
#to_s ⇒ Object
Returns a human readable string
460 461 462 |
# File 'lib/intermine/model.rb', line 460 def to_s return "#{@model.name}.#{@name}" end |
#where(*args) ⇒ Object
call-seq:
where(*constraints) => PathQuery::Query
Returns a new query on this table in the originating service will all attribute columns selected for output and the given constraints applied.
zen = model.table('Gene').where(:symbol => 'zen').one
puts "Zen is short for #{zen.name}, and has a length of #{zen.length}"
415 416 417 418 419 420 |
# File 'lib/intermine/model.rb', line 415 def where(*args) q = new_query q.select("*") q.where(*args) return q end |