voruby 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (257) hide show
  1. data/Rakefile.rb +107 -224
  2. data/lib/misc.rb +1 -0
  3. data/lib/misc/misc.rb +60 -0
  4. data/lib/misc/propertyfile.rb +31 -0
  5. data/lib/symphony.rb +1 -0
  6. data/lib/symphony/symphony.rb +247 -0
  7. data/lib/voruby.rb +186 -0
  8. data/lib/voruby/active_votable/active_votable.rb +468 -347
  9. data/lib/voruby/adql/1.0/adql.rb +2418 -0
  10. data/lib/voruby/adql/support.rb +2 -0
  11. data/lib/voruby/misc.rb +351 -0
  12. data/lib/voruby/misc/connection_monitor.rb +97 -0
  13. data/lib/voruby/misc/libxml_ext.rb +121 -0
  14. data/lib/voruby/misc/rexml_ext.rb +223 -0
  15. data/lib/voruby/resolver/resolver.rb +12 -0
  16. data/lib/voruby/resolver/sesame.rb +299 -0
  17. data/lib/voruby/sky_query/sky_query.rb +192 -0
  18. data/lib/voruby/stc/1.10/coords.rb +2272 -0
  19. data/lib/voruby/stc/1.10/region.rb +892 -0
  20. data/lib/voruby/stc/1.10/stc.rb +3271 -0
  21. data/lib/voruby/stc/1.30/stc.rb +8666 -0
  22. data/lib/voruby/stc/support.rb +2 -0
  23. data/lib/voruby/ucd/ucd.rb +173 -0
  24. data/lib/voruby/voevent/1.1/voevent.rb +1124 -0
  25. data/lib/voruby/voevent/support.rb +5 -0
  26. data/lib/voruby/votable/1.0/votable.rb +1807 -0
  27. data/lib/voruby/votable/1.1/votable.rb +2100 -0
  28. data/lib/voruby/votable/votable.rb +305 -0
  29. data/lib/voruby/wesix/wesix.rb +491 -0
  30. data/lib/voruby/xlink/1.2/xlink.rb +21 -0
  31. data/test/voruby/active_votable/complex.vot +60 -0
  32. data/test/voruby/active_votable/error.vot +6 -0
  33. data/test/voruby/active_votable/large.vot +130040 -0
  34. data/test/voruby/active_votable/simple1.vot +38 -0
  35. data/test/voruby/active_votable/simple2.vot +38 -0
  36. data/test/voruby/active_votable/test.rb +193 -0
  37. data/test/voruby/adql/1.0/adql-alias.sql +1 -0
  38. data/test/voruby/adql/1.0/adql-alias.xml +26 -0
  39. data/test/voruby/adql/1.0/adql-avg.sql +1 -0
  40. data/test/voruby/adql/1.0/adql-avg.xml +31 -0
  41. data/test/voruby/adql/1.0/adql-circle.sql +1 -0
  42. data/test/voruby/adql/1.0/adql-circle.xml +46 -0
  43. data/test/voruby/adql/1.0/adql-expr.sql +1 -0
  44. data/test/voruby/adql/1.0/adql-expr.xml +34 -0
  45. data/test/voruby/adql/1.0/adql-function.sql +1 -0
  46. data/test/voruby/adql/1.0/adql-function.xml +41 -0
  47. data/test/voruby/adql/1.0/adql-group.sql +1 -0
  48. data/test/voruby/adql/1.0/adql-group.xml +51 -0
  49. data/test/voruby/adql/1.0/adql-having.sql +1 -0
  50. data/test/voruby/adql/1.0/adql-having.xml +25 -0
  51. data/test/voruby/adql/1.0/adql-like.sql +1 -0
  52. data/test/voruby/adql/1.0/adql-like.xml +17 -0
  53. data/test/voruby/adql/1.0/adql-order.sql +1 -0
  54. data/test/voruby/adql/1.0/adql-order.xml +37 -0
  55. data/test/voruby/adql/1.0/adql-simple.sql +1 -0
  56. data/test/voruby/adql/1.0/adql-simple.xml +12 -0
  57. data/test/voruby/adql/1.0/adql-top.sql +1 -0
  58. data/test/voruby/adql/1.0/adql-top.xml +33 -0
  59. data/test/voruby/adql/1.0/test.rb +2220 -0
  60. data/test/voruby/misc/test.rb +32 -0
  61. data/test/voruby/resolver/sesame/test.rb +56 -0
  62. data/test/voruby/sky_query/test.rb +107 -0
  63. data/test/voruby/stc/1.10/coords_test.rb +3704 -0
  64. data/test/voruby/stc/1.10/region_test.rb +993 -0
  65. data/test/voruby/stc/1.10/stc-catalog-entry-location.xml +112 -0
  66. data/test/voruby/stc/1.10/stc-obs-data-location.xml +126 -0
  67. data/test/voruby/stc/1.10/stc-region-circle.xml +5 -0
  68. data/test/voruby/stc/1.10/stc-region-convex.xml +11 -0
  69. data/test/voruby/stc/1.10/stc-region-convexhull.xml +5 -0
  70. data/test/voruby/stc/1.10/stc-region-ellipse.xml +7 -0
  71. data/test/voruby/stc/1.10/stc-region-intersection.xml +25 -0
  72. data/test/voruby/stc/1.10/stc-region-negation.xml +7 -0
  73. data/test/voruby/stc/1.10/stc-region-polygon.xml +13 -0
  74. data/test/voruby/stc/1.10/stc-region-sector.xml +6 -0
  75. data/test/voruby/stc/1.10/stc-region-union.xml +25 -0
  76. data/test/voruby/stc/1.10/stc-resource-profile.xml +60 -0
  77. data/test/voruby/stc/1.10/stc-search-location.xml +54 -0
  78. data/test/voruby/stc/1.10/stc_test.rb +4626 -0
  79. data/test/voruby/stc/1.30/stc-catalog-entry-location.xml +210 -0
  80. data/test/voruby/stc/1.30/stc-obs-data-location-arecibo.xml +353 -0
  81. data/test/voruby/stc/1.30/stc-obs-data-location-fits.xml +250 -0
  82. data/test/voruby/stc/1.30/stc-obs-data-location-xlink.xml +63 -0
  83. data/test/voruby/stc/1.30/stc-obs-data-location.xml +216 -0
  84. data/test/voruby/stc/1.30/stc-resource-profile-unusual-ref-pos.xml +39 -0
  85. data/test/voruby/stc/1.30/stc-resource-profile.xml +129 -0
  86. data/test/voruby/stc/1.30/stc-search-location-arecibo.xml +86 -0
  87. data/test/voruby/stc/1.30/stc-search-location.xml +101 -0
  88. data/test/voruby/stc/1.30/test.rb +6274 -0
  89. data/test/voruby/ucd/test.rb +48 -0
  90. data/test/voruby/voevent/1.1/test.rb +812 -0
  91. data/test/{voevent/voevent_v1_1.xml → voruby/voevent/1.1/voevent.xml} +2 -2
  92. data/test/voruby/voregistry/0.3/test.rb +137 -0
  93. data/test/voruby/votable/1.0/test.rb +714 -0
  94. data/test/voruby/votable/1.0/votable.basic.xml +660 -0
  95. data/test/voruby/votable/1.0/votable.html +86 -0
  96. data/test/voruby/votable/1.0/votable.ns.xml +56 -0
  97. data/test/voruby/votable/1.1/test.rb +785 -0
  98. data/test/voruby/votable/1.1/votable.basic.xml +38 -0
  99. data/test/voruby/votable/1.1/votable.html +86 -0
  100. data/test/voruby/votable/1.1/votable.ns.xml +56 -0
  101. data/test/voruby/votable/test.rb +15 -0
  102. data/test/voruby/wesix/test.rb +268 -0
  103. data/test/voruby/wesix/testr.fits +28 -0
  104. metadata +234 -247
  105. data/REQUIREMENTS +0 -6
  106. data/lib/voruby/active_votable/loader.rb +0 -5
  107. data/lib/voruby/adql/adql.rb +0 -2787
  108. data/lib/voruby/adql/ext.rb +0 -14
  109. data/lib/voruby/adql/loader.rb +0 -6
  110. data/lib/voruby/adql/operations.rb +0 -54
  111. data/lib/voruby/adql/parser.rb +0 -160
  112. data/lib/voruby/adql/transforms.rb +0 -573
  113. data/lib/voruby/ext.rb +0 -17
  114. data/lib/voruby/loader.rb +0 -4
  115. data/lib/voruby/misc/propertyfile.rb +0 -36
  116. data/lib/voruby/plastic/applications.rb +0 -174
  117. data/lib/voruby/plastic/constants.rb +0 -30
  118. data/lib/voruby/plastic/loader.rb +0 -10
  119. data/lib/voruby/plastic/plastic.rb +0 -1
  120. data/lib/voruby/resources/conesearch/conesearch.rb +0 -9
  121. data/lib/voruby/resources/conesearch/conesearch_v0_2.rb +0 -55
  122. data/lib/voruby/resources/conesearch/conesearch_v0_3.rb +0 -50
  123. data/lib/voruby/resources/conesearch/conesearch_v1_0.rb +0 -72
  124. data/lib/voruby/resources/conesearch/loader.rb +0 -4
  125. data/lib/voruby/resources/loader.rb +0 -50
  126. data/lib/voruby/resources/nodes.rb +0 -190
  127. data/lib/voruby/resources/openskynode/loader.rb +0 -4
  128. data/lib/voruby/resources/openskynode/openskynode.rb +0 -9
  129. data/lib/voruby/resources/openskynode/openskynode_v0_1.rb +0 -54
  130. data/lib/voruby/resources/sia/loader.rb +0 -5
  131. data/lib/voruby/resources/sia/sia.rb +0 -9
  132. data/lib/voruby/resources/sia/sia_v0_6.rb +0 -90
  133. data/lib/voruby/resources/sia/sia_v0_7.rb +0 -89
  134. data/lib/voruby/resources/sia/sia_v1_0.rb +0 -122
  135. data/lib/voruby/resources/stsci.rb +0 -59
  136. data/lib/voruby/resources/vodataservice/coverage_v0_2.rb +0 -195
  137. data/lib/voruby/resources/vodataservice/coverage_v0_3.rb +0 -158
  138. data/lib/voruby/resources/vodataservice/loader.rb +0 -5
  139. data/lib/voruby/resources/vodataservice/vodataservice.rb +0 -9
  140. data/lib/voruby/resources/vodataservice/vodataservice_v0_4.rb +0 -189
  141. data/lib/voruby/resources/vodataservice/vodataservice_v0_5.rb +0 -163
  142. data/lib/voruby/resources/vodataservice/vodataservice_v1_0.rb +0 -221
  143. data/lib/voruby/resources/voregistry/loader.rb +0 -4
  144. data/lib/voruby/resources/voregistry/voregistry.rb +0 -9
  145. data/lib/voruby/resources/voregistry/voregistry_v0_2.rb +0 -40
  146. data/lib/voruby/resources/voregistry/voregistry_v0_3.rb +0 -30
  147. data/lib/voruby/resources/voregistry/voregistry_v1_0.rb +0 -86
  148. data/lib/voruby/resources/voresource/loader.rb +0 -17
  149. data/lib/voruby/resources/voresource/voresource.rb +0 -9
  150. data/lib/voruby/resources/voresource/voresource_v0_10.rb +0 -327
  151. data/lib/voruby/resources/voresource/voresource_v0_9.rb +0 -405
  152. data/lib/voruby/resources/voresource/voresource_v1_0.rb +0 -230
  153. data/lib/voruby/services/ext.rb +0 -11
  154. data/lib/voruby/services/gestalt/footprint.rb +0 -95
  155. data/lib/voruby/services/gestalt/wcs_fixer.rb +0 -105
  156. data/lib/voruby/services/gestalt/wesix.rb +0 -155
  157. data/lib/voruby/services/loader.rb +0 -7
  158. data/lib/voruby/services/registry/registry.rb +0 -53
  159. data/lib/voruby/services/resolver/resolver.rb +0 -35
  160. data/lib/voruby/services/schema/schema.rb +0 -644
  161. data/lib/voruby/sesame/loader.rb +0 -6
  162. data/lib/voruby/sesame/sesame_v1_0.rb +0 -64
  163. data/lib/voruby/simple/loader.rb +0 -6
  164. data/lib/voruby/simple/parameters.rb +0 -196
  165. data/lib/voruby/simple/sap.rb +0 -446
  166. data/lib/voruby/spacetime/loader.rb +0 -3
  167. data/lib/voruby/spacetime/spacetime.rb +0 -607
  168. data/lib/voruby/stc/coords_v1_20.rb +0 -900
  169. data/lib/voruby/stc/loader.rb +0 -55
  170. data/lib/voruby/stc/region_v1_20.rb +0 -274
  171. data/lib/voruby/stc/stc_v1_20.rb +0 -1196
  172. data/lib/voruby/util.rb +0 -27
  173. data/lib/voruby/voevent/loader.rb +0 -7
  174. data/lib/voruby/voevent/voevent_v1_0.rb +0 -213
  175. data/lib/voruby/voevent/voevent_v1_1.rb +0 -196
  176. data/lib/voruby/votables/chandra.rb +0 -373
  177. data/lib/voruby/votables/data.rb +0 -179
  178. data/lib/voruby/votables/galex.rb +0 -377
  179. data/lib/voruby/votables/int.rb +0 -354
  180. data/lib/voruby/votables/libxml_parser.rb +0 -411
  181. data/lib/voruby/votables/libxml_votable.rb +0 -67
  182. data/lib/voruby/votables/loader.rb +0 -10
  183. data/lib/voruby/votables/meta.rb +0 -763
  184. data/lib/voruby/votables/misc.rb +0 -51
  185. data/lib/voruby/votables/nsa.rb +0 -410
  186. data/lib/voruby/votables/rexml_parser.rb +0 -408
  187. data/lib/voruby/votables/rexml_votable.rb +0 -67
  188. data/lib/voruby/votables/sdss.rb +0 -356
  189. data/lib/voruby/votables/transforms.rb +0 -388
  190. data/lib/voruby/votables/tree.rb +0 -45
  191. data/lib/voruby/votables/types.rb +0 -391
  192. data/lib/voruby/votables/votable.rb +0 -687
  193. data/test/active_votable/database.yml +0 -6
  194. data/test/active_votable/test.vot +0 -168492
  195. data/test/active_votable/unittest.rb +0 -41
  196. data/test/adql/test1.adql +0 -49
  197. data/test/adql/test2.adql +0 -51
  198. data/test/adql/test3.adql +0 -81
  199. data/test/adql/test4.adql +0 -53
  200. data/test/adql/test5.adql +0 -55
  201. data/test/adql/test6.adql +0 -18
  202. data/test/adql/test7.adql +0 -48
  203. data/test/adql/unittest.rb +0 -1672
  204. data/test/plastic/test.rb +0 -44
  205. data/test/plastic/test.vot +0 -5385
  206. data/test/plastic/unittest.rb +0 -66
  207. data/test/resources/conesearch/conesearch_v0_3.xml +0 -31
  208. data/test/resources/conesearch/conesearch_v1_0.xml +0 -86
  209. data/test/resources/conesearch/unittest_v0_3.rb +0 -22
  210. data/test/resources/conesearch/unittest_v1_0.rb +0 -24
  211. data/test/resources/openskynode/open_sky_node_v0_1.xml +0 -32
  212. data/test/resources/openskynode/unittest_v0_1.rb +0 -31
  213. data/test/resources/sia/simple_image_access_v0_7.xml +0 -36
  214. data/test/resources/sia/simple_image_access_v1_0.xml +0 -122
  215. data/test/resources/sia/unittest_v0_7.rb +0 -24
  216. data/test/resources/sia/unittest_v1_0.rb +0 -29
  217. data/test/resources/stsci.xml +0 -336
  218. data/test/resources/unittest_stsci.rb +0 -25
  219. data/test/resources/vodataservice/catalog_service_resource_v1_0.xml +0 -128
  220. data/test/resources/vodataservice/data_collection_resource_v0_5.xml +0 -54
  221. data/test/resources/vodataservice/data_collection_resource_v1_0.xml +0 -117
  222. data/test/resources/vodataservice/data_service_resource_v1_0.xml +0 -115
  223. data/test/resources/vodataservice/sky_service_resource_v0_10.xml +0 -45
  224. data/test/resources/vodataservice/table_service_resource_v1_0.xml +0 -122
  225. data/test/resources/vodataservice/tabular_sky_service_resource_v0_10.xml +0 -60
  226. data/test/resources/vodataservice/unittest_v0_5.rb +0 -126
  227. data/test/resources/vodataservice/unittest_v1_0.rb +0 -151
  228. data/test/resources/voregistry/authority_resource_v0_3.xml +0 -20
  229. data/test/resources/voregistry/authority_resource_v1_0.xml +0 -82
  230. data/test/resources/voregistry/registry_service_v0_3.xml +0 -20
  231. data/test/resources/voregistry/registry_service_v1_0.xml +0 -107
  232. data/test/resources/voregistry/unittest_v0_3.rb +0 -31
  233. data/test/resources/voregistry/unittest_v1_0.rb +0 -34
  234. data/test/resources/voresource/organisation_resource_v1_0.xml +0 -90
  235. data/test/resources/voresource/resource_organisation_v0_10.xml +0 -22
  236. data/test/resources/voresource/resource_service_v0_10.xml +0 -19
  237. data/test/resources/voresource/resource_v0_10.xml +0 -19
  238. data/test/resources/voresource/resource_v1_0.xml +0 -79
  239. data/test/resources/voresource/service_resource_v1_0.xml +0 -91
  240. data/test/resources/voresource/unittest_v0_10.rb +0 -61
  241. data/test/resources/voresource/unittest_v0_9.rb +0 -4
  242. data/test/resources/voresource/unittest_v1_0.rb +0 -190
  243. data/test/services/gestalt/unittest.rb +0 -74
  244. data/test/services/registry/unittest.rb +0 -34
  245. data/test/services/resolver/unittest.rb +0 -38
  246. data/test/simple/unittest.rb +0 -46
  247. data/test/spacetime/unittest.rb +0 -39
  248. data/test/stc/catalog_entry_location_v1_20.xml +0 -112
  249. data/test/stc/obs_data_location_v1_20.xml +0 -108
  250. data/test/stc/search_location_v1_20.xml +0 -54
  251. data/test/stc/stc_resource_profile_v1_20.xml +0 -60
  252. data/test/stc/unittest_v1_20.rb +0 -620
  253. data/test/voevent/unittest_v1_0.rb +0 -79
  254. data/test/voevent/unittest_v1_1.rb +0 -70
  255. data/test/voevent/voevent_v1_0.xml +0 -96
  256. data/test/votables/test.vot +0 -366
  257. data/test/votables/unittest.rb +0 -54
@@ -1,6 +0,0 @@
1
- * ruby >= 1.8.6
2
- * libxml (http://xmlsoft.org/)
3
- * libxml-ruby installed via gem (i.e. "gem install libxml-ruby")
4
- * xml-mapping installed via gem (i.e. "gem install xml-mapping")
5
- * activerecord installed via gem (i.e. "gem install activerecord") for ActiveVotable
6
- * activesupport installed via gem (i.e. "gem install activesupport") for ActiveVotable
@@ -1,5 +0,0 @@
1
- require 'voruby/loader'
2
-
3
- require 'active_record'
4
- require 'active_support/inflector'
5
- require 'xml/libxml'
@@ -1,2787 +0,0 @@
1
- require 'voruby/adql/loader'
2
-
3
- # A set of classes designed to read and manipulate ADQL[http://www.ivoa.net/Documents/latest/ADQL.html].
4
- module VORuby
5
-
6
- module ADQL
7
- # Acts as glue between xsi:types and their corresponding
8
- # domain objects in the * hierarchy.
9
- class ObjectBuilder
10
- def self.classes
11
- {:allSelectionItemType => AllSelectionItem,
12
- :columnReferenceType => ColumnReference,
13
- :tableType => ArchiveTable,
14
- :atomType => Atom,
15
- :stringType => StringType,
16
- :realType => RealType,
17
- :integerType => IntegerType,
18
- :binaryExprType => BinaryExpr,
19
- :unaryExprType => UnaryExpr,
20
- :closedExprType => ClosedExpr,
21
- :trigonometricFunctionType => TrigonometricFunction,
22
- :trigonometricFunctionNameType => TrigonometricFunctionName,
23
- :mathFunctionType => MathFunction,
24
- :mathFunctionNameType => MathFunctionName,
25
- :aggregateFunctionType => AggregateFunction,
26
- :aggregateFunctionNameType => AggregateFunctionName,
27
- :userDefinedFunctionType => UserDefinedFunction,
28
- :aliasSelectionItemType => AliasSelectionItem,
29
- :likePredType => LikePred,
30
- :notLikePredType => NotLikePred,
31
- :closedSearchType => ClosedSearch,
32
- :intersectionSearchType => IntersectionSearch,
33
- :unionSearchType => UnionSearch,
34
- :comparisonPredType => ComparisonPred,
35
- :betweenPredType => BetweenPred,
36
- :notBetweenPredType => NotBetweenPred,
37
- :includeTableType => IncludeTable,
38
- :dropTableType => DropTable,
39
- :xMatchType => XMatch,
40
- :xMatchTableAliasType => XMatchTableAlias,
41
- :comparisonType => Comparison,
42
- :regionSearchType => RegionSearch,
43
- :inverseSearchType => InverseSearch,
44
- :inclusionSetType => InclusionSet,
45
- :inclusiveSearchType => InclusiveSearch,
46
- :exclusiveSearchType => ExclusiveSearch,
47
- :subQuerySetType => SubQuerySet,
48
- :joinTableType => JoinTable,
49
- :constantListSetType => ConstantListSet,
50
- :orderType => Order,
51
- :circleType => Circle,
52
- :boxType => Box,
53
- :archiveTableType => ArchiveTable}
54
- end
55
-
56
- # Get the domain class associated with a particular xsi:type.
57
- def self.get_class_for(type)
58
- klass = self.classes()[type.to_sym] || self.classes()[type]
59
- raise "Unable to find type #{type}" if !klass
60
- return klass
61
- end
62
- end
63
-
64
- # The abstract base type for any of items to be selected in a query.
65
- class SelectionItem
66
- def self.from_xml(node)
67
- #type_s = node.elements['xsi:type']
68
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
69
- return ObjectBuilder.get_class_for(type_s).from_xml(node)
70
- end
71
- end
72
-
73
- # The base type for a scalar expression.
74
- class ScalarExpression < SelectionItem
75
- attr_reader :value
76
-
77
- def initialize(val)
78
- self.value = val
79
- end
80
-
81
- def is_scalar?(v)
82
- if v.is_a?(String) or v.is_a?(Integer) or v.is_a?(Float)
83
- return true
84
- else
85
- return false
86
- end
87
- end
88
-
89
- def value=(v)
90
- if self.is_scalar?(v)
91
- @value = v
92
- else
93
- raise "Scalar expression must contain scalar values"
94
- end
95
- end
96
-
97
- def to_s
98
- "{value=#{self.value}}"
99
- end
100
-
101
- def self.from_xml(node)
102
- #type_s = node.attributes['xsi:type']
103
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
104
- return ObjectBuilder.get_class_for(type_s).from_xml(node)
105
- end
106
- end
107
-
108
- # Represents an expression inside a bracket.
109
- class ClosedExpr < ScalarExpression
110
- attr_reader :value
111
-
112
- def initialize(val)
113
- self.value = val
114
- end
115
-
116
- def value=(v)
117
- VOTables::VOTable::Misc::TypeCheck.new(v, ScalarExpression).check()
118
- @value = v
119
- end
120
-
121
- def self.from_xml(node)
122
- expr_node = REXML::XPath.first(node, 'Arg')
123
- expr = ScalarExpression.from_xml(expr_node)
124
- return ClosedExpr.new(expr)
125
- end
126
- end
127
-
128
- # Used for expressing operations like A+B.
129
- class BinaryOperator
130
- attr_reader :operator
131
-
132
- @@operators = ['+', '-', '*', '/']
133
-
134
- def initialize(operator, op_list=nil)
135
- @op_list = op_list || @@operators
136
- self.operator = operator
137
- end
138
-
139
- def operator=(o)
140
- if @op_list.include?(o)
141
- @operator = o
142
- else
143
- raise "Binary operator is not valid. Use one of: " +
144
- @op_list.join(', ')
145
- end
146
- end
147
-
148
- def to_s
149
- "{operator=#{self.operator}}"
150
- end
151
- end
152
-
153
- # Represents a binary expression such as a+b.
154
- class BinaryExpr < ScalarExpression
155
- attr_reader :oper, :arg1, :arg2
156
-
157
- def initialize(arg1, oper, arg2)
158
- super("#{arg1} #{oper} #{arg2}")
159
-
160
- self.arg1 = arg1
161
- self.arg2 = arg2
162
- self.oper = oper
163
- end
164
-
165
- def arg1=(a)
166
- begin
167
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
168
- rescue VOTables::VOTable::Misc::TypeException
169
- @arg1 = ScalarExpression.new(a)
170
- else
171
- @arg1 = a
172
- end
173
- end
174
-
175
- def arg2=(a)
176
- begin
177
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
178
- rescue VOTables::VOTable::Misc::TypeException
179
- @arg2 = ScalarExpression.new(a)
180
- else
181
- @arg2 = a
182
- end
183
- end
184
-
185
- def oper=(o)
186
- begin
187
- VOTables::VOTable::Misc::TypeCheck.new(o, BinaryOperator).check()
188
- rescue VOTables::VOTable::Misc::TypeException
189
- @oper = BinaryOperator.new(o)
190
- else
191
- @oper = o
192
- end
193
- end
194
-
195
- def to_s
196
- "{arg1=#{self.arg1},oper=#{self.oper},arg2=#{self.arg2}}"
197
- end
198
-
199
- def self.from_xml(node)
200
- oper = BinaryOperator.new(node.attributes['Oper'])
201
- arg1_node, arg2_node = node.elements.to_a('Arg')
202
- arg1 = ScalarExpression.from_xml(arg1_node)
203
- arg2 = ScalarExpression.from_xml(arg2_node)
204
- return BinaryExpr.new(arg1, oper, arg2)
205
- end
206
- end
207
-
208
- # Operators for expressing a single element operation.
209
- class UnaryOperator
210
- attr_reader :operator
211
-
212
- @@operators = ['+', '-']
213
-
214
- def initialize(operator, op_list=nil)
215
- @op_list = op_list || @@operators
216
- self.operator = operator
217
- end
218
-
219
- def operator=(o)
220
- if @op_list.include?(o)
221
- @operator = o
222
- else
223
- raise "Unary operator is not valid. Use one of: " +
224
- @op_list.join(', ')
225
- end
226
- end
227
-
228
- def to_s
229
- "{operator=#{self.operator}}"
230
- end
231
- end
232
-
233
- # Represents an unary expression such as -(a.ra)
234
- class UnaryExpr < ScalarExpression
235
- attr_reader :arg, :oper
236
-
237
- def initialize(oper, arg)
238
- super("#{oper}#{arg}")
239
-
240
- self.arg = arg
241
- self.oper = oper
242
- end
243
-
244
- def arg=(a)
245
- begin
246
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
247
- rescue VOTables::VOTable::Misc::TypeException
248
- @arg = ScalarExpression.new(a)
249
- else
250
- @arg = a
251
- end
252
- end
253
-
254
- def oper=(o)
255
- begin
256
- VOTables::VOTable::Misc::TypeCheck.new(o, UnaryOperator).check()
257
- rescue VOTables::VOTable::Misc::TypeException
258
- @oper = UnaryOperator.new(o)
259
- else
260
- @oper = o
261
- end
262
- end
263
-
264
- def to_s
265
- "{arg=#{self.oper},oper=#{self.arg}}"
266
- end
267
-
268
- def self.from_xml(node)
269
- oper = UnaryOperator.new(node.attributes['Oper'])
270
- arg_node = REXML::XPath.first(node, 'Arg')
271
- arg = ScalarExpression.from_xml(arg_node)
272
- return UnaryExpr.new(oper, arg)
273
- end
274
- end
275
-
276
- # Represents a column.
277
- class ColumnReference < ScalarExpression
278
- attr_accessor :table, :name, :xpath_name
279
-
280
- def initialize(table, name, xpath_name=nil)
281
- super("#{table}.#{name} #{xpath_name || ''}")
282
-
283
- self.table = table
284
- self.name = name
285
- self.xpath_name = xpath_name
286
- end
287
-
288
- def to_s
289
- self.value
290
- end
291
-
292
- def self.from_xml(el)
293
- table = el.attributes['Table']
294
- name = el.attributes['Name']
295
- xpath = el.attributes['xpathName']
296
- cr = ColumnReference.new(table, name, xpath)
297
- end
298
- end
299
-
300
- # Encapsulates basic literals such as Strings, Integers and Real numbers.
301
- class Atom < ScalarExpression
302
- attr_reader :literal
303
- attr_accessor :unit
304
-
305
- def initialize(literal, unit=nil)
306
- super("#{literal}#{unit || ''}")
307
-
308
- self.literal = literal
309
- self.unit = unit
310
- end
311
-
312
- def literal=(l)
313
- begin
314
- VOTables::VOTable::Misc::TypeCheck.new(l, LiteralType).check()
315
- rescue VOTables::VOTable::Misc::TypeException
316
- if l.is_a?(Float)
317
- @literal = RealType.new(l)
318
- elsif l.is_a?(Integer)
319
- @literal = IntegerType.new(l)
320
- elsif l.is_a?(String)
321
- @literal = StringType.new(l)
322
- else
323
- raise "Literal is not a real, integer or string"
324
- end
325
- else
326
- @literal = l
327
- end
328
- end
329
-
330
- def to_s
331
- "{literal=#{self.literal},unit=#{self.unit}}"
332
- end
333
-
334
- def self.from_xml(node)
335
- literal_node = REXML::XPath.first(node, 'Literal')
336
- literal = LiteralType.from_xml(literal_node)
337
- return Atom.new(literal)
338
- end
339
- end
340
-
341
- # The base type for all literals.
342
- class LiteralType
343
- def to_s
344
- "{value=#{self.value}}"
345
- end
346
-
347
- def self.from_xml(node)
348
- #type_s = node.attributes['xsi:type']
349
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
350
- literal = ObjectBuilder.get_class_for(type_s).from_xml(node)
351
- return literal
352
- end
353
- end
354
-
355
- # The base type for all numbers.
356
- class NumberType < LiteralType
357
- def self.from_xml(node)
358
- #type_s = node.attributes['xsi:type']
359
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
360
- number = ObjectBuilder.get_class_for(type_s).from_xml(node)
361
- end
362
- end
363
-
364
- # Represents a real number.
365
- class RealType < NumberType
366
- attr_reader :value
367
-
368
- def initialize(value)
369
- self.value = value
370
- end
371
-
372
- def value=(v)
373
- begin
374
- VOTables::VOTable::Misc::TypeCheck.new(v, Float).check()
375
- rescue VOTables::VOTable::Misc::TypeException
376
- if v.is_a?(Integer)
377
- @value = v.to_f
378
- else
379
- raise VOTables::VOTable::Misc::TypeException
380
- end
381
- else
382
- @value = v
383
- end
384
- end
385
-
386
- def self.from_xml(node)
387
- return RealType.new(node.attributes['Value'].to_f)
388
- end
389
- end
390
-
391
- # Represents an integer.
392
- class IntegerType < NumberType
393
- attr_reader :value
394
-
395
- def initialize(value)
396
- self.value = value
397
- end
398
-
399
- def value=(v)
400
- VOTables::VOTable::Misc::TypeCheck.new(v, Integer).check()
401
- @value = v
402
- end
403
-
404
- def self.from_xml(node)
405
- return IntegerType.new(node.attributes['Value'].to_i)
406
- end
407
- end
408
-
409
- # Represents a string literal.
410
- class StringType < LiteralType
411
- attr_reader :value
412
-
413
- def initialize(value)
414
- self.value = value
415
- end
416
-
417
- def value=(v)
418
- VOTables::VOTable::Misc::TypeCheck.new(v, String).check()
419
- @value = v
420
- end
421
-
422
- def self.from_xml(node)
423
- return StringType.new(node.attributes['Value'])
424
- end
425
- end
426
-
427
- # The base type for a function.
428
- class FunctionType < ScalarExpression
429
- def to_s
430
- "{name=#{self.name}}"
431
- end
432
- end
433
-
434
- # Option of selecting all or distinct elements in a query.
435
- class SelectionOption
436
- attr_reader :option
437
-
438
- def initialize(option)
439
- self.option = option
440
- end
441
-
442
- def option=(o)
443
- begin
444
- VOTables::VOTable::Misc::TypeCheck.new(o, AllOrDistinct).check()
445
- rescue VOTables::VOTable::Misc::TypeException
446
- @option = AllOrDistinct.new(o)
447
- else
448
- @option = o
449
- end
450
- end
451
-
452
- def content
453
- self.option.option
454
- end
455
-
456
- def to_s
457
- "{option=#{self.option}}"
458
- end
459
-
460
- def self.from_xml(node)
461
- option = AllOrDistinct.new(node.attributes['Option'])
462
- return SelectionOption.new(option)
463
- end
464
- end
465
-
466
- # Enumeration for All and Distinct options.
467
- class AllOrDistinct
468
- attr_reader :option, :option_list
469
-
470
- @@options = ['ALL', 'DISTINCT']
471
-
472
- def initialize(option, option_list=nil)
473
- @option_list = option_list || @@options
474
- self.option = option
475
- end
476
-
477
- def option=(o)
478
- if @option_list.include?(o)
479
- @option = o
480
- else
481
- raise "Option is not valid. Use one of: " +
482
- @option_list.join(', ')
483
- end
484
- end
485
-
486
- def to_s
487
- "{option=#{self.option}}"
488
- end
489
- end
490
-
491
- # Represents a trigonometric function.
492
- class TrigonometricFunction < FunctionType
493
- attr_reader :name, :arg, :allow
494
-
495
- def initialize(name, arg, allow=nil)
496
- self.name = name
497
- self.arg = arg
498
- self.allow = allow
499
- end
500
-
501
- def name=(n)
502
- begin
503
- VOTables::VOTable::Misc::TypeCheck.new(n, TrigonometricFunctionName).check()
504
- rescue VOTables::VOTable::Misc::TypeException
505
- @name = TrigonometricFunctionName.new(n)
506
- else
507
- @name = n
508
- end
509
- end
510
-
511
- def arg=(a)
512
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionItem).check()
513
- @arg = a
514
- end
515
-
516
- def allow=(a)
517
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionOption).check()
518
- @allow = a
519
- end
520
-
521
- def to_s
522
- "{name=#{self.name},allow=#{self.allow},arg=#{self.arg}}"
523
- end
524
-
525
- def self.from_xml(node)
526
- name = TrigonometricFunctionName.from_xml(node)
527
- arg_node = REXML::XPath.first(node, 'Arg')
528
- arg = Arg.from_xml(arg_node)
529
- allow_node = REXML::XPath.first(node, 'Allow')
530
- allow = nil
531
- if allow_node
532
- allow = Allow.from_xml(allow_node)
533
- end
534
- return TrigonometricFunction.new(name, arg, allow)
535
- end
536
- end
537
-
538
- # Enumeration of allowed trigonometric functions.
539
- class TrigonometricFunctionName
540
- attr_reader :value, :values_list
541
-
542
- @@values = ['SIN', 'COS', 'TAN', 'COT', 'ASIN', 'ACOS', 'ATAN', 'ATAN2']
543
-
544
- def initialize(value, values_list=nil)
545
- @values_list = values_list || @@values
546
- self.value = value
547
- end
548
-
549
- def value=(v)
550
- if @values_list.include?(v)
551
- @value = v
552
- else
553
- raise "Value is not valid. Use one of: " +
554
- @values_list.join(', ')
555
- end
556
- end
557
-
558
- def to_s
559
- "{value=#{self.value}}"
560
- end
561
-
562
- def self.from_xml(node)
563
- return TrigonometricFunctionName.new(node.attributes['Name'])
564
- end
565
- end
566
-
567
- # Represents a math function.
568
- class MathFunction < FunctionType
569
- attr_reader :name, :arg, :allow
570
-
571
- def initialize(name, arg, allow=nil)
572
- self.name = name
573
- self.arg = arg
574
- self.allow = allow
575
- end
576
-
577
- def name=(n)
578
- begin
579
- VOTables::VOTable::Misc::TypeCheck.new(n, MathFunctionName).check()
580
- rescue VOTables::VOTable::Misc::TypeException
581
- @name = MathFunctionName.new(n)
582
- else
583
- @name = n
584
- end
585
- end
586
-
587
- def arg=(a)
588
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionItem).check()
589
- @arg = a
590
- end
591
-
592
- def allow=(a)
593
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionOption).check()
594
- @allow = a
595
- end
596
-
597
- def self.from_xml(node)
598
- name = MathFunctionName.from_xml(node)
599
- arg_node = REXML::XPath.first(node, 'Arg')
600
- arg = Arg.from_xml(arg_node)
601
- allow_node = REXML::XPath.first(node, 'Allow')
602
- allow = nil
603
- if allow_node
604
- allow = Allow.from_xml(allow_node)
605
- end
606
- return MathFunction.new(name, arg, allow)
607
- end
608
-
609
- def to_s
610
- "{name=#{self.name},arg=#{self.arg},allow=#{self.allow}}"
611
- end
612
- end
613
-
614
- # Enumeration of allowed math functions.
615
- class MathFunctionName
616
- attr_reader :value, :values_list
617
-
618
- @@values = ['ABS', 'CEILING', 'DEGREES', 'EXP', 'FLOOR', 'LOG',
619
- 'PI', 'POWER', 'RADIANS', 'SQRT', 'SQUARE', 'LOG10',
620
- 'RAND', 'ROUND', 'TRUNCATE']
621
-
622
- def initialize(value, values_list=nil)
623
- @values_list = values_list || @@values
624
- self.value = value
625
- end
626
-
627
- def value=(v)
628
- if @values_list.include?(v)
629
- @value = v
630
- else
631
- raise "Value is not valid. Use one of: " +
632
- @values_list.join(', ')
633
- end
634
- end
635
-
636
- def to_s
637
- "{value=#{self.value}}"
638
- end
639
-
640
- def self.from_xml(node)
641
- return MathFunctionName.new(node.attributes['Name'])
642
- end
643
- end
644
-
645
- # Represents an aggregate function.
646
- class AggregateFunction < FunctionType
647
- attr_reader :name, :arg, :allow
648
-
649
- def initialize(name, arg, allow=nil)
650
- self.name = name
651
- self.arg = arg
652
- self.allow = allow
653
- end
654
-
655
- def name=(n)
656
- begin
657
- VOTables::VOTable::Misc::TypeCheck.new(n, AggregateFunctionName).check()
658
- rescue VOTables::VOTable::Misc::TypeException
659
- @name = AggregateFunctionName.new(n)
660
- else
661
- @name = n
662
- end
663
- end
664
-
665
- def arg=(a)
666
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionItem).check()
667
- @arg = a
668
- end
669
-
670
- def allow=(a)
671
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionOption).check()
672
- @allow = a
673
- end
674
-
675
- def to_s
676
- "{name=#{self.name},arg=#{self.arg},allow=#{self.allow}}"
677
- end
678
-
679
- def self.from_xml(node)
680
- name = AggregateFunctionName.from_xml(node)
681
- arg_node = REXML::XPath.first(node, 'Arg')
682
- arg = Arg.from_xml(arg_node)
683
- allow_node = REXML::XPath.first(node, 'Allow')
684
- allow = nil
685
- if allow_node
686
- allow = Allow.from_xml(allow_node)
687
- end
688
- return AggregateFunction.new(name, arg, allow)
689
- end
690
- end
691
-
692
- # Enumeration of allowed aggregate functions.
693
- class AggregateFunctionName
694
- attr_reader :value, :values_list
695
-
696
- @@values = ['AVG', 'MIN', 'MAX', 'SUM', 'COUNT']
697
-
698
- def initialize(value, values_list=nil)
699
- @values_list = values_list || @@values
700
- self.value = value
701
- end
702
-
703
- def value=(v)
704
- if @values_list.include?(v)
705
- @value = v
706
- else
707
- raise "Value is not valid. Use one of: " +
708
- @values_list.join(', ')
709
- end
710
- end
711
-
712
- def to_s
713
- "{value=#{self.value}}"
714
- end
715
-
716
- def self.from_xml(node)
717
- return AggregateFunctionName.new(node.attributes['Name'])
718
- end
719
- end
720
-
721
- # Used to select an expression as a new alias column.
722
- class AliasSelectionItem < SelectionItem
723
- attr_reader :expression
724
- attr_accessor :as
725
-
726
- def initialize(expression, as=nil)
727
- self.expression = expression
728
- self.as = as
729
- end
730
-
731
- def expression=(e)
732
- begin
733
- VOTables::VOTable::Misc::TypeCheck.new(e, ScalarExpression).check()
734
- rescue VOTables::VOTable::Misc::TypeException
735
- @expression = ScalarExpression.new(e)
736
- else
737
- @expression = e
738
- end
739
- end
740
-
741
- def to_s
742
- "{expression=#{self.expression},as=#{self.as}}"
743
- end
744
-
745
- def self.from_xml(node)
746
- as = node.attributes['As']
747
- expr_node = REXML::XPath.first(node, 'Expression')
748
- expr = ScalarExpression.from_xml(expr_node)
749
- return AliasSelectionItem.new(expr, as)
750
- end
751
- end
752
-
753
- # Represent all columns as in Select * query.
754
- class AllSelectionItem < SelectionItem
755
- @@value = '*'
756
-
757
- def initialize;end
758
-
759
- def self.value
760
- return @@value
761
- end
762
-
763
- def to_s
764
- "{expression=#{self.value}}"
765
- end
766
-
767
- def self.from_xml(node)
768
- return AllSelectionItem.new()
769
- end
770
- end
771
-
772
- # The comparison operators such as Less-than or More-than, etc.
773
- class Comparison
774
- attr_reader :value, :values_list
775
-
776
- @@values = ['=', '<>', '>', '>=', '<', '<=']
777
-
778
- def initialize(value, values_list=nil)
779
- @values_list = values_list || @@values
780
- self.value = value
781
- end
782
-
783
- def value=(v)
784
- if @values_list.include?(v)
785
- @value = v
786
- else
787
- raise "Value is not valid. Use one of: " +
788
- @values_list.join(', ')
789
- end
790
- end
791
-
792
- def to_s
793
- "{value=#{self.value}}"
794
- end
795
-
796
- def self.from_xml(node)
797
- return Comparison.new(node.attributes['Comparison'])
798
- end
799
- end
800
-
801
- # The base type for all tables used in the From clause of the query.
802
- class FromTable
803
- def self.from_xml(node)
804
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
805
- table = ObjectBuilder.get_class_for(type_s).from_xml(node)
806
- end
807
- end
808
-
809
- # Same as a TableType with an additional archive name.
810
- class ArchiveTable < FromTable
811
- attr_accessor :archive, :name, :alias_name
812
-
813
- def initialize(archive, name, alias_name=nil)
814
- self.archive = archive
815
- self.name = name
816
- self.alias_name = alias_name
817
- end
818
-
819
- def to_s
820
- "{archive=#{self.archive},name=#{self.name},alias=#{self.alias_name}}"
821
- end
822
-
823
- def self.from_xml(node)
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
-
829
- at = ArchiveTable.new(archive, name, alias_name)
830
- end
831
- end
832
-
833
- # Represents a table with its name and its alias name.
834
- class Table < FromTable
835
- attr_accessor :name, :alias_name, :xpath_name
836
-
837
- def initialize(name, alias_name=nil, xpath_name=nil)
838
- self.name = name
839
- self.alias_name = alias_name
840
- self.xpath_name = xpath_name
841
- end
842
-
843
- def to_s
844
- "{name=#{self.name},alias=#{self.alias_name},xpath=#{self.xpath_name}}"
845
- end
846
-
847
- def self.from_xml(node)
848
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
849
- table = ObjectBuilder.get_class_for(type_s).from_xml(node)
850
- end
851
- end
852
-
853
- # The base type for all table inclusion or drop types used in a cross match expression.
854
- class XMatchTableAlias
855
- def to_s
856
- "{name=#{self.name}}"
857
- end
858
-
859
- def self.from_xml(node)
860
- #type_s = node.attributes['xsi:type']
861
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
862
- xtable = ObjectBuilder.get_class_for(type_s).from_xml(node)
863
- end
864
- end
865
-
866
- # Used for adding a table for the Xmatch operation.
867
- class IncludeTable < XMatchTableAlias
868
- attr_accessor :name
869
-
870
- def initialize(name)
871
- self.name = name
872
- end
873
-
874
- def self.from_xml(node)
875
- name = node.attributes['Name']
876
- return IncludeTable.new(name)
877
- end
878
- end
879
-
880
- # Used for avoiding a table in Xmatch.
881
- class DropTable < XMatchTableAlias
882
- attr_accessor :name
883
-
884
- def initialize(name)
885
- self.name = name
886
- end
887
-
888
- def self.from_xml(node)
889
- name = node.attributes['Name']
890
- return DropTable.new(name)
891
- end
892
- end
893
-
894
- # The base type for searches in Where and Having clauses of the query.
895
- class Search
896
- def self.from_xml(node)
897
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
898
- search = ObjectBuilder.get_class_for(type_s).from_xml(node)
899
- end
900
- end
901
-
902
- # Represents expressions like a AND b.
903
- class IntersectionSearch < Search
904
- attr_reader :cond1, :cond2
905
-
906
- def initialize(cond1, cond2)
907
- self.cond1 = cond1
908
- self.cond2 = cond2
909
- end
910
-
911
- def cond1=(cond)
912
- VOTables::VOTable::Misc::TypeCheck.new(cond, Search).check()
913
- @cond1 = cond
914
- end
915
-
916
- def cond2=(cond)
917
- VOTables::VOTable::Misc::TypeCheck.new(cond, Search).check()
918
- @cond2 = cond
919
- end
920
-
921
- def to_s
922
- "{cond1=#{self.cond1},cond2=#{self.cond2}}"
923
- end
924
-
925
- def self.from_xml(node)
926
- cond1_node, cond2_node = node.elements.to_a('Condition')
927
- cond1 = Search.from_xml(cond1_node)
928
- cond2 = Search.from_xml(cond2_node)
929
- return IntersectionSearch.new(cond1, cond2)
930
- end
931
-
932
- # This method finds a condition given its attributes and it returns it
933
- def find_condition(type, attributes)
934
- condition = self.cond1.find_condition(type, attributes)
935
- if condition == nil
936
- condition = self.cond2.find_condition(type, attributes)
937
- end
938
-
939
- return condition
940
- end
941
-
942
- # This method removes a condition. -1 means that the condition must
943
- # be removed. 1 means that the condition given its attributes wasn't
944
- # found, so that the process must continue.
945
- def remove_condition(type, attributes)
946
- cond1 = self.cond1.remove_condition(type, attributes)
947
- if cond1 == -1
948
- return self.cond2
949
- elsif cond1 == 1
950
- cond2 = self.cond2.remove_condition(type, attributes)
951
- if cond2 == -1
952
- return self.cond1
953
- elsif cond2 == 1
954
- return 1
955
- end
956
- else
957
- self.cond1 = cond1
958
- return self
959
- end
960
- end
961
-
962
- # This method modifies a condition given its old attributes,
963
- # replacing the old attributes with the new attributes.
964
- def modify_condition(type, attributes_old, attributes_new)
965
- cond1 = self.cond1.modify_condition(type, attributes_old, attributes_new)
966
- if cond1 != nil
967
- self.cond1 = cond1
968
- else
969
- cond2 = self.cond2.modify_condition(type, attributes_old, attributes_new)
970
- if cond2 != nil
971
- self.cond2 = cond2
972
- else
973
- return nil
974
- end
975
- end
976
-
977
- return self
978
- end
979
-
980
- # This method replaces a condition for a new condition. -1 means that
981
- # the condition must be replaced for the new condition. 1 means that
982
- # the process must continue.
983
- def replace_condition(type, attributes, new_condition)
984
- cond1 = self.cond1.replace_condition(type, attributes, new_condition)
985
- if cond1 == -1
986
- self.cond1 = new_condition
987
- return self
988
- elsif cond1 == 1
989
- cond2 = self.cond2.replace_condition(type, attributes, new_condition)
990
- if cond2 == -1
991
- self.cond2 = new_condition
992
- return self
993
- elsif cond2 == 1
994
- return 1
995
- end
996
- else
997
- return self
998
- end
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
1007
- end
1008
-
1009
- # Represents expressions like A Or B.
1010
- class UnionSearch < Search
1011
- attr_reader :cond1, :cond2
1012
-
1013
- def initialize(cond1, cond2)
1014
- self.cond1 = cond1
1015
- self.cond2 = cond2
1016
- end
1017
-
1018
- def cond1=(cond)
1019
- VOTables::VOTable::Misc::TypeCheck.new(cond, Search).check()
1020
- @cond1 = cond
1021
- end
1022
-
1023
- def cond2=(cond)
1024
- VOTables::VOTable::Misc::TypeCheck.new(cond, Search).check()
1025
- @cond2 = cond
1026
- end
1027
-
1028
- def to_s
1029
- "{cond1=#{self.cond1},cond2=#{self.cond2}}"
1030
- end
1031
-
1032
- def self.from_xml(node)
1033
- cond1_node, cond2_node = node.elements.to_a('Condition')
1034
- cond1 = Search.from_xml(cond1_node)
1035
- cond2 = Search.from_xml(cond2_node)
1036
- return UnionSearch.new(cond1, cond2)
1037
- end
1038
-
1039
- # This method finds a condition given its attributes and it returns it
1040
- def find_condition(type, attributes)
1041
- condition = self.cond1.find_condition(type, attributes)
1042
- if condition == nil
1043
- condition = self.cond2.find_condition(type, attributes)
1044
- end
1045
-
1046
- return condition
1047
- end
1048
-
1049
- # This method removes a condition. -1 means that the condition must
1050
- # be removed. 1 means that the condition given its attributes wasn't
1051
- # found, so that the process must continue.
1052
- def remove_condition(type, attributes)
1053
- cond1 = self.cond1.remove_condition(type, attributes)
1054
- if cond1 == -1
1055
- return self.cond2
1056
- elsif cond1 == 1
1057
- cond2 = self.cond2.remove_condition(type, attributes)
1058
- if cond2 == -1
1059
- return self.cond1
1060
- elsif cond2 == 1
1061
- return 1
1062
- end
1063
- else
1064
- self.cond1 = cond1
1065
- return self
1066
- end
1067
- end
1068
-
1069
- # This method modifies a condition given its old attributes,
1070
- # replacing the old attributes with the new attributes.
1071
- def modify_condition(type, attributes_old, attributes_new)
1072
- cond1 = self.cond1.modify_condition(type, attributes_old, attributes_new)
1073
- if cond1 != nil
1074
- self.cond1 = cond1
1075
- else
1076
- cond2 = self.cond2.modify_condition(type, attributes_old, attributes_new)
1077
- if cond2 != nil
1078
- self.cond2 = cond2
1079
- else
1080
- return nil
1081
- end
1082
- end
1083
-
1084
- return self
1085
- end
1086
-
1087
- # This method replaces a condition for a new condition. -1 means that
1088
- # the condition must be replaced for the new condition. 1 means that
1089
- # the process must continue
1090
- def replace_condition(type, attributes, new_condition)
1091
- cond1 = self.cond1.replace_condition(type, attributes, new_condition)
1092
- if cond1 == -1
1093
- self.cond1 = new_condition
1094
- return self
1095
- elsif cond1 == 1
1096
- cond2 = self.cond2.replace_condition(type, attributes, new_condition)
1097
- if cond2 == -1
1098
- self.cond2 = new_condition
1099
- return self
1100
- elsif cond2 == 1
1101
- return 1
1102
- end
1103
- else
1104
- return self
1105
- end
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
1114
- end
1115
-
1116
- # A cross match expression.
1117
- class XMatch < Search
1118
- attr_reader :tables, :nature, :sigma
1119
-
1120
- def initialize(tables, nature, sigma)
1121
- self.tables = tables
1122
- self.nature = nature
1123
- self.sigma = sigma
1124
- end
1125
-
1126
- def tables=(ts)
1127
- raise "Specify at least two tables" if !ts or ts.length < 2
1128
-
1129
- ts.each do |t|
1130
- VOTables::VOTable::Misc::TypeCheck.new(t, XMatchTableAlias)
1131
- end
1132
-
1133
- @tables = ts
1134
- end
1135
-
1136
- def nature=(n)
1137
- begin
1138
- VOTables::VOTable::Misc::TypeCheck.new(n, Comparison).check()
1139
- rescue VOTables::VOTable::Misc::TypeException
1140
- @nature = Comparison.new(n)
1141
- else
1142
- @nature = n
1143
- end
1144
- end
1145
-
1146
- def sigma=(s)
1147
- begin
1148
- VOTables::VOTable::Misc::TypeCheck.new(s, NumberType).check()
1149
- rescue VOTables::VOTable::Misc::TypeException
1150
- if s.is_a?(Float)
1151
- @sigma = RealType.new(s)
1152
- elsif s.is_a?(Integer)
1153
- @sigma = IntegerType.new(s)
1154
- else
1155
- raise "Sigma must be a float or integer"
1156
- end
1157
- else
1158
- @sigma = s
1159
- end
1160
- end
1161
-
1162
- def to_s
1163
- tables = self.tables.collect{|x| x.to_s}.join('|')
1164
- "{tables=#{tables},nature=#{self.nature},sigma=#{self.sigma}}"
1165
- end
1166
-
1167
- def self.from_xml(node)
1168
- tables = []
1169
- node.elements.each('Table') do |tbl_node|
1170
- table = XMatchTableAlias.from_xml(tbl_node)
1171
- tables.push(table)
1172
- end
1173
-
1174
- nature_node = REXML::XPath.first(node, 'Nature')
1175
- nature = Nature.from_xml(nature_node)
1176
-
1177
- sigma_node = REXML::XPath.first(node, 'Sigma')
1178
- sigma = Sigma.from_xml(sigma_node)
1179
-
1180
- return XMatch.new(tables, nature, sigma)
1181
- end
1182
- end
1183
-
1184
- # The Like expression of a query.
1185
- class LikePred < Search
1186
- attr_reader :arg, :pattern
1187
-
1188
- def initialize(arg, pattern)
1189
- self.arg = arg
1190
- self.pattern = pattern
1191
- end
1192
-
1193
- def arg=(a)
1194
- begin
1195
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1196
- rescue VOTables::VOTable::Misc::TypeException
1197
- @arg = ScalarExpression.new(a)
1198
- else
1199
- @arg = a
1200
- end
1201
- end
1202
-
1203
- def pattern=(p)
1204
- begin
1205
- VOTables::VOTable::Misc::TypeCheck.new(p, Atom).check()
1206
- rescue VOTables::VOTable::Misc::TypeException
1207
- @pattern = Atom.new(p)
1208
- else
1209
- @pattern = p
1210
- end
1211
- end
1212
-
1213
- def to_s
1214
- "{arg=#{self.arg},pattern=#{self.pattern}}"
1215
- end
1216
-
1217
- def self.from_xml(node)
1218
- arg_node = REXML::XPath.first(node, 'Arg')
1219
- arg = Arg.from_xml(arg_node)
1220
- pattern_node = REXML::XPath.first(node, 'Pattern')
1221
- pattern = Pattern.from_xml(pattern_node)
1222
-
1223
- return LikePred.new(arg, pattern)
1224
- end
1225
-
1226
- def self.create_new_object(attributes)
1227
- arg = ColumnReference.new(attributes['table'], attributes['name'], nil)
1228
- pattern = StringType.new(attributes['pattern'])
1229
- return LikePred.new(arg, pattern)
1230
- end
1231
-
1232
- def match_attributtes(attributes)
1233
- return true if self.arg.table == attributes['table'] and
1234
- self.arg.name == attributes['name'] and
1235
- self.pattern.literal.value == attributes['pattern']
1236
- return false
1237
- end
1238
-
1239
- # This method finds a condition given its attributes and it returns it
1240
- def find_condition(type, attributes)
1241
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1242
- return self if self.match_attributtes(attributes)
1243
- return nil
1244
- end
1245
- return nil
1246
- end
1247
-
1248
- # This method removes a condition. -1 means that the condition must
1249
- # be removed. 1 means that the condition given its attributes wasn't
1250
- # found, so that the process must continue.
1251
- def remove_condition(type, attributes)
1252
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1253
- return -1 if self.match_attributtes(attributes)
1254
- return 1
1255
- end
1256
- return 1
1257
- end
1258
-
1259
- # This method modifies a condition given its old attributes,
1260
- # replacing the old attributes with the new attributes.
1261
- def modify_condition(type, attributes_old, attributes_new)
1262
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1263
- if self.match_attributtes(attributes_old)
1264
- return LikePred.create_new_object(attributes_new)
1265
- else
1266
- return nil
1267
- end
1268
- end
1269
- return nil
1270
- end
1271
-
1272
- # This method replaces a condition given its attributes.
1273
- # Returns -1 if the object must be replaced, or returns 1 if
1274
- # isn't the object that must be replaced, so the process must continue
1275
- def replace_condition(type, attributes, new_condition)
1276
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1277
- return -1 if self.match_attributtes(attributes)
1278
- return 1
1279
- end
1280
- return 1
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
1289
- end
1290
-
1291
- # The Not Like expression of a query.
1292
- class NotLikePred < LikePred
1293
- def self.from_xml(node)
1294
- arg_node = REXML::XPath.first(node, 'Arg')
1295
- arg = Arg.from_xml(arg_node)
1296
- pattern_node = REXML::XPath.first(node, 'Pattern')
1297
- pattern = Pattern.from_xml(pattern_node)
1298
- return NotLikePred.new(arg, pattern)
1299
- end
1300
- end
1301
-
1302
- # Represents SQL NOT IN expression.
1303
- class ExclusiveSearch < Search
1304
- attr_reader :expression, :set
1305
-
1306
- def initialize(expression, set)
1307
- self.expression = expression
1308
- self.set = set
1309
- end
1310
-
1311
- def expression=(e)
1312
- begin
1313
- VOTables::VOTable::Misc::TypeCheck.new(e, ScalarExpression).check()
1314
- rescue VOTables::VOTable::Misc::TypeException
1315
- @expression = ScalarExpression.new(e)
1316
- else
1317
- @expression = e
1318
- end
1319
- end
1320
-
1321
- def set=(s)
1322
- VOTables::VOTable::Misc::TypeCheck.new(s, InclusionSet).check()
1323
- @set = s
1324
- end
1325
-
1326
- def to_s
1327
- "{expression=#{self.expression},set=#{self.set}}"
1328
- end
1329
-
1330
- def self.from_xml(node)
1331
- expr_node = REXML::XPath.first(node, 'Expression')
1332
- expr = Expression.from_xml(expr_node)
1333
- set_node = REXML::XPath.first(node, 'Set')
1334
- set = Set.from_xml(set_node)
1335
- return ExclusiveSearch.new(expr, set)
1336
- end
1337
- end
1338
-
1339
- # The base type for selection set in a SQL IN expression.
1340
- class InclusionSet
1341
- def self.from_xml(node)
1342
- #type_s = node.attributes['xsi:type']
1343
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
1344
- return ObjectBuilder.get_class_for(type_s).from_xml(node)
1345
- end
1346
- end
1347
-
1348
- # Represents the subquery in a SQL IN expression.
1349
- class SubQuerySet < InclusionSet
1350
- attr_reader :selection
1351
-
1352
- def initialize(selection)
1353
- self.selection = selection
1354
- end
1355
-
1356
- def selection=(s)
1357
- VOTables::VOTable::Misc::TypeCheck.new(s, Select).check()
1358
- @selection = s
1359
- end
1360
-
1361
- def to_s
1362
- "{selection=#{self.selection}}"
1363
- end
1364
-
1365
- def self.from_xml(node)
1366
- select_node = REXML::XPath.first(node, 'Select')
1367
- select = Select.from_xml(select_node)
1368
- return SubQuerySet.new(select)
1369
- end
1370
- end
1371
-
1372
- # Represents expressions like (A).
1373
- class ClosedSearch < Search
1374
- attr_reader :condition
1375
-
1376
- def initialize(condition)
1377
- self.condition = condition
1378
- end
1379
-
1380
- def condition=(c)
1381
- VOTables::VOTable::Misc::TypeCheck.new(c, Search).check()
1382
- @condition = c
1383
- end
1384
-
1385
- def to_s
1386
- "{condition=#{self.condition}}"
1387
- end
1388
-
1389
- def self.from_xml(node)
1390
- cond_node = REXML::XPath.first(node, 'Condition')
1391
- cond = Condition.from_xml(cond_node)
1392
- return ClosedSearch.new(cond)
1393
- end
1394
- end
1395
-
1396
- # Represents the Comparison of two expressions.
1397
- class ComparisonPred < Search
1398
- attr_reader :arg1, :arg2, :comparison
1399
-
1400
- def initialize(arg1, comparison, arg2)
1401
- self.arg1 = arg1
1402
- self.comparison = comparison
1403
- self.arg2 = arg2
1404
- end
1405
-
1406
- def arg1=(a)
1407
- begin
1408
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1409
- rescue VOTables::VOTable::Misc::TypeException
1410
- @arg1 = ScalarExpression.new(a)
1411
- else
1412
- @arg1 = a
1413
- end
1414
- end
1415
-
1416
- def arg2=(a)
1417
- begin
1418
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1419
- rescue VOTables::VOTable::Misc::TypeException
1420
- @arg2 = ScalarExpression.new(a)
1421
- else
1422
- @arg2 = a
1423
- end
1424
- end
1425
-
1426
- def comparison=(c)
1427
- begin
1428
- VOTables::VOTable::Misc::TypeCheck.new(c, Comparison).check()
1429
- rescue VOTables::VOTable::Misc::TypeException
1430
- @comparison = Comparison.new(c)
1431
- else
1432
- @comparison = c
1433
- end
1434
- end
1435
-
1436
- def to_s
1437
- "{arg1=#{self.arg1},comparison=#{self.comparison},arg2=#{self.arg2}}"
1438
- end
1439
-
1440
- def self.from_xml(node)
1441
- comparison_s = node.attributes['Comparison']
1442
- arg1_node, arg2_node = node.elements.to_a('Arg')
1443
- arg1 = Arg.from_xml(arg1_node)
1444
- arg2 = Arg.from_xml(arg2_node)
1445
-
1446
- return ComparisonPred.new(arg1, comparison_s, arg2)
1447
- end
1448
-
1449
- def self.create_new_object(attributes)
1450
- arg1 = ColumnReference.new(attributes['table'], attributes['name'], nil)
1451
-
1452
- arg2 = nil
1453
- if attributes['value'].is_a?(Float)
1454
- arg2 = Atom.new(RealType.new(attributes['value']))
1455
- elsif attributes['value'].is_a?(Integer)
1456
- arg2 = Atom.new(IntegerType.new(attributes['value']))
1457
- elsif attributes['value'].is_a?(String)
1458
- arg2 = Atom.new(StringType.new(attributes['value']))
1459
- else
1460
- raise "value is not a real, integer or string"
1461
- end
1462
-
1463
- return ComparisonPred.new(arg1, attributes['comparison'], arg2)
1464
- end
1465
-
1466
- def match_attributtes(attributes)
1467
- return true if self.arg1.table == attributes['table'] and
1468
- self.arg1.name == attributes['name'] and
1469
- self.comparison.value == attributes['comparison'] and
1470
- self.arg2.literal.value == attributes['value']
1471
- return false
1472
- end
1473
-
1474
- # This method finds a condition given its attributes and it returns it
1475
- def find_condition(type, attributes)
1476
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1477
- return self if self.match_attributtes(attributes)
1478
- return nil
1479
- end
1480
- return nil
1481
- end
1482
-
1483
- # This method removes a condition. -1 means that the condition must
1484
- # be removed. 1 means that the condition given its attributes wasn't
1485
- # found, so that the process must continue.
1486
- def remove_condition(type, attributes)
1487
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1488
- return -1 if self.match_attributtes(attributes)
1489
- return 1
1490
- end
1491
- return 1
1492
- end
1493
-
1494
- # This method modifies a condition given its old attributes,
1495
- # replacing the old attributes with the new attributes.
1496
- def modify_condition(type, attributes_old, attributes_new)
1497
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1498
- if self.match_attributtes(attributes_old)
1499
- return ComparisonPred.create_new_object(attributes_new)
1500
- else
1501
- return nil
1502
- end
1503
- end
1504
- return nil
1505
- end
1506
-
1507
- # This method replaces a condition given its attributes.
1508
- # Returns -1 if the object must be replaced, or returns 1 if
1509
- # isn't the object that must be replaced, so the process must continue
1510
- def replace_condition(type, attributes, new_condition)
1511
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1512
- return -1 if self.match_attributtes(attributes)
1513
- return 1
1514
- end
1515
- return 1
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
1524
- end
1525
-
1526
- # Represents the Between expression of a query.
1527
- class BetweenPred < Search
1528
- attr_reader :arg1, :arg2, :arg3
1529
-
1530
- def initialize(arg1, arg2, arg3)
1531
- self.arg1 = arg1
1532
- self.arg2 = arg2
1533
- self.arg3 = arg3
1534
- end
1535
-
1536
- def arg1=(a)
1537
- begin
1538
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1539
- rescue VOTables::VOTable::Misc::TypeException
1540
- @arg1 = ScalarExpression.new(a)
1541
- else
1542
- @arg1 = a
1543
- end
1544
- end
1545
-
1546
- def arg2=(a)
1547
- begin
1548
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1549
- rescue VOTables::VOTable::Misc::TypeException
1550
- @arg2 = ScalarExpression.new(a)
1551
- else
1552
- @arg2 = a
1553
- end
1554
- end
1555
-
1556
- def arg3=(a)
1557
- begin
1558
- VOTables::VOTable::Misc::TypeCheck.new(a, ScalarExpression).check()
1559
- rescue VOTables::VOTable::Misc::TypeException
1560
- @arg3 = ScalarExpression.new(a)
1561
- else
1562
- @arg3 = a
1563
- end
1564
- end
1565
-
1566
- def to_s
1567
- "{arg1=#{self.arg1},arg2=#{self.arg2},arg3=#{self.arg3}}"
1568
- end
1569
-
1570
- def self.from_xml(node)
1571
- arg1_node, arg2_node, arg3_node = node.elements.to_a('Arg')
1572
- arg1 = Arg.from_xml(arg1_node)
1573
- arg2 = Arg.from_xml(arg2_node)
1574
- arg3 = Arg.from_xml(arg3_node)
1575
-
1576
- return BetweenPred.new(arg1, arg2, arg3)
1577
- end
1578
-
1579
- def self.create_new_object(attributes)
1580
- arg1 = ColumnReference.new(attributes['table'], attributes['name'], nil)
1581
-
1582
- arg2 = nil
1583
- arg3 = nil
1584
- if attributes['value_min'].is_a?(Float) and attributes['value_max'].is_a?(Float)
1585
- arg2 = Atom.new(RealType.new(attributes['value_min']))
1586
- arg3 = Atom.new(RealType.new(attributes['value_max']))
1587
- elsif attributes['value_min'].is_a?(Integer) and attributes['value_max'].is_a?(Integer)
1588
- arg2 = Atom.new(IntegerType.new(attributes['value_min']))
1589
- arg3 = Atom.new(IntegerType.new(attributes['value_max']))
1590
- else
1591
- raise "value is not a real or integer"
1592
- end
1593
-
1594
- return BetweenPred.new(arg1, arg2, arg3)
1595
- end
1596
-
1597
- def match_attributtes(attributes)
1598
- return true if self.arg1.table == attributes['table'] and
1599
- self.arg1.name == attributes['name'] and
1600
- self.arg2.literal.value == attributes['value_min'] and
1601
- self.arg3.literal.value == attributes['value_max']
1602
- return false
1603
- end
1604
-
1605
- # This method finds a condition given its attributes and it returns it
1606
- def find_condition(type, attributes)
1607
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1608
- return self if self.match_attributtes(attributes)
1609
- return nil
1610
- end
1611
- return nil
1612
- end
1613
-
1614
- # This method removes a condition. -1 means that the condition must
1615
- # be removed. 1 means that the condition given its attributes wasn't
1616
- # found, so that the process must continue.
1617
- def remove_condition(type, attributes)
1618
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1619
- return -1 if self.match_attributtes(attributes)
1620
- return 1
1621
- end
1622
- return 1
1623
- end
1624
-
1625
- # This method modifies a condition given its old attributes,
1626
- # replacing the old attributes with the new attributes.
1627
- def modify_condition(type, attributes_old, attributes_new)
1628
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1629
- if self.match_attributtes(attributes_old)
1630
- return BetweenPred.create_new_object(attributes_new)
1631
- else
1632
- return nil
1633
- end
1634
- end
1635
- return nil
1636
- end
1637
-
1638
- # This method replaces a condition given its attributes.
1639
- # Returns -1 if the object must be replaced, or returns 1 if
1640
- # isn't the object that must be replaced, so the process must continue
1641
- def replace_condition(type, attributes, new_condition)
1642
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1643
- return -1 if self.match_attributtes(attributes)
1644
- return 1
1645
- end
1646
- return 1
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
1655
- end
1656
-
1657
- # Represents expressions like Not A.
1658
- class NotBetweenPred < BetweenPred
1659
- def self.from_xml(node)
1660
- arg1_node, arg2_node, arg3_node = node.elements.to_a('Arg')
1661
- arg1 = Arg.from_xml(arg1_node)
1662
- arg2 = Arg.from_xml(arg2_node)
1663
- arg3 = Arg.from_xml(arg3_node)
1664
- return NotBetweenPred.new(arg1, arg2, arg3)
1665
- end
1666
- end
1667
-
1668
- # Abstract Shape type. Shape definitions; Allsky, Circle, Polygon,
1669
- # Box, and Sector are derived from Shape; Ellipse is derived from
1670
- # Circle; Polygon includes also Vertex and SmallCircle
1671
- class Shape
1672
- def self.from_xml(node)
1673
- type_s = node.find_attribute('type', 'http://www.w3.org/2001/XMLSchema-instance')
1674
- type_s = type_s.slice(type_s.index(':')+1, type_s.length)
1675
- return ObjectBuilder.get_class_for(type_s).from_xml(node)
1676
- end
1677
- end
1678
-
1679
- # Circle shape. The circle is defined by a center and a radius
1680
- class Circle < Shape
1681
- attr_reader :ra, :dec, :radius, :system, :shape
1682
-
1683
- def initialize(ra, dec, radius, system='J2000')
1684
- self.ra = ra
1685
- self.dec = dec
1686
- self.radius = radius
1687
- self.system = system
1688
- self.shape = 'CIRCLE'
1689
- end
1690
-
1691
- def ra=(ra)
1692
- begin
1693
- VOTables::VOTable::Misc::TypeCheck.new(ra, RealType).check()
1694
- rescue VOTables::VOTable::Misc::TypeException
1695
- @ra = RealType.new(ra)
1696
- else
1697
- @ra = ra
1698
- end
1699
- end
1700
-
1701
- def dec=(dec)
1702
- begin
1703
- VOTables::VOTable::Misc::TypeCheck.new(dec, RealType).check()
1704
- rescue VOTables::VOTable::Misc::TypeException
1705
- @dec = RealType.new(dec)
1706
- else
1707
- @dec = dec
1708
- end
1709
- end
1710
-
1711
- def radius=(radius)
1712
- begin
1713
- VOTables::VOTable::Misc::TypeCheck.new(radius, RealType).check()
1714
- rescue VOTables::VOTable::Misc::TypeException
1715
- @radius = RealType.new(radius)
1716
- else
1717
- @radius = radius
1718
- end
1719
- end
1720
-
1721
- def system=(sys)
1722
- begin
1723
- VOTables::VOTable::Misc::TypeCheck.new(sys, StringType).check()
1724
- rescue VOTables::VOTable::Misc::TypeException
1725
- @system = StringType.new(sys)
1726
- else
1727
- @system = sys
1728
- end
1729
- end
1730
-
1731
- def shape=(sh)
1732
- begin
1733
- VOTables::VOTable::Misc::TypeCheck.new(sh, StringType).check()
1734
- rescue VOTables::VOTable::Misc::TypeException
1735
- @shape = StringType.new(sh)
1736
- else
1737
- @shape = sh
1738
- end
1739
- end
1740
-
1741
- def to_s
1742
- "{shape=#{self.shape},system=#{self.system},ra=#{self.ra},dec=#{self.dec},radius=#{self.radius}}"
1743
- end
1744
-
1745
- def self.from_xml(node)
1746
- unit = node.attributes['unit'] || 'deg'
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
1753
- ra_s, dec_s = center.split(/\s+/)
1754
- ra = RealType.new(ra_s.to_f)
1755
- dec = RealType.new(dec_s.to_f)
1756
-
1757
- radius_tag = region_prefix ? "#{region_prefix}:Radius" : 'Radius'
1758
- radius_s = REXML::XPath.first(node, radius_tag).text
1759
- radius = RealType.new(radius_s.to_f)
1760
-
1761
- return Circle.new(ra, dec, radius)
1762
- end
1763
-
1764
- def self.create_new_object(attributes)
1765
- ra = RealType.new(attributes['ra'])
1766
- dec = RealType.new(attributes['dec'])
1767
- radius = RealType.new(attributes['radius'])
1768
-
1769
- return Circle.new(ra, dec, radius)
1770
- end
1771
-
1772
- def match_attributtes(attributes)
1773
- return true if self.ra.value == attributes['ra'] and
1774
- self.dec.value == attributes['dec'] and
1775
- self.radius.value == attributes['radius']
1776
- return false
1777
- end
1778
- end
1779
-
1780
- # Box shape. The box is defined by a center and a size
1781
- class Box < Shape
1782
- attr_reader :ra, :dec, :dra, :ddec, :system, :shape
1783
-
1784
- def initialize(ra, dec, dra, ddec, system='J2000')
1785
- self.ra = ra
1786
- self.dec = dec
1787
- self.dra = dra#deltha RA
1788
- self.ddec = ddec#deltha DEC
1789
- self.system = system
1790
- self.shape = 'BOX'
1791
- end
1792
-
1793
- def ra=(ra)
1794
- begin
1795
- VOTables::VOTable::Misc::TypeCheck.new(ra, RealType).check()
1796
- rescue VOTables::VOTable::Misc::TypeException
1797
- @ra = RealType.new(ra)
1798
- else
1799
- @ra = ra
1800
- end
1801
- end
1802
-
1803
- def dec=(dec)
1804
- begin
1805
- VOTables::VOTable::Misc::TypeCheck.new(dec, RealType).check()
1806
- rescue VOTables::VOTable::Misc::TypeException
1807
- @dec = RealType.new(dec)
1808
- else
1809
- @dec = dec
1810
- end
1811
- end
1812
-
1813
- def dra=(dra)
1814
- begin
1815
- VOTables::VOTable::Misc::TypeCheck.new(dra, RealType).check()
1816
- rescue VOTables::VOTable::Misc::TypeException
1817
- @dra = RealType.new(dra)
1818
- else
1819
- @dra = dra
1820
- end
1821
- end
1822
-
1823
- def ddec=(ddec)
1824
- begin
1825
- VOTables::VOTable::Misc::TypeCheck.new(ddec, RealType).check()
1826
- rescue VOTables::VOTable::Misc::TypeException
1827
- @ddec = RealType.new(ddec)
1828
- else
1829
- @ddec = ddec
1830
- end
1831
- end
1832
-
1833
- def system=(sys)
1834
- begin
1835
- VOTables::VOTable::Misc::TypeCheck.new(sys, StringType).check()
1836
- rescue VOTables::VOTable::Misc::TypeException
1837
- @system = StringType.new(sys)
1838
- else
1839
- @system = sys
1840
- end
1841
- end
1842
-
1843
- def shape=(sh)
1844
- begin
1845
- VOTables::VOTable::Misc::TypeCheck.new(sh, StringType).check()
1846
- rescue VOTables::VOTable::Misc::TypeException
1847
- @shape = StringType.new(sh)
1848
- else
1849
- @shape = sh
1850
- end
1851
- end
1852
-
1853
- def to_s
1854
- "{shape=#{self.shape},system=#{self.system},ra=#{self.ra}," +
1855
- "dec=#{self.dec},dra=#{self.dra},ddec=#{self.ddec}}"
1856
- end
1857
-
1858
- def self.from_xml(node)
1859
- unit = node.attributes['unit'] || 'deg'
1860
-
1861
- center = REXML::XPath.first(node, 'reg:Center').text
1862
- ra_s, dec_s = center.split(/\s+/)
1863
- ra = RealType.new(ra_s.to_f)
1864
- dec = RealType.new(dec_s.to_f)
1865
-
1866
- size = REXML::XPath.first(node, 'reg:Size').text
1867
- dra_s, ddec_s = size.split(/\s+/)
1868
- dra = RealType.new(dra_s.to_f)
1869
- ddec = RealType.new(ddec_s.to_f)
1870
-
1871
- return Box.new(ra, dec, dra, ddec)
1872
- end
1873
-
1874
- def self.create_new_object(attributes)
1875
- ra = RealType.new(attributes['ra'])
1876
- dec = RealType.new(attributes['dec'])
1877
- dra = RealType.new(attributes['dra'])
1878
- ddec = RealType.new(attributes['ddec'])
1879
-
1880
- return Box.new(ra, dec, dra, ddec)
1881
- end
1882
-
1883
- def match_attributtes(attributes)
1884
- return true if self.ra.value == attributes['ra'] and
1885
- self.dec.value == attributes['dec'] and
1886
- self.dra.value == attributes['dra'] and
1887
- self.ddec.value == attributes['ddec']
1888
- return false
1889
- end
1890
- end
1891
-
1892
- # Represents the Regions such as circle in Where clause.
1893
- class RegionSearch < Search
1894
- attr_reader :shape, :intersection
1895
-
1896
- def initialize(shape, intersection='overlaps')
1897
- self.shape = shape
1898
- self.intersection = intersection
1899
- end
1900
-
1901
- def shape=(s)
1902
- VOTables::VOTable::Misc::TypeCheck.new(s, Shape).check()
1903
- @shape = s
1904
- end
1905
-
1906
- def intersection=(i)
1907
- begin
1908
- VOTables::VOTable::Misc::TypeCheck.new(i, StringType).check()
1909
- rescue VOTables::VOTable::Misc::TypeException
1910
- @intersection = StringType.new(i)
1911
- else
1912
- @intersection = i
1913
- end
1914
- end
1915
-
1916
- def to_s
1917
- "{region={intersection=#{self.intersection},shape=#{self.shape}}}"
1918
- end
1919
-
1920
- def self.from_xml(node)
1921
- inter = node.attributes['intersection'].to_s
1922
- region_node = REXML::XPath.first(node, 'Region')
1923
- sh = Shape.from_xml(region_node)
1924
- return RegionSearch.new(sh, inter)
1925
- end
1926
-
1927
- def self.create_new_object(attributes)
1928
- sh = ObjectBuilder.get_class_for(attributes['shape_type']).create_new_object(attributes)
1929
- return RegionSearch.new(sh, attributes['intersection'].to_s)
1930
- end
1931
-
1932
- def match_attributtes(attributes)
1933
- return self.shape.match_attributtes(attributes)
1934
- end
1935
-
1936
- # This method finds a condition given its attributes and it returns it
1937
- def find_condition(type, attributes)
1938
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1939
- return self if self.match_attributtes(attributes)
1940
- return nil
1941
- end
1942
- return nil
1943
- end
1944
-
1945
- # This method removes a condition. -1 means that the condition must
1946
- # be removed. 1 means that the condition given its attributes wasn't
1947
- # found, so that the process must continue.
1948
- def remove_condition(type, attributes)
1949
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1950
- return -1 if self.match_attributtes(attributes)
1951
- return 1
1952
- end
1953
- return 1
1954
- end
1955
-
1956
- # This method modifies a condition given its old attributes,
1957
- # replacing the old attributes with the new attributes.
1958
- def modify_condition(type, attributes_old, attributes_new)
1959
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1960
- if self.match_attributtes(attributes_old)
1961
- return RegionSearch.create_new_object(attributes_new)
1962
- else
1963
- return nil
1964
- end
1965
- end
1966
- return nil
1967
- end
1968
-
1969
- # This method replaces a condition given its attributes.
1970
- # Returns -1 if the object must be replaced, or returns 1 if
1971
- # isn't the object that must be replaced, so the process must continue
1972
- def replace_condition(type, attributes, new_condition)
1973
- if ObjectBuilder.get_class_for(type).to_s() == self.class.to_s()
1974
- return -1 if self.match_attributtes(attributes)
1975
- return 1
1976
- end
1977
- return 1
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
1985
- end
1986
-
1987
- # Represents expressions like Not A.
1988
- class InverseSearch < Search
1989
- attr_reader :condition
1990
-
1991
- def initialize(condition)
1992
- self.condition = condition
1993
- end
1994
-
1995
- def condition=(c)
1996
- VOTables::VOTable::Misc::TypeCheck.new(c, Search).check()
1997
- @condition = c
1998
- end
1999
-
2000
- def to_s
2001
- "{condition=#{self.condition}}"
2002
- end
2003
-
2004
- def self.from_xml(node)
2005
- cond_node = REXML::XPath.first(node, 'Condition')
2006
- cond = Condition.from_xml(cond_node)
2007
- return InverseSearch.new(cond)
2008
- end
2009
- end
2010
-
2011
- # Represents the Having expression part of a query.
2012
- class Having
2013
- attr_reader :condition
2014
-
2015
- def initialize(condition)
2016
- self.condition = condition
2017
- end
2018
-
2019
- def condition=(c)
2020
- VOTables::VOTable::Misc::TypeCheck.new(c, Search).check()
2021
- @condition = c
2022
- end
2023
-
2024
- def to_s
2025
- "{condition=#{self.condition}}"
2026
- end
2027
-
2028
- def self.from_xml(node)
2029
- cond_node = REXML::XPath.first(node, 'Condition')
2030
- cond = Condition.from_xml(cond_node)
2031
- return Having.new(cond)
2032
- end
2033
- end
2034
-
2035
- # Represents the Group By expression part of a query.
2036
- class GroupBy
2037
- attr_reader :columns
2038
-
2039
- def initialize(columns)
2040
- self.columns = columns
2041
- end
2042
-
2043
- def columns=(c)
2044
- raise "Provide at least one condition" if c.size < 1
2045
-
2046
- @columns = []
2047
- c.each do |col|
2048
- VOTables::VOTable::Misc::TypeCheck.new(col, ColumnReference).check()
2049
- @columns.push(col)
2050
- end
2051
- end
2052
-
2053
- def to_s
2054
- cols = self.columns.collect{|x| x.to_s}.join('|')
2055
- "{columns=#{cols}}"
2056
- end
2057
-
2058
- def self.from_xml(node)
2059
- columns = []
2060
- node.elements.each('Column') do |col_node|
2061
- col = Column.from_xml(col_node)
2062
- columns.push(col)
2063
- end
2064
-
2065
- return GroupBy.new(columns)
2066
- end
2067
- end
2068
-
2069
- # Represents the Where part of the query.
2070
- class Where
2071
- attr_reader :condition
2072
-
2073
- def initialize(condition)
2074
- self.condition = condition
2075
- end
2076
-
2077
- def condition=(c)
2078
- VOTables::VOTable::Misc::TypeCheck.new(c, Search).check()
2079
- @condition = c
2080
- end
2081
-
2082
- def to_s
2083
- "{condition=#{self.condition}}"
2084
- end
2085
-
2086
- def self.from_xml(node)
2087
- cond_node = REXML::XPath.first(node, 'Condition')
2088
- cond = Condition.from_xml(cond_node)
2089
- return Where.new(cond)
2090
- end
2091
-
2092
- # This method finds a condition given its attributes and it returns it
2093
- def find_condition(type, attributes)
2094
- return self.condition.find_condition(type, attributes)
2095
- end
2096
-
2097
- # This method removes a condition. -1 means that the condition must
2098
- # be removed. 1 means that the condition given its attributes wasn't
2099
- # found. The other case is that the condition was changed in another
2100
- # place, for example could have been removed in the intersectionSearchType
2101
- # called.
2102
- def remove_condition(type, attributes)
2103
- condition = self.condition.remove_condition(type, attributes)
2104
- if condition == -1
2105
- self.condition = nil
2106
- elsif condition != 1
2107
- self.condition = condition
2108
- end
2109
- end
2110
-
2111
- # This method modify a condition given its old attributtes,
2112
- # replacing the old attributes with the new attributes.
2113
- def modify_condition(type, attributes_old, attributes_new)
2114
- self.condition = self.condition.modify_condition(type, attributes_old, attributes_new)
2115
- end
2116
-
2117
- # This method replaces a condition for a new condition. -1 means that
2118
- # the condition must be replaced. 1 means that the old condition in
2119
- # this case wasn't found so that the old condition won't be replaced.
2120
- # The other case is that the condition was changed in another place,
2121
- # for example could have been replaced in the intersectionSearchType
2122
- # called.
2123
- def replace_condition(type, attributes, new_condition)
2124
- condition = self.condition.replace_condition(type, attributes, new_condition)
2125
- if condition == -1
2126
- self.condition = new_condition
2127
- elsif condition != 1
2128
- self.condition = condition
2129
- end
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
2137
- end
2138
-
2139
- # Represents the From part of the query.
2140
- class From
2141
- attr_reader :tables
2142
-
2143
- def initialize(tables)
2144
- self.tables = tables
2145
- end
2146
-
2147
- def tables=(ts)
2148
- raise "Specify at least one table" if ts.size < 1
2149
-
2150
- @tables = []
2151
- ts.each do |t|
2152
- VOTables::VOTable::Misc::TypeCheck.new(t, FromTable).check()
2153
- @tables.push(t)
2154
- end
2155
- end
2156
-
2157
- def to_s
2158
- tables = self.tables.collect{|x| x.to_s}.join('|')
2159
- "{tables=#{tables}}"
2160
- end
2161
-
2162
- def self.from_xml(node)
2163
- table_list = []
2164
- node.elements.each("Table") do |tbl_node|
2165
- table = Table.from_xml(tbl_node)
2166
- table_list.push(table)
2167
- end
2168
-
2169
- return From.new(table_list)
2170
- end
2171
- end
2172
-
2173
- # List of items to be selected in the Query.
2174
- class SelectionList
2175
- attr_reader :items
2176
-
2177
- def initialize(items)
2178
- self.items = items
2179
- end
2180
-
2181
- def items=(is)
2182
- raise "Specify at least one item" if is.size < 1
2183
-
2184
- @items = []
2185
- is.each do |i|
2186
- VOTables::VOTable::Misc::TypeCheck.new(i, SelectionItem).check()
2187
- @items.push(i)
2188
- end
2189
- end
2190
-
2191
- def to_s
2192
- items = self.items.collect{|x| x.to_s}.join('|')
2193
- return "{items=#{items}}"
2194
- end
2195
-
2196
- def self.from_xml(node)
2197
- item_list = []
2198
- node.elements.each('Item') do |item_node|
2199
- item_list.push(Item.from_xml(item_node))
2200
- end
2201
-
2202
- return SelectionList.new(item_list)
2203
- end
2204
-
2205
- def add(attributes)
2206
- new_item = nil
2207
- if attributes['name'] == AllSelectionItem.value
2208
- new_item = AllSelectionItem.new()
2209
- else
2210
- new_item = ColumnReference.new(attributes['table'],
2211
- attributes['name'], attributes['xpath_name'])
2212
- end
2213
- self.items.push(new_item) if new_item and find(attributes) == nil
2214
- end
2215
-
2216
- def remove(attributes)
2217
- remove_item = find(attributes)
2218
- self.items.delete(remove_item) if remove_item != nil
2219
- end
2220
-
2221
- def find(attributes)
2222
- self.items().each do |item|
2223
- if !item.is_a?(AllSelectionItem)
2224
- return item if item.name() == attributes['name'] and item.table() == attributes['table']
2225
- elsif item.is_a?(AllSelectionItem)
2226
- return item if AllSelectionItem.value == attributes['name']
2227
- end
2228
- end
2229
- return nil
2230
- end
2231
-
2232
- def is_empty
2233
- self.items().empty?
2234
- end
2235
- end
2236
-
2237
- # Represents the TOP part of a query.
2238
- class SelectionLimit
2239
- attr_reader :top
2240
-
2241
- def initialize(top)
2242
- self.top = top
2243
- end
2244
-
2245
- def top=(t)
2246
- raise "Provide an integer > 0" if t < 1 or !t.is_a?(Integer)
2247
- @top = t
2248
- end
2249
-
2250
- def to_s
2251
- "{top=#{self.top}}"
2252
- end
2253
-
2254
- def self.from_xml(node)
2255
- top = node.attributes['Top'].to_i
2256
- return SelectionLimit.new(top)
2257
- end
2258
- end
2259
-
2260
- # Represents the SQL INTO expression.
2261
- class Into
2262
- attr_accessor :table_name
2263
-
2264
- def initialize(name)
2265
- self.table_name = name
2266
- end
2267
-
2268
- def to_s
2269
- "{table_name=#{self.table_name}}"
2270
- end
2271
-
2272
- def self.from_xml(node)
2273
- table_name_node = REXML::XPath.first(node, 'TableName')
2274
- table_name = TableName.from_xml(table_name_node)
2275
- return Into.new(table_name)
2276
- end
2277
- end
2278
-
2279
- # Ascending or Descending order of an Order by term.
2280
- class OrderDirection
2281
- attr_reader :value
2282
-
2283
- @@options = ['ASC', 'DESC']
2284
-
2285
- def initialize(value, options_list=nil)
2286
- @options_list = options_list || @@options
2287
- self.value = value
2288
- end
2289
-
2290
- def value=(v)
2291
- if @options_list.include?(v)
2292
- @value = v
2293
- else
2294
- raise "Value is not valid. Use one of: " +
2295
- @options_list.join(', ')
2296
- end
2297
- end
2298
-
2299
- def to_s
2300
- "{value=#{self.value}}"
2301
- end
2302
- end
2303
-
2304
- # Option for setting the direction for Order By.
2305
- class OrderOption
2306
- attr_reader :direction
2307
-
2308
- def initialize(direction)
2309
- self.direction = direction
2310
- end
2311
-
2312
- def direction=(d)
2313
- begin
2314
- VOTables::VOTable::Misc::TypeCheck.new(d, OrderDirection).check()
2315
- rescue VOTables::VOTable::Misc::TypeException
2316
- @direction = OrderDirection.new(d)
2317
- else
2318
- @direction = d
2319
- end
2320
- end
2321
-
2322
- def to_s
2323
- "{direction=#{self.direction}}"
2324
- end
2325
-
2326
- def self.from_xml(node)
2327
- return OrderOption.new(node.attributes['Direction'])
2328
- end
2329
- end
2330
-
2331
- # Represents the ORDER BY part of a query.
2332
- class Order
2333
- attr_reader :expression, :order
2334
-
2335
- def initialize(expression, order=nil)
2336
- self.expression = expression
2337
- self.order = order
2338
- end
2339
-
2340
- def expression=(e)
2341
- VOTables::VOTable::Misc::TypeCheck.new(e, ScalarExpression).check()
2342
- @expression = e
2343
- end
2344
-
2345
- def order=(o)
2346
- begin
2347
- VOTables::VOTable::Misc::TypeCheck.new(o, OrderOption).check()
2348
- rescue VOTables::VOTable::Misc::TypeException
2349
- @order = OrderOption.new(o)
2350
- else
2351
- @order = o
2352
- end
2353
- end
2354
-
2355
- def to_s
2356
- "{expression=#{self.expression},order=#{self.order}}"
2357
- end
2358
-
2359
- def self.from_xml(node)
2360
- expr_node = REXML::XPath.first(node, 'Expression')
2361
- expr = Expression.from_xml(expr_node)
2362
- order_option_node = REXML::XPath.first(node, 'Order')
2363
- order_option = OrderOption.from_xml(order_option_node)
2364
- return Order.new(expr, order_option)
2365
- end
2366
- end
2367
-
2368
- # List of expressions in which order the results should be provided.
2369
- class OrderExpression
2370
- attr_reader :items
2371
-
2372
- def initialize(items)
2373
- self.items = items
2374
- end
2375
-
2376
- def items=(is)
2377
- raise "Specify at least one item" if is.size < 1
2378
-
2379
- @items = []
2380
- is.each do |i|
2381
- VOTables::VOTable::Misc::TypeCheck.new(i, Order).check()
2382
- @items.push(i)
2383
- end
2384
- end
2385
-
2386
- def to_s
2387
- items = self.items.collect{|x| x.to_s}.join('|')
2388
- "{items=#{items}}"
2389
- end
2390
-
2391
- def self.from_xml(node)
2392
- items = []
2393
- node.elements.each('Item') do |item_node|
2394
- item = Item.from_xml(item_node)
2395
- items.push(item)
2396
- end
2397
-
2398
- return OrderExpression.new(items)
2399
- end
2400
- end
2401
-
2402
- # Represents a list of constants provided for a SQL IN expression.
2403
- class ConstantListSet < InclusionSet
2404
- attr_reader :items
2405
-
2406
- def initialize(items)
2407
- self.items = items
2408
- end
2409
-
2410
- def items=(is)
2411
- raise "Specify at least one item" if is.size < 1
2412
-
2413
- @items = []
2414
- is.each do |i|
2415
- begin
2416
- VOTables::VOTable::Misc::TypeCheck.new(i, LiteralType).check()
2417
- rescue VOTables::VOTable::Misc::TypeException
2418
- if i.is_a?(String)
2419
- @items.push(StringType.new(i))
2420
- elsif i.is_a?(Integer)
2421
- @items.push(IntegerType.new(i))
2422
- elsif i.is_a?(Float)
2423
- @items.push(RealType.new(i))
2424
- else
2425
- raise "Item must be of type LiteralType"
2426
- end
2427
- else
2428
- @items.push(i)
2429
- end
2430
- end
2431
- end
2432
-
2433
- def to_s
2434
- items = self.items.collect{|x| x.to_s}.join('|')
2435
- "{items=#{items}}"
2436
- end
2437
-
2438
- def self.from_xml(node)
2439
- item_list = []
2440
- node.elements.each('Item') do |item_node|
2441
- item = Item.from_xml(item_node)
2442
- item_list.push(Item.from_xml(item_node))
2443
- end
2444
-
2445
- return ConstantListSet.new(item_list)
2446
- end
2447
- end
2448
-
2449
- # Represents SQL IN expression.
2450
- class InclusiveSearch < Search
2451
- attr_reader :expression, :set
2452
-
2453
- def initialize(expression, set)
2454
- self.expression = expression
2455
- self.set = set
2456
- end
2457
-
2458
- def expression=(e)
2459
- VOTables::VOTable::Misc::TypeCheck.new(e, ScalarExpression).check()
2460
- @expression = e
2461
- end
2462
-
2463
- def set=(s)
2464
- VOTables::VOTable::Misc::TypeCheck.new(s, InclusionSet).check()
2465
- @set = s
2466
- end
2467
-
2468
- def to_s
2469
- "{expression=#{self.expression},set=#{self.set}}"
2470
- end
2471
-
2472
- def self.from_xml(node)
2473
- expr_node = REXML::XPath.first(node, 'Expression')
2474
- expr = Expression.from_xml(expr_node)
2475
- set_node = REXML::XPath.first(node, 'Set')
2476
- set = Set.from_xml(set_node)
2477
- return InclusiveSearch.new(expr, set)
2478
- end
2479
- end
2480
-
2481
- # The SELECT part of a query.
2482
- class Select
2483
- attr_reader :allow, :restrict, :selection_list, :in_to, :from,
2484
- :where, :group_by, :having, :order_by
2485
- attr_accessor :start_comment, :end_comment
2486
-
2487
- def initialize(selection_list, allow=nil, restrict=nil, in_to=nil,
2488
- from=nil, where=nil, group_by=nil, having=nil, order_by=nil,
2489
- start_comment=nil, end_comment=nil)
2490
- self.selection_list = selection_list
2491
- self.allow = allow
2492
- self.restrict = restrict
2493
- self.in_to = in_to
2494
- self.from = from
2495
- self.where = where
2496
- self.group_by = group_by
2497
- self.having = having
2498
- self.order_by = order_by
2499
- self.start_comment = start_comment
2500
- self.end_comment = end_comment
2501
- end
2502
-
2503
- def selection_list=(sl)
2504
- VOTables::VOTable::Misc::TypeCheck.new(sl, SelectionList).check()
2505
- @selection_list = sl
2506
- end
2507
-
2508
- def allow=(a)
2509
- begin
2510
- VOTables::VOTable::Misc::TypeCheck.new(a, SelectionOption).check()
2511
- rescue VOTables::VOTable::Misc::TypeException
2512
- @allow = SelectionOption.new(a)
2513
- else
2514
- @allow = a
2515
- end
2516
- end
2517
-
2518
- def restrict=(r)
2519
- begin
2520
- VOTables::VOTable::Misc::TypeCheck.new(r, SelectionLimit).check()
2521
- rescue VOTables::VOTable::Misc::TypeException
2522
- @restrict = SelectionLimit.new(r)
2523
- else
2524
- @restrict = r
2525
- end
2526
- end
2527
-
2528
- def in_to=(it)
2529
- begin
2530
- VOTables::VOTable::Misc::TypeCheck.new(it, Into).check()
2531
- rescue VOTables::VOTable::Misc::TypeException
2532
- @in_to = Into.new(it)
2533
- else
2534
- @in_to = it
2535
- end
2536
- end
2537
-
2538
- def from=(f)
2539
- VOTables::VOTable::Misc::TypeCheck.new(f, From).check()
2540
- @from = f
2541
- end
2542
-
2543
- def where=(w)
2544
- VOTables::VOTable::Misc::TypeCheck.new(w, Where).check()
2545
- @where = w
2546
- end
2547
-
2548
- def group_by=(gb)
2549
- VOTables::VOTable::Misc::TypeCheck.new(gb, GroupBy).check()
2550
- @group_by = gb
2551
- end
2552
-
2553
- def having=(h)
2554
- VOTables::VOTable::Misc::TypeCheck.new(h, Having).check()
2555
- @having = h
2556
- end
2557
-
2558
- def order_by=(ob)
2559
- VOTables::VOTable::Misc::TypeCheck.new(ob, OrderExpression).check()
2560
- @order_by = ob
2561
- end
2562
-
2563
- def to_s
2564
- "{allow=#{self.allow},restrict=#{self.restrict},selection_list=#{self.selection_list}," +
2565
- "in_to=#{self.in_to},from=#{self.from},where=#{self.where},group_by=#{self.group_by}," +
2566
- "having=#{self.having},order_by=#{self.order_by},start_comment=#{self.start_comment}," +
2567
- "end_comment=#{self.end_comment}}"
2568
- end
2569
-
2570
- def to_file(file_path)
2571
- file = File.new(file_path, 'w')
2572
- file.syswrite(self.to_adqlx)
2573
- file.close()
2574
- end
2575
-
2576
- def self.from_xml(node)
2577
- # SelectionList
2578
- sl_node = REXML::XPath.first(node, 'SelectionList') or raise "No SelectionList element"
2579
- selection_list = SelectionList.from_xml(sl_node)
2580
-
2581
- # Allow
2582
- allow_node = REXML::XPath.first(node, 'Allow')
2583
- allow = nil
2584
- allow = Allow.from_xml(allow_node) if allow_node
2585
-
2586
- # Restrict
2587
- restrict_node = REXML::XPath.first(node, 'Restrict')
2588
- restrict = nil
2589
- restrict = Restrict.from_xml(restrict_node) if restrict_node
2590
-
2591
- # InTo
2592
- into_node = REXML::XPath.first(node, 'InTo')
2593
- into = nil
2594
- into = InTo.from_xml(into_node) if into_node
2595
-
2596
- # From
2597
- from_node = REXML::XPath.first(node, 'From')
2598
- from = nil
2599
- from = From.from_xml(from_node) if from_node
2600
-
2601
- # Where
2602
- where_node = REXML::XPath.first(node, 'Where')
2603
- where = nil
2604
- where = Where.from_xml(where_node) if where_node
2605
-
2606
- # GroupBy
2607
- groupby_node = REXML::XPath.first(node, 'GroupBy')
2608
- groupby = nil
2609
- groupby = GroupBy.from_xml(groupby_node) if groupby_node
2610
-
2611
- # Having
2612
- having_node = REXML::XPath.first(node, 'Having')
2613
- having = nil
2614
- having = Having.from_xml(having_node) if having_node
2615
-
2616
- # OrderBy
2617
- orderby_node = REXML::XPath.first(node, 'OrderBy')
2618
- orderby = nil
2619
- orderby = OrderBy.from_xml(orderby_node) if orderby_node
2620
-
2621
- # StartComment
2622
- start_comment_node = REXML::XPath.first(node, 'StartComment')
2623
- start_comment = nil
2624
- start_comment = StartComment.from_xml(start_comment_node) if start_comment_node
2625
-
2626
- # EndComment
2627
- end_comment_node = REXML::XPath.first(node, 'EndComment')
2628
- end_comment = nil
2629
- end_comment = EndComment.from_xml(end_comment_node) if end_comment_node
2630
-
2631
- return Select.new(selection_list, allow, restrict, into,
2632
- from, where, groupby, having, orderby,
2633
- start_comment, end_comment)
2634
- end
2635
- end
2636
-
2637
- # Represents user defined function expressions.
2638
- class UserDefinedFunction < ScalarExpression
2639
- attr_accessor :name
2640
- attr_reader :params
2641
-
2642
- def initialize(name, params=nil)
2643
- self.name = name
2644
- self.params = params
2645
- end
2646
-
2647
- def params=(ps)
2648
- if ps
2649
- raise "Provide at least 1 parameter" if ps.size < 1
2650
-
2651
- @params = []
2652
- ps.each do |p|
2653
- VOTables::VOTable::Misc::TypeCheck.new(p, ScalarExpression)
2654
- @params.push(p)
2655
- end
2656
- end
2657
- end
2658
-
2659
- def to_s
2660
- params = self.params.collect{|x| x.to_s}.join('|')
2661
- "{name=#{self.name},params=#{params}}"
2662
- end
2663
-
2664
- def self.from_xml(node)
2665
- name = REXML::XPath.first(node, 'Name').text
2666
- params = []
2667
- node.elements.each('Params') do |param_node|
2668
- params.push(ScalarExpression.from_xml(param_node))
2669
- end
2670
- params = nil if params.size < 1
2671
- return UserDefinedFunction.new(name, params)
2672
- end
2673
- end
2674
-
2675
- # Denotes the type of a Join operation.
2676
- class JointTableQualifier
2677
- attr_reader :value
2678
-
2679
- @@joins = ['LEFT_OUTER', 'RIGHT_OUTER', 'FULL_OUTER',
2680
- 'INNER', 'CROSS']
2681
-
2682
- def initialize(value, join_list=nil)
2683
- @join_list = join_list || @@joins
2684
- self.value = value
2685
- end
2686
-
2687
- def value=(v)
2688
- if @join_list.include?(v)
2689
- @value = v
2690
- else
2691
- raise "Join type is not valid. Use one of: " +
2692
- @join_list.join(', ')
2693
- end
2694
- end
2695
-
2696
- def to_s
2697
- "{value=#{self.value}}"
2698
- end
2699
-
2700
- def self.from_xml(node)
2701
- return JointTableQualifier.new(node.text)
2702
- end
2703
- end
2704
-
2705
- # Represents SQL JOIN expression.
2706
- class JoinTable < FromTable
2707
- attr_reader :qualifier, :tables, :condition
2708
-
2709
- def initialize(qualifier, tables, condition)
2710
- self.qualifier = qualifier
2711
- self.tables = tables
2712
- self.condition = condition
2713
- end
2714
-
2715
- def qualifier=(q)
2716
- begin
2717
- VOTables::VOTable::Misc::TypeCheck.new(q, JointTableQualifier).check()
2718
- rescue VOTables::VOTable::Misc::TypeException
2719
- @qualifier = JointTableQualifier.new(q)
2720
- else
2721
- @qualifier = q
2722
- end
2723
- end
2724
-
2725
- def tables=(ts)
2726
- VOTables::VOTable::Misc::TypeCheck.new(ts, ArrayOfFromTable).check()
2727
- @tables = ts
2728
- end
2729
-
2730
- def condition=(c)
2731
- VOTables::VOTable::Misc::TypeCheck.new(c, ComparisonPred).check()
2732
- @condition = c
2733
- end
2734
-
2735
- def to_s
2736
- "{qualifier=#{self.qualifier},tables=#{self.tables},condition=#{self.condition}}"
2737
- end
2738
-
2739
- def self.from_xml(node)
2740
- qual_node = REXML::XPath.first(node, 'Qualifier')
2741
- qual = Qualifier.from_xml(qual_node)
2742
- tables_node = REXML::XPath.first(node, 'Tables')
2743
- tables = Tables.from_xml(tables_node)
2744
- cond_node = REXML::XPath.first(node, 'Condition')
2745
- cond = Condition.from_xml(cond_node)
2746
- return JoinTable.new(qual, tables, cond)
2747
- end
2748
- end
2749
-
2750
- # Represents an array of tables in the from expression.def expression.
2751
- class ArrayOfFromTable
2752
- attr_reader :from_tables
2753
-
2754
- def initialize(tables)
2755
- self.from_tables = tables
2756
- end
2757
-
2758
- def from_tables=(fts)
2759
- raise "Provide at least one table" if fts.size < 1
2760
-
2761
- @from_tables = []
2762
- if fts
2763
- fts.each do |ft|
2764
- VOTables::VOTable::Misc::TypeCheck.new(ft, FromTable)
2765
- @from_tables.push(ft)
2766
- end
2767
- end
2768
- end
2769
-
2770
- def to_s
2771
- tables = self.from_tables.collect{|x| x.to_s}.join('|')
2772
- "{from_tables=#{tables}}"
2773
- end
2774
-
2775
- def self.from_xml(node)
2776
- from_tables = []
2777
- node.elements.to_a('Table').each do |ftbl|
2778
- from_tables.push(FromTable.from_xml(ftbl))
2779
- end
2780
-
2781
- return ArrayOfFromTable.new(from_tables)
2782
- end
2783
- end
2784
-
2785
- end
2786
-
2787
- end