alf 0.9.3 → 0.10.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 (270) hide show
  1. data/CHANGELOG.md +255 -129
  2. data/Gemfile +31 -1
  3. data/Gemfile.lock +17 -20
  4. data/LICENCE.md +1 -1
  5. data/Manifest.txt +2 -0
  6. data/README.md +37 -43
  7. data/TODO.md +1 -1
  8. data/alf.gemspec +10 -7
  9. data/alf.noespec +24 -13
  10. data/bin/alf +2 -2
  11. data/doc/commands/exec.md +16 -0
  12. data/doc/commands/help.md +11 -0
  13. data/doc/commands/main.md +33 -0
  14. data/doc/commands/show.md +19 -0
  15. data/doc/operators/non_relational/autonum.md +23 -0
  16. data/doc/operators/non_relational/clip.md +31 -0
  17. data/doc/operators/non_relational/coerce.md +15 -0
  18. data/doc/operators/non_relational/compact.md +20 -0
  19. data/doc/operators/non_relational/defaults.md +32 -0
  20. data/doc/operators/non_relational/generator.md +20 -0
  21. data/doc/operators/non_relational/sort.md +24 -0
  22. data/doc/operators/relational/extend.md +18 -0
  23. data/doc/operators/relational/group.md +27 -0
  24. data/doc/operators/relational/intersect.md +13 -0
  25. data/doc/operators/relational/join.md +27 -0
  26. data/doc/operators/relational/matching.md +20 -0
  27. data/doc/operators/relational/minus.md +12 -0
  28. data/doc/operators/relational/not-matching.md +20 -0
  29. data/doc/operators/relational/project.md +28 -0
  30. data/doc/operators/relational/quota.md +21 -0
  31. data/doc/operators/relational/rank.md +27 -0
  32. data/doc/operators/relational/rename.md +17 -0
  33. data/doc/operators/relational/restrict.md +25 -0
  34. data/doc/operators/relational/summarize.md +25 -0
  35. data/doc/operators/relational/ungroup.md +20 -0
  36. data/doc/operators/relational/union.md +14 -0
  37. data/doc/operators/relational/unwrap.md +20 -0
  38. data/doc/operators/relational/wrap.md +24 -0
  39. data/examples/csv/suppliers.csv +6 -0
  40. data/examples/logs/access.log +1000 -0
  41. data/examples/logs/combined.alf +2 -0
  42. data/examples/logs/hits.alf +14 -0
  43. data/examples/logs/not_found.alf +7 -0
  44. data/examples/logs/robots-cheating.alf +11 -0
  45. data/examples/logs/robots.alf +8 -0
  46. data/examples/northwind/customers.csv +92 -0
  47. data/examples/northwind/northwind.db +0 -0
  48. data/examples/northwind/orders.csv +831 -0
  49. data/examples/operators/clip.alf +1 -1
  50. data/examples/operators/database.alf +5 -6
  51. data/examples/operators/defaults.alf +1 -1
  52. data/examples/operators/group.alf +1 -1
  53. data/examples/operators/project.alf +2 -1
  54. data/examples/operators/pseudo-with.alf +2 -2
  55. data/examples/operators/quota.alf +2 -2
  56. data/examples/operators/summarize.alf +2 -2
  57. data/lib/alf/aggregator/aggregators.rb +77 -0
  58. data/lib/alf/aggregator/base.rb +95 -0
  59. data/lib/alf/aggregator/class_methods.rb +57 -0
  60. data/lib/alf/buffer/sorted.rb +48 -0
  61. data/lib/alf/command/class_methods.rb +27 -0
  62. data/lib/alf/command/doc_manager.rb +72 -0
  63. data/lib/alf/command/exec.rb +12 -0
  64. data/lib/alf/command/help.rb +31 -0
  65. data/lib/alf/command/main.rb +146 -0
  66. data/lib/alf/command/show.rb +33 -0
  67. data/lib/alf/environment/base.rb +37 -0
  68. data/lib/alf/environment/class_methods.rb +93 -0
  69. data/lib/alf/environment/explicit.rb +38 -0
  70. data/lib/alf/environment/folder.rb +62 -0
  71. data/lib/alf/extra/csv.rb +104 -0
  72. data/lib/alf/extra/logs.rb +100 -0
  73. data/lib/alf/extra/sequel.rb +77 -0
  74. data/lib/alf/{yaml.rb → extra/yaml.rb} +0 -0
  75. data/lib/alf/extra.rb +5 -0
  76. data/lib/alf/iterator/base.rb +38 -0
  77. data/lib/alf/iterator/class_methods.rb +22 -0
  78. data/lib/alf/iterator/proxy.rb +33 -0
  79. data/lib/alf/lispy/instance_methods.rb +157 -0
  80. data/lib/alf/operator/base.rb +74 -0
  81. data/lib/alf/operator/binary.rb +32 -0
  82. data/lib/alf/operator/cesure.rb +45 -0
  83. data/lib/alf/operator/class_methods.rb +132 -0
  84. data/lib/alf/operator/experimental.rb +9 -0
  85. data/lib/alf/operator/non_relational/autonum.rb +24 -0
  86. data/lib/alf/operator/non_relational/clip.rb +20 -0
  87. data/lib/alf/operator/non_relational/coerce.rb +21 -0
  88. data/lib/alf/operator/non_relational/compact.rb +62 -0
  89. data/lib/alf/operator/non_relational/defaults.rb +25 -0
  90. data/lib/alf/operator/non_relational/generator.rb +38 -0
  91. data/lib/alf/operator/non_relational/sort.rb +23 -0
  92. data/lib/alf/operator/nullary.rb +20 -0
  93. data/lib/alf/operator/relational/extend.rb +24 -0
  94. data/lib/alf/operator/relational/group.rb +32 -0
  95. data/lib/alf/operator/relational/intersect.rb +37 -0
  96. data/lib/alf/operator/relational/join.rb +106 -0
  97. data/lib/alf/operator/relational/matching.rb +45 -0
  98. data/lib/alf/operator/relational/minus.rb +37 -0
  99. data/lib/alf/operator/relational/not_matching.rb +45 -0
  100. data/lib/alf/operator/relational/project.rb +22 -0
  101. data/lib/alf/operator/relational/quota.rb +51 -0
  102. data/lib/alf/operator/relational/rank.rb +55 -0
  103. data/lib/alf/operator/relational/rename.rb +19 -0
  104. data/lib/alf/operator/relational/restrict.rb +20 -0
  105. data/lib/alf/operator/relational/summarize.rb +83 -0
  106. data/lib/alf/operator/relational/ungroup.rb +25 -0
  107. data/lib/alf/operator/relational/union.rb +32 -0
  108. data/lib/alf/operator/relational/unwrap.rb +21 -0
  109. data/lib/alf/operator/relational/wrap.rb +22 -0
  110. data/lib/alf/operator/shortcut.rb +53 -0
  111. data/lib/alf/operator/signature.rb +262 -0
  112. data/lib/alf/operator/transform.rb +27 -0
  113. data/lib/alf/operator/unary.rb +38 -0
  114. data/lib/alf/reader/alf_file.rb +24 -0
  115. data/lib/alf/reader/base.rb +119 -0
  116. data/lib/alf/reader/class_methods.rb +82 -0
  117. data/lib/alf/reader/rash.rb +28 -0
  118. data/lib/alf/relation/class_methods.rb +37 -0
  119. data/lib/alf/relation/instance_methods.rb +127 -0
  120. data/lib/alf/renderer/base.rb +72 -0
  121. data/lib/alf/renderer/class_methods.rb +58 -0
  122. data/lib/alf/renderer/rash.rb +19 -0
  123. data/lib/alf/{text.rb → renderer/text.rb} +1 -1
  124. data/lib/alf/tools/coerce.rb +14 -0
  125. data/lib/alf/tools/miscellaneous.rb +77 -0
  126. data/lib/alf/tools/to_lispy.rb +99 -0
  127. data/lib/alf/tools/to_ruby_literal.rb +14 -0
  128. data/lib/alf/tools/tuple_handle.rb +50 -0
  129. data/lib/alf/types/attr_list.rb +56 -0
  130. data/lib/alf/types/attr_name.rb +28 -0
  131. data/lib/alf/types/boolean.rb +12 -0
  132. data/lib/alf/types/heading.rb +96 -0
  133. data/lib/alf/types/ordering.rb +93 -0
  134. data/lib/alf/types/renaming.rb +57 -0
  135. data/lib/alf/types/summarization.rb +76 -0
  136. data/lib/alf/types/tuple_computation.rb +61 -0
  137. data/lib/alf/types/tuple_expression.rb +61 -0
  138. data/lib/alf/types/tuple_predicate.rb +49 -0
  139. data/lib/alf/version.rb +2 -2
  140. data/lib/alf.rb +193 -3714
  141. data/spec/integration/__database__/group.alf +1 -1
  142. data/spec/integration/__database__/suppliers_csv.csv +6 -0
  143. data/spec/integration/command/alf/alf.db +0 -0
  144. data/spec/integration/command/alf/alf_env_sqlite.cmd +1 -0
  145. data/spec/integration/command/alf/alf_env_sqlite.stdout +9 -0
  146. data/spec/integration/command/alf/alf_help.cmd +1 -0
  147. data/spec/integration/command/alf/alf_help.stdout +67 -0
  148. data/spec/integration/command/autonum/autonum_0.cmd +1 -1
  149. data/spec/integration/command/coerce/coerce_1.cmd +1 -0
  150. data/spec/integration/command/coerce/coerce_1.stdout +5 -0
  151. data/spec/integration/command/defaults/defaults_0.cmd +1 -1
  152. data/spec/integration/command/defaults/defaults_0.stdout +9 -9
  153. data/spec/integration/command/defaults/defaults_2.cmd +1 -0
  154. data/spec/integration/command/defaults/defaults_2.stdout +9 -0
  155. data/spec/integration/command/generator/generator_1.cmd +1 -0
  156. data/spec/integration/command/generator/generator_1.stdout +10 -0
  157. data/spec/integration/command/generator/generator_2.cmd +1 -0
  158. data/spec/integration/command/generator/generator_2.stdout +5 -0
  159. data/spec/integration/command/generator/generator_3.cmd +1 -0
  160. data/spec/integration/command/generator/generator_3.stdout +5 -0
  161. data/spec/integration/command/group/group_0.cmd +1 -1
  162. data/spec/integration/command/group/group_1.cmd +1 -1
  163. data/spec/integration/command/help/help_1.cmd +1 -0
  164. data/spec/integration/command/help/help_1.stdout +22 -0
  165. data/spec/integration/command/quota/quota_0.cmd +1 -1
  166. data/spec/integration/command/rank/rank_1.cmd +1 -1
  167. data/spec/integration/command/rank/rank_1.stdout +10 -10
  168. data/spec/integration/command/rank/rank_2.cmd +1 -1
  169. data/spec/integration/command/rank/rank_2.stdout +10 -10
  170. data/spec/integration/command/rank/rank_3.cmd +1 -1
  171. data/spec/integration/command/rank/rank_3.stdout +10 -10
  172. data/spec/integration/command/rank/rank_4.cmd +1 -1
  173. data/spec/integration/command/rank/rank_5.cmd +1 -1
  174. data/spec/integration/command/show/show_csv.cmd +1 -0
  175. data/spec/integration/command/show/show_csv.stdout +6 -0
  176. data/spec/integration/command/show/show_rash_2.cmd +1 -1
  177. data/spec/integration/command/show/show_rash_2.stdout +5 -5
  178. data/spec/integration/command/sort/sort_0.cmd +1 -1
  179. data/spec/integration/command/sort/sort_1.cmd +1 -1
  180. data/spec/integration/command/sort/sort_1.stdout +2 -2
  181. data/spec/integration/command/sort/sort_2.cmd +1 -0
  182. data/spec/integration/command/sort/sort_2.stdout +9 -0
  183. data/spec/integration/command/sort/sort_3.cmd +1 -0
  184. data/spec/integration/command/sort/sort_3.stdout +9 -0
  185. data/spec/integration/command/summarize/summarize_0.cmd +1 -1
  186. data/spec/integration/command/ungroup/ungroup_0.cmd +1 -1
  187. data/spec/integration/command/wrap/wrap_0.cmd +1 -1
  188. data/spec/integration/semantics/test_project.alf +5 -6
  189. data/spec/integration/semantics/test_rank.alf +16 -16
  190. data/spec/integration/test_command.rb +17 -6
  191. data/spec/integration/test_examples.rb +1 -1
  192. data/spec/regression/logs/apache_combined.log +5 -0
  193. data/spec/regression/logs/test_path_attribute.rb +25 -0
  194. data/spec/regression/relation/test_relation_allbut_all.rb +14 -0
  195. data/spec/shared/an_operator_class.rb +10 -5
  196. data/spec/spec_helper.rb +1 -7
  197. data/spec/unit/assumptions/test_set.rb +64 -0
  198. data/spec/unit/command/doc_manager/dynamic.md +1 -0
  199. data/spec/unit/command/doc_manager/example.md +1 -0
  200. data/spec/unit/command/doc_manager/example_1.txt +11 -0
  201. data/spec/unit/command/doc_manager/static.md +1 -0
  202. data/spec/unit/command/doc_manager/test_call.rb +49 -0
  203. data/spec/unit/csv/input.csv +3 -0
  204. data/spec/unit/csv/test_reader.rb +66 -0
  205. data/spec/unit/csv/test_renderer.rb +73 -0
  206. data/spec/unit/lispy/test_relation.rb +37 -0
  207. data/spec/unit/lispy/test_run.rb +40 -0
  208. data/spec/unit/lispy/test_tuple.rb +36 -0
  209. data/spec/unit/logs/apache_combined.log +5 -0
  210. data/spec/unit/logs/postgresql.log +29 -0
  211. data/spec/unit/logs/test_reader.rb +56 -0
  212. data/spec/unit/operator/non_relational/compact/{buffer_based.rb → test_buffer_based.rb} +0 -0
  213. data/spec/unit/operator/non_relational/test_clip.rb +1 -1
  214. data/spec/unit/operator/non_relational/test_coerce.rb +35 -0
  215. data/spec/unit/operator/non_relational/test_defaults.rb +15 -2
  216. data/spec/unit/operator/non_relational/test_generator.rb +78 -0
  217. data/spec/unit/operator/relational/join/test_hash_based.rb +4 -4
  218. data/spec/unit/operator/relational/matching/test_hash_based.rb +6 -6
  219. data/spec/unit/operator/relational/not_matching/test_hash_based.rb +4 -4
  220. data/spec/unit/operator/relational/summarize/test_hash_based.rb +10 -6
  221. data/spec/unit/operator/relational/summarize/test_sort_based.rb +18 -7
  222. data/spec/unit/operator/relational/test_group.rb +8 -8
  223. data/spec/unit/operator/relational/test_intersect.rb +3 -3
  224. data/spec/unit/operator/relational/test_minus.rb +3 -3
  225. data/spec/unit/operator/relational/test_project.rb +12 -2
  226. data/spec/unit/operator/relational/test_quota.rb +5 -6
  227. data/spec/unit/operator/relational/test_summarize.rb +9 -11
  228. data/spec/unit/operator/relational/test_union.rb +1 -1
  229. data/spec/unit/operator/relational/test_wrap.rb +1 -1
  230. data/spec/unit/operator/signature/test_collect_on.rb +45 -0
  231. data/spec/unit/operator/signature/test_initialize.rb +17 -0
  232. data/spec/unit/operator/signature/test_install.rb +56 -0
  233. data/spec/unit/operator/signature/test_option_parser.rb +36 -0
  234. data/spec/unit/operator/signature/test_parse_args.rb +60 -0
  235. data/spec/unit/operator/signature/test_parse_argv.rb +87 -0
  236. data/spec/unit/operator/signature/test_to_lispy.rb +102 -0
  237. data/spec/unit/operator/signature/test_to_shell.rb +103 -0
  238. data/spec/unit/operator/test_non_relational.rb +3 -1
  239. data/spec/unit/relation/test_relops.rb +20 -15
  240. data/spec/unit/sequel/alf.db +0 -0
  241. data/spec/unit/sequel/test_environment.rb +54 -0
  242. data/spec/unit/test_aggregator.rb +32 -22
  243. data/spec/unit/test_environment.rb +5 -0
  244. data/spec/unit/test_lispy.rb +4 -0
  245. data/spec/unit/test_relation.rb +5 -0
  246. data/spec/unit/text/test_cell.rb +6 -6
  247. data/spec/unit/text/test_row.rb +3 -3
  248. data/spec/unit/text/test_table.rb +6 -6
  249. data/spec/unit/tools/test_coalesce.rb +15 -0
  250. data/spec/unit/tools/test_coerce.rb +10 -0
  251. data/spec/unit/tools/test_to_lispy.rb +138 -0
  252. data/spec/unit/tools/test_to_ruby_literal.rb +10 -0
  253. data/spec/unit/tools/test_tuple_handle.rb +1 -59
  254. data/spec/unit/types/test_attr_list.rb +106 -0
  255. data/spec/unit/types/test_attr_name.rb +52 -0
  256. data/spec/unit/{test_heading.rb → types/test_heading.rb} +10 -0
  257. data/spec/unit/types/test_ordering.rb +127 -0
  258. data/spec/unit/types/test_renaming.rb +55 -0
  259. data/spec/unit/types/test_summarization.rb +63 -0
  260. data/spec/unit/types/test_tuple_computation.rb +60 -0
  261. data/spec/unit/types/test_tuple_expression.rb +64 -0
  262. data/spec/unit/types/test_tuple_predicate.rb +79 -0
  263. data/tasks/debug_mail.rake +1 -1
  264. data/tasks/debug_mail.txt +5 -0
  265. data/tasks/gh-pages.rake +63 -0
  266. metadata +325 -52
  267. data/spec/unit/operator/test_command_methods.rb +0 -38
  268. data/spec/unit/tools/test_ordering_key.rb +0 -94
  269. data/spec/unit/tools/test_parse_commandline_args.rb +0 -47
  270. data/spec/unit/tools/test_projection_key.rb +0 -83
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Alf - Relational Algebra at your fingertips (version 0.9.3)
1
+ # Alf - Relational Algebra at your fingertips (version 0.10.0)
2
2
 
3
3
  ## Description
4
4
 
@@ -12,19 +12,24 @@ _relations_... Let's stop the segregation ;-)
12
12
 
13
13
  ### Install
14
14
 
15
- % [sudo] gem install alf
15
+ % [sudo] gem install alf [fastercsv, ...]
16
16
  % alf --help
17
17
 
18
18
  ### Bundler & Require
19
19
 
20
20
  # API is not considered stable enough for now, please use
21
- gem "alf", "= 0.9.2"
21
+ gem "alf", "= 0.10.0"
22
+
23
+ # The following should not break your code, but is a bit less safe,
24
+ # until 1.0.0 has been reached
25
+ gem "alf", "~> 0.10.0"
22
26
 
23
27
  ### Links
24
28
 
25
- * {http://rubydoc.info/github/blambeau/alf/master/frames} (read this file there!)
26
- * {http://github.com/blambeau/alf} (source code)
27
- * {http://revision-zero.org} (author's blog)
29
+ * http://blambeau.github.com/alf
30
+ * http://rubydoc.info/gems/alf
31
+ * http://github.com/blambeau/alf
32
+ * http://rubygems.org/gems/alf
28
33
 
29
34
  ### Quick overview
30
35
 
@@ -65,9 +70,9 @@ of a truly relational algebra approach. Objectives behind Alf are manifold:
65
70
 
66
71
  * Alf is also an educational tool, that I've written to draw people attention
67
72
  about the ill-known relational theory (and ill-represented by SQL). The tool
68
- is largely inspired from TUTORIAL D, the tutorial language of Chris Date and
73
+ is largely inspired from **Tutorial D**, the tutorial language of Chris Date and
69
74
  Hugh Darwen in their books, more specifically in
70
- {http://www.thethirdmanifesto.com/ The Third Manifesto (TTM)}.
75
+ {http://www.thethirdmanifesto.com/ *The Third Manifesto* (TTM)}.
71
76
  However, Alf only provides an overview of the relational _algebra_ defined
72
77
  there (Alf is neither a relational _database_, nor a relational _language_).
73
78
  I hope that people (especially talented developers) will be sufficiently
@@ -76,7 +81,7 @@ of a truly relational algebra approach. Objectives behind Alf are manifold:
76
81
  the following query for the kind of things that you'll never ever have in SQL
77
82
  (see also 'alf help quota', 'alf help wrap', 'alf help group', ...):
78
83
 
79
- % alf --text summarize supplies --by=sid -- total "sum(:qty)" -- which "group(:pid)"
84
+ % alf --text summarize supplies -- sid -- total "sum{ qty }" which "collect{ pid }"
80
85
 
81
86
  * Last, but not least, Alf is an attempt to help me test some research ideas and
82
87
  communicate about them with people that already know (all or part) of the TTM
@@ -87,7 +92,7 @@ of a truly relational algebra approach. Objectives behind Alf are manifold:
87
92
  'research work in progress', and used with care because not necessarily in
88
93
  conformance with the TTM.
89
94
 
90
- % alf --text quota supplies --by=sid --order=qty -- pos "count()"
95
+ % alf --text quota supplies -- sid -- qty -- pos "count()"
91
96
 
92
97
  ## Overview of relational theory
93
98
 
@@ -233,7 +238,7 @@ you want! The same query, in shell:
233
238
 
234
239
  ## What is Alf exactly?
235
240
 
236
- The Third Manifesto defines a series of prescriptions, proscriptions and very
241
+ *The Third Manifesto* defines a series of prescriptions, proscriptions and very
237
242
  strong suggestions for designing a truly relational _language_, called a _D_,
238
243
  as an alternative to SQL for managing relational databases. This is far behind
239
244
  my objective with Alf, as it does not touch at database issues at all (persistence,
@@ -267,7 +272,7 @@ section about versioning policy at the end of this file).
267
272
  If you take a look at .alf example files, you'll find functional ruby expressions
268
273
  like the following (called Lispy expressions):
269
274
 
270
- % cat examples/minus.alf
275
+ % cat examples/operators/minus.alf
271
276
 
272
277
  # Give all suppliers, except those living in Paris
273
278
  (minus :suppliers,
@@ -280,7 +285,7 @@ like the following (called Lispy expressions):
280
285
  You can simply execute such expressions with the alf command line itself (the
281
286
  three following invocations return the same result):
282
287
 
283
- % alf examples/minus.alf | alf show
288
+ % alf examples/operators/minus.alf | alf show
284
289
  % alf show minus
285
290
  % alf -e "(restrict :suppliers, lambda{ city != 'Paris' })" | alf show
286
291
 
@@ -373,7 +378,7 @@ operators works on relations and return relations), you can use a sub expression
373
378
  :supplies),
374
379
  :cities),
375
380
  [:country],
376
- :which => Agg::group(:pid),
381
+ :which => Agg::collect(:pid),
377
382
  :total => Agg::sum{ qty })
378
383
 
379
384
  Of course, complex queries quickly become unreadable that way. But you can always
@@ -384,30 +389,19 @@ split complex tasks in more simple ones:
384
389
  supplying = (join with_countries, :supplies)
385
390
  (summarize supplying,
386
391
  [:country],
387
- :which => Agg::group(:pid),
392
+ :which => Agg::collect(:pid),
388
393
  :total => Agg::sum{ qty })
389
394
 
390
395
  And here is the result !
391
396
 
392
- +----------+----------+--------+
393
- | :country | :which | :total |
394
- +----------+----------+--------+
395
- | England | +------+ | 2200 |
396
- | | | :pid | | |
397
- | | +------+ | |
398
- | | | P1 | | |
399
- | | | P2 | | |
400
- | | | P3 | | |
401
- | | | P4 | | |
402
- | | | P5 | | |
403
- | | | P6 | | |
404
- | | +------+ | |
405
- | France | +------+ | 200 |
406
- | | | :pid | | |
407
- | | +------+ | |
408
- | | | P2 | | |
409
- | | +------+ | |
410
- +----------+----------+--------+
397
+ +------+--------+--------------------------+
398
+ | :sid | :total | :which |
399
+ +------+--------+--------------------------+
400
+ | S1 | 1300 | [P1, P2, P3, P4, P5, P6] |
401
+ | S2 | 700 | [P1, P2] |
402
+ | S3 | 200 | [P2] |
403
+ | S4 | 900 | [P2, P4, P5] |
404
+ +------+--------+--------------------------+
411
405
 
412
406
  ### Reference API
413
407
 
@@ -522,11 +516,11 @@ For example, try the following:
522
516
  ### Recognized data streams/files (.rash files)
523
517
 
524
518
  For educational purposes, 'suppliers' and 'cities' inputs are magically resolved
525
- as denoting the files examples/suppliers.rash and examples/cities.rash,
526
- respectively. You'll find other data files: parts.rash, supplies.rash that are
527
- resolved magically as well and with which you can play. For non-educational
528
- purposes, operands may always be explicit files, or you can force the folder in
529
- which datasource files have to be found:
519
+ as denoting the files examples/operators/suppliers.rash and
520
+ examples/operators/cities.rash, respectively. You'll find other data files:
521
+ parts.rash, supplies.rash that are resolved magically as well and with which you
522
+ can play. For non-educational purposes, operands may always be explicit files,
523
+ or you can force the folder in which datasource files have to be found:
530
524
 
531
525
  # The following invocations are equivalent
532
526
  % alf restrict /tmp/foo.rash -- "..."
@@ -541,13 +535,13 @@ operand on standard input if not specific as command argument. For example, the
541
535
  invocation below is equivalent to the one given above.
542
536
 
543
537
  # display suppliers that live in Paris
544
- % cat examples/suppliers.rash | alf restrict -- "city == 'Paris'"
538
+ % cat examples/operators/suppliers.rash | alf restrict -- "city == 'Paris'"
545
539
 
546
540
  Similarly, when only one operand is present in invocations of binary operators,
547
541
  they read their left operand from standard input. Therefore, the join given in
548
542
  previous section can also be written as follows:
549
543
 
550
- % cat examples/suppliers.rash | alf join cities
544
+ % cat examples/operators/suppliers.rash | alf join cities
551
545
 
552
546
  The relational algebra is _closed_ under its operators, which means that these
553
547
  operators take relations as operands and return a relation. Therefore operator
@@ -595,7 +589,7 @@ a .yaml file, as follows:
595
589
  You'll also find .alf files in the examples folder, that contain more complex
596
590
  examples in the Ruby functional syntax (see section below).
597
591
 
598
- % cat examples/group.alf
592
+ % cat examples/operators/group.alf
599
593
  #!/usr/bin/env alf
600
594
  (group :supplies, [:pid, :qty], :supplying)
601
595
 
@@ -779,7 +773,7 @@ following template for contributions in lib/alf/renderer
779
773
  third manifesto paper} itself?
780
774
  - Also have a look at {http://www.dcs.warwick.ac.uk/~hugh/TTM/Projects.html other
781
775
  implementation projects}, especially {http://dbappbuilder.sourceforge.net/Rel.php Rel}
782
- which provides an implementation of the TUTORIAL D language.
776
+ which provides an implementation of the **Tutorial D** language.
783
777
  - {https://github.com/dkubb/veritas Dan Kubb's Veritas} project is worth considering
784
778
  also in the Ruby community. While very similar to Alf in providing a pure ruby
785
779
  algebra implementation, Veritas mostly provides a framework for manipulating
data/TODO.md CHANGED
@@ -4,7 +4,7 @@
4
4
  (rename :suppliers, [:name, :city], :suffix => "_sup")
5
5
  (rename :suppliers, [:name, :city], lambda{|name| name.upcase})
6
6
 
7
- * WRAP: provide a multi-wraping ability?
7
+ * WRAP: provide a multi-wrapping ability?
8
8
 
9
9
  (wrap (wrap :supplies, [:a, :b], :x), [:x, :c], :y)
10
10
  => (wrap :supplies, :x => [:a, :b], :y => [:x, :c])
data/alf.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.description = "Alf brings the relational algebra both in Shell and in Ruby. In Shell, because \nmanipulating any relation-like data source should be as straightforward as a \none-liner. In Ruby, because I've never understood why programming languages \nprovide data structures like arrays, hashes, sets, trees and graphs but not \n_relations_... Let's stop the segregation ;-)"
31
31
 
32
32
  # The URL of this gem home page (optional)
33
- s.homepage = "http://rubydoc.info/github/blambeau/alf/master/frames"
33
+ s.homepage = "http://blambeau.github.com/alf"
34
34
 
35
35
  # Gem publication date (required but auto)
36
36
  #
@@ -124,15 +124,18 @@ Gem::Specification.new do |s|
124
124
  # for each development dependency. These gems are required for developers
125
125
  #
126
126
  s.add_development_dependency("rake", "~> 0.9.2")
127
- s.add_development_dependency("bundler", "~> 1.0")
128
127
  s.add_development_dependency("rspec", "~> 2.6.0")
128
+ s.add_development_dependency("wlang", "~> 0.10.2")
129
129
  s.add_development_dependency("rcov", "~> 0.9.9")
130
130
  s.add_development_dependency("yard", "~> 0.7.2")
131
- s.add_development_dependency("bluecloth", "~> 2.0.9")
132
- s.add_development_dependency("wlang", "~> 0.10.1")
133
- s.add_development_dependency("noe", "~> 1.3.0")
134
- s.add_dependency("quickl", "~> 0.2.2")
135
- s.add_dependency("myrrha", "~> 1.0.0")
131
+ s.add_development_dependency("bluecloth", "~> 2.1.0")
132
+ s.add_development_dependency("redcarpet", "~> 1.17.2")
133
+ s.add_development_dependency("fastercsv", "~> 1.5.4")
134
+ s.add_development_dependency("request-log-analyzer", "~> 1.11.0")
135
+ s.add_development_dependency("sequel", "~> 3.25.0")
136
+ s.add_development_dependency("sqlite3", "~> 1.3.0")
137
+ s.add_dependency("quickl", "~> 0.4.0")
138
+ s.add_dependency("myrrha", "~> 1.2.0")
136
139
 
137
140
  # The version of ruby required by this gem
138
141
  #
data/alf.noespec CHANGED
@@ -1,16 +1,22 @@
1
1
  template-info:
2
2
  name: "ruby"
3
- version: 1.3.0
3
+ version: 1.5.0
4
4
  manifest:
5
+ tasks/spec_test.rake:
6
+ ignore: true
7
+ spec/test___lower__.rb:
8
+ ignore: true
5
9
  tasks/unit_test.rake:
6
10
  safe-override: false
11
+ tasks/debug_mail.txt:
12
+ safe-override: false
7
13
  variables:
8
14
  lower:
9
15
  alf
10
16
  upper:
11
17
  Alf
12
18
  version:
13
- 0.9.3
19
+ 0.10.0
14
20
  summary: |-
15
21
  Relational Algebra at your fingertips
16
22
  description: |-
@@ -22,17 +28,22 @@ variables:
22
28
  authors:
23
29
  - {name: Bernard Lambeau, email: blambeau@gmail.com}
24
30
  links:
25
- - http://rubydoc.info/github/blambeau/alf/master/frames
31
+ - http://blambeau.github.com/alf
26
32
  - http://github.com/blambeau/alf
27
33
  - http://rubygems.org/gems/alf
34
+ - http://rubydoc.info/gems/alf
28
35
  dependencies:
29
- - {name: rake, version: "~> 0.9.2", groups: [development]}
30
- - {name: bundler, version: "~> 1.0", groups: [development]}
31
- - {name: rspec, version: "~> 2.6.0", groups: [development]}
32
- - {name: rcov, version: "~> 0.9.9", groups: [development]}
33
- - {name: yard, version: "~> 0.7.2", groups: [development]}
34
- - {name: bluecloth, version: "~> 2.0.9", groups: [development]}
35
- - {name: wlang, version: "~> 0.10.1", groups: [development]}
36
- - {name: noe, version: "~> 1.3.0", groups: [development]}
37
- - {name: quickl, version: "~> 0.2.2", groups: [runtime]}
38
- - {name: myrrha, version: "~> 1.0.0", groups: [runtime]}
36
+ - {name: quickl, version: "~> 0.4.0", groups: [runtime ]}
37
+ - {name: myrrha, version: "~> 1.2.0", groups: [runtime ]}
38
+ - {name: rake, version: "~> 0.9.2", groups: [test, release]}
39
+ - {name: rspec, version: "~> 2.6.0", groups: [test, release]}
40
+ - {name: wlang, version: "~> 0.10.2", groups: [release ]}
41
+ - {name: rcov, version: "~> 0.9.9", groups: [doc ]}
42
+ - {name: yard, version: "~> 0.7.2", groups: [doc ]}
43
+ - {name: bluecloth, version: "~> 2.1.0", groups: [doc ]}
44
+ - {name: redcarpet, version: "~> 1.17.2", groups: [doc ]}
45
+ - {name: fastercsv, version: "~> 1.5.4", groups: [extra ]}
46
+ - {name: request-log-analyzer, version: "~> 1.11.0", groups: [extra]}
47
+ - {name: sequel, version: "~> 3.25.0", groups: [extra ]}
48
+ - {name: sqlite3, version: "~> 1.3.0", groups: [extra ]}
49
+
data/bin/alf CHANGED
@@ -18,10 +18,10 @@ module AlfLauncher
18
18
  def self.start(argv)
19
19
  load
20
20
  if ENV["ALF_OPTS"]
21
- argv = Alf::Tools::parse_commandline_args(ENV["ALF_OPTS"]) + argv
21
+ argv = Quickl.parse_commandline_args(ENV["ALF_OPTS"]) + argv
22
22
  end
23
23
  Alf::Command::Main.run(argv, __FILE__)
24
24
  end
25
25
 
26
26
  end # module AlfLaucher
27
- AlfLauncher.start(ARGV)
27
+ AlfLauncher.start(ARGV)
@@ -0,0 +1,16 @@
1
+
2
+ Executes an .alf file on current environment
3
+
4
+ SYNOPSIS
5
+
6
+ alf #(command_name) [FILE]
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ This command executes the .alf file passed as first argument (or what comes
15
+ on standard input) as a alf query to be executed on the current environment.
16
+
@@ -0,0 +1,11 @@
1
+
2
+ Show help about a specific command
3
+
4
+ SYNOPSIS
5
+
6
+ alf #(command_name) COMMAND
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
@@ -0,0 +1,33 @@
1
+
2
+ alf - Relational algebra at your fingertips
3
+
4
+ SYNOPSIS
5
+
6
+ alf [--version] [--help]
7
+ alf -e '(lispy command)'
8
+ alf [FILE.alf]
9
+ alf [alf opts] OPERATOR [operator opts] ARGS ...
10
+ alf help OPERATOR
11
+
12
+ OPTIONS
13
+
14
+ #(summarized_options)
15
+
16
+ RELATIONAL OPERATORS
17
+
18
+ #(summarized_subcommands relational_operators)
19
+
20
+ EXPERIMENTAL RELATIONAL OPERATORS
21
+
22
+ #(summarized_subcommands experimental_operators)
23
+
24
+ NON-RELATIONAL OPERATORS
25
+
26
+ #(summarized_subcommands non_relational_operators)
27
+
28
+ OTHER NON-RELATIONAL COMMANDS
29
+
30
+ #(summarized_subcommands other_non_relational_commands)
31
+
32
+ See 'alf help COMMAND' for details about a specific command.
33
+
@@ -0,0 +1,19 @@
1
+
2
+ Output input tuples through a specific renderer (text, yaml, ...)
3
+
4
+ SYNOPSIS
5
+
6
+ alf #(command_name) DATASET
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ When a dataset name is specified as commandline arg, request the
15
+ environment to provide this dataset and prints it. Otherwise, take what
16
+ comes on standard input.
17
+
18
+ Note that this command is not an operator and should not be piped anymore.
19
+
@@ -0,0 +1,23 @@
1
+
2
+ Extend its operand with an unique autonumber attribute
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This non-relational operator guarantees uniqueness of output tuples by adding
11
+ an attribute called AS whose value is an auto-numbered Integer.
12
+
13
+ If the presence of duplicates was the only "non-relational" aspect of the input,
14
+ the result is a valid relation for which AS is a candidate key.
15
+
16
+ EXAMPLE
17
+
18
+ # Autonumber suppliers with default attribute name
19
+ !(alf autonum suppliers)
20
+
21
+ # Autonumber suppliers with a `unique_id` attribute
22
+ !(alf autonum suppliers -- unique_id)
23
+
@@ -0,0 +1,31 @@
1
+
2
+ Clip input tuples to a subset of attributes
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ This operator clips tuples on attributes whose names are specified in
15
+ ATTRIBUTES. This is similar to the relational PROJECT operator, expect
16
+ that CLIP does not remove duplicates afterwards.
17
+
18
+ Clipping may therefore lead to bags of tuples instead of sets. The result
19
+ is therefore **not** a valid relation unless a candidate key is preserved.
20
+
21
+ With the allbut option, the operator keeps attributes in ATTRIBUTES, instead
22
+ of projecting them away.
23
+
24
+ EXAMPLE
25
+
26
+ # Clip suppliers on `name` and `city`
27
+ !(alf clip suppliers -- name city)
28
+
29
+ # Clip suppliers on all other attributes
30
+ !(alf clip suppliers --allbut -- name city)
31
+
@@ -0,0 +1,15 @@
1
+
2
+ Force attribute coercion according to a heading
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This operator coerces attributes of the input tuples according to HEADING.
11
+
12
+ EXAMPLE
13
+
14
+ alf coerce parts -- weight Float color Color
15
+
@@ -0,0 +1,20 @@
1
+
2
+ Remove tuple duplicates
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This non-relational operator removes duplicates from its input operand.
11
+ In other words, it converts a bag of tuples to a set of tuples in a
12
+ brute-force manner.
13
+
14
+ If the presence of duplicates was the only "non-relational" aspect of
15
+ the operand, the result is a valid relation.
16
+
17
+ EXAMPLE
18
+
19
+ alf compact suppliers
20
+
@@ -0,0 +1,32 @@
1
+
2
+ Force default values on missing/nil attributes
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ This non-relational operator rewrites input tuples to ensure that all values
15
+ for attribute names specified in DEFAULTS are present and not nil. Missing or
16
+ nil attributes are replaced by the specified default value.
17
+
18
+ A value specified in DEFAULTS may be any tuple expression. This allows computing
19
+ the default value as an expression on the current tuple.
20
+
21
+ With the strict option, the operator projects resulting tuples on attributes for
22
+ which a default value has been specified. Using the strict mode guarantees that
23
+ the heading of all tuples is the same, and that no nil value ever remains.
24
+
25
+ Note that this operator never removes duplicates. Even in strict mode the result
26
+ might be an invalid relation.
27
+
28
+ EXAMPLE
29
+
30
+ alf defaults suppliers -- country "'Belgium'"
31
+ alf defaults --strict suppliers -- country "'Belgium'"
32
+
@@ -0,0 +1,20 @@
1
+
2
+ Generate a relation with an auto-numbered attribute
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This non-relational operator generates a relation of one attribute called AS,
11
+ whose value is an auto-number ranging from 1 to SIZE, inclusively.
12
+
13
+ EXAMPLE
14
+
15
+ # Default behavior: AS is `num` and SIZE is 10
16
+ !(alf generator)
17
+
18
+ # That you can override
19
+ !(alf generator -- 5 -- id)
20
+
@@ -0,0 +1,24 @@
1
+
2
+ Sort input tuples according to an order relation
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This non-relational operator sorts input tuples according to ORDERING.
11
+
12
+ This is, of course, a non relational operator as relations are unordered
13
+ sets. It is provided for displaying purposes and normalization of
14
+ non-relational inputs.
15
+
16
+ EXAMPLE
17
+
18
+ # Sort suppliers by name
19
+ !(alf sort suppliers -- name asc)
20
+
21
+ # Sort suppliers by city in descending order, then on name on ascending
22
+ # order
23
+ !(alf sort suppliers -- city desc name asc)
24
+
@@ -0,0 +1,18 @@
1
+
2
+ Relational extension (additional, computed attributes)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This operator extends its operand with new attributes whose value is the result
11
+ of evaluating tuple expressions specified in EXT. The latter are specified as
12
+ (name, expression) pairs.
13
+
14
+ EXAMPLE
15
+
16
+ # Compute a few attributes on suppliers by extension
17
+ !(alf extend supplies -- big "qty > 100" price "qty * 12.2")
18
+
@@ -0,0 +1,27 @@
1
+
2
+ Relational grouping (relation-valued attributes)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ This operator groups attributes in ATTRIBUTES as a new, relation-valued
15
+ attribute named AS.
16
+
17
+ With the allbut option, it groups all attributes not specified in ATTRIBUTES
18
+ instead.
19
+
20
+ EXAMPLE
21
+
22
+ # Group pid and qty as a relation-valued attribute names supplying
23
+ !(alf group supplies -- pid qty -- supplying)
24
+
25
+ # Group all but pid ...
26
+ !(alf group supplies --allbut -- pid -- supplying)
27
+
@@ -0,0 +1,13 @@
1
+
2
+ Relational intersection (aka a logical and)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This operator computes the relational intersection of its operands. Such
11
+ intersection is simply the set of tuples that appear both in LEFT and in
12
+ RIGHT.
13
+
@@ -0,0 +1,27 @@
1
+
2
+ Relational join (and cartesian product)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This operator computes the (natural) join of its operands.
11
+
12
+ Natural join means that, unlike what is commonly used in SQL, the join is
13
+ performed on common attribute names. You can use the `rename` operator if this
14
+ behavior does not fit your needs.
15
+
16
+ When operands have no attribute in common, this operator naturally "degenerates"
17
+ to a cartesian product.
18
+
19
+ EXAMPLE
20
+
21
+ # Computes natural join of suppliers and supplies (on sid, the only
22
+ # attribute they have in common)
23
+ !(alf join suppliers supplies)
24
+
25
+ # The following example demontrates the cartesian product with a generated
26
+ # relation
27
+ !(alf generator -- 3 -- num | alf join cities)