intermine 0.98.08 → 0.98.09

Sign up to get free protection for your applications and to get access to all the features.
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