voruby 1.1 → 1.1.1

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/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