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.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/intermine/model.rb', line 353 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
344 345 346 |
# File 'lib/intermine/model.rb', line 344 def fields @fields end |
#model ⇒ Object (readonly)
The InterMine Model
341 342 343 |
# File 'lib/intermine/model.rb', line 341 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.
456 457 458 459 460 461 |
# File 'lib/intermine/model.rb', line 456 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.
432 433 434 |
# File 'lib/intermine/model.rb', line 432 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.
443 444 445 |
# File 'lib/intermine/model.rb', line 443 def has_field?(name) return @fields.has_key?(name) end |
#inspect ⇒ Object
Return a fuller string representation.
469 470 471 |
# File 'lib/intermine/model.rb', line 469 def inspect return "<#{self.class.name}:#{self.object_id} #{to_s}>" end |
#new_query ⇒ Object Also known as: query
384 385 386 387 |
# File 'lib/intermine/model.rb', line 384 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
403 404 405 406 407 |
# File 'lib/intermine/model.rb', line 403 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
486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
# File 'lib/intermine/model.rb', line 486 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.
637 638 639 640 641 642 643 644 645 646 647 648 649 |
# File 'lib/intermine/model.rb', line 637 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.
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 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
# File 'lib/intermine/model.rb', line 511 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 instance_var = instance_variable_get("@" + fd.name) if fd.referencedType.model.is_lazy and instance_var.nil? and not instance_variable_get("@" + fd.name + "_ISNULL") q = __cd__.select(:id, fd.name + ".*").where(:id => objectId).outerjoin(fd.name) first_result = q.results.first unless first_result.nil? instance_var = first_result[fd.name] if instance_var.nil? if fs.is_a?(CollectionDescriptor) and instance_var.nil? instance_var = [] else instance_variable_set("@" + fd.name + "_ISNULL", true) end end instance_variable_set("@" + fd.name, instance_var) end end if instance_var.nil? and fd.is_a?(CollectionDescriptor) return [] else return instance_var end 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 = [] unless val.nil? 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 end instance_variable_set("@" + fd.name, instance_var) else if val.nil? instance_variable_set("@" + fd.name + "_ISNULL", true) elsif 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
464 465 466 |
# File 'lib/intermine/model.rb', line 464 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}"
419 420 421 422 423 424 |
# File 'lib/intermine/model.rb', line 419 def where(*args) q = new_query q.select("*") q.where(*args) return q end |