voruby 1.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/REQUIREMENTS CHANGED
@@ -1,6 +1,6 @@
1
- * ruby >= 1.8.4
1
+ * ruby >= 1.8.6
2
2
  * libxml (http://xmlsoft.org/)
3
3
  * libxml-ruby installed via gem (i.e. "gem install libxml-ruby")
4
4
  * xml-mapping installed via gem (i.e. "gem install xml-mapping")
5
- * activerecord installed via gem (i.e. "gem install activerecord")
6
- * activesupport installed via gem (i.e. "gem install activesupport")
5
+ * activerecord installed via gem (i.e. "gem install activerecord") for ActiveVotable
6
+ * activesupport installed via gem (i.e. "gem install activesupport") for ActiveVotable
data/Rakefile.rb CHANGED
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
6
6
 
7
7
  require 'rubygems'
8
8
 
9
- PKG_VERSION = ENV['version'] || '1.1' # VORuby version
9
+ PKG_VERSION = ENV['version'] || '1.1.1' # VORuby version
10
10
 
11
11
  task :default => [:doc] # By default, create documentation: rake
12
12
 
@@ -217,6 +217,8 @@ namespace 'voevent' do
217
217
  end
218
218
 
219
219
  namespace 'stc' do
220
+ task :test => ['v1_20:test']
221
+
220
222
  namespace 'v1_20' do
221
223
  Rake::TestTask.new(:test) do |t| # rake stc:v1_20:test
222
224
  t.test_files = FileList['test/stc/unittest_v1_20.rb']
@@ -271,11 +273,13 @@ end
271
273
 
272
274
  dist_dirs = ['lib', 'test']
273
275
  spec = Gem::Specification.new do |s|
276
+ s.required_ruby_version = '>= 1.8.6' # because of changes in REXML
277
+
274
278
  s.files = FileList['Rakefile.rb', 'LICENSE', 'REQUIREMENTS']
275
279
  dist_dirs.each do |dir|
276
280
  s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
277
281
  end
278
- s.add_dependency('libxml-ruby', '>= 0.3.8')
282
+ s.add_dependency('libxml-ruby', '= 0.3.8.4')
279
283
  s.add_dependency('xml-mapping', '>= 0.8.1')
280
284
  s.add_dependency('activerecord', '>= 1.14')
281
285
  s.add_dependency('activesupport', '>= 1.3')
@@ -68,7 +68,7 @@ module VORuby
68
68
  # This allows all the power of a full database manager + ActiveRecord
69
69
  # to be used in searching and manipulating the VOTable. It assumes
70
70
  # that the VOTable has one resource with one table and that the table
71
- # is encoded as text and binary.
71
+ # is encoded as text and not binary.
72
72
  #
73
73
  # ActiveVotable.establish_connection(
74
74
  # :adapter => 'postgresql'
@@ -93,6 +93,7 @@ module VORuby
93
93
  @@arow = []
94
94
  @@ordered_columns = []
95
95
  @@items_per_page = 20
96
+ @@added_col = false
96
97
 
97
98
  DATATYPE_CONVERSIONS = {
98
99
  'boolean' => :boolean,
@@ -112,16 +113,24 @@ module VORuby
112
113
  @@actions = {
113
114
  :on_start_element => {
114
115
  'FIELD' => Proc.new { |name, attrs|
115
- field_name = ActiveVotable.columnize(attrs['name'] || attrs['ID'] || "unknown_column_#{rand(1000000)}")
116
+ vot_col_name = attrs['name'] || attrs['ID'] || "unknown_column_#{rand(1000000)}"
117
+ field_name = ActiveVotable.columnize(vot_col_name)
116
118
  field_name = 'record_id' if field_name == 'id'
117
119
  field_type = ActiveVotable.column_type(attrs['datatype'] || 'char', attrs['arraysize'])
118
- @@ordered_columns << {:name => field_name, :type => field_type}
120
+ @@ordered_columns << {
121
+ :id => attrs['ID'],
122
+ :vot_col_name => vot_col_name, :name => field_name,
123
+ :datatype => attrs['datatype'], :type => field_type,
124
+ :ucd => attrs['ucd'],
125
+ :arraysize => attrs['arraysize']
126
+ }
119
127
 
120
128
  ActiveRecord::Schema.define do
121
129
  add_column(ActiveVotable.table_name(), field_name, field_type)
122
130
  end
123
131
  },
124
132
  'TD' => Proc.new{ |name, attrs|
133
+ @@added_col = false
125
134
  @@end_of_cell = false
126
135
  },
127
136
  'TABLEDATA' => Proc.new{ |name, attrs|
@@ -150,6 +159,7 @@ module VORuby
150
159
  },
151
160
  'TD' => Proc.new { |name|
152
161
  @@end_of_cell = true
162
+ @@arow << nil if !@@added_col # This is necessary because a blank tag doesn't trigger an on_characters callback.
153
163
  },
154
164
  'TABLEDATA' => Proc.new { |name|
155
165
  connection().commit_db_transaction()
@@ -157,6 +167,7 @@ module VORuby
157
167
  },
158
168
  :on_characters => Proc.new { |chars|
159
169
  @@arow << chars if !@@end_of_cell
170
+ @@added_col = true
160
171
  },
161
172
  :on_cdata_block => Proc.new{ |cdata|
162
173
  @@arow << cdata if !@@end_of_cell # not sure if this is safe
@@ -179,7 +190,9 @@ module VORuby
179
190
  ActiveVotable.src = src
180
191
  ActiveVotable.parser = VOTableExtractor.new(src, @@actions)
181
192
 
182
- set_table_name(tbl_name || "votable_#{Time.now.to_i}_#{rand(1000000)}")
193
+ tname = tbl_name || "votable_#{Time.now.to_i}_#{rand(1000000)}"
194
+ ActiveVotable.table_name = tname
195
+ set_table_name(tname)
183
196
 
184
197
  create_basic_schema()
185
198
  parse()
@@ -187,6 +200,24 @@ module VORuby
187
200
  return self
188
201
  end
189
202
  end
203
+
204
+ # Instantiate a VOTable that already exists inside
205
+ # the database. If the optional block is provided
206
+ # ActiveVotable.drop() will be called automatically.
207
+ # [_tbl_name:]
208
+ # The name of the database table the VOTable lives in.
209
+ def self.from_db_table(tbl_name, metadata=[], &block)
210
+ ActiveVotable.table_name = tbl_name
211
+ set_table_name(tbl_name)
212
+ @@ordered_columns = metadata
213
+
214
+ if block
215
+ block.call(self)
216
+ drop()
217
+ else
218
+ return self
219
+ end
220
+ end
190
221
 
191
222
  # Set the file name of the source VOTable.
192
223
  def self.src=(src)
@@ -208,6 +239,17 @@ module VORuby
208
239
  def self.parser
209
240
  @@parser
210
241
  end
242
+
243
+ # Set the name of the database table to use to store the VOTable.
244
+ # Typically you'll never use this directly but rather use build().
245
+ def self.table_name=(tbl_name)
246
+ @@table_name = tbl_name
247
+ end
248
+
249
+ # Get the name of the database table the VOTable is stored in.
250
+ def self.table_name
251
+ @@table_name
252
+ end
211
253
 
212
254
  # Set the number of records per page for use in paging results.
213
255
  def self.items_per_page=(num)
@@ -240,7 +282,11 @@ module VORuby
240
282
  # Erase the table out of the database.
241
283
  def self.drop
242
284
  ActiveRecord::Schema.define do
243
- drop_table ActiveVotable::table_name
285
+ begin
286
+ drop_table ActiveVotable::table_name
287
+ rescue ActiveRecord::StatementInvalid
288
+ # If a table has already gone bye-bye, well, that's life.
289
+ end
244
290
  end
245
291
  end
246
292
 
@@ -271,7 +317,7 @@ module VORuby
271
317
  case type
272
318
  when :integer then value.to_i
273
319
  when :float then value.to_f
274
- when :string then value
320
+ when :string then value.to_s
275
321
  when :boolean
276
322
  (value != 'false' and value != '0') ? true: false
277
323
  else value
@@ -311,6 +357,11 @@ module VORuby
311
357
  def self.page(page=1)
312
358
  find(:all, :order => 'id', :page => page)
313
359
  end
360
+
361
+ # Find the total number of pages.
362
+ def self.number_of_pages
363
+ (count() / items_per_page().to_f).ceil()
364
+ end
314
365
 
315
366
  # Iterate through each page in the VOTable. The
316
367
  # block receives the page number and the list of
@@ -329,6 +380,10 @@ module VORuby
329
380
  block.call(record)
330
381
  end
331
382
  end
383
+
384
+ def self.metadata
385
+ @@ordered_columns
386
+ end
332
387
 
333
388
  end
334
389
  end
@@ -809,22 +809,22 @@ module VORuby
809
809
  # Same as a TableType with an additional archive name.
810
810
  class ArchiveTable < FromTable
811
811
  attr_accessor :archive, :name, :alias_name
812
-
812
+
813
813
  def initialize(archive, name, alias_name=nil)
814
814
  self.archive = archive
815
815
  self.name = name
816
816
  self.alias_name = alias_name
817
817
  end
818
-
818
+
819
819
  def to_s
820
820
  "{archive=#{self.archive},name=#{self.name},alias=#{self.alias_name}}"
821
821
  end
822
-
822
+
823
823
  def self.from_xml(node)
824
- archive = node.attributes['Archive'] or raise "No ArchiveTable attribute 'Archive'"
825
- #name = CGI::escapeHTML(node.attributes['Name']) or raise "No ArchiveTable attribute 'Name'"
826
- name = node.attributes['Name'] or raise "No ArchiveTable attribute 'Name'"
827
- alias_name = node.attributes['Alias']
824
+ archive = node.attributes['Archive'] or '' #or raise "No ArchiveTable attribute 'Archive'"
825
+ name = CGI::escapeHTML(node.attributes['Name']) or raise "No ArchiveTable attribute 'Name'"
826
+ #name = node.attributes['Name'] or raise "No ArchiveTable attribute 'Name'"
827
+ alias_name = node.attributes['Alias'] or ''
828
828
 
829
829
  at = ArchiveTable.new(archive, name, alias_name)
830
830
  end
@@ -997,6 +997,13 @@ module VORuby
997
997
  return self
998
998
  end
999
999
  end
1000
+
1001
+ # This method counts the number of times that a condition appears.
1002
+ def count_condition(attributes, times)
1003
+ times = self.cond1.count_condition(attributes, times)
1004
+ times = self.cond2.count_condition(attributes, times)
1005
+ return times
1006
+ end
1000
1007
  end
1001
1008
 
1002
1009
  # Represents expressions like A Or B.
@@ -1097,6 +1104,13 @@ module VORuby
1097
1104
  return self
1098
1105
  end
1099
1106
  end
1107
+
1108
+ # This method counts the number of times that a condition appears.
1109
+ def count_condition(attributes, times)
1110
+ times = self.cond1.count_condition(attributes, times)
1111
+ times = self.cond2.count_condition(attributes, times)
1112
+ return times
1113
+ end
1100
1114
  end
1101
1115
 
1102
1116
  # A cross match expression.
@@ -1265,6 +1279,13 @@ module VORuby
1265
1279
  end
1266
1280
  return 1
1267
1281
  end
1282
+
1283
+ # This method counts the number of times that a condition appears.
1284
+ def count_condition(attributes, times)
1285
+ return times += 1 if self.arg.table == attributes['table'] and
1286
+ self.arg.name == attributes['name']
1287
+ return times
1288
+ end
1268
1289
  end
1269
1290
 
1270
1291
  # The Not Like expression of a query.
@@ -1493,6 +1514,13 @@ module VORuby
1493
1514
  end
1494
1515
  return 1
1495
1516
  end
1517
+
1518
+ # This method counts the number of times that a condition appears.
1519
+ def count_condition(attributes, times)
1520
+ return times += 1 if self.arg1.table == attributes['table'] and
1521
+ self.arg1.name == attributes['name']
1522
+ return times
1523
+ end
1496
1524
  end
1497
1525
 
1498
1526
  # Represents the Between expression of a query.
@@ -1617,6 +1645,13 @@ module VORuby
1617
1645
  end
1618
1646
  return 1
1619
1647
  end
1648
+
1649
+ # This method counts the number of times that a condition appears.
1650
+ def count_condition(attributes, times)
1651
+ return times += 1 if self.arg1.table == attributes['table'] and
1652
+ self.arg1.name == attributes['name']
1653
+ return times
1654
+ end
1620
1655
  end
1621
1656
 
1622
1657
  # Represents expressions like Not A.
@@ -1709,15 +1744,20 @@ module VORuby
1709
1744
 
1710
1745
  def self.from_xml(node)
1711
1746
  unit = node.attributes['unit'] || 'deg'
1712
-
1713
- center = REXML::XPath.first(node, 'reg:Center', {'reg' => 'http://www.ivoa.net/xml/STC/STCregion/v1.10'}).text
1747
+
1748
+ # Find the prefix for STCregion.
1749
+ region_prefix = node.namespaces.index('http://www.ivoa.net/xml/STC/STCregion/v1.10')
1750
+
1751
+ center_tag = region_prefix ? "#{region_prefix}:Center" : 'Center'
1752
+ center = REXML::XPath.first(node, center_tag).text
1714
1753
  ra_s, dec_s = center.split(/\s+/)
1715
1754
  ra = RealType.new(ra_s.to_f)
1716
1755
  dec = RealType.new(dec_s.to_f)
1717
-
1718
- radius_s = REXML::XPath.first(node, 'reg:Radius', {'reg' => 'http://www.ivoa.net/xml/STC/STCregion/v1.10'}).text
1756
+
1757
+ radius_tag = region_prefix ? "#{region_prefix}:Radius" : 'Radius'
1758
+ radius_s = REXML::XPath.first(node, radius_tag).text
1719
1759
  radius = RealType.new(radius_s.to_f)
1720
-
1760
+
1721
1761
  return Circle.new(ra, dec, radius)
1722
1762
  end
1723
1763
 
@@ -1936,6 +1976,12 @@ module VORuby
1936
1976
  end
1937
1977
  return 1
1938
1978
  end
1979
+
1980
+ # This method counts the number of times that a condition appears.
1981
+ def count_condition(attributes, times)
1982
+ #TODO
1983
+ return 1
1984
+ end
1939
1985
  end
1940
1986
 
1941
1987
  # Represents expressions like Not A.
@@ -2082,6 +2128,12 @@ module VORuby
2082
2128
  self.condition = condition
2083
2129
  end
2084
2130
  end
2131
+
2132
+ # This method counts the number of times that a condition appears.
2133
+ def count_condition(attributes)
2134
+ times = 0
2135
+ return self.condition.count_condition(attributes, times)
2136
+ end
2085
2137
  end
2086
2138
 
2087
2139
  # Represents the From part of the query.
@@ -3,9 +3,8 @@ class REXML::Element
3
3
  if !ns
4
4
  return self.attributes[attr_name]
5
5
  else
6
- ns_index = self.namespaces.index(ns)
7
- if ns_index
8
- ns_prefix = self.prefixes[ns_index]
6
+ ns_prefix = self.namespaces.index(ns)
7
+ if ns_prefix
9
8
  return self.attributes["#{ns_prefix}:#{attr_name}"]
10
9
  else
11
10
  return nil
@@ -1,4 +1,5 @@
1
1
  require 'rexml/element'
2
+ require 'cgi'
2
3
 
3
4
  require 'voruby/loader'
4
5
  require 'voruby/votables/misc'
@@ -64,6 +64,7 @@ module VORuby
64
64
  text_node :value, '', :optional => false
65
65
 
66
66
  def value=(short_name)
67
+ short_name.strip!
67
68
  raise RuntimeError, "ShortName '#{short_name}' must have <= 16 characters" if short_name.size > 16
68
69
 
69
70
  @value = short_name
@@ -84,8 +85,12 @@ module VORuby
84
85
  def value=(uri)
85
86
  # Strictly, this should be ivo only, but I notice that sometimes http is used.
86
87
  #raise RuntimeError, "IdentifierURI '#{uri}' in wrong format" if !uri.strip.match('^(ivo|http):')
87
-
88
- @value = URI.parse(uri.strip)
88
+
89
+ begin
90
+ @value = URI.parse(uri.strip)
91
+ rescue URI::InvalidURIError
92
+ return nil
93
+ end
89
94
  end
90
95
  end
91
96
 
@@ -27,8 +27,8 @@ module VORuby
27
27
  params['in2'] = radius
28
28
  params['in3'] = multiple_tables
29
29
 
30
- map_names = @driver.makeCircleMap(params.to_soap_map)['makeCircleMapReturn']
31
-
30
+ map_names = driver.makeCircleMap(params.to_soap_map)['makeCircleMapReturn']
31
+
32
32
  map_names = [map_names] if !map_names.is_a?(Array)
33
33
  return map_names
34
34
  end
@@ -7,7 +7,7 @@ module VORuby
7
7
  class WesixException < RuntimeError; end
8
8
  class NoVotableException < WesixException
9
9
  def initialize
10
- super('VOTABLE missing from SOAP response. ' +
10
+ super('VOTable missing from SOAP response. ' +
11
11
  'Often this is caused by an overly large catalog. ' +
12
12
  'Try increasing your detection threshold.')
13
13
  end
@@ -16,7 +16,7 @@ module VORuby
16
16
  @driver.wiredump_dev = $stderr if debug
17
17
  end
18
18
 
19
- def self.from_wsdl(wsdl='http://vizier.cfa.harvard.edu:8080/axis/services/Sesame?wsdl', debug=false)
19
+ def self.from_wsdl(wsdl='http://cdsws.u-strasbg.fr/axis/services/Sesame?wsdl', debug=false)
20
20
  return Sesame.new(SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver, debug)
21
21
  end
22
22