intermine 0.98.08 → 0.98.09

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -52,17 +52,10 @@ end
52
52
 
53
53
  Rake::TestTask.new(:live_tests) do |t|
54
54
  t.libs << "test"
55
- t.test_files = FileList['test/live_test.rb'] << FileList['test/live_summary_test.rb']
55
+ t.test_files = FileList['test/live_test.rb'] << FileList['test/live_summary_test.rb'] << FileList['test/live_results.rb']
56
56
  t.verbose = true
57
57
  end
58
58
 
59
- Rake::TestTask.new(:live_summary) do |t|
60
- t.libs << "test"
61
- t.test_files = FileList['test/live_summary_test.rb']
62
- t.verbose = true
63
- end
64
-
65
-
66
59
  Rake::RDocTask.new do |t|
67
60
  t.title = 'InterMine Webservice Client Documentation'
68
61
  t.rdoc_files.include 'README.rdoc'
@@ -430,6 +430,9 @@ module InterMine::PathQuery
430
430
  # puts r.to_h # Materialize the row an a Hash
431
431
  # end
432
432
  #
433
+ # This method is now deprecated and will be removed in version 1
434
+ # Please use Query#rows
435
+ #
433
436
  def each_row(start=nil, size=nil)
434
437
  start = start.nil? ? @start : start
435
438
  size = size.nil? ? @size : size
@@ -447,6 +450,9 @@ module InterMine::PathQuery
447
450
  # end
448
451
  # end
449
452
  #
453
+ # This method is now deprecated and will be removed in version 1
454
+ # Please use Query#results
455
+ #
450
456
  def each_result(start=nil, size=nil)
451
457
  start = start.nil? ? @start : start
452
458
  size = size.nil? ? @size : size
@@ -462,7 +468,7 @@ module InterMine::PathQuery
462
468
  return results_reader.get_size
463
469
  end
464
470
 
465
- # Returns an Array of ResultRow objects containing the
471
+ # Returns an Enumerable of ResultRow objects containing the
466
472
  # data returned by running this query, starting at the given offset and
467
473
  # containing up to the given maximum size.
468
474
  #
@@ -477,15 +483,12 @@ module InterMine::PathQuery
477
483
  def rows(start=nil, size=nil)
478
484
  start = start.nil? ? @start : start
479
485
  size = size.nil? ? @size : size
480
- res = []
481
- results_reader(start, size).each_row {|row|
482
- res << row
483
- }
484
- res
486
+ return Results::RowReader.new(@url, self, start, size)
485
487
  end
486
488
 
487
489
  # Return objects corresponding to the type of data requested, starting
488
- # at the given row offset.
490
+ # at the given row offset. Returns an Enumerable of InterMineObject,
491
+ # where each value is read one at a time from the connection.
489
492
  #
490
493
  # genes = query.results
491
494
  # genes.last.symbol
@@ -494,47 +497,49 @@ module InterMine::PathQuery
494
497
  def results(start=nil, size=nil)
495
498
  start = start.nil? ? @start : start
496
499
  size = size.nil? ? @size : size
497
- res = []
498
- results_reader(start, size).each_result {|row|
499
- res << row
500
- }
501
- res
500
+ return Results::ObjectReader.new(@url, self, start, size)
502
501
  end
503
502
 
504
- def summary_items(summary_path, start=0, size=nil)
503
+ # Return an Enumerable of summary items starting at the given offset.
504
+ #
505
+ # summary = query.summary_items("chromosome.primaryIdentifier")
506
+ # top_chromosome = summary[0]["item"]
507
+ # no_in_top_chrom = summary[0]["count"]
508
+ #
509
+ # This can be made more efficient by passing in a size - ie, if
510
+ # you only want the top item, pass in an offset of 0 and a size of 1
511
+ # and only that row will be fetched.
512
+ #
513
+ def summaries(path, start=0, size=nil)
505
514
  q = self.clone
506
- q.add_views(summary_path)
507
- rr = q.results_reader(start, size)
508
- if block_given?
509
- rr.each_summary(summary_path) {|summary|
510
- yield summary
511
- }
512
- else
513
- ret = []
514
- rr.each_summary(summary_path) {|summary|
515
- ret << summary
516
- }
517
- return ret
518
- end
515
+ q.add_views(path)
516
+ return Results::SummaryReader.new(@url, q, start, size, path)
519
517
  end
520
518
 
521
- def summarise(summary_path, start=0, size=nil)
522
- path = make_path(add_prefix(summary_path))
523
- q = self.clone
524
- q.add_views(summary_path)
525
- rr = q.results_reader(start, size)
526
- if InterMine::Metadata::Model::NUMERIC_TYPES.include? path.end_type
527
- h = {}
528
- rr.each_summary(summary_path) { |summary|
529
- h = Hash[summary.map {|k, v| [k, v.to_f]}]
530
- }
531
- return h
519
+ # Return a summary for a column as a Hash
520
+ #
521
+ # For numeric values the hash has four keys: "average", "stdev", "min", and "max".
522
+ #
523
+ # summary = query.summarise("length")
524
+ # puts summary["average"]
525
+ #
526
+ # For non-numeric values, the hash will have each possible value as a key, and the
527
+ # count of the occurrences of that value in this query's result set as the
528
+ # corresponding value:
529
+ #
530
+ # summary = query.summarise("chromosome.primaryIdentifier")
531
+ # puts summary["2L"]
532
+ #
533
+ # To limit the size of the result set you can use start and size as per normal
534
+ # queries - this has no real effect with numeric queries, which always return the
535
+ # same information.
536
+ #
537
+ def summarise(path, start=0, size=nil)
538
+ t = make_path(add_prefix(path)).end_type
539
+ if InterMine::Metadata::Model::NUMERIC_TYPES.include? t
540
+ return Hash[summaries(path, start, size).first.map {|k, v| [k, v.to_f]}]
532
541
  else
533
- h = {}
534
- rr.each_summary(summary_path) {|summary|
535
- h[summary["item"]] = summary["count"]
536
- }
537
- return h
542
+ return Hash[summaries(path, start, size).map {|sum| [sum["item"], sum["count"]]}]
538
543
  end
539
544
  end
540
545
 
@@ -1639,21 +1644,96 @@ module InterMine::PathQuery
1639
1644
  return p
1640
1645
  end
1641
1646
 
1647
+ # Returns an Enumerable of ResultRow objects containing the
1648
+ # data returned by running this query, starting at the given offset and
1649
+ # containing up to the given maximum size.
1650
+ #
1651
+ # The webservice enforces a maximum page-size of 10,000,000 rows,
1652
+ # independent of any size you specify - this can be obviated with paging
1653
+ # for large result sets.
1654
+ #
1655
+ # names = template.rows("A" => "eve").map {|r| r["name"]}
1656
+ #
1657
+ def rows(params = {}, start=0, size=nil)
1658
+ runner = (params.empty?) ? self : get_adjusted(params)
1659
+ return self.class.superclass.instance_method(:rows).bind(runner).call(start, size)
1660
+ end
1661
+
1642
1662
  def each_row(params = {}, start=0, size=nil)
1643
1663
  runner = (params.empty?) ? self : get_adjusted(params)
1644
1664
  runner.results_reader(start, size).each_row {|r| yield r}
1645
1665
  end
1646
1666
 
1667
+ # Return objects corresponding to the type of data requested, starting
1668
+ # at the given row offset. Returns an Enumerable of InterMineObject,
1669
+ # where each value is read one at a time from the connection.
1670
+ #
1671
+ # template.results("A" => "eve").each {|gene|
1672
+ # puts gene.symbol
1673
+ # }
1674
+ #
1675
+ def results(params = {}, start=0, size=nil)
1676
+ runner = (params.empty?) ? self : get_adjusted(params)
1677
+ return self.class.superclass.instance_method(:results).bind(runner).call(start, size)
1678
+ end
1679
+
1647
1680
  def each_result(params = {}, start=0, size=nil)
1648
1681
  runner = (params.empty?) ? self : get_adjusted(params)
1649
1682
  runner.results_reader(start, size).each_result {|r| yield r}
1650
1683
  end
1651
1684
 
1685
+ # Return an Enumerable of summary items starting at the given offset.
1686
+ #
1687
+ # summary = template.summary_items("chromosome.primaryIdentifier", {"A" => "Pentose Phosphate Pathway"})
1688
+ # top_chromosome = summary[0]["item"]
1689
+ # no_in_top_chrom = summary[0]["count"]
1690
+ #
1691
+ # This can be made more efficient by passing in a size - ie, if
1692
+ # you only want the top item, pass in an offset of 0 and a size of 1
1693
+ # and only that row will be fetched.
1694
+ #
1695
+ def summaries(path, params = {}, start=0, size=nil)
1696
+ runner = (params.empty?) ? self : get_adjusted(params)
1697
+ return self.class.superclass.instance_method(:summaries).bind(runner).call(path, start, size)
1698
+ end
1699
+
1700
+ # Return a summary for a column as a Hash
1701
+ #
1702
+ # For numeric values the hash has four keys: "average", "stdev", "min", and "max".
1703
+ #
1704
+ # summary = template.summarise("length", {"A" => "eve"})
1705
+ # puts summary["average"]
1706
+ #
1707
+ # For non-numeric values, the hash will have each possible value as a key, and the
1708
+ # count of the occurrences of that value in this query's result set as the
1709
+ # corresponding value:
1710
+ #
1711
+ # summary = template.summarise("chromosome.primaryIdentifier", {"A" => "eve"})
1712
+ # puts summary["2L"]
1713
+ #
1714
+ # To limit the size of the result set you can use start and size as per normal
1715
+ # queries - this has no real effect with numeric queries, which always return the
1716
+ # same information.
1717
+ #
1718
+ def summarise(path, params={}, start=0, size=nil)
1719
+ t = make_path(add_prefix(path)).end_type
1720
+ if InterMine::Metadata::Model::NUMERIC_TYPES.include? t
1721
+ return Hash[summaries(path, params, start, size).first.map {|k, v| [k, v.to_f]}]
1722
+ else
1723
+ return Hash[summaries(path, params, start, size).map {|sum| [sum["item"], sum["count"]]}]
1724
+ end
1725
+ end
1726
+
1727
+ # Return the number of result rows this query will return in its current state.
1728
+ # This makes a very small request to the webservice, and is the most efficient
1729
+ # method of getting the size of the result set.
1652
1730
  def count(params = {})
1653
1731
  runner = (params.empty?) ? self : get_adjusted(params)
1654
1732
  runner.results_reader.get_size
1655
1733
  end
1656
1734
 
1735
+ # Return a clone of the current template. Changes made to the clone will not effect
1736
+ # the cloned query.
1657
1737
  def clone
1658
1738
  other = super
1659
1739
  other.instance_variable_set(:@constraints, @constraints.map {|c| c.clone})
@@ -209,7 +209,6 @@ module InterMine::Results
209
209
  end
210
210
  end
211
211
 
212
-
213
212
  # The class responsible for retrieving results and processing them
214
213
  #
215
214
  # query.each_row do |row|
@@ -251,7 +250,10 @@ module InterMine::Results
251
250
 
252
251
  # Iterate over the result set one ResultsRow at a time
253
252
  def each_row
254
- processor = lambda {|x| ResultsRow.new(x.chomp("," + $/), @query.views) }
253
+ processor = lambda {|line|
254
+ x = line.chomp.chomp(",")
255
+ x.empty? ? nil : ResultsRow.new(x, @query.views)
256
+ }
255
257
  read_result_set(params("jsonrows"), processor) {|x|
256
258
  yield x
257
259
  }
@@ -274,7 +276,10 @@ module InterMine::Results
274
276
  #
275
277
  def each_result
276
278
  model = @query.model
277
- processor = lambda {|x| model.make_new(JSON.parse(x.chomp("," + $/)))}
279
+ processor = lambda {|line|
280
+ x = line.chomp.chomp(",")
281
+ x.empty? ? nil : model.make_new(JSON.parse(x))
282
+ }
278
283
  read_result_set(params("jsonobjects"), processor) {|x|
279
284
  yield x
280
285
  }
@@ -283,7 +288,10 @@ module InterMine::Results
283
288
  def each_summary(summary_path)
284
289
  extra = {"summaryPath" => @query.add_prefix(summary_path)}
285
290
  p = params("jsonrows").merge(extra)
286
- processor = lambda {|x| JSON.parse(x.chomp("," + $/)) }
291
+ processor = lambda {|line|
292
+ x = line.chomp.chomp(",")
293
+ x.empty? ? nil : JSON.parse(x)
294
+ }
287
295
  read_result_set(p, processor) {|x|
288
296
  yield x
289
297
  }
@@ -300,9 +308,11 @@ module InterMine::Results
300
308
  begin
301
309
  row = processor.call(line)
302
310
  rescue => e
303
- raise ServiceError, "Error parsing #{line}: #{e.message}"
311
+ raise ServiceError, "Error parsing '#{line}': #{e.message}"
312
+ end
313
+ unless row.nil?
314
+ yield row
304
315
  end
305
- yield row
306
316
  else
307
317
  container << line
308
318
  if line.chomp($/).end_with?("[")
@@ -330,7 +340,9 @@ module InterMine::Results
330
340
  if sock.eof?
331
341
  holdover = line
332
342
  else
333
- yield line
343
+ unless line.empty?
344
+ yield line
345
+ end
334
346
  end
335
347
  }
336
348
  sock.close
@@ -363,6 +375,35 @@ module InterMine::Results
363
375
  end
364
376
  end
365
377
 
378
+ class RowReader < ResultsReader
379
+
380
+ include Enumerable
381
+
382
+ alias :each :each_row
383
+ end
384
+
385
+ class ObjectReader < ResultsReader
386
+
387
+ include Enumerable
388
+
389
+ alias :each :each_result
390
+
391
+ end
392
+
393
+ class SummaryReader < ResultsReader
394
+
395
+ include Enumerable
396
+
397
+ def initialize(uri, query, start, size, path)
398
+ super(uri, query, start, size)
399
+ @path = path
400
+ end
401
+
402
+ def each
403
+ each_summary(@path) {|x| yield x}
404
+ end
405
+ end
406
+
366
407
  # Errors if there are problems retrieving results from the webservice.
367
408
  class ServiceError < RuntimeError
368
409
  end
@@ -1,3 +1,9 @@
1
1
  module Intermine
2
- VERSION = "0.98.08"
2
+
3
+ # Webservice Client Version number
4
+ #
5
+ # Changes:
6
+ # 0.98.09 - Major changes to results - now with thorough-going Enumerable support
7
+ # 0.98.08 - Added column summary support
8
+ VERSION = "0.98.09"
3
9
  end
@@ -6,7 +6,7 @@ require "intermine/service"
6
6
  class LiveDemoTest < Test::Unit::TestCase
7
7
 
8
8
  def setup
9
- @service = Service.new("http://localhost:8080/intermine-test")
9
+ @service = Service.new("http://localhost/intermine-test", "Z1a3D3U16cicCdS0T6y4bdN1SQh")
10
10
  end
11
11
 
12
12
  def testVersion
@@ -22,35 +22,15 @@ class LiveDemoTest < Test::Unit::TestCase
22
22
  assert_equal(3, @service.query("Department").where(:name => "Sales").count)
23
23
  end
24
24
 
25
- end
26
-
27
- class LiveFlyMineTest < Test::Unit::TestCase
28
-
29
- def setup
30
- @service = Service.new("www.flymine.org/query")
25
+ def testGetTemplate
26
+ template = @service.template("ManagerLookup")
27
+ assert_equal("ManagerLookup", template.name)
28
+ assert_equal(1, template.constraints.length)
31
29
  end
32
30
 
33
- # Tests a number of integrated features:
34
- # * Getting a template
35
- # * Passing template parameters
36
- # * getting counts
37
- # * getting rows
38
- # * getting records
39
- #
40
- def testBigResultSet
41
- template = @service.template("Chromosome_Gene")
42
- args = {"A" => {"!=" => '2L'}}
43
- size = template.count(args)
44
- i = 0
45
- template.each_row(args) do |r|
46
- i += 1
47
- end
48
- assert_equal(size, i)
49
- i = 0
50
- template.each_result(args) do |r|
51
- i += 1
52
- end
53
- assert_equal(size, i)
31
+ def testGetLists
32
+ list = @service.list("My-Favourite-Employees")
33
+ assert_equal(4, list.size)
54
34
  end
55
- end
56
35
 
36
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intermine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 391
4
+ hash: 389
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 98
9
- - 8
10
- version: 0.98.08
9
+ - 9
10
+ version: 0.98.09
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Kalderimis