omf_web 0.9.1 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. data/.gitignore +0 -1
  2. data/README.md +8 -2
  3. data/doc/screenshot.png +0 -0
  4. data/example/{basic → NOT_WORKING/basic}/hello-world-wired.rb +0 -0
  5. data/example/{basic → NOT_WORKING/basic}/visualisation.yml +0 -0
  6. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklynDemo.sq3 +0 -0
  7. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_gps.dat +0 -0
  8. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_server.rb +0 -0
  9. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_wimax.dat +0 -0
  10. data/example/{brooklyn → NOT_WORKING/brooklyn}/sql_source.rb +0 -0
  11. data/example/{code → NOT_WORKING/code}/code_server.rb +0 -0
  12. data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/parse_log.rb +0 -0
  13. data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/pxe_slice-2012-06-02t02.25.00-04.00.log +0 -0
  14. data/example/{frisbee → NOT_WORKING/frisbee}/progress_chart.yaml +0 -0
  15. data/example/{frisbee → NOT_WORKING/frisbee}/progress_tab.yaml +0 -0
  16. data/example/{frisbee → NOT_WORKING/frisbee}/progress_table.yaml +0 -0
  17. data/example/{frisbee → NOT_WORKING/frisbee}/viz_server.rb +0 -0
  18. data/example/{gec12 → NOT_WORKING/gec12}/gec12-53.rb +0 -0
  19. data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo.sq3 +0 -0
  20. data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo_server.rb +0 -0
  21. data/example/{gec12 → NOT_WORKING/gec12}/visualization.rb +0 -0
  22. data/example/{incoming → NOT_WORKING/incoming}/ofpu_barchart_widget.yaml +0 -0
  23. data/example/{log → NOT_WORKING/log}/log_config.xml +0 -0
  24. data/example/{log → NOT_WORKING/log}/log_server.rb +0 -0
  25. data/example/{network → NOT_WORKING/network}/flow_tab.yaml +0 -0
  26. data/example/{network → NOT_WORKING/network}/network_server.rb +0 -0
  27. data/example/{text → NOT_WORKING/text}/test.md +0 -0
  28. data/example/{text → NOT_WORKING/text}/test.rb +0 -0
  29. data/example/{wimax → NOT_WORKING/wimax}/downlink.yaml +0 -0
  30. data/example/{wimax → NOT_WORKING/wimax}/power.yaml +0 -0
  31. data/example/{wimax → NOT_WORKING/wimax}/snapshot.db +0 -0
  32. data/example/{wimax → NOT_WORKING/wimax}/snapshot.sql +0 -0
  33. data/example/{wimax → NOT_WORKING/wimax}/test.rb +0 -0
  34. data/example/{wimax → NOT_WORKING/wimax}/uplink.yaml +0 -0
  35. data/example/{wimax → NOT_WORKING/wimax}/viz_server.rb +0 -0
  36. data/example/demo/data_sources/mobile_network.rb +3 -0
  37. data/example/demo/data_sources/static_network.rb +54 -0
  38. data/example/demo/widgets/charts_tab.yaml +21 -16
  39. data/example/demo/widgets/linked_graphs_tab.yaml +95 -0
  40. data/example/demo/widgets/mobile_network_widget.yaml +1 -1
  41. data/example/demo/widgets/pie_chart_widget.yaml +1 -1
  42. data/lib/omf-web/config.ru +2 -2
  43. data/lib/omf-web/data_source_proxy.rb +81 -19
  44. data/lib/omf-web/rack/websocket_handler.rb +77 -23
  45. data/lib/omf-web/theme/abstract_page.rb +43 -26
  46. data/lib/omf-web/theme/bright/code_renderer.rb +1 -1
  47. data/lib/omf-web/theme/bright/page.rb +1 -0
  48. data/lib/omf-web/theme/bright/tabbed_renderer.rb +7 -0
  49. data/lib/omf-web/version.rb +7 -0
  50. data/lib/omf-web/widget/data_widget.rb +38 -46
  51. data/lib/omf-web/widget/layout/stacked_layout.rb +2 -1
  52. data/lib/omf-web/widget/layout/tabbed_layout.rb +1 -2
  53. data/{MARUKU-LICENSE → lib/omf-web/widget/text/maruku/MARUKU-LICENSE} +0 -0
  54. data/lib/{maruku → omf-web/widget/text/maruku}/helpers.rb +0 -0
  55. data/lib/{maruku → omf-web/widget/text/maruku}/input/parse_block.rb +0 -0
  56. data/lib/{maruku → omf-web/widget/text/maruku}/output/to_html.rb +26 -21
  57. data/lib/omf-web/widget/text/maruku.rb +5 -0
  58. data/omf_web.gemspec +2 -1
  59. data/share/htdocs/{js → UNUSED}/log/table.js +0 -0
  60. data/share/htdocs/{css → graph/css}/graph.css +0 -0
  61. data/share/htdocs/{image/graph → graph/img}/bar_chart.png +0 -0
  62. data/share/htdocs/{image/graph → graph/img}/donut_chart.png +0 -0
  63. data/share/htdocs/{image/graph → graph/img}/funnel.png +0 -0
  64. data/share/htdocs/{image/graph → graph/img}/info.png +0 -0
  65. data/share/htdocs/{image/graph → graph/img}/line_chart.png +0 -0
  66. data/share/htdocs/{image/graph → graph/img}/line_chart_fill.png +0 -0
  67. data/share/htdocs/{image/graph → graph/img}/misc.png +0 -0
  68. data/share/htdocs/{image/graph → graph/img}/overview.png +0 -0
  69. data/share/htdocs/{image/graph → graph/img}/pie_chart.png +0 -0
  70. data/share/htdocs/{image/graph → graph/img}/scatter_plot.png +0 -0
  71. data/share/htdocs/{image/graph → graph/img}/stacked_bar_chart.png +0 -0
  72. data/share/htdocs/{image/graph → graph/img}/stacked_line_chart.png +0 -0
  73. data/share/htdocs/{image/graph → graph/img}/table.png +0 -0
  74. data/share/htdocs/{js/graph → graph/js}/abstract_chart.js +1 -1
  75. data/share/htdocs/{js/graph → graph/js}/abstract_nv_chart.js +8 -13
  76. data/share/htdocs/{js/graph → graph/js}/abstract_widget.js +9 -16
  77. data/share/htdocs/{js/graph → graph/js}/axis.js +1 -1
  78. data/share/htdocs/{js/graph → graph/js}/barchart.js +2 -2
  79. data/share/htdocs/{js/graph → graph/js}/code_mirror.js +1 -5
  80. data/share/htdocs/{js/graph → graph/js}/discrete_bar_chart.js +1 -1
  81. data/share/htdocs/{js/graph → graph/js}/histogram2.js +1 -1
  82. data/share/htdocs/{js/graph → graph/js}/holt_winters_chart.js +1 -1
  83. data/share/htdocs/{js/graph → graph/js}/line_chart3.js +1 -1
  84. data/share/htdocs/{js/graph → graph/js}/line_chart_with_focus.js +1 -1
  85. data/share/htdocs/{js/graph → graph/js}/map2.js +1 -1
  86. data/share/htdocs/{js/graph → graph/js}/multi_barchart.js +1 -1
  87. data/share/htdocs/graph/js/network2.js +412 -0
  88. data/share/htdocs/{js/graph → graph/js}/pie_chart2.js +1 -1
  89. data/share/htdocs/{js/graph → graph/js}/scatter_plot.js +1 -1
  90. data/share/htdocs/{js/graph → graph/js}/table2.js +17 -20
  91. data/share/htdocs/js/data_source2.js +187 -60
  92. data/share/htdocs/js/require3.js +38 -57
  93. data/share/htdocs/theme/bright/css/bright.css +4 -4
  94. data/share/htdocs/vendor/jquery/jquery.js +9404 -0
  95. data/share/htdocs/vendor/osa/LICENSE.txt +11 -0
  96. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_green_left.svg +0 -0
  97. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_yellow_right.svg +0 -0
  98. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_awareness.svg +0 -0
  99. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_camera-web.svg +0 -0
  100. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_cloud.svg +0 -0
  101. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_contract.svg +0 -0
  102. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_database.svg +0 -0
  103. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop.svg +0 -0
  104. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop_imac.svg +0 -0
  105. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-music.svg +0 -0
  106. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-scanner.svg +0 -0
  107. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb-wifi.svg +0 -0
  108. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb.svg +0 -0
  109. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-wireless-router.svg +0 -0
  110. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_disposal.svg +0 -0
  111. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-harddisk.svg +0 -0
  112. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-optical.svg +0 -0
  113. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_firewall.svg +0 -0
  114. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_home.svg +0 -0
  115. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_hub.svg +0 -0
  116. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_iPhone.svg +0 -0
  117. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_drive.svg +0 -0
  118. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_plc.svg +0 -0
  119. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_thermometer.svg +0 -0
  120. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_id_card.svg +0 -0
  121. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_image-generic.svg +0 -0
  122. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_laptop.svg +0 -0
  123. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lifecycle.svg +0 -0
  124. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lightning.svg +0 -0
  125. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-flash.svg +0 -0
  126. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-optical.svg +0 -0
  127. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-tape.svg +0 -0
  128. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_mobile_pda.svg +0 -0
  129. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_padlock.svg +0 -0
  130. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_printer.svg +0 -0
  131. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server.svg +0 -0
  132. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_application.svg +0 -0
  133. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_database.svg +0 -0
  134. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_directory.svg +0 -0
  135. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_distribution.svg +0 -0
  136. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_file.svg +0 -0
  137. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_gateway.svg +0 -0
  138. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_identity.svg +0 -0
  139. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_mail.svg +0 -0
  140. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_media.svg +0 -0
  141. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_monitor.svg +0 -0
  142. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_proxy.svg +0 -0
  143. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_terminal.svg +0 -0
  144. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_web.svg +0 -0
  145. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-branch.svg +0 -0
  146. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-factory.svg +0 -0
  147. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-head-office.svg +0 -0
  148. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-neighbourhood.svg +0 -0
  149. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_audit.svg +0 -0
  150. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_black_hat.svg +0 -0
  151. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue.svg +0 -0
  152. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_security_specialist.svg +0 -0
  153. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_sysadmin.svg +0 -0
  154. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tester.svg +0 -0
  155. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tie.svg +0 -0
  156. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green.svg +0 -0
  157. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_architect.svg +0 -0
  158. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_business_manager.svg +0 -0
  159. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_developer.svg +0 -0
  160. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_operations.svg +0 -0
  161. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_project_manager.svg +0 -0
  162. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_service_manager.svg +0 -0
  163. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_warning.svg +0 -0
  164. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_large_group.svg +0 -0
  165. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_users_blue_green.svg +0 -0
  166. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_vpn.svg +0 -0
  167. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_warning.svg +0 -0
  168. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_wireless_network.svg +0 -0
  169. data/share/htdocs/{image → vendor/unknown/image}/.DS_Store +0 -0
  170. data/share/htdocs/{image → vendor/unknown/image}/add_icon.gif +0 -0
  171. data/share/htdocs/{image → vendor/unknown/image}/alertbad_icon.gif +0 -0
  172. data/share/htdocs/{image → vendor/unknown/image}/alertgood_icon.gif +0 -0
  173. data/share/htdocs/{image → vendor/unknown/image}/back_disabled.jpg +0 -0
  174. data/share/htdocs/{image → vendor/unknown/image}/back_disabled.png +0 -0
  175. data/share/htdocs/{image → vendor/unknown/image}/back_enabled.jpg +0 -0
  176. data/share/htdocs/{image → vendor/unknown/image}/back_enabled.png +0 -0
  177. data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.jpg +0 -0
  178. data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.png +0 -0
  179. data/share/htdocs/{image → vendor/unknown/image}/bottom-bg.gif +0 -0
  180. data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.jpg +0 -0
  181. data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.png +0 -0
  182. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.jpg +0 -0
  183. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.png +0 -0
  184. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.jpg +0 -0
  185. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.png +0 -0
  186. data/share/htdocs/{image → vendor/unknown/image}/icon-remove.gif +0 -0
  187. data/share/htdocs/{image → vendor/unknown/image}/indicator.gif +0 -0
  188. data/share/htdocs/{image → vendor/unknown/image}/laptop.png +0 -0
  189. data/share/htdocs/{image → vendor/unknown/image}/logo-bottom.gif +0 -0
  190. data/share/htdocs/{image → vendor/unknown/image}/nav-tab-arrow.gif +0 -0
  191. data/share/htdocs/{image → vendor/unknown/image}/norbit_big.gif +0 -0
  192. data/share/htdocs/{image → vendor/unknown/image}/norbit_clipart.png +0 -0
  193. data/share/htdocs/{image → vendor/unknown/image}/progress_bar.gif +0 -0
  194. data/share/htdocs/{image → vendor/unknown/image}/right-bg.gif +0 -0
  195. data/share/htdocs/{image → vendor/unknown/image}/sort_asc.png +0 -0
  196. data/share/htdocs/{image → vendor/unknown/image}/sort_asc_disabled.png +0 -0
  197. data/share/htdocs/{image → vendor/unknown/image}/sort_both.png +0 -0
  198. data/share/htdocs/{image → vendor/unknown/image}/sort_desc.png +0 -0
  199. data/share/htdocs/{image → vendor/unknown/image}/sort_desc_disabled.png +0 -0
  200. data/share/htdocs/{image → vendor/unknown/image}/spinner.gif +0 -0
  201. data/share/htdocs/{svg → vendor/unknown/svg}/ap.svg +0 -0
  202. data/share/htdocs/{svg → vendor/unknown/svg}/router.svg +0 -0
  203. metadata +198 -216
  204. data/example/demo/widgets/dashboard_tab.yaml +0 -28
  205. data/example/demo/widgets/download_tab.yaml +0 -42
  206. data/example/demo/widgets/edit_tab.yaml +0 -20
  207. data/example/demo/widgets/generator_tab.yaml +0 -12
  208. data/lib/omf-oml/endpoint.rb +0 -175
  209. data/lib/omf-oml/indexed_table.rb +0 -57
  210. data/lib/omf-oml/network.rb +0 -413
  211. data/lib/omf-oml/oml_tuple.rb +0 -62
  212. data/lib/omf-oml/schema.rb +0 -191
  213. data/lib/omf-oml/sequel/sequel_server.rb +0 -412
  214. data/lib/omf-oml/sql_row.rb +0 -302
  215. data/lib/omf-oml/sql_source.rb +0 -131
  216. data/lib/omf-oml/table.rb +0 -131
  217. data/lib/omf-oml/tuple.rb +0 -97
  218. data/lib/omf_oml.rb +0 -4
  219. data/share/htdocs/css/coderay.css +0 -127
  220. data/share/htdocs/css/ie.css +0 -40
  221. data/share/htdocs/css/lightbox.css +0 -62
  222. data/share/htdocs/css/scaffold.css +0 -74
  223. data/share/htdocs/css/screen.css +0 -1313
  224. data/share/htdocs/css/search.css +0 -102
  225. data/share/htdocs/css/table.css +0 -538
  226. data/share/htdocs/css/table2.css +0 -191
  227. data/share/htdocs/css/welcome.css +0 -103
  228. data/share/htdocs/css/wfob.css +0 -171
  229. data/share/htdocs/css/wshow.css +0 -69
  230. data/share/htdocs/gec9_demo.html +0 -39
  231. data/share/htdocs/images +0 -1
  232. data/share/htdocs/js/graph/histogram.js +0 -229
  233. data/share/htdocs/js/graph/line_chart.js +0 -342
  234. data/share/htdocs/js/graph/line_chart2.js +0 -232
  235. data/share/htdocs/js/graph/line_chart_fc.js +0 -94
  236. data/share/htdocs/js/graph/map.js +0 -85
  237. data/share/htdocs/js/graph/network.js +0 -591
  238. data/share/htdocs/js/graph/network2.js +0 -318
  239. data/share/htdocs/js/graph/pie_chart.js +0 -130
  240. data/share/htdocs/js/graph/table.js +0 -94
  241. data/share/htdocs/js/require2.js +0 -1998
  242. data/share/htdocs/js/timelines.js +0 -101
  243. data/share/htdocs/stylesheet/grid.css +0 -31
@@ -1,191 +0,0 @@
1
-
2
- require 'omf_common/lobject'
3
- require 'omf_oml'
4
-
5
- module OMF::OML
6
-
7
- # This class represents the schema of an OML measurement stream.
8
- #
9
- class OmlSchema < OMF::Common::LObject
10
-
11
- CLASS2TYPE = {
12
- TrueClass => 'boolean',
13
- FalseClass => 'boolean',
14
- String => 'string',
15
- Symbol => 'string',
16
- Fixnum => 'decimal',
17
- Float => 'double',
18
- Time => 'dateTime'
19
- }
20
-
21
- # Map various type definitions (all lower case) into a single one
22
- ANY2TYPE = {
23
- 'integer' => :integer,
24
- 'int' => :integer,
25
- 'bigint' => :integer,
26
- 'unsigned integer' => :integer,
27
- 'float' => :float,
28
- 'real' => :float,
29
- 'double' => :float,
30
- 'text' => :string,
31
- 'string' => :string,
32
- 'date' => :date,
33
- 'dateTime'.downcase => :dateTime, # should be 'datetime' but we downcase the string for comparison
34
- 'key' => :key,
35
- }
36
-
37
- def self.create(schema_description)
38
- if schema_description.kind_of? self
39
- return schema_description
40
- end
41
- return self.new(schema_description)
42
- end
43
-
44
- # Return the col name at a specific index
45
- #
46
- def name_at(index)
47
- @schema[index][:name]
48
- end
49
-
50
- # Return the col index for column named +name+
51
- #
52
- def index_for_col(name)
53
- name = name.to_sym
54
- @schema.each_with_index do |col, i|
55
- return i if col[:name] == name
56
- end
57
- raise "Unknonw column '#{name}'"
58
- end
59
-
60
- # Return the column names as an array
61
- #
62
- def names
63
- @schema.collect do |col| col[:name] end
64
- end
65
-
66
- # Return the col type at a specific index
67
- #
68
- def type_at(index)
69
- @schema[index][:type]
70
- end
71
-
72
- def columns
73
- @schema
74
- end
75
-
76
- def insert_column_at(index, col)
77
- if col.kind_of?(Symbol) || col.kind_of?(String)
78
- col = [col]
79
- end
80
- if col.kind_of? Array
81
- # should be [name, type]
82
- if col.length == 1
83
- col = {:name => col[0].to_sym,
84
- :type => :string,
85
- :title => col[0].to_s.split('_').collect {|s| s.capitalize}.join(' ')}
86
- elsif col.length == 2
87
- col = {:name => col[0].to_sym,
88
- :type => col[1].to_sym,
89
- :title => col[0].to_s.split('_').collect {|s| s.capitalize}.join(' ')}
90
- elsif col.length == 3
91
- col = {:name => col[0].to_sym, :type => col[1].to_sym, :title => col[2]}
92
- else
93
- throw "Simple column schema should consist of [name, type, title] array, but found '#{col.inspect}'"
94
- end
95
- elsif col.kind_of? Hash
96
- # ensure there is a :title property
97
- unless col[:title]
98
- col[:title] = col[:name].to_s.split('_').collect {|s| s.capitalize}.join(' ')
99
- end
100
- end
101
-
102
- # should normalize type
103
- if type = col[:type]
104
- unless type = ANY2TYPE[type.to_s.downcase]
105
- warn "Unknown type definition '#{col[:type]}', default to 'string'"
106
- type = :string
107
- end
108
- else
109
- warn "Missing type definition in '#{col[:name]}', default to 'string'"
110
- type = :string
111
- end
112
- col[:type] = type
113
-
114
- col[:type_conversion] = case type
115
- when :string
116
- lambda do |r| r end
117
- when :key
118
- lambda do |r| r end
119
- when :integer
120
- lambda do |r| r.to_i end
121
- when :float
122
- lambda do |r| r.to_f end
123
- when :date
124
- lambda do |r| Date.parse(r) end
125
- when :dateTime
126
- lambda do |r| Time.parse(r) end
127
- else raise "Unrecognized Schema type '#{type}'"
128
- end
129
-
130
- @schema.insert(index, col)
131
- end
132
-
133
- def each_column(&block)
134
- @schema.each do |c|
135
- block.call(c)
136
- end
137
- end
138
-
139
- # Translate a record described in a hash of 'col_name => value'
140
- # to a row array
141
- #
142
- def hash_to_row(hrow, set_nil_when_missing = false)
143
- @schema.collect do |cdescr|
144
- cname = cdescr[:name]
145
- unless hrow.key? cname
146
- next nil if set_nil_when_missing
147
- raise "Missing record element '#{cname}' in record '#{hrow}'"
148
- end
149
- cdescr[:type_conversion].call(hrow[cname])
150
- end
151
- end
152
-
153
- # Cast each element in 'row' into its proper type according to this schema
154
- #
155
- def cast_row(raw_row)
156
- unless raw_row.length == @schema.length
157
- raise "Row needs to have same size as schema (#{raw_row.inspect})"
158
- end
159
- # This can be done more elegantly in 1.9
160
- row = []
161
- raw_row.each_with_index do |el, i|
162
- row << @schema[i][:type_conversion].call(el)
163
- end
164
- row
165
- end
166
-
167
- def describe
168
- @schema.map {|c| {:name => c[:name], :type => c[:type], :title => c[:title] }}
169
- end
170
-
171
- def to_json(*opt)
172
- describe.to_json(*opt)
173
- end
174
-
175
- protected
176
-
177
- # schema_description - Array containing [name, type*] for every column in table
178
- # TODO: define format of TYPE
179
- #
180
- def initialize(schema_description)
181
- # check if columns are described by hashes or 2-arrays
182
- @schema = []
183
- schema_description.each_with_index do |cdesc, i|
184
- insert_column_at(i, cdesc)
185
- end
186
- debug "schema: '#{describe.inspect}'"
187
-
188
- end
189
- end # OmlSchema
190
-
191
- end
@@ -1,412 +0,0 @@
1
- require 'rubygems'
2
- require 'rexml/document'
3
- require 'time'
4
- require 'logger'
5
- require 'sequel'
6
-
7
- require 'omf_common/lobject'
8
- require 'omf_oml'
9
-
10
- # module OMF::OML
11
- # module Sequel; end
12
- # end
13
-
14
- module OMF::OML::Sequel
15
- module Server
16
-
17
- class Query < OMF::Common::LObject
18
-
19
- def self.parse(xmls, repoFactory = RepositoryFactory.new, logger = Logger.new(STDOUT))
20
- if xmls.kind_of? String
21
- doc = REXML::Document.new(xmls)
22
- root = doc.root
23
- else
24
- root = xmls
25
- end
26
- unless root.name == 'query'
27
- raise "XML fragment needs to start with 'query' but does start with '#{root.name}"
28
- end
29
- q = self.new(root, repoFactory, logger)
30
- q.relation
31
- end
32
-
33
- def initialize(queryEl, repoFactory, logger)
34
- @queryEl = queryEl
35
- @repoFactory = repoFactory || RepositoryFactory.new
36
- @logger = logger || Logger.new(STDOUT)
37
- @tables = {}
38
- @lastRel = nil
39
- @offset = 0
40
- @limit = 0
41
- queryEl.children.each do |el|
42
- @lastRel = parse_el(el, @lastRel)
43
- end
44
- if @limit > 0
45
- @lastRel = @lastRel.limit(@limit, @offset)
46
- end
47
- end
48
-
49
- def each(&block)
50
- # sel_mgr = relation
51
- # unless sel_mgr.kind_of? SelectionManager
52
- # raise "Can only be called on SELECT statement"
53
- # end
54
- # puts sel_mgr.engine
55
- relation.each(&block)
56
- end
57
-
58
- def relation
59
- raise "No query defined, yet" unless @lastRel
60
- @lastRel
61
- end
62
-
63
- # Requested format for result. Default is 'xml'
64
- def rformat
65
- @queryEl.attributes['rformat'] || 'xml'
66
- end
67
-
68
- def parse_el(el, lastRel)
69
- if (el.kind_of? REXML::Text)
70
- # skip
71
- return lastRel
72
- end
73
- args = parse_args(el)
74
- @logger.debug "CHILD #{el.name}"
75
- # keep the last table for this level to be used
76
- # to create proper columns.
77
- # NOTE: This is not fool-proof but we need columns
78
- # to later resolve the column type.
79
- #
80
- name = el.name.downcase
81
- if lastRel.nil?
82
- case name
83
- when /repository/
84
- lastRel = repo = parse_repository(el)
85
- @tables = repo.tables
86
- @logger.debug "Created repository: #{lastRel}"
87
- else
88
- raise "Need to start with 'table' declaration, but does with '#{name}'"
89
- end
90
- elsif name == 'table'
91
- lastRel = parse_table(el)
92
- elsif name == 'project'
93
- # turn all arguments into proper columns
94
- # cols = convert_to_cols(args)
95
- lastRel = lastRel.select(*args)
96
- # elsif lastRel.kind_of?(::Arel::Table) && name == 'as'
97
- # # keep track of all created tables
98
- # lastRel = lastRel.alias(*args)
99
- # @repository.add_table(args[0], lastRel)
100
- elsif name == 'skip'
101
- @offset = args[0].to_i
102
- elsif name == 'take'
103
- @limit = args[0].to_i
104
- else
105
- @logger.debug "Sending '#{name}' to #{lastRel.class}"
106
- lastRel = lastRel.send(name, *args)
107
- end
108
- @logger.debug "lastRel for <#{el}> is #{lastRel.class}"
109
- lastRel
110
- end
111
-
112
- def parse_repository(el)
113
- @repository = @repoFactory.create_from_xml(el, @logger)
114
- end
115
-
116
-
117
- # Return the arguments defined in @parentEl as array
118
- def parse_args(parentEl)
119
- args = []
120
- parentEl.children.each do |el|
121
- next if (el.kind_of? REXML::Text)
122
- unless el.name == 'arg'
123
- raise "Expected argument definition but got element '#{el.name}"
124
- end
125
- args << parse_arg(el)
126
- end
127
- args
128
- end
129
-
130
- # Return the arguments defined in @parentEl as array
131
- def parse_arg(pel)
132
- res = nil
133
- #col = nil
134
- pel.children.each do |el|
135
- if (el.kind_of? REXML::Text)
136
- val = el.value
137
- next if val.strip.empty? # skip text between els
138
- return parse_arg_primitive(pel, val)
139
- else
140
- name = el.name.downcase
141
- case name
142
- when /col/
143
- res = parse_column(el)
144
- when /eq/
145
- if res.nil?
146
- raise "Missing 'col' definiton before 'eq'."
147
- end
148
- p = parse_args(el)
149
- unless p.length == 1
150
- raise "'eq' can only hnadle 1 argument, but is '#{p.inspect}'"
151
- end
152
- res = {res => p[0]}
153
- else
154
- raise "Need to be 'col' declaration, but is '#{name}'"
155
- end
156
- end
157
- end
158
- res
159
- end
160
-
161
- def parse_arg_primitive(pel, value)
162
- type = pel.attributes['type'] || 'string'
163
- case type
164
- when /string/
165
- value
166
- when /boolean/
167
- value.downcase == 'true' || value == '1'
168
- when /decimal/
169
- value.to_i
170
- when /double/
171
- value.to_f
172
- when /dateTime/
173
- Time.xmlschema
174
- else
175
- raise "Unknown arg type '#{type}"
176
- end
177
- end
178
-
179
- def convert_to_cols(args)
180
- args.collect do |arg|
181
- if arg.kind_of? String
182
- table = @repository.get_first_table()
183
- raise "Unknown table for column '#{arg}'" unless table
184
- table[arg]
185
- else
186
- arg
187
- end
188
- end
189
- end
190
-
191
- # <col name='oml_sender_id' table='iperf_TCP_Info'/>
192
- def parse_column(el)
193
- unless colName = el.attributes['name']
194
- raise "Missing 'name' attribute for 'col' element"
195
- end
196
- col = colName
197
- unless tblName = el.attributes['table']
198
- raise "Missing 'table' attribute for col '#{colName}'"
199
- end
200
- unless @tables.member?(tblName.to_sym)
201
- raise "Unknown table name '#{tblName}' (#{el})"
202
- end
203
- col = "#{tblName}__#{colName}"
204
-
205
- if colAlias = el.attributes['alias']
206
- col = "#{col}___#{colAlias}"
207
- end
208
- col.to_sym
209
- end
210
-
211
- def parse_table(el)
212
- unless name = el.attributes['tname']
213
- raise "Missing 'tname' attribute for 'table' element"
214
- end
215
- if talias = el.attributes['talias']
216
- name = "#{name}___#{talias}"
217
- @tables << talias.to_sym
218
- end
219
-
220
- @repository[name.to_sym]
221
- end
222
-
223
- end # Query
224
-
225
- class RepositoryFactory < OMF::Common::LObject
226
-
227
- def initialize(opts = {})
228
- @opts = opts
229
- end
230
-
231
- def create_from_xml(el, logger)
232
- name = el ? el.attributes['name'] : nil
233
- raise "<repository> is missing attribute 'name'" unless name
234
- create(name, logger)
235
- end
236
-
237
- def create(database, logger = Logger.new(STDOUT))
238
- opts = @opts.dup
239
- if pre = opts[:database_prefix]
240
- database = pre + database
241
- opts.delete(:database_prefix)
242
- end
243
- if post = opts[:database_postfix]
244
- database = database + post
245
- opts.delete(:database_postfix)
246
- end
247
- opts[:database] = database
248
- ::Sequel.connect(opts)
249
- end
250
-
251
- end # RepositoryFactory
252
- end # Server
253
- end
254
-
255
- module Sequel
256
- class Dataset
257
- CLASS2TYPE = {
258
- TrueClass => 'boolean',
259
- FalseClass => 'boolean',
260
- String => 'string',
261
- Symbol => 'string',
262
- Fixnum => 'decimal',
263
- Float => 'double',
264
- Time => 'dateTime'
265
- }
266
-
267
- def row_description(row)
268
- n = naked
269
- cols = n.columns
270
- descr = {}
271
- cols.collect do |cn|
272
- cv = row[cn]
273
- descr[cn] = CLASS2TYPE[cv.class]
274
- end
275
- descr
276
- end
277
-
278
- def schema_for_row(row)
279
- n = naked
280
- cols = n.columns
281
- descr = {}
282
- cols.collect do |cn|
283
- cv = row[cn]
284
- {:name => cn, :type => CLASS2TYPE[cv.class]}
285
- end
286
- end
287
- end
288
- end
289
-
290
-
291
-
292
- def test_sequel_server()
293
-
294
- tests = []
295
-
296
- tests << %{
297
- <query>
298
- <repository name='test'/>
299
- <table tname='iperf_TCP_Info'/>
300
- <project>
301
- <arg><col name='Bandwidth_avg' table='iperf_TCP_Info'/></arg>
302
- </project>
303
- </query>
304
- }
305
-
306
- tests << %{
307
- <query>
308
- <repository name='test'/>
309
- <table tname='iperf_TCP_Info' talias='t'/>
310
- <project>
311
- <arg>
312
- <col name='oml_sender_id' alias='foo' table='t'/>
313
- </arg>
314
- <arg>
315
- <col name='oml_ts_server' table='t' alias='goo'/>
316
- </arg>
317
- <arg><col name='Bandwidth_avg' table='t'/></arg>
318
- </project>
319
- <where>
320
- <arg>
321
- <col name='oml_sender_id' table='t'/>
322
- <eq>
323
- <arg type='decimal'> 2</arg>
324
- </eq>
325
- </arg>
326
- </where>
327
- </query>
328
- }
329
-
330
- # mc = repo[:mediacontent]
331
- # mc2 = mc.alias
332
- # accessed = mc2.where(mc2[:status].eq('Accessed')).project(:oml_ts_server, :name)
333
- # q = mc.project(:name).join(accessed).on(mc[:name].eq(mc2[:name]))
334
-
335
- # tests << %{
336
- # <query>
337
- # <repository name='prefetching_4'/>
338
- # <table tname='mediacontent'/>
339
- # <project>
340
- # <arg type='string'>name</arg>
341
- # </project>
342
- # <join>
343
- # <arg>
344
- # <table tname='mediacontent' talias='mediacontent1'/>
345
- # <where>
346
- # <arg>
347
- # <col name='status' table='mediacontent' talias='mediacontent1'/>
348
- # <eq>
349
- # <arg type='string'>Accessed</arg>
350
- # </eq>
351
- # </arg>
352
- # </where>
353
- # <project>
354
- # <arg type='string'>oml_ts_server</arg>
355
- # <arg type='string'>name</arg>
356
- # </project>
357
- # </arg>
358
- # </join>
359
- # <on>
360
- # <arg>
361
- # <col name='name' table='mediacontent'/>
362
- # <eq>
363
- # <arg>
364
- # <col name='name' table='mediacontent' talias='mediacontent1'/>
365
- # </arg>
366
- # </eq>
367
- # </arg>
368
- # </on>
369
- # </query>
370
- # }
371
-
372
- factory = OMF::OML::Sequel::Server::RepositoryFactory.new(
373
- :adapter => 'sqlite',
374
- :database_prefix => '/Users/max/src/omf_mytestbed_net/omf-common/test/',
375
- :database_postfix => '.sq3'
376
- )
377
-
378
- repo = factory.create('test')
379
- puts repo.tables
380
-
381
- tests.each do |t|
382
- ds = OMF::OML::Sequel::Server::Query.parse(t, factory)
383
- puts ds.inspect
384
- puts ds.columns.inspect
385
- puts ds.first.inspect
386
- end
387
-
388
- first = true
389
- types = []
390
- ds = OMF::OML::Sequel::Server::Query.parse(tests[1], factory).limit(10)
391
- ds.each do |r|
392
- if (first)
393
- puts ds.row_description(r).inspect
394
- puts ds.schema_for_row(r).inspect
395
- #puts (ds.schema_for_row(r).methods - Object.new.methods).sort
396
- # cols = ds.columns
397
- # #cols.collect do |c|
398
- # cols.each do |c|
399
- # puts "#{c} : #{OML::Sequel::XML::Server::Query::CLASS2TYPE[r[c].class]}"
400
- # end
401
- first = false
402
- # puts types.inspect
403
- end
404
- puts r.inspect
405
- end
406
- puts "QUERY: done"
407
- end
408
-
409
- if $0 == __FILE__
410
- test_sequel_server
411
- end
412
-