Class: InterMine::PathQuery::Query
- Inherits:
-
Object
- Object
- InterMine::PathQuery::Query
- Defined in:
- lib/intermine/query.rb
Overview
A class representing a structured query against an InterMine Data-Warehouse
Queries represent structured requests for data from an InterMine data-warehouse. They consist basically of output columns you select, and a set of constraints on the results to return. These are known as the “view” and the “constraints”. In a nod to the SQL-origins of the queries, and to the syntax of ActiveRecord, there is both a method-chaining SQL-ish DSL, and a more isolating common InterMine DSL.
query = service.query("Gene").select("*").where("proteins.molecularWeight" => {">" => 10000})
query.each_result do |gene|
puts gene.symbol
end
OR:
query = service.query("Gene")
query.add_views("*")
query.add_constraint("proteins.molecularWeight", ">", 10000)
...
The main differences from SQL are that the joining between tables is implicit and automatic. Simply by naming the column “Gene.proteins.molecularWeight” we have access to the protein table joined onto the gene table. (A consequence of this is that all queries must have a unique root that all paths descend from, and we do not permit right outer joins.)
You can define the following features of a query:
* The output column
* The filtering constraints (what values certain columns must or must not have)
* The sort order of the results
* The way constraints are combined (AND or OR)
In processing results, there are two powerful result formats available, depending on whether you want to process results row by row, or whether you would like the information grouped into logically coherent records. The latter is more similar to the ORM model, and can be seen above. The mechanisms we offer for row access allow accessing cell values of the result table transparently by index or column-name.
:include:contact_header.rdoc
Direct Known Subclasses
Constant Summary collapse
- LOWEST_CODE =
The first possible constraint code
"A"
- HIGHEST_CODE =
The last possible constraint code
"Z"
Instance Attribute Summary collapse
-
#constraints ⇒ Object
readonly
All the current constraints on the query.
-
#joins ⇒ Object
readonly
All the current Join objects on the query.
-
#list_append_uri ⇒ Object
readonly
URLs for internal consumption.
-
#list_upload_uri ⇒ Object
readonly
URLs for internal consumption.
-
#logic ⇒ Object
readonly
The current logic (as a LogicGroup).
-
#model ⇒ Object
readonly
The data model associated with the query.
-
#name ⇒ Object
The (optional) name of the query.
-
#root ⇒ Object
The root class of the query.
-
#service ⇒ Object
readonly
The service this query is associated with.
-
#size ⇒ Object
The number of rows to return - defaults to nil (all rows).
-
#sort_order ⇒ Object
readonly
The current sort-order.
-
#start ⇒ Object
The index of the first row to return - defaults to 0 (first row).
-
#title ⇒ Object
A human readable title of the query (eg: “Gene –> Protein Domain”).
-
#views ⇒ Object
readonly
All the columns currently selected for output.
Class Method Summary collapse
-
.is_valid_code(str) ⇒ Object
Whether or not the argument is a valid constraint code.
-
.parser(model) ⇒ Object
Return a parser for deserialising queries.
Instance Method Summary collapse
-
#add_constraint(*parameters) ⇒ Object
Add a constraint to the query matching the given parameters, and return the created constraint.
-
#add_join(path, style = "OUTER") ⇒ Object
(also: #join)
Declare how a particular join should be treated.
-
#add_prefix(x) ⇒ Object
Adds the root prefix to the given string.
-
#add_sort_order(path, direction = "ASC") ⇒ Object
(also: #order_by, #order)
Add a sort order element to sort order information.
-
#add_views(*views) ⇒ Object
(also: #add_to_select)
Add the given views (output columns) to the query.
-
#all ⇒ Object
Return all result record objects returned by running this query.
-
#all_rows ⇒ Object
Return all the rows returned by running the query.
-
#coded_constraints ⇒ Object
Return all the constraints that have codes and can thus participate in logic.
-
#count ⇒ Object
Return the number of result rows this query will return in its current state.
-
#each_result(start = nil, size = nil) ⇒ Object
Iterate over the results, one record at a time.
-
#each_row(start = nil, size = nil) ⇒ Object
Iterate over the results of this query one row at a time.
-
#eql?(other) ⇒ Boolean
Return true if the other query has exactly the same configuration, and belongs to the same service.
-
#first(start = 0) ⇒ Object
Get the first result record from the query, starting at the given offset.
-
#first_row(start = 0) ⇒ Object
Get the first row of results from the query, starting at the given offset.
-
#get_constraint(code) ⇒ Object
Get the constraint on the query with the given code.
-
#initialize(model, root = nil, service = nil) ⇒ Query
constructor
Construct a new query object.
-
#inspect ⇒ Object
Return an informative textual representation of the query.
-
#limit(size) ⇒ Object
Set the maximum number of rows this query will return.
- #make_path(path) ⇒ Object
-
#next_code ⇒ Object
Get the next available code for the query.
-
#offset(start) ⇒ Object
Set the index of the first row of results this query will return.
-
#outerjoin(path) ⇒ Object
Explicitly declare a join to be an outer join.
-
#params ⇒ Object
Return the parameter hash for running this query in its current state.
-
#path(pathstr) ⇒ Object
Returns a Path object constructed from the given path-string, taking the current state of the query into account (its data-model and subclass constraints).
-
#remove_constraint(code) ⇒ Object
Remove the constraint with the given code from the query.
-
#results(start = nil, size = nil) ⇒ Object
Return objects corresponding to the type of data requested, starting at the given row offset.
-
#results_reader(start = 0, size = nil) ⇒ Object
Get your own result reader for handling the results at a low level.
-
#rows(start = nil, size = nil) ⇒ Object
Returns an Enumerable of ResultRow objects containing the data returned by running this query, starting at the given offset and containing up to the given maximum size.
- #sequences(range) ⇒ Object
-
#set_logic(value) ⇒ Object
(also: #constraintLogic=)
Set the logic to the given value.
-
#sortOrder=(so) ⇒ Object
Set the sort order completely, replacing the current sort order.
-
#subclass_constraints ⇒ Object
Return all the constraints that restrict the class of paths in the query.
-
#subclasses ⇒ Object
Get the current sub-class map for this query.
-
#summaries(path, start = 0, size = nil) ⇒ Object
Return an Enumerable of summary items starting at the given offset.
-
#summarise(path, start = 0, size = nil) ⇒ Object
Return a summary for a column as a Hash.
-
#to_s ⇒ Object
Return the textual representation of the query.
-
#to_xml ⇒ Object
Return an XML document node representing the XML form of the query.
-
#used_codes ⇒ Object
Return the list of currently used codes by the query.
-
#view=(*view) ⇒ Object
(also: #select)
Replace any currently existing views with the given view list.
-
#where(*wheres) ⇒ Object
Add a constraint clause to the query.
Constructor Details
#initialize(model, root = nil, service = nil) ⇒ Query
Construct a new query object. You should not use this directly. Instead use the factory methods in Service.
query = service.query("Gene")
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/intermine/query.rb', line 290 def initialize(model, root=nil, service=nil) @model = model @service = service @url = (@service.nil?) ? nil : @service.root + Service::QUERY_RESULTS_PATH @list_upload_uri = (@service.nil?) ? nil : @service.root + Service::QUERY_TO_LIST_PATH @list_append_uri = (@service.nil?) ? nil : @service.root + Service::QUERY_APPEND_PATH if root @root = InterMine::Metadata::Path.new(root, model).rootClass end @size = nil @start = 0 @constraints = [] @joins = [] @views = [] @sort_order = [] @used_codes = [] @logic_parser = LogicParser.new(self) @constraint_factory = ConstraintFactory.new(self) end |
Instance Attribute Details
#constraints ⇒ Object (readonly)
All the current constraints on the query
262 263 264 |
# File 'lib/intermine/query.rb', line 262 def constraints @constraints end |
#joins ⇒ Object (readonly)
All the current Join objects on the query
259 260 261 |
# File 'lib/intermine/query.rb', line 259 def joins @joins end |
#list_append_uri ⇒ Object (readonly)
URLs for internal consumption.
277 278 279 |
# File 'lib/intermine/query.rb', line 277 def list_append_uri @list_append_uri end |
#list_upload_uri ⇒ Object (readonly)
URLs for internal consumption.
277 278 279 |
# File 'lib/intermine/query.rb', line 277 def list_upload_uri @list_upload_uri end |
#logic ⇒ Object (readonly)
The current logic (as a LogicGroup)
271 272 273 |
# File 'lib/intermine/query.rb', line 271 def logic @logic end |
#model ⇒ Object (readonly)
The data model associated with the query
256 257 258 |
# File 'lib/intermine/query.rb', line 256 def model @model end |
#name ⇒ Object
The (optional) name of the query. Used in automatic access (eg: “query1”)
247 248 249 |
# File 'lib/intermine/query.rb', line 247 def name @name end |
#root ⇒ Object
The root class of the query.
253 254 255 |
# File 'lib/intermine/query.rb', line 253 def root @root end |
#service ⇒ Object (readonly)
The service this query is associated with
274 275 276 |
# File 'lib/intermine/query.rb', line 274 def service @service end |
#size ⇒ Object
The number of rows to return - defaults to nil (all rows)
280 281 282 |
# File 'lib/intermine/query.rb', line 280 def size @size end |
#sort_order ⇒ Object (readonly)
The current sort-order.
268 269 270 |
# File 'lib/intermine/query.rb', line 268 def sort_order @sort_order end |
#start ⇒ Object
The index of the first row to return - defaults to 0 (first row)
283 284 285 |
# File 'lib/intermine/query.rb', line 283 def start @start end |
#title ⇒ Object
A human readable title of the query (eg: “Gene –> Protein Domain”)
250 251 252 |
# File 'lib/intermine/query.rb', line 250 def title @title end |
#views ⇒ Object (readonly)
All the columns currently selected for output.
265 266 267 |
# File 'lib/intermine/query.rb', line 265 def views @views end |
Class Method Details
.is_valid_code(str) ⇒ Object
Whether or not the argument is a valid constraint code.
to be valid, it must be a one character string between A and Z inclusive.
904 905 906 |
# File 'lib/intermine/query.rb', line 904 def self.is_valid_code(str) return (str.length == 1) && (str >= LOWEST_CODE) && (str <= HIGHEST_CODE) end |
.parser(model) ⇒ Object
Return a parser for deserialising queries.
parser = Query.parser(service.model)
query = parser.parse(string)
query.each_row |r|
puts r.to_h
end
318 319 320 |
# File 'lib/intermine/query.rb', line 318 def self.parser(model) return QueryLoader.new(model) end |
Instance Method Details
#add_constraint(*parameters) ⇒ Object
Add a constraint to the query matching the given parameters, and return the created constraint.
con = query.add_constraint("length", ">", 500)
Note that (at least for now) the style of argument used by where and add_constraint is not compatible. This is on the TODO list.
761 762 763 764 765 |
# File 'lib/intermine/query.rb', line 761 def add_constraint(*parameters) con = @constraint_factory.make_constraint(parameters) @constraints << con return con end |
#add_join(path, style = "OUTER") ⇒ Object Also known as: join
Declare how a particular join should be treated.
The default join style is for an INNER join, but joins can optionally be declared to be LEFT OUTER joins. The difference is that with an inner join, each join in the query implicitly constrains the values of that path to be non-null, whereas an outer-join allows null values in the joined path. If the path passed to the constructor has a chain of joins, the last section is the one the join is applied to.
query = service.query("Gene")
# Allow genes without proteins
query.add_join("proteins")
# Demand the results contain only those genes that have interactions that have interactingGenes,
# but allow those interactingGenes to not have any proteins.
query.add_join("interactions.interactingGenes.proteins")
The valid join styles are OUTER and INNER (case-insensitive). There is never any need to declare a join to be INNER, as it is inner by default. Consider using Query#outerjoin which is more explicitly declarative.
701 702 703 704 705 706 707 708 |
# File 'lib/intermine/query.rb', line 701 def add_join(path, style="OUTER") p = InterMine::Metadata::Path.new(add_prefix(path), @model, subclasses) if @root.nil? @root = p.rootClass end @joins << Join.new(p, style) return self end |
#add_prefix(x) ⇒ Object
Adds the root prefix to the given string.
Arguments:
x
-
An object with a #to_s method
Returns the prefixed string.
914 915 916 917 918 919 920 921 |
# File 'lib/intermine/query.rb', line 914 def add_prefix(x) x = x.to_s if @root && !x.start_with?(@root.name) return @root.name + "." + x else return x end end |
#add_sort_order(path, direction = "ASC") ⇒ Object Also known as: order_by, order
Add a sort order element to sort order information. A sort order consists of the name of an output column and (optionally) the direction to sort in. The default direction is “ASC”. The valid directions are “ASC” and “DESC” (case-insensitive).
query.add_sort_order("length")
query.add_sort_order("proteins.primaryIdentifier", "desc")
725 726 727 728 729 730 731 732 |
# File 'lib/intermine/query.rb', line 725 def add_sort_order(path, direction="ASC") p = self.path(path) if !@views.include? p raise ArgumentError, "Sort order (#{p}) not in view (#{@views.map {|v| v.to_s}.inspect} in #{self.name || 'unnamed query'})" end @sort_order << SortOrder.new(p, direction) return self end |
#add_views(*views) ⇒ Object Also known as: add_to_select
Add the given views (output columns) to the query.
Any columns ending in “*” will be interpreted as a request to add all attribute columns from that table to the query
Any columns that name a class or reference will add the id of that object to the query. This is helpful for creating lists and other specialist services.
query = service.query("Gene")
query.add_views("*")
query.add_to_select("*")
query.add_views("proteins.*")
query.add_views("pathways.*", "organism.shortName")
query.add_views("proteins", "exons")
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
# File 'lib/intermine/query.rb', line 617 def add_views(*views) views.flatten.map do |x| y = add_prefix(x) if y.end_with?("*") prefix = y.chomp(".*") path = make_path(prefix) add_views(path.end_cd.attributes.map {|x| prefix + "." + x.name}) else path = make_path(y) path = make_path(y.to_s + ".id") unless path.is_attribute? if @root.nil? @root = path.rootClass end @views << path end end return self end |
#all ⇒ Object
Return all result record objects returned by running this query.
551 552 553 |
# File 'lib/intermine/query.rb', line 551 def all return self.results end |
#all_rows ⇒ Object
Return all the rows returned by running the query
556 557 558 |
# File 'lib/intermine/query.rb', line 556 def all_rows return self.rows end |
#coded_constraints ⇒ Object
Return all the constraints that have codes and can thus participate in logic.
324 325 326 |
# File 'lib/intermine/query.rb', line 324 def coded_constraints return @constraints.select {|x| !x.is_a?(SubClassConstraint)} end |
#count ⇒ Object
Return the number of result rows this query will return in its current state. This makes a very small request to the webservice, and is the most efficient method of getting the size of the result set.
467 468 469 |
# File 'lib/intermine/query.rb', line 467 def count return results_reader.get_size end |
#each_result(start = nil, size = nil) ⇒ Object
Iterate over the results, one record at a time.
query.each_result do |gene|
puts gene.symbol
gene.proteins.each do |prot|
puts prot.primaryIdentifier
end
end
This method is now deprecated and will be removed in version 1 Please use Query#results
456 457 458 459 460 461 462 |
# File 'lib/intermine/query.rb', line 456 def each_result(start=nil, size=nil) start = start.nil? ? @start : start size = size.nil? ? @size : size results_reader(start, size).each_result {|row| yield row } end |
#each_row(start = nil, size = nil) ⇒ Object
Iterate over the results of this query one row at a time.
Rows support both array-like index based access as well as hash-like key based access. For key based acces you can use either the full path or the headless short version:
query.each_row do |row|
puts r["Gene.symbol"], r["proteins.primaryIdentifier"]
puts r[0]
puts r.to_a # Materialize the row an an Array
puts r.to_h # Materialize the row an a Hash
end
This method is now deprecated and will be removed in version 1 Please use Query#rows
436 437 438 439 440 441 442 |
# File 'lib/intermine/query.rb', line 436 def each_row(start=nil, size=nil) start = start.nil? ? @start : start size = size.nil? ? @size : size results_reader(start, size).each_row {|row| yield row } end |
#eql?(other) ⇒ Boolean
Return true if the other query has exactly the same configuration, and belongs to the same service.
370 371 372 373 374 375 376 |
# File 'lib/intermine/query.rb', line 370 def eql?(other) if other.is_a? Query return self.service == other.service && self.to_xml_to_s == other.to_xml.to_s else return false end end |
#first(start = 0) ⇒ Object
Get the first result record from the query, starting at the given offset. If the offset is large, then this is not an efficient way to retrieve this data, and you may with to consider a looping approach or row based access instead.
564 565 566 567 568 569 570 571 572 573 574 |
# File 'lib/intermine/query.rb', line 564 def first(start=0) current_row = 0 # Have to iterate as start refers to row count results_reader.each_result { |r| if current_row == start return r end current_row += 1 } return nil end |
#first_row(start = 0) ⇒ Object
Get the first row of results from the query, starting at the given offset.
577 578 579 |
# File 'lib/intermine/query.rb', line 577 def first_row(start = 0) return self.results(start, 1).first end |
#get_constraint(code) ⇒ Object
Get the constraint on the query with the given code. Raises an error if there is no such constraint.
583 584 585 586 587 588 589 590 |
# File 'lib/intermine/query.rb', line 583 def get_constraint(code) @constraints.each do |x| if x.respond_to?(:code) and x.code == code return x end end raise ArgumentError, "#{code} not in query" end |
#inspect ⇒ Object
Return an informative textual representation of the query.
938 939 940 |
# File 'lib/intermine/query.rb', line 938 def inspect return "<#{self.class.name} query=#{self.to_s.inspect}>" end |
#limit(size) ⇒ Object
Set the maximum number of rows this query will return.
This method can be used to set a default maximum size for a query. Set to nil for all rows. The value given here will be overridden by any value supplied by #each_row or #each_result, unless that value is nil, in which case this value will be used. If unset, the query will return all results.
Returns self for method chaining.
See also #size= and #offset
400 401 402 403 |
# File 'lib/intermine/query.rb', line 400 def limit(size) @size = size return self end |
#make_path(path) ⇒ Object
636 637 638 |
# File 'lib/intermine/query.rb', line 636 def make_path(path) return InterMine::Metadata::Path.new(path, @model, subclasses) end |
#next_code ⇒ Object
Get the next available code for the query.
883 884 885 886 887 888 889 890 |
# File 'lib/intermine/query.rb', line 883 def next_code c = LOWEST_CODE while Query.is_valid_code(c) return c unless used_codes.include?(c) c = c.next end raise RuntimeError, "Maximum number of codes reached - all 26 have been allocated" end |
#offset(start) ⇒ Object
Set the index of the first row of results this query will return.
This method can be used to set a value for the query offset. The value given here will be overridden by any value supplied by #each_row or #each_result. If unset, results will start from the first row.
Returns self for method chaining.
See also #start= and #limit
415 416 417 418 |
# File 'lib/intermine/query.rb', line 415 def offset(start) @start = start return self end |
#outerjoin(path) ⇒ Object
Explicitly declare a join to be an outer join.
713 714 715 |
# File 'lib/intermine/query.rb', line 713 def outerjoin(path) return add_join(path) end |
#params ⇒ Object
Return the parameter hash for running this query in its current state.
924 925 926 927 928 929 930 |
# File 'lib/intermine/query.rb', line 924 def params hash = {"query" => self.to_xml} if @service and @service.token hash["token"] = @service.token end return hash end |
#path(pathstr) ⇒ Object
Returns a Path object constructed from the given path-string, taking the current state of the query into account (its data-model and subclass constraints).
770 771 772 |
# File 'lib/intermine/query.rb', line 770 def path(pathstr) return InterMine::Metadata::Path.new(add_prefix(pathstr), @model, subclasses) end |
#remove_constraint(code) ⇒ Object
Remove the constraint with the given code from the query. If no such constraint exists, no error will be raised.
595 596 597 598 599 |
# File 'lib/intermine/query.rb', line 595 def remove_constraint(code) @constraints.reject! do |x| x.respond_to?(:code) and x.code == code end end |
#results(start = nil, size = nil) ⇒ Object
Return objects corresponding to the type of data requested, starting at the given row offset. Returns an Enumerable of InterMineObject, where each value is read one at a time from the connection.
genes = query.results
genes.last.symbol
=> "eve"
497 498 499 500 501 |
# File 'lib/intermine/query.rb', line 497 def results(start=nil, size=nil) start = start.nil? ? @start : start size = size.nil? ? @size : size return Results::ObjectReader.new(@url, self, start, size) end |
#results_reader(start = 0, size = nil) ⇒ Object
Get your own result reader for handling the results at a low level. If no columns have been selected for output before requesting results, all attribute columns will be selected.
381 382 383 384 385 386 |
# File 'lib/intermine/query.rb', line 381 def results_reader(start=0, size=nil) if @views.empty? select("*") end return Results::ResultsReader.new(@url, self, start, size) end |
#rows(start = nil, size = nil) ⇒ Object
Returns an Enumerable of ResultRow objects containing the data returned by running this query, starting at the given offset and containing up to the given maximum size.
The webservice enforces a maximum page-size of 10,000,000 rows, independent of any size you specify - this can be obviated with paging for large result sets.
rows = query.rows
rows.last["symbol"]
=> "eve"
483 484 485 486 487 |
# File 'lib/intermine/query.rb', line 483 def rows(start=nil, size=nil) start = start.nil? ? @start : start size = size.nil? ? @size : size return Results::RowReader.new(@url, self, start, size) end |
#sequences(range) ⇒ Object
546 547 548 |
# File 'lib/intermine/query.rb', line 546 def sequences(range) return Results::SeqReader.new(@service.root, clone, range) end |
#set_logic(value) ⇒ Object Also known as: constraintLogic=
Set the logic to the given value.
The value will be parsed for consistency is it is a logic string.
Returns self to support chaining.
871 872 873 874 875 876 877 878 |
# File 'lib/intermine/query.rb', line 871 def set_logic(value) if value.is_a?(LogicGroup) @logic = value else @logic = @logic_parser.parse_logic(value) end return self end |
#sortOrder=(so) ⇒ Object
Set the sort order completely, replacing the current sort order.
query.sortOrder = "Gene.length asc Gene.proteins.length desc"
The sort order expression will be parsed and checked for conformity with the current state of the query.
740 741 742 743 744 745 746 747 748 749 |
# File 'lib/intermine/query.rb', line 740 def sortOrder=(so) if so.is_a?(Array) sos = so else sos = so.split(/(ASC|DESC|asc|desc)/).map {|x| x.strip}.every(2) end sos.each do |args| add_sort_order(*args) end end |
#subclass_constraints ⇒ Object
Return all the constraints that restrict the class of paths in the query.
330 331 332 |
# File 'lib/intermine/query.rb', line 330 def subclass_constraints return @constraints.select {|x| x.is_a?(SubClassConstraint)} end |
#subclasses ⇒ Object
Get the current sub-class map for this query.
This contains information about which fields of this query have been declared to be restricted to contain only a subclass of their normal type.
> query = service.query("Gene")
> query.where(:microArrayResults => service.model.table("FlyAtlasResult"))
> query.subclasses
=> {"Gene.microArrayResults" => "FlyAtlasResult"}
671 672 673 674 675 676 677 678 679 |
# File 'lib/intermine/query.rb', line 671 def subclasses subclasses = {} @constraints.each do |con| if con.is_a?(SubClassConstraint) subclasses[con.path.to_s] = con.sub_class.to_s end end return subclasses end |
#summaries(path, start = 0, size = nil) ⇒ Object
Return an Enumerable of summary items starting at the given offset.
summary = query.summary_items("chromosome.primaryIdentifier")
top_chromosome = summary[0]["item"]
no_in_top_chrom = summary[0]["count"]
This can be made more efficient by passing in a size - ie, if you only want the top item, pass in an offset of 0 and a size of 1 and only that row will be fetched.
513 514 515 516 517 |
# File 'lib/intermine/query.rb', line 513 def summaries(path, start=0, size=nil) q = self.clone q.add_views(path) return Results::SummaryReader.new(@url, q, start, size, path) end |
#summarise(path, start = 0, size = nil) ⇒ Object
Return a summary for a column as a Hash
For numeric values the hash has four keys: “average”, “stdev”, “min”, and “max”.
summary = query.summarise("length")
puts summary["average"]
For non-numeric values, the hash will have each possible value as a key, and the count of the occurrences of that value in this query’s result set as the corresponding value:
summary = query.summarise("chromosome.primaryIdentifier")
puts summary["2L"]
To limit the size of the result set you can use start and size as per normal queries - this has no real effect with numeric queries, which always return the same information.
537 538 539 540 541 542 543 544 |
# File 'lib/intermine/query.rb', line 537 def summarise(path, start=0, size=nil) t = make_path(add_prefix(path)).end_type if InterMine::Metadata::Model::NUMERIC_TYPES.include? t return Hash[summaries(path, start, size).first.map {|k, v| [k, v.to_f]}] else return Hash[summaries(path, start, size).map {|sum| [sum["item"], sum["count"]]}] end end |
#to_s ⇒ Object
Return the textual representation of the query. Here it returns the Query XML
933 934 935 |
# File 'lib/intermine/query.rb', line 933 def to_s return to_xml.to_s end |
#to_xml ⇒ Object
Return an XML document node representing the XML form of the query.
This is the canonical serialisable form of the query.
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/intermine/query.rb', line 338 def to_xml doc = REXML::Document.new if @sort_order.empty? so = SortOrder.new(@views.first, "ASC") else so = @sort_order.join(" ") end query = doc.add_element("query", { "name" => @name, "model" => @model.name, "title" => @title, "sortOrder" => so, "view" => @views.join(" "), "constraintLogic" => @logic }.delete_if { |k, v | !v }) @joins.each { |join| query.add_element("join", join.attrs) } subclass_constraints.each { |con| query.add_element(con.to_elem) } coded_constraints.each { |con| query.add_element(con.to_elem) } return doc end |
#used_codes ⇒ Object
Return the list of currently used codes by the query.
893 894 895 896 897 898 899 |
# File 'lib/intermine/query.rb', line 893 def used_codes if @constraints.empty? return [] else return @constraints.select {|x| !x.is_a?(SubClassConstraint)}.map {|x| x.code} end end |
#view=(*view) ⇒ Object Also known as: select
Replace any currently existing views with the given view list. If the view is not already an Array, it will be split by commas and whitespace.
645 646 647 648 649 650 651 652 653 654 655 656 |
# File 'lib/intermine/query.rb', line 645 def view=(*view) @views = [] view.each do |v| if v.is_a?(Array) views = v else views = v.to_s.split(/(?:,\s*|\s+)/) end add_views(*views) end return self end |
#where(*wheres) ⇒ Object
Add a constraint clause to the query.
query.where(:symbol => "eve")
query.where(:symbol => %{eve h bib zen})
query.where(:length => {:le => 100}, :symbol => "eve*")
Interprets the arguments in a style similar to that of ActiveRecord constraints, and adds them to the query. If multiple constraints are supplied in a single hash (as in the third example), then the order in which they are applied to the query (and thus the codes they will receive) is not predictable. To determine the order use chained where clauses or use multiple hashes:
query.where({:length => {:le => 100}}, {:symbol => "eve*"})
Returns self to support method chaining
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 |
# File 'lib/intermine/query.rb', line 792 def where(*wheres) if @views.empty? self.select('*') end wheres.each do |w| w.each do |k,v| if v.is_a?(Hash) parameters = {:path => k} v.each do |subk, subv| normalised_k = subk.to_s.upcase.gsub(/_/, " ") if subk == :with parameters[:extra_value] = subv elsif subk == :sub_class parameters[subk] = subv elsif subk == :code parameters[:code] = subv elsif LoopConstraint.valid_ops.include?(normalised_k) parameters[:op] = normalised_k parameters[:loopPath] = subv else if subv.nil? if subk == "=" parameters[:op] = "IS NULL" elsif subk == "!=" parameters[:op] = "IS NOT NULL" else parameters[:op] = normalised_k end elsif subv.is_a?(Range) or subv.is_a?(Array) if subk == "=" parameters[:op] = "ONE OF" elsif subk == "!=" parameters[:op] = "NONE OF" else parameters[:op] = normalised_k end parameters[:values] = subv.to_a elsif subv.is_a?(Lists::List) if subk == "=" parameters[:op] = "IN" elsif subk == "!=" parameters[:op] = "NOT IN" else parameters[:op] = normalised_k end parameters[:value] = subv.name else parameters[:op] = normalised_k parameters[:value] = subv end end end add_constraint(parameters) elsif v.is_a?(Range) or v.is_a?(Array) add_constraint(k.to_s, 'ONE OF', v.to_a) elsif v.is_a?(InterMine::Metadata::ClassDescriptor) add_constraint(:path => k.to_s, :sub_class => v.name) elsif v.is_a?(InterMine::Lists::List) add_constraint(k.to_s, 'IN', v.name) elsif v.nil? add_constraint(k.to_s, "IS NULL") else if path(k.to_s).is_attribute? add_constraint(k.to_s, '=', v) else add_constraint(k.to_s, 'LOOKUP', v) end end end end return self end |