alf 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env alf
2
2
  (group :supplies, [:pid, :qty], :supplying)
3
- (group :supplies, [:sid], :supplying, true)
3
+ (group :supplies, [:sid], :supplying, :allbut => true)
@@ -0,0 +1,6 @@
1
+ sid,name,status,city
2
+ S1,Smith,20,London
3
+ S2,Jones,10,Paris
4
+ S3,Blake,30,Paris
5
+ S4,Clark,20,London
6
+ S5,Adams,30,Athens
Binary file
@@ -0,0 +1 @@
1
+ alf --env=$(_("command/alf/alf.db",__FILE__)) show suppliers
@@ -0,0 +1,9 @@
1
+ +------+-------+---------+--------+
2
+ | :sid | :name | :status | :city |
3
+ +------+-------+---------+--------+
4
+ | S1 | Smith | 20 | London |
5
+ | S2 | Jones | 10 | Paris |
6
+ | S3 | Blake | 30 | Paris |
7
+ | S4 | Clark | 20 | London |
8
+ | S5 | Adams | 30 | Athens |
9
+ +------+-------+---------+--------+
@@ -0,0 +1 @@
1
+ alf --help
@@ -0,0 +1,67 @@
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
+ -e, --execute Execute one line of script (Lispy API)
15
+ --rash Render output as ruby hashes
16
+ --text Render output as a text table
17
+ --yaml Render output as a yaml output
18
+ --csv Render output as a csv file
19
+ --env=ENV Set the environment to use
20
+ --input-reader=READER Specify the kind of reader when reading on $stdin (rash,alf,csv,logs)
21
+ -Idirectory Specify $LOAD_PATH directory (may be used more than once)
22
+ -rlibrary Require the library, before executing alf
23
+ -h, --help Show help
24
+ -v, --version Show version
25
+
26
+ RELATIONAL OPERATORS
27
+
28
+ project Relational projection (clip + compact)
29
+ extend Relational extension (additional, computed attributes)
30
+ rename Relational renaming (rename some attributes)
31
+ restrict Relational restriction (aka where, predicate filtering)
32
+ join Relational join (and cartesian product)
33
+ intersect Relational intersection (aka a logical and)
34
+ minus Relational minus (aka difference)
35
+ union Relational union
36
+ matching Relational matching (join + project back on left)
37
+ not-matching Relational not matching (inverse of matching)
38
+ wrap Relational wrapping (tuple-valued attributes)
39
+ unwrap Relational un-wrapping (inverse of wrap)
40
+ group Relational grouping (relation-valued attributes)
41
+ ungroup Relational un-grouping (inverse of group)
42
+ summarize Relational summarization (group-by + aggregate ops)
43
+ rank Relational ranking (explicit tuple positions)
44
+
45
+ EXPERIMENTAL RELATIONAL OPERATORS
46
+
47
+ quota Generalized quota-queries (position, sum progression, etc.)
48
+
49
+ NON-RELATIONAL OPERATORS
50
+
51
+ autonum Extend its operand with an unique autonumber attribute
52
+ defaults Force default values on missing/nil attributes
53
+ compact Remove tuple duplicates
54
+ sort Sort input tuples according to an order relation
55
+ clip Clip input tuples to a subset of attributes
56
+ coerce Force attribute coercion according to a heading
57
+ generator Generate a relation with an auto-numbered attribute
58
+
59
+ OTHER NON-RELATIONAL COMMANDS
60
+
61
+ exec Executes an .alf file on current environment
62
+ help Show help about a specific command
63
+ show Output input tuples through a specific renderer (text, yaml, ...)
64
+
65
+ See 'alf help COMMAND' for details about a specific command.
66
+
67
+ SystemExit
@@ -1 +1 @@
1
- alf --text autonum suppliers
1
+ alf --text autonum suppliers
@@ -0,0 +1 @@
1
+ alf coerce suppliers_csv -- sid Symbol status Integer
@@ -0,0 +1,5 @@
1
+ {:sid => :S1, :name => "Smith", :status => 20, :city => "London"}
2
+ {:sid => :S2, :name => "Jones", :status => 10, :city => "Paris"}
3
+ {:sid => :S3, :name => "Blake", :status => 30, :city => "Paris"}
4
+ {:sid => :S4, :name => "Clark", :status => 20, :city => "London"}
5
+ {:sid => :S5, :name => "Adams", :status => 30, :city => "Athens"}
@@ -1 +1 @@
1
- alf --text defaults suppliers -- country "'Belgium'"
1
+ alf --text defaults suppliers -- country "'Belgium'"
@@ -1,9 +1,9 @@
1
- +----------+------+-------+---------+--------+
2
- | :country | :sid | :name | :status | :city |
3
- +----------+------+-------+---------+--------+
4
- | Belgium | S1 | Smith | 20 | London |
5
- | Belgium | S2 | Jones | 10 | Paris |
6
- | Belgium | S3 | Blake | 30 | Paris |
7
- | Belgium | S4 | Clark | 20 | London |
8
- | Belgium | S5 | Adams | 30 | Athens |
9
- +----------+------+-------+---------+--------+
1
+ +------+-------+---------+--------+----------+
2
+ | :sid | :name | :status | :city | :country |
3
+ +------+-------+---------+--------+----------+
4
+ | S1 | Smith | 20 | London | Belgium |
5
+ | S2 | Jones | 10 | Paris | Belgium |
6
+ | S3 | Blake | 30 | Paris | Belgium |
7
+ | S4 | Clark | 20 | London | Belgium |
8
+ | S5 | Adams | 30 | Athens | Belgium |
9
+ +------+-------+---------+--------+----------+
@@ -0,0 +1 @@
1
+ alf --text defaults suppliers -- country "city"
@@ -0,0 +1,9 @@
1
+ +------+-------+---------+--------+----------+
2
+ | :sid | :name | :status | :city | :country |
3
+ +------+-------+---------+--------+----------+
4
+ | S1 | Smith | 20 | London | London |
5
+ | S2 | Jones | 10 | Paris | Paris |
6
+ | S3 | Blake | 30 | Paris | Paris |
7
+ | S4 | Clark | 20 | London | London |
8
+ | S5 | Adams | 30 | Athens | Athens |
9
+ +------+-------+---------+--------+----------+
@@ -0,0 +1 @@
1
+ alf generator
@@ -0,0 +1,10 @@
1
+ {:num => 1}
2
+ {:num => 2}
3
+ {:num => 3}
4
+ {:num => 4}
5
+ {:num => 5}
6
+ {:num => 6}
7
+ {:num => 7}
8
+ {:num => 8}
9
+ {:num => 9}
10
+ {:num => 10}
@@ -0,0 +1 @@
1
+ alf generator -- 5
@@ -0,0 +1,5 @@
1
+ {:num => 1}
2
+ {:num => 2}
3
+ {:num => 3}
4
+ {:num => 4}
5
+ {:num => 5}
@@ -0,0 +1 @@
1
+ alf generator -- 5 -- id
@@ -0,0 +1,5 @@
1
+ {:id => 1}
2
+ {:id => 2}
3
+ {:id => 3}
4
+ {:id => 4}
5
+ {:id => 5}
@@ -1 +1 @@
1
- alf --text group supplies -- pid qty supplying
1
+ alf --text group supplies -- pid qty -- supplying
@@ -1 +1 @@
1
- alf --text group --allbut supplies -- sid supplying
1
+ alf --text group --allbut supplies -- sid -- supplying
@@ -0,0 +1 @@
1
+ alf help show
@@ -0,0 +1,22 @@
1
+
2
+ Output input tuples through a specific renderer (text, yaml, ...)
3
+
4
+ SYNOPSIS
5
+
6
+ alf show DATASET
7
+
8
+ OPTIONS
9
+
10
+ --rash Render output as ruby hashes
11
+ --text Render output as a text table
12
+ --yaml Render output as a yaml output
13
+ --csv Render output as a csv file
14
+
15
+ DESCRIPTION
16
+
17
+ When a dataset name is specified as commandline arg, request the
18
+ environment to provide this dataset and prints it. Otherwise, take what
19
+ comes on standard input.
20
+
21
+ Note that this command is not an operator and should not be piped anymore.
22
+
@@ -1 +1 @@
1
- alf --text quota supplies -- --by=sid --order=qty position count sum_qty "sum(:qty)"
1
+ alf --text quota supplies -- sid -- qty -- position "count()" sum_qty "sum{ qty }"
@@ -1 +1 @@
1
- alf --text rank parts --order=weight
1
+ alf --text rank parts -- weight
@@ -1,10 +1,10 @@
1
- +------+-------+--------+------------+--------+-------+
2
- | :pid | :name | :color | :weight | :city | :rank |
3
- +------+-------+--------+------------+--------+-------+
4
- | P1 | Nut | Red | 12.0000000 | London | 0 |
5
- | P5 | Cam | Blue | 12.0000000 | Paris | 0 |
6
- | P4 | Screw | Red | 14.0000000 | London | 2 |
7
- | P2 | Bolt | Green | 17.0000000 | Paris | 3 |
8
- | P3 | Screw | Blue | 17.0000000 | Oslo | 3 |
9
- | P6 | Cog | Red | 19.0000000 | London | 5 |
10
- +------+-------+--------+------------+--------+-------+
1
+ +------+-------+--------+---------+--------+-------+
2
+ | :pid | :name | :color | :weight | :city | :rank |
3
+ +------+-------+--------+---------+--------+-------+
4
+ | P1 | Nut | Red | 12.000 | London | 0 |
5
+ | P5 | Cam | Blue | 12.000 | Paris | 0 |
6
+ | P4 | Screw | Red | 14.000 | London | 2 |
7
+ | P2 | Bolt | Green | 17.000 | Paris | 3 |
8
+ | P3 | Screw | Blue | 17.000 | Oslo | 3 |
9
+ | P6 | Cog | Red | 19.000 | London | 5 |
10
+ +------+-------+--------+---------+--------+-------+
@@ -1 +1 @@
1
- alf --text rank parts --order=weight -- pos
1
+ alf --text rank parts -- weight -- pos
@@ -1,10 +1,10 @@
1
- +------+-------+--------+------------+--------+------+
2
- | :pid | :name | :color | :weight | :city | :pos |
3
- +------+-------+--------+------------+--------+------+
4
- | P1 | Nut | Red | 12.0000000 | London | 0 |
5
- | P5 | Cam | Blue | 12.0000000 | Paris | 0 |
6
- | P4 | Screw | Red | 14.0000000 | London | 2 |
7
- | P2 | Bolt | Green | 17.0000000 | Paris | 3 |
8
- | P3 | Screw | Blue | 17.0000000 | Oslo | 3 |
9
- | P6 | Cog | Red | 19.0000000 | London | 5 |
10
- +------+-------+--------+------------+--------+------+
1
+ +------+-------+--------+---------+--------+------+
2
+ | :pid | :name | :color | :weight | :city | :pos |
3
+ +------+-------+--------+---------+--------+------+
4
+ | P1 | Nut | Red | 12.000 | London | 0 |
5
+ | P5 | Cam | Blue | 12.000 | Paris | 0 |
6
+ | P4 | Screw | Red | 14.000 | London | 2 |
7
+ | P2 | Bolt | Green | 17.000 | Paris | 3 |
8
+ | P3 | Screw | Blue | 17.000 | Oslo | 3 |
9
+ | P6 | Cog | Red | 19.000 | London | 5 |
10
+ +------+-------+--------+---------+--------+------+
@@ -1 +1 @@
1
- alf --text rank parts --order=weight,pid
1
+ alf --text rank parts -- weight pid
@@ -1,10 +1,10 @@
1
- +------+-------+--------+------------+--------+-------+
2
- | :pid | :name | :color | :weight | :city | :rank |
3
- +------+-------+--------+------------+--------+-------+
4
- | P1 | Nut | Red | 12.0000000 | London | 0 |
5
- | P5 | Cam | Blue | 12.0000000 | Paris | 1 |
6
- | P4 | Screw | Red | 14.0000000 | London | 2 |
7
- | P2 | Bolt | Green | 17.0000000 | Paris | 3 |
8
- | P3 | Screw | Blue | 17.0000000 | Oslo | 4 |
9
- | P6 | Cog | Red | 19.0000000 | London | 5 |
10
- +------+-------+--------+------------+--------+-------+
1
+ +------+-------+--------+---------+--------+-------+
2
+ | :pid | :name | :color | :weight | :city | :rank |
3
+ +------+-------+--------+---------+--------+-------+
4
+ | P1 | Nut | Red | 12.000 | London | 0 |
5
+ | P5 | Cam | Blue | 12.000 | Paris | 1 |
6
+ | P4 | Screw | Red | 14.000 | London | 2 |
7
+ | P2 | Bolt | Green | 17.000 | Paris | 3 |
8
+ | P3 | Screw | Blue | 17.000 | Oslo | 4 |
9
+ | P6 | Cog | Red | 19.000 | London | 5 |
10
+ +------+-------+--------+---------+--------+-------+
@@ -1 +1 @@
1
- alf rank parts --order=weight,desc -- position
1
+ alf rank parts -- weight desc -- position
@@ -1 +1 @@
1
- alf rank parts --order=weight,desc,pid,asc -- position
1
+ alf rank parts -- weight desc pid asc -- position
@@ -0,0 +1 @@
1
+ alf show suppliers --csv
@@ -0,0 +1,6 @@
1
+ sid,name,status,city
2
+ S1,Smith,20,London
3
+ S2,Jones,10,Paris
4
+ S3,Blake,30,Paris
5
+ S4,Clark,20,London
6
+ S5,Adams,30,Athens
@@ -1 +1 @@
1
- alf -rdate extend suppliers -- date "Date.parse('2011-07-22')"
1
+ alf -ruri extend suppliers -- uri "URI.parse(name)"
@@ -1,5 +1,5 @@
1
- {:sid => "S1", :name => "Smith", :status => 20, :city => "London", :date => Marshal.load("\x04\bU:\tDate[\bU:\rRational[\ai\x03\xA9\xF1Ji\ai\x00i\x03\x19\x15#")}
2
- {:sid => "S2", :name => "Jones", :status => 10, :city => "Paris", :date => Marshal.load("\x04\bU:\tDate[\bU:\rRational[\ai\x03\xA9\xF1Ji\ai\x00i\x03\x19\x15#")}
3
- {:sid => "S3", :name => "Blake", :status => 30, :city => "Paris", :date => Marshal.load("\x04\bU:\tDate[\bU:\rRational[\ai\x03\xA9\xF1Ji\ai\x00i\x03\x19\x15#")}
4
- {:sid => "S4", :name => "Clark", :status => 20, :city => "London", :date => Marshal.load("\x04\bU:\tDate[\bU:\rRational[\ai\x03\xA9\xF1Ji\ai\x00i\x03\x19\x15#")}
5
- {:sid => "S5", :name => "Adams", :status => 30, :city => "Athens", :date => Marshal.load("\x04\bU:\tDate[\bU:\rRational[\ai\x03\xA9\xF1Ji\ai\x00i\x03\x19\x15#")}
1
+ {:sid => "S1", :name => "Smith", :status => 20, :city => "London", :uri => Marshal.load("\x04\bo:\x11URI::Generic\x10:\f@scheme0:\n@user0:\x0E@password0:\n@host0:\n@port0:\n@pathI\"\nSmith\x06:\x06ET:\v@query0:\f@opaque0:\x0E@registry0:\x0E@fragment0:\f@parser0")}
2
+ {:sid => "S2", :name => "Jones", :status => 10, :city => "Paris", :uri => Marshal.load("\x04\bo:\x11URI::Generic\x10:\f@scheme0:\n@user0:\x0E@password0:\n@host0:\n@port0:\n@pathI\"\nJones\x06:\x06ET:\v@query0:\f@opaque0:\x0E@registry0:\x0E@fragment0:\f@parser0")}
3
+ {:sid => "S3", :name => "Blake", :status => 30, :city => "Paris", :uri => Marshal.load("\x04\bo:\x11URI::Generic\x10:\f@scheme0:\n@user0:\x0E@password0:\n@host0:\n@port0:\n@pathI\"\nBlake\x06:\x06ET:\v@query0:\f@opaque0:\x0E@registry0:\x0E@fragment0:\f@parser0")}
4
+ {:sid => "S4", :name => "Clark", :status => 20, :city => "London", :uri => Marshal.load("\x04\bo:\x11URI::Generic\x10:\f@scheme0:\n@user0:\x0E@password0:\n@host0:\n@port0:\n@pathI\"\nClark\x06:\x06ET:\v@query0:\f@opaque0:\x0E@registry0:\x0E@fragment0:\f@parser0")}
5
+ {:sid => "S5", :name => "Adams", :status => 30, :city => "Athens", :uri => Marshal.load("\x04\bo:\x11URI::Generic\x10:\f@scheme0:\n@user0:\x0E@password0:\n@host0:\n@port0:\n@pathI\"\nAdams\x06:\x06ET:\v@query0:\f@opaque0:\x0E@registry0:\x0E@fragment0:\f@parser0")}
@@ -1 +1 @@
1
- alf --text sort suppliers -- name asc
1
+ alf --text sort suppliers -- name
@@ -1 +1 @@
1
- alf --text sort suppliers -- city desc name asc
1
+ alf --text sort suppliers -- name desc
@@ -1,9 +1,9 @@
1
1
  +------+-------+---------+--------+
2
2
  | :sid | :name | :status | :city |
3
3
  +------+-------+---------+--------+
4
- | S3 | Blake | 30 | Paris |
4
+ | S1 | Smith | 20 | London |
5
5
  | S2 | Jones | 10 | Paris |
6
6
  | S4 | Clark | 20 | London |
7
- | S1 | Smith | 20 | London |
7
+ | S3 | Blake | 30 | Paris |
8
8
  | S5 | Adams | 30 | Athens |
9
9
  +------+-------+---------+--------+
@@ -0,0 +1 @@
1
+ alf --text sort suppliers -- city name
@@ -0,0 +1,9 @@
1
+ +------+-------+---------+--------+
2
+ | :sid | :name | :status | :city |
3
+ +------+-------+---------+--------+
4
+ | S5 | Adams | 30 | Athens |
5
+ | S4 | Clark | 20 | London |
6
+ | S1 | Smith | 20 | London |
7
+ | S3 | Blake | 30 | Paris |
8
+ | S2 | Jones | 10 | Paris |
9
+ +------+-------+---------+--------+
@@ -0,0 +1 @@
1
+ alf --text sort suppliers -- city desc name asc
@@ -0,0 +1,9 @@
1
+ +------+-------+---------+--------+
2
+ | :sid | :name | :status | :city |
3
+ +------+-------+---------+--------+
4
+ | S3 | Blake | 30 | Paris |
5
+ | S2 | Jones | 10 | Paris |
6
+ | S4 | Clark | 20 | London |
7
+ | S1 | Smith | 20 | London |
8
+ | S5 | Adams | 30 | Athens |
9
+ +------+-------+---------+--------+
@@ -1 +1 @@
1
- alf --text summarize supplies -- --by=sid total_qty "sum(:qty)"
1
+ alf --text summarize supplies -- sid -- total_qty "sum{ qty }"
@@ -1 +1 @@
1
- alf --text ungroup group -- supplying
1
+ alf --text ungroup group -- supplying
@@ -1 +1 @@
1
- alf --text wrap suppliers -- city status loc_and_status
1
+ alf --text wrap suppliers -- city status -- loc_and_status
@@ -1,9 +1,8 @@
1
- cities = relation(
2
- {:city => 'London'},
3
- {:city => 'Paris'},
4
- {:city => 'Athens'}
5
- )
1
+ cities = Relation(
2
+ Tuple(:city => 'London'),
3
+ Tuple(:city => 'Paris'),
4
+ Tuple(:city => 'Athens'))
6
5
  (specify \
7
6
  "(project ..., [...]) should remove duplicates",
8
7
  (rel_equal \
9
- (project :suppliers, [:city]), cities))
8
+ (project :suppliers, [:city]), cities))
@@ -1,34 +1,34 @@
1
- input = rel(
2
- {:id => 1, :weight => 10.0},
3
- {:id => 2, :weight => 12.0},
4
- {:id => 3, :weight => 12.0}
1
+ input = Relation(
2
+ Tuple(:id => 1, :weight => 10.0),
3
+ Tuple(:id => 2, :weight => 12.0),
4
+ Tuple(:id => 3, :weight => 12.0)
5
5
  )
6
6
 
7
7
  (specify "rank should respect < by default",
8
8
  (rel_equal \
9
- (rel (tuple :id => 1, :weight => 10.0, :rank => 0),
10
- (tuple :id => 2, :weight => 12.0, :rank => 1),
11
- (tuple :id => 3, :weight => 12.0, :rank => 1)),
9
+ (Relation Tuple(:id => 1, :weight => 10.0, :rank => 0),
10
+ Tuple(:id => 2, :weight => 12.0, :rank => 1),
11
+ Tuple(:id => 3, :weight => 12.0, :rank => 1)),
12
12
  (rank input, [:weight])))
13
13
 
14
14
  (specify "rank should support a strict order",
15
15
  (rel_equal \
16
- (rel (tuple :id => 1, :weight => 10.0, :rank => 0),
17
- (tuple :id => 2, :weight => 12.0, :rank => 1),
18
- (tuple :id => 3, :weight => 12.0, :rank => 2)),
16
+ (Relation Tuple(:id => 1, :weight => 10.0, :rank => 0),
17
+ Tuple(:id => 2, :weight => 12.0, :rank => 1),
18
+ Tuple(:id => 3, :weight => 12.0, :rank => 2)),
19
19
  (rank input, [:weight, :id])))
20
20
 
21
21
  (specify "rank should support a reverse order",
22
22
  (rel_equal \
23
- (rel (tuple :id => 1, :weight => 10.0, :rank => 2),
24
- (tuple :id => 2, :weight => 12.0, :rank => 0),
25
- (tuple :id => 3, :weight => 12.0, :rank => 0)),
23
+ (Relation Tuple(:id => 1, :weight => 10.0, :rank => 2),
24
+ Tuple(:id => 2, :weight => 12.0, :rank => 0),
25
+ Tuple(:id => 3, :weight => 12.0, :rank => 0)),
26
26
  (rank input, [[:weight, :desc]])))
27
27
 
28
28
  (specify "rank should allow specifying a name",
29
29
  (rel_equal \
30
- (rel (tuple :id => 1, :weight => 10.0, :pos => 0),
31
- (tuple :id => 2, :weight => 12.0, :pos => 1),
32
- (tuple :id => 3, :weight => 12.0, :pos => 1)),
30
+ (Relation Tuple(:id => 1, :weight => 10.0, :pos => 0),
31
+ Tuple(:id => 2, :weight => 12.0, :pos => 1),
32
+ Tuple(:id => 3, :weight => 12.0, :pos => 1)),
33
33
  (rank input, [:weight], :pos)))
34
34
 
@@ -6,17 +6,23 @@ describe "Alf's alf command / " do
6
6
  specify{ cmd.should =~ /^alf / }
7
7
 
8
8
  describe "#{File.basename(input)}: #{cmd}" do
9
- let(:argv) { Alf::Tools::parse_commandline_args(cmd)[1..-1] }
9
+ let(:argv) { Quickl.parse_commandline_args(cmd)[1..-1] }
10
10
  let(:stdout) { File.join(File.dirname(input), "#{File.basename(input, ".cmd")}.stdout") }
11
- let(:expected) { wlang(File.read(stdout), binding) }
11
+ let(:stderr) { File.join(File.dirname(input), "#{File.basename(input, ".cmd")}.stderr") }
12
+ let(:stdout_expected) { File.exists?(stdout) ? wlang(File.read(stdout), binding) : "" }
13
+ let(:stderr_expected) { File.exists?(stderr) ? wlang(File.read(stderr), binding) : "" }
12
14
 
13
15
  before{
14
16
  $oldstdout = $stdout
17
+ $oldstderr = $stderr
15
18
  $stdout = StringIO.new
19
+ $stderr = StringIO.new
16
20
  }
17
21
  after {
18
22
  $stdout = $oldstdout
23
+ $stderr = $oldstderr
19
24
  $oldstdout = nil
25
+ $oldstderr = nil
20
26
  }
21
27
 
22
28
  specify{
@@ -25,12 +31,17 @@ describe "Alf's alf command / " do
25
31
  main = Alf::Command::Main.new
26
32
  main.environment = Alf::Environment.folder(dir)
27
33
  main.run(argv, __FILE__)
28
- rescue SystemExit
29
- $stdout << SystemExit << "\n"
34
+ rescue => ex
35
+ begin
36
+ Alf::Command::Main.handle_error(ex, main)
37
+ rescue SystemExit
38
+ $stdout << "SystemExit" << "\n"
39
+ end
30
40
  end
31
- $stdout.string.should(eq(expected)) unless RUBY_VERSION < "1.9"
41
+ $stdout.string.should(eq(stdout_expected)) unless RUBY_VERSION < "1.9"
42
+ $stderr.string.should(eq(stderr_expected)) unless RUBY_VERSION < "1.9"
32
43
  }
33
44
  end
34
45
  end
35
46
 
36
- end
47
+ end
@@ -7,7 +7,7 @@ Dir["#{File.expand_path('../../../examples', __FILE__)}/**/*.alf"].each do |file
7
7
  let(:example_env) { Alf::Environment.folder(example_dir) }
8
8
 
9
9
  it "should run without error" do
10
- Alf.lispy(example_env).compile(File.read(example_path)).to_rel
10
+ Alf.lispy(example_env).compile(File.read(example_path), example_path).to_rel
11
11
  end
12
12
 
13
13
  end
@@ -0,0 +1,5 @@
1
+ 125.76.230.10 - - [02/Sep/2009:03:33:46 +0200] "GET /cart/install.txt HTTP/1.1" 404 214 "-" "Toata dragostea mea pentru diavola"
2
+ 125.76.230.10 - - [02/Sep/2009:03:33:47 +0200] "GET /store/install.txt HTTP/1.1" 404 215 "-" "Toata dragostea mea pentru diavola"
3
+ 10.0.1.1 - - [02/Sep/2009:05:08:33 +0200] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
4
+ 10.0.1.1 - - [02/Sep/2009:06:41:51 +0200] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
5
+ 69.41.0.45 - - [02/Sep/2009:12:02:40 +0200] "GET //phpMyAdmin/ HTTP/1.1" 404 209 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ describe "path attributes in log" do
3
+
4
+ let(:env){ Alf::Environment.folder(File.dirname(__FILE__)) }
5
+
6
+ subject{
7
+ Alf.lispy(env).evaluate <<-EOF
8
+ (restrict :apache_combined, lambda{ path =~ /install.txt/ })
9
+ EOF
10
+ }
11
+
12
+ specify {
13
+ subject.should be_a(Alf::Relation)
14
+ projected = subject.project([:path])
15
+ projected.should == Alf::Relation[
16
+ {:path => "/cart/install.txt" },
17
+ {:path => "/store/install.txt"}
18
+ ]
19
+ projected.extend(:short_path => lambda{ path[0..1] }).should == Alf::Relation[
20
+ {:path => "/cart/install.txt", :short_path => "/c" },
21
+ {:path => "/store/install.txt", :short_path => "/s"}
22
+ ]
23
+ }
24
+
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'date'
3
+ module Alf
4
+ describe Relation, "allbut" do
5
+
6
+ describe "when all attributes are projected away" do
7
+ subject{
8
+ Relation[{:sid => "P1"}].allbut([:sid])
9
+ }
10
+ it{ should eql(Relation[{}]) }
11
+ end
12
+
13
+ end
14
+ end
@@ -1,7 +1,6 @@
1
1
  shared_examples_for "An operator class" do
2
2
 
3
- it "should not have public set_args, _each and _prepare methods" do
4
- operator_class.public_method_defined?(:set_args).should be_false
3
+ it "should not have public _each and _prepare methods" do
5
4
  operator_class.public_method_defined?(:_each).should be_false
6
5
  operator_class.public_method_defined?(:_prepare).should be_false
7
6
  end
@@ -26,10 +25,16 @@ shared_examples_for "An operator class" do
26
25
  operator_class.should respond_to(:binary?)
27
26
  end
28
27
 
28
+ it "should have a nullary? class method" do
29
+ operator_class.should respond_to(:nullary?)
30
+ end
31
+
29
32
  it "should implement unary? and binary? accurately" do
30
- operator_class.unary?.should_not eq(operator_class.binary?)
31
- operator_class.unary?.should eq(operator_class.ancestors.include?(Alf::Operator::Unary))
32
- operator_class.binary?.should eq(operator_class.ancestors.include?(Alf::Operator::Binary))
33
+ op = operator_class
34
+ (op.nullary? || op.unary? || op.binary?).should be_true
35
+ (op.nullary? && op.unary?).should be_false
36
+ (op.nullary? && op.binary?).should be_false
37
+ (op.unary? && op.binary?).should be_false
33
38
  end
34
39
 
35
40
  end