intermine 0.98.11 → 0.99.00

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