voruby 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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