intermine 0.98.11 → 0.99.00

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/TODO ADDED
@@ -0,0 +1,3 @@
1
+ json formats (and benchmarks)
2
+ test for CD.find
3
+
@@ -675,13 +675,10 @@ module InterMine::Lists
675
675
  def make_list_names(objs)
676
676
  current_names = list_names
677
677
  return objs.map do |x|
678
- case x
679
- when List
680
- x.name
681
- when x.respond_to?(:list_upload_uri)
682
- create_list(x).name
683
- when current_names.include?(x.to_s)
684
- x.to_s
678
+ case
679
+ when x.is_a?(List) then x.name
680
+ when x.respond_to?(:list_upload_uri) then create_list(x).name
681
+ when current_names.include?(x.to_s) then x.to_s
685
682
  else
686
683
  raise ArgumentError, "#{x} is not a list you can access"
687
684
  end
@@ -711,15 +708,17 @@ module InterMine::Lists
711
708
  else
712
709
  begin
713
710
  container = JSON.parse(response.body)
714
- raise ServiceError, container["error"]
711
+ err = container["error"]
715
712
  rescue
716
713
  response.error!
717
714
  end
715
+ raise ServiceError, container["error"]
718
716
  end
719
717
  end
720
718
 
721
719
  # Routine for creating a list from a PathQuery::Query
722
720
  def create_list_from_query(query, tags=[], name=nil, description=nil)
721
+ query = get_listable_query(query)
723
722
  uri = query.list_upload_uri
724
723
  list_params = {
725
724
  "listName" => name,
@@ -731,6 +730,19 @@ module InterMine::Lists
731
730
  return Net::HTTP.post_form(URI.parse(uri), params)
732
731
  end
733
732
 
733
+ def get_listable_query(query)
734
+ clone = query.clone()
735
+ views = clone.views
736
+ selected_classes = views.map {|x| x.prefix}.uniq {|p| p.to_s}
737
+ if selected_classes.size == 1
738
+ return clone.select(selected_classes.first.append("id"))
739
+ elsif selected_classes.size == 0
740
+ return clone.select("#{clone.root.name}.id")
741
+ end
742
+ # Bound to fail, but let the service provide the message.
743
+ return clone
744
+ end
745
+
734
746
  # Routine for creating a List in a webservice from a list of Ids.
735
747
  def create_list_from_ids(ids, type, tags=[], name=nil, description=nil)
736
748
  if @service.model.get_cd(type).nil?
@@ -402,6 +402,46 @@ module Metadata
402
402
  return q
403
403
  end
404
404
 
405
+ # call-seq:
406
+ # find(*attributes) => Enumerable[InterMineObject]
407
+ #
408
+ # Get the items in the database matching the identifiers.
409
+ #
410
+ # zen = model.table("Gene").find("zen")
411
+ # puts zen.length, zen.organism.name
412
+ #
413
+ # find may retrun multiple results:
414
+ #
415
+ # genes = model.table("Gene").find("zen", "eve", "r", "h")
416
+ #
417
+ # The search mechanism used is a "lookup" constraint, so extra-values
418
+ # may be provided to distinguish search terms by passing key-value pairs:
419
+ #
420
+ # starting_with_c = model.table("Gene").find("c*" => "D. melanogaster")
421
+ #
422
+ def find(*attrs)
423
+ q = new_query
424
+ q.select("*")
425
+ attrs.each do |attr|
426
+ if attr.is_a? Hash
427
+ attr.each do |term, extra|
428
+ q.or(@root, "LOOKUP", term, extra)
429
+ end
430
+ else
431
+ q.or(@root, "LOOKUP", attr)
432
+ end
433
+ end
434
+
435
+ c = q.count()
436
+ if c < 1
437
+ raise ItemNotFoundError
438
+ elsif c == 1
439
+ return q.results.first
440
+ else
441
+ return q.results
442
+ end
443
+ end
444
+
405
445
  # call-seq:
406
446
  # where(*constraints) => PathQuery::Query
407
447
  #
@@ -749,11 +789,55 @@ module Metadata
749
789
  end
750
790
  end
751
791
 
792
+ # call-seq:
793
+ # end => ClassDescriptor | ReferenceDescriptor | AttributeDescriptor
794
+ #
795
+ # Return the last element of this path
796
+ #
797
+ def end
798
+ return @elements.last
799
+ end
800
+
801
+ # call-seq:
802
+ # prefix => Path
803
+ #
804
+ # Return the Path one above this.
805
+ def prefix
806
+ if @elements.size == 1
807
+ raise PathException, "Root paths do not have a prefix"
808
+ end
809
+ new_str = @elements[0, @elements.size - 1].map {|x| x.name}.join(".")
810
+ return Path.new(new_str, @model, @subclasses)
811
+ end
812
+
813
+ # call-seq:
814
+ # append(part, ...) => Path
815
+ #
816
+ # Return a new path by adding elements to this path.
817
+ #
818
+ def append(*parts)
819
+ new_str = self.to_s + "." + parts.join(".")
820
+ return Path.new(new_str, @model, @subclasses)
821
+ end
822
+
752
823
  # Two paths can be said to be equal when they stringify to the same representation.
753
824
  def ==(other)
754
825
  return self.to_s == other.to_s
755
826
  end
756
827
 
828
+ # Two paths are identical when they have the same everything.
829
+ def eql?(other)
830
+ begin
831
+ return (self == other) && @model.eql?(other.model) && @subclasses.eql?(other.subclasses)
832
+ rescue
833
+ return false
834
+ end
835
+ end
836
+
837
+ def hash
838
+ return 17 * @model.hash * 11 * @subclasses.hash * 3 * to_s.hash
839
+ end
840
+
757
841
  # Get the number of elements in the path
758
842
  def length
759
843
  return @elements.length
@@ -880,6 +964,9 @@ module Metadata
880
964
  end
881
965
  end
882
966
  end
967
+
968
+ class ItemNotFoundError < RuntimeError
969
+ end
883
970
  end
884
971
  end
885
972
 
@@ -762,6 +762,32 @@ module InterMine::PathQuery
762
762
  @constraints << con
763
763
  return con
764
764
  end
765
+
766
+ def or(*parameters)
767
+ logic = @logic
768
+ new_con = add_constraint(*parameters)
769
+
770
+ if logic
771
+ set_logic(LogicGroup.new(logic, "OR", new_con))
772
+ elsif @constraints.size > 1
773
+ set_logic(@constraints.map {|c| c.code }.join(" or "))
774
+ end
775
+
776
+ return self
777
+ end
778
+
779
+ def and(*parameters)
780
+ logic = @logic
781
+ new_con = add_constraint(*parameters)
782
+
783
+ if logic
784
+ set_logic(LogicGroup.new(logic, "AND", new_con))
785
+ elsif @constraints.size > 1
786
+ set_logic(@constraints.map {|c| c.code }.join(" and "))
787
+ end
788
+
789
+ return self
790
+ end
765
791
 
766
792
  # Returns a Path object constructed from the given path-string,
767
793
  # taking the current state of the query into account (its data-model
@@ -826,7 +852,7 @@ module InterMine::PathQuery
826
852
  end
827
853
  parameters[:values] = subv.to_a
828
854
  elsif subv.is_a?(Lists::List)
829
- if subk == "="
855
+ if subk == "=" or subk == "<" or subk == "<="
830
856
  parameters[:op] = "IN"
831
857
  elsif subk == "!="
832
858
  parameters[:op] = "NOT IN"
@@ -834,6 +860,19 @@ module InterMine::PathQuery
834
860
  parameters[:op] = normalised_k
835
861
  end
836
862
  parameters[:value] = subv.name
863
+ elsif subv.is_a? Query
864
+ if subk == "=" or subk == "<" or subk == "<="
865
+ parameters[:op] = "IN"
866
+ elsif subk == "!="
867
+ parameters[:op] = "NOT IN"
868
+ else
869
+ parameters[:op] = normalised_k
870
+ end
871
+ s = subv.service
872
+ l = s.create_list(subv)
873
+
874
+ parameters[:value] = l.name
875
+
837
876
  else
838
877
  parameters[:op] = normalised_k
839
878
  parameters[:value] = subv
@@ -85,12 +85,12 @@ module InterMine::Results
85
85
  def [](arg, length=nil)
86
86
  unless length.nil?
87
87
  raise ArgumentError, "when providing a length, the first argument must be an Integer" unless arg.is_a? Integer
88
- return @results[arg, length].map {|x| x["value"]}
88
+ return @results[arg, length].map {|x| value_of(x)}
89
89
  end
90
90
 
91
91
  case arg
92
92
  when Range
93
- return @results[arg].map {|x| x["value"]}
93
+ return @results[arg].map {|x| value_of(x)}
94
94
  when Integer
95
95
  idx = arg
96
96
  else
@@ -103,17 +103,17 @@ module InterMine::Results
103
103
 
104
104
  raise IndexError, "Argument out of range" if cell.nil?
105
105
 
106
- return cell["value"]
106
+ return value_of(cell)
107
107
  end
108
108
 
109
109
  # Returns the first value in this row
110
110
  def first
111
- return @results[0]["value"]
111
+ return value_of(@results[0])
112
112
  end
113
113
 
114
114
  # Returns the last value in this row
115
115
  def last
116
- return @results.last["value"]
116
+ return value_of(@results.last)
117
117
  end
118
118
 
119
119
  # Iterate over the values in this row in the
@@ -134,9 +134,11 @@ module InterMine::Results
134
134
  def each(&block)
135
135
  if block
136
136
  if block.arity == 1
137
- @results.each {|x| block.call(x["value"])}
137
+ @results.each {|x| block.call(value_of(x))}
138
138
  else block.arity == 2
139
- (0 ... @results.size).to_a.each {|i| block.call(@columns[i], @results[i]["value"])}
139
+ (0 ... @results.size).to_a.each {|i|
140
+ block.call(@columns[i], value_of(@results[i]))
141
+ }
140
142
  end
141
143
  end
142
144
  return self
@@ -154,7 +156,7 @@ module InterMine::Results
154
156
 
155
157
  # Return an Array version of the row.
156
158
  def to_a
157
- return @results.map {|x| x["value"]}
159
+ return @results.map {|x| value_of(x)}
158
160
  end
159
161
 
160
162
  # Return a Hash version of the row. All keys in this
@@ -185,11 +187,15 @@ module InterMine::Results
185
187
  # CSV or TSV file. The optional separator argument will be used to delimit
186
188
  # columns
187
189
  def to_csv(sep="\t")
188
- return @results.map {|x| x["value"].inspect}.join(sep)
190
+ return @results.map {|x| value_of(x).inspect}.join(sep)
189
191
  end
190
192
 
191
193
  private
192
194
 
195
+ def value_of(cell)
196
+ return cell["value"]
197
+ end
198
+
193
199
  # Return the index for a string or symbol key.
194
200
  def index_for(key)
195
201
  if @indexes.nil?
@@ -209,6 +215,13 @@ module InterMine::Results
209
215
  end
210
216
  end
211
217
 
218
+ class NewResultRow < ResultsRow
219
+
220
+ def value_of(cell)
221
+ return cell
222
+ end
223
+ end
224
+
212
225
  # The class responsible for retrieving results and processing them
213
226
  #
214
227
  # query.each_row do |row|
@@ -250,11 +263,13 @@ module InterMine::Results
250
263
 
251
264
  # Iterate over the result set one ResultsRow at a time
252
265
  def each_row
266
+ cls = @query.service.version >= 8 ? NewResultRow : ResultsRow
267
+ format = @query.service.version >= 8 ? "json" : "jsonrows"
253
268
  processor = lambda {|line|
254
269
  x = line.chomp.chomp(",")
255
- x.empty? ? nil : ResultsRow.new(x, @query.views)
270
+ x.empty? ? nil : cls.new(x, @query.views)
256
271
  }
257
- read_result_set(params("jsonrows"), processor) {|x|
272
+ read_result_set(params(format), processor) {|x|
258
273
  yield x
259
274
  }
260
275
  end
@@ -12,5 +12,7 @@ module Intermine
12
12
  # 0.98.10 - Added status property to lists
13
13
  # 0.98.09 - Major changes to results - now with thorough-going Enumerable support
14
14
  # 0.98.08 - Added column summary support
15
- VERSION = "0.98.11"
15
+ # 0.99.00 - Added coercion from query to lists in "IN/NOT IN" constraints
16
+ # - Added support for "json" format (performance) improvement
17
+ VERSION = "0.99.00"
16
18
  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/intermine-test", "Z1a3D3U16cicCdS0T6y4bdN1SQh")
9
+ @service = Service.new("localhost/intermine-test", "test-user-token")
10
10
  @temp_lists = []
11
11
  end
12
12
 
@@ -48,42 +48,42 @@ class LiveDemoTest < Test::Unit::TestCase
48
48
  def testListEnumerability
49
49
  list = @service.list("My-Favourite-Employees")
50
50
  names = list.map {|emp| emp.name }
51
- exp = ["Bernd Stromberg", "David Brent", "Neil Godwin", "Timo Becker"]
51
+ exp = ["David Brent", "Neil Godwin", "Bernd Stromberg", "Timo Becker"]
52
52
  assert_equal(exp, names)
53
53
 
54
- old = list.select {|emp| emp.age > 55}
54
+ old = list.select {|emp| emp.age > 42}
55
55
  assert_equal(1, old.size)
56
- assert_equal("David Brent", old.first.name)
56
+ assert_equal("Neil Godwin", old.first.name)
57
57
 
58
58
  sum = list.reduce(0) {|m, i| m + i.age}
59
- assert_equal(185, sum)
59
+ assert_equal(159, sum)
60
60
  end
61
61
 
62
62
  def testLazyReferenceFetching
63
63
  list = @service.list("My-Favourite-Employees")
64
64
 
65
65
  deps = list.map {|emp| emp.department.name }
66
- exp = ["Schadensregulierung M-Z", "Sales",
67
- "Human Resources", "Schadensregulierung"]
66
+ exp = ["Sales", "Human Resources",
67
+ "Schadensregulierung M-Z", "Schadensregulierung"]
68
68
  assert_equal(exp, deps)
69
69
 
70
70
  comps = list.map {|emp| emp.department.company.name }
71
- exp = ["Capitol Versicherung AG", "Wernham-Hogg",
72
- "Wernham-Hogg", "Capitol Versicherung AG"]
71
+ exp = [ "Wernham-Hogg","Wernham-Hogg",
72
+ "Capitol Versicherung AG", "Capitol Versicherung AG"]
73
73
  assert_equal(exp, comps)
74
74
  end
75
75
 
76
76
  def testLazyCollectionFetching
77
77
  list = @service.list("My-Favourite-Employees")
78
78
  emps = list.map {|manager| manager.department.employees.map {|employee| employee.age} }
79
- exp = [[42, 28, 29, 46, 28, 48],
80
- [62, 64, 58, 35, 36, 46],
81
- [41, 57, 36],
82
- [63, 37, 61, 55, 58, 45]]
79
+ exp = [[34, 36, 41, 55, 61, 61],
80
+ [44, 49, 62],
81
+ [30, 37, 45, 46, 58, 64],
82
+ [36, 37, 39, 49, 57, 59]]
83
83
  assert_equal(exp, emps)
84
84
 
85
85
  sum = list.reduce(0) {|m, manager| m + manager.department.employees.reduce(0) {|n, emp| n + emp.age}}
86
- assert_equal(975, sum)
86
+ assert_equal(1000, sum)
87
87
  end
88
88
 
89
89
  def testListCreation
@@ -130,4 +130,15 @@ class LiveDemoTest < Test::Unit::TestCase
130
130
  assert_equal(tags.sort, new_list.tags.sort)
131
131
  end
132
132
 
133
+ def testCoercingQueriesToLists
134
+ q1 = @service.query("Bank")
135
+ q2 = @service.query("Bank").where("corporateCustomers.id" => {'!=' => nil})
136
+
137
+ assert_equal(2, @service.query("Bank").where("Bank" => {:not_in => q2}).count)
138
+
139
+ l = @service.subtract([q1], [q2])
140
+ @temp_lists << l
141
+ assert_equal(2, l.size)
142
+ end
143
+
133
144
  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: 385
5
- prerelease: false
4
+ hash: 403
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 98
9
- - 11
10
- version: 0.98.11
8
+ - 99
9
+ - 0
10
+ version: 0.99.00
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Kalderimis
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-01 00:00:00 +00:00
19
- default_executable:
18
+ date: 2011-12-12 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: json
@@ -149,9 +148,9 @@ files:
149
148
  - LICENCE
150
149
  - Rakefile
151
150
  - README.rdoc
151
+ - TODO
152
152
  - Gemfile
153
153
  - contact_header.rdoc
154
- has_rdoc: true
155
154
  homepage: http://www.intermine.org
156
155
  licenses:
157
156
  - LGPL
@@ -185,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
184
  requirements: []
186
185
 
187
186
  rubyforge_project: intermine
188
- rubygems_version: 1.3.7
187
+ rubygems_version: 1.7.2
189
188
  signing_key:
190
189
  specification_version: 3
191
190
  summary: Webservice Client Library for InterMine Data-Warehouses