axiom 0.1.1 → 0.2.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 (311) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -1
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +10 -7
  5. data/Gemfile +4 -0
  6. data/Gemfile.devtools +27 -13
  7. data/Guardfile +2 -2
  8. data/README.md +36 -30
  9. data/TODO +22 -24
  10. data/axiom.gemspec +9 -9
  11. data/benchmarks/memory.rb +1 -2
  12. data/benchmarks/speed.rb +7 -8
  13. data/config/flay.yml +1 -1
  14. data/config/reek.yml +19 -7
  15. data/config/rubocop.yml +6 -9
  16. data/lib/axiom.rb +28 -13
  17. data/lib/axiom/aggregate/mean.rb +4 -3
  18. data/lib/axiom/aggregate/sum.rb +1 -1
  19. data/lib/axiom/algebra/extension.rb +1 -1
  20. data/lib/axiom/algebra/join.rb +4 -27
  21. data/lib/axiom/algebra/product.rb +3 -3
  22. data/lib/axiom/algebra/projection.rb +2 -2
  23. data/lib/axiom/algebra/rename.rb +2 -2
  24. data/lib/axiom/algebra/rename/aliases.rb +3 -3
  25. data/lib/axiom/algebra/summarization.rb +3 -3
  26. data/lib/axiom/attribute.rb +5 -4
  27. data/lib/axiom/attribute/comparable.rb +15 -11
  28. data/lib/axiom/attribute/date.rb +1 -1
  29. data/lib/axiom/attribute/date_time.rb +1 -1
  30. data/lib/axiom/attribute/length_comparable.rb +39 -0
  31. data/lib/axiom/attribute/numeric.rb +1 -26
  32. data/lib/axiom/attribute/relation.rb +64 -0
  33. data/lib/axiom/attribute/string.rb +1 -28
  34. data/lib/axiom/attribute/time.rb +1 -1
  35. data/lib/axiom/attribute/tuple.rb +50 -0
  36. data/lib/axiom/attribute/value_comparable.rb +42 -0
  37. data/lib/axiom/function.rb +1 -1
  38. data/lib/axiom/function/binary.rb +4 -16
  39. data/lib/axiom/function/comparable.rb +1 -1
  40. data/lib/axiom/function/connective/conjunction.rb +1 -1
  41. data/lib/axiom/function/connective/disjunction.rb +1 -1
  42. data/lib/axiom/function/connective/negation.rb +1 -1
  43. data/lib/axiom/function/numeric/exponentiation.rb +1 -1
  44. data/lib/axiom/function/numeric/square_root.rb +1 -1
  45. data/lib/axiom/function/predicate/enumerable.rb +0 -14
  46. data/lib/axiom/function/predicate/exclusion.rb +1 -1
  47. data/lib/axiom/function/predicate/inclusion.rb +1 -1
  48. data/lib/axiom/function/proposition.rb +12 -25
  49. data/lib/axiom/function/unary.rb +92 -106
  50. data/lib/axiom/relation.rb +3 -3
  51. data/lib/axiom/relation/base.rb +15 -0
  52. data/lib/axiom/relation/header.rb +25 -22
  53. data/lib/axiom/relation/index.rb +91 -0
  54. data/lib/axiom/relation/keys.rb +3 -3
  55. data/lib/axiom/relation/materialized.rb +48 -4
  56. data/lib/axiom/relation/operation/binary.rb +5 -5
  57. data/lib/axiom/relation/operation/group.rb +95 -0
  58. data/lib/axiom/relation/operation/limit.rb +15 -15
  59. data/lib/axiom/relation/operation/offset.rb +12 -12
  60. data/lib/axiom/relation/operation/reverse.rb +9 -9
  61. data/lib/axiom/relation/operation/set.rb +1 -1
  62. data/lib/axiom/relation/operation/{order.rb → sorted.rb} +29 -28
  63. data/lib/axiom/relation/operation/{order → sorted}/direction.rb +4 -4
  64. data/lib/axiom/relation/operation/{order → sorted}/direction_set.rb +3 -3
  65. data/lib/axiom/relation/operation/ungroup.rb +82 -0
  66. data/lib/axiom/relation/operation/unwrap.rb +80 -0
  67. data/lib/axiom/relation/operation/wrap.rb +85 -0
  68. data/lib/axiom/relation/proxy.rb +5 -6
  69. data/lib/axiom/relation/variable.rb +1 -2
  70. data/lib/axiom/support/aliasable.rb +3 -5
  71. data/lib/axiom/support/equalizer.rb +10 -12
  72. data/lib/axiom/support/operation/binary.rb +3 -2
  73. data/lib/axiom/support/operation/unary.rb +1 -1
  74. data/lib/axiom/tuple.rb +76 -26
  75. data/lib/axiom/types/relation.rb +13 -0
  76. data/lib/axiom/types/tuple.rb +13 -0
  77. data/lib/axiom/version.rb +1 -1
  78. data/spec/integration/axiom/relation/efficient_enumerable_spec.rb +9 -9
  79. data/spec/integration/axiom/relation/writable_relations_spec.rb +12 -12
  80. data/spec/shared/invertible_method_behaviour.rb +1 -1
  81. data/spec/spec_helper.rb +8 -6
  82. data/spec/unit/axiom/aggregate/call_spec.rb +7 -12
  83. data/spec/unit/axiom/aggregate/class_methods/default_spec.rb +7 -2
  84. data/spec/unit/axiom/aggregate/default_spec.rb +1 -1
  85. data/spec/unit/axiom/aggregate/finalize_spec.rb +1 -1
  86. data/spec/unit/axiom/aggregate/maximum/type_spec.rb +2 -6
  87. data/spec/unit/axiom/aggregate/mean/class_methods/call_spec.rb +2 -2
  88. data/spec/unit/axiom/aggregate/mean/class_methods/finalize_spec.rb +10 -3
  89. data/spec/unit/axiom/aggregate/minimum/type_spec.rb +2 -6
  90. data/spec/unit/axiom/aggregate/sum/default_spec.rb +32 -6
  91. data/spec/unit/axiom/aggregate/sum/type_spec.rb +2 -6
  92. data/spec/unit/axiom/aggregate/variance/class_methods/call_spec.rb +6 -6
  93. data/spec/unit/axiom/algebra/difference/each_spec.rb +3 -3
  94. data/spec/unit/axiom/algebra/extension/class_methods/new_spec.rb +1 -1
  95. data/spec/unit/axiom/algebra/extension/each_spec.rb +2 -2
  96. data/spec/unit/axiom/algebra/intersection/each_spec.rb +3 -3
  97. data/spec/unit/axiom/algebra/join/each_spec.rb +6 -6
  98. data/spec/unit/axiom/algebra/product/each_spec.rb +2 -2
  99. data/spec/unit/axiom/algebra/projection/each_spec.rb +2 -2
  100. data/spec/unit/axiom/algebra/rename/directions_spec.rb +3 -3
  101. data/spec/unit/axiom/algebra/rename/each_spec.rb +2 -2
  102. data/spec/unit/axiom/algebra/restriction/delete_spec.rb +3 -3
  103. data/spec/unit/axiom/algebra/restriction/each_spec.rb +12 -11
  104. data/spec/unit/axiom/algebra/restriction/insert_spec.rb +3 -3
  105. data/spec/unit/axiom/algebra/restriction/methods/restrict_spec.rb +4 -4
  106. data/spec/unit/axiom/algebra/summarization/each_spec.rb +2 -2
  107. data/spec/unit/axiom/algebra/summarization/eql_spec.rb +1 -1
  108. data/spec/unit/axiom/algebra/summarization/summaries/summarize_by_spec.rb +4 -4
  109. data/spec/unit/axiom/algebra/summarization/summaries/to_hash_spec.rb +2 -2
  110. data/spec/unit/axiom/algebra/summarization/summary/summarize_by_spec.rb +1 -1
  111. data/spec/unit/axiom/algebra/union/each_spec.rb +4 -4
  112. data/spec/unit/axiom/aliasable/fixtures/classes.rb +3 -1
  113. data/spec/unit/axiom/aliasable/inheritable_alias_spec.rb +18 -27
  114. data/spec/unit/axiom/attribute/call_spec.rb +1 -1
  115. data/spec/unit/axiom/attribute/class_methods/coerce_spec.rb +57 -51
  116. data/spec/unit/axiom/attribute/class_methods/new_spec.rb +1 -1
  117. data/spec/unit/axiom/attribute/comparable/asc_spec.rb +4 -2
  118. data/spec/unit/axiom/attribute/comparable/desc_spec.rb +4 -2
  119. data/spec/unit/axiom/attribute/comparable/range_spec.rb +20 -0
  120. data/spec/unit/axiom/attribute/eql_spec.rb +1 -1
  121. data/spec/unit/axiom/attribute/equality_operator_spec.rb +1 -1
  122. data/spec/unit/axiom/attribute/include_predicate_spec.rb +1 -1
  123. data/spec/unit/axiom/attribute/name_spec.rb +1 -1
  124. data/spec/unit/axiom/attribute/optional_predicate_spec.rb +1 -1
  125. data/spec/unit/axiom/attribute/relation/class_methods/new_spec.rb +56 -0
  126. data/spec/unit/axiom/attribute/relation/class_methods/type_spec.rb +13 -0
  127. data/spec/unit/axiom/attribute/relation/header_spec.rb +13 -0
  128. data/spec/unit/axiom/attribute/relation/new_relation_spec.rb +15 -0
  129. data/spec/unit/axiom/attribute/rename_spec.rb +1 -1
  130. data/spec/unit/axiom/attribute/required_predicate_spec.rb +1 -1
  131. data/spec/unit/axiom/attribute/tuple/class_methods/new_spec.rb +56 -0
  132. data/spec/unit/axiom/attribute/tuple/class_methods/type_spec.rb +13 -0
  133. data/spec/unit/axiom/attribute/tuple/header_spec.rb +13 -0
  134. data/spec/unit/axiom/equalizer/class_method/new_spec.rb +24 -54
  135. data/spec/unit/axiom/evaluator/context/add_spec.rb +7 -7
  136. data/spec/unit/axiom/evaluator/context/element_reader_spec.rb +4 -4
  137. data/spec/unit/axiom/evaluator/context/functions_spec.rb +1 -1
  138. data/spec/unit/axiom/evaluator/context/method_missing_spec.rb +3 -3
  139. data/spec/unit/axiom/evaluator/context/respond_to_predicate_spec.rb +3 -3
  140. data/spec/unit/axiom/evaluator/context/send_spec.rb +8 -8
  141. data/spec/unit/axiom/function/binary/call_spec.rb +1 -1
  142. data/spec/unit/axiom/function/binary/type_spec.rb +12 -10
  143. data/spec/unit/axiom/function/comparable/class_methods/included_spec.rb +2 -2
  144. data/spec/unit/axiom/function/connective/negation/inverse_spec.rb +1 -1
  145. data/spec/unit/axiom/function/predicate/call_spec.rb +5 -4
  146. data/spec/unit/axiom/function/predicate/enumerable/call_spec.rb +12 -2
  147. data/spec/unit/axiom/function/predicate/eql_spec.rb +4 -3
  148. data/spec/unit/axiom/function/predicate/equality/methods/eq_spec.rb +5 -1
  149. data/spec/unit/axiom/function/predicate/exclusion/class_methods/call_spec.rb +37 -8
  150. data/spec/unit/axiom/function/predicate/exclusion/methods/exclude_spec.rb +6 -2
  151. data/spec/unit/axiom/function/predicate/greater_than/methods/gt_spec.rb +5 -1
  152. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/methods/gte_spec.rb +5 -1
  153. data/spec/unit/axiom/function/predicate/inclusion/class_methods/call_spec.rb +37 -8
  154. data/spec/unit/axiom/function/predicate/inclusion/methods/include_spec.rb +6 -2
  155. data/spec/unit/axiom/function/predicate/inequality/methods/ne_spec.rb +5 -1
  156. data/spec/unit/axiom/function/predicate/less_than/methods/lt_spec.rb +5 -1
  157. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/methods/lte_spec.rb +5 -1
  158. data/spec/unit/axiom/function/predicate/match/methods/match_spec.rb +7 -3
  159. data/spec/unit/axiom/function/predicate/no_match/methods/no_match_spec.rb +6 -2
  160. data/spec/unit/axiom/function/proposition/call_spec.rb +6 -4
  161. data/spec/unit/axiom/function/proposition/class_methods/{new_spec.rb → coerce_spec.rb} +17 -17
  162. data/spec/unit/axiom/function/proposition/eql_spec.rb +4 -4
  163. data/spec/unit/axiom/function/proposition/equality_operator_spec.rb +3 -3
  164. data/spec/unit/axiom/function/proposition/inverse_spec.rb +4 -4
  165. data/spec/unit/axiom/function/proposition/rename_spec.rb +1 -1
  166. data/spec/unit/axiom/function/type_spec.rb +1 -1
  167. data/spec/unit/axiom/function/unary/call_spec.rb +1 -1
  168. data/spec/unit/axiom/function/unary/callable/call_spec.rb +3 -13
  169. data/spec/unit/axiom/function/unary/callable/included_spec.rb +2 -2
  170. data/spec/unit/axiom/function/unary/type_spec.rb +11 -1
  171. data/spec/unit/axiom/relation/base/eql_spec.rb +1 -1
  172. data/spec/unit/axiom/relation/base/equality_operator_spec.rb +138 -0
  173. data/spec/unit/axiom/relation/class_methods/new_spec.rb +7 -7
  174. data/spec/unit/axiom/relation/directions_spec.rb +2 -2
  175. data/spec/unit/axiom/relation/each_spec.rb +5 -5
  176. data/spec/unit/axiom/relation/element_reader_spec.rb +1 -1
  177. data/spec/unit/axiom/relation/empty/each_spec.rb +1 -1
  178. data/spec/unit/axiom/relation/empty_predicate_spec.rb +1 -1
  179. data/spec/unit/axiom/relation/eql_spec.rb +1 -1
  180. data/spec/unit/axiom/relation/equality_operator_spec.rb +1 -1
  181. data/spec/unit/axiom/relation/header/class_methods/coerce_spec.rb +2 -2
  182. data/spec/unit/axiom/relation/header/class_methods/new_spec.rb +3 -3
  183. data/spec/unit/axiom/relation/header/context_spec.rb +2 -2
  184. data/spec/unit/axiom/relation/header/each_spec.rb +2 -2
  185. data/spec/unit/axiom/relation/header/extend_spec.rb +1 -1
  186. data/spec/unit/axiom/relation/header/{call_spec.rb → fetch_spec.rb} +1 -1
  187. data/spec/unit/axiom/relation/header/project_spec.rb +1 -1
  188. data/spec/unit/axiom/relation/header/rename_spec.rb +19 -5
  189. data/spec/unit/axiom/relation/header/size_spec.rb +14 -0
  190. data/spec/unit/axiom/relation/header_spec.rb +1 -1
  191. data/spec/unit/axiom/relation/index/each_spec.rb +33 -0
  192. data/spec/unit/axiom/relation/index/element_reader_spec.rb +17 -0
  193. data/spec/unit/axiom/relation/index/left_shift_operator_spec.rb +23 -0
  194. data/spec/unit/axiom/relation/index/merge_spec.rb +19 -0
  195. data/spec/unit/axiom/relation/keys/class_methods/coerce_spec.rb +19 -2
  196. data/spec/unit/axiom/relation/keys/class_methods/new_spec.rb +1 -1
  197. data/spec/unit/axiom/relation/keys/each_spec.rb +2 -2
  198. data/spec/unit/axiom/relation/materialize_spec.rb +1 -1
  199. data/spec/unit/axiom/relation/materialized/class_methods/new_spec.rb +30 -4
  200. data/spec/unit/axiom/relation/materialized/directions_spec.rb +1 -1
  201. data/spec/unit/axiom/relation/materialized/materialized_predicate_spec.rb +1 -1
  202. data/spec/unit/axiom/relation/materialized_predicate_spec.rb +1 -1
  203. data/spec/unit/axiom/relation/operation/binary/class_methods/included_spec.rb +2 -2
  204. data/spec/unit/axiom/relation/operation/binary/class_methods/new_spec.rb +6 -6
  205. data/spec/unit/axiom/relation/operation/combination/class_methods/combine_tuples_spec.rb +4 -4
  206. data/spec/unit/axiom/relation/operation/group/each_spec.rb +33 -0
  207. data/spec/unit/axiom/relation/operation/group/header_spec.rb +22 -0
  208. data/spec/unit/axiom/relation/operation/group/methods/group_spec.rb +25 -0
  209. data/spec/unit/axiom/relation/operation/limit/class_methods/new_spec.rb +4 -4
  210. data/spec/unit/axiom/relation/operation/limit/directions_spec.rb +3 -3
  211. data/spec/unit/axiom/relation/operation/limit/each_spec.rb +4 -4
  212. data/spec/unit/axiom/relation/operation/limit/limit_spec.rb +2 -2
  213. data/spec/unit/axiom/relation/operation/offset/class_methods/new_spec.rb +4 -4
  214. data/spec/unit/axiom/relation/operation/offset/directions_spec.rb +3 -3
  215. data/spec/unit/axiom/relation/operation/offset/each_spec.rb +4 -4
  216. data/spec/unit/axiom/relation/operation/offset/offset_spec.rb +2 -2
  217. data/spec/unit/axiom/relation/operation/reverse/class_methods/new_spec.rb +6 -6
  218. data/spec/unit/axiom/relation/operation/reverse/directions_spec.rb +3 -3
  219. data/spec/unit/axiom/relation/operation/reverse/each_spec.rb +4 -4
  220. data/spec/unit/axiom/relation/operation/set/class_methods/included_spec.rb +2 -2
  221. data/spec/unit/axiom/relation/operation/{order → sorted}/ascending/class_methods/call_spec.rb +22 -1
  222. data/spec/unit/axiom/relation/operation/sorted/ascending/class_methods/reverse_spec.rb +11 -0
  223. data/spec/unit/axiom/relation/operation/{order/descending → sorted/ascending}/reverse_spec.rb +2 -2
  224. data/spec/unit/axiom/relation/operation/{order → sorted}/class_methods/new_spec.rb +4 -4
  225. data/spec/unit/axiom/relation/operation/{order → sorted}/delete_spec.rb +12 -6
  226. data/spec/unit/axiom/relation/operation/{order → sorted}/descending/class_methods/call_spec.rb +22 -1
  227. data/spec/unit/axiom/relation/operation/sorted/descending/class_methods/reverse_spec.rb +11 -0
  228. data/spec/unit/axiom/relation/operation/{order/ascending → sorted/descending}/reverse_spec.rb +2 -2
  229. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/attribute_spec.rb +4 -4
  230. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/call_spec.rb +7 -7
  231. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/class_methods/coerce_spec.rb +2 -2
  232. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/eql_predicate_spec.rb +4 -4
  233. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/name_spec.rb +4 -4
  234. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/rename_spec.rb +5 -5
  235. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/reverse_spec.rb +9 -9
  236. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/attributes_spec.rb +1 -1
  237. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/coerce_spec.rb +3 -3
  238. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/new_spec.rb +1 -1
  239. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/eql_spec.rb +1 -1
  240. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/equality_operator_spec.rb +1 -1
  241. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/project_spec.rb +1 -1
  242. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/rename_spec.rb +1 -1
  243. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/reverse_spec.rb +2 -2
  244. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/sort_tuples_spec.rb +1 -1
  245. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/to_ary_spec.rb +1 -1
  246. data/spec/unit/axiom/relation/operation/{order → sorted}/directions_spec.rb +1 -1
  247. data/spec/unit/axiom/relation/operation/{order → sorted}/each_spec.rb +3 -3
  248. data/spec/unit/axiom/relation/operation/{order → sorted}/eql_spec.rb +1 -1
  249. data/spec/unit/axiom/relation/operation/{order → sorted}/header_spec.rb +1 -1
  250. data/spec/unit/axiom/relation/operation/{order → sorted}/insert_spec.rb +12 -6
  251. data/spec/unit/axiom/relation/operation/{order → sorted}/methods/sort_by_spec.rb +24 -24
  252. data/spec/unit/axiom/relation/operation/sorted/methods/sort_spec.rb +19 -0
  253. data/spec/unit/axiom/relation/operation/ungroup/each_spec.rb +33 -0
  254. data/spec/unit/axiom/relation/operation/ungroup/header_spec.rb +19 -0
  255. data/spec/unit/axiom/relation/operation/ungroup/methods/ungroup_spec.rb +21 -0
  256. data/spec/unit/axiom/relation/operation/unwrap/each_spec.rb +33 -0
  257. data/spec/unit/axiom/relation/operation/unwrap/header_spec.rb +19 -0
  258. data/spec/unit/axiom/relation/operation/unwrap/methods/unwrap_spec.rb +21 -0
  259. data/spec/unit/axiom/relation/operation/wrap/each_spec.rb +33 -0
  260. data/spec/unit/axiom/relation/operation/wrap/header_spec.rb +22 -0
  261. data/spec/unit/axiom/relation/operation/wrap/methods/wrap_spec.rb +25 -0
  262. data/spec/unit/axiom/relation/proxy/each_spec.rb +2 -2
  263. data/spec/unit/axiom/relation/proxy/respond_to_predicate_spec.rb +48 -12
  264. data/spec/unit/axiom/relation/replace_spec.rb +8 -8
  265. data/spec/unit/axiom/tuple/class_methods/coerce_spec.rb +7 -1
  266. data/spec/unit/axiom/tuple/{call_spec.rb → fetch_spec.rb} +1 -1
  267. data/spec/unit/axiom/tuple/inspect_spec.rb +14 -0
  268. data/spec/unit/axiom/tuple/rename_spec.rb +17 -0
  269. data/spec/unit/axiom/tuple/size_spec.rb +14 -0
  270. data/spec/unit/axiom/tuple/to_ary_spec.rb +22 -5
  271. data/spec/unit/axiom/tuple/to_hash_spec.rb +14 -0
  272. data/spec/unit/axiom/types/relation/class_methods/primitive_spec.rb +13 -0
  273. data/spec/unit/axiom/types/tuple/class_methods/primitive_spec.rb +13 -0
  274. data/spec/unit/axiom/visitable/accept_spec.rb +1 -1
  275. data/spec/unit/date/pred_spec.rb +1 -1
  276. data/spec/unit/time/pred_spec.rb +1 -1
  277. metadata +631 -107
  278. data/spec/unit/axiom/aggregate/hash_spec.rb +0 -15
  279. data/spec/unit/axiom/algebra/extension/hash_spec.rb +0 -15
  280. data/spec/unit/axiom/algebra/projection/hash_spec.rb +0 -16
  281. data/spec/unit/axiom/algebra/rename/aliases/hash_spec.rb +0 -15
  282. data/spec/unit/axiom/algebra/rename/hash_spec.rb +0 -15
  283. data/spec/unit/axiom/algebra/restriction/hash_spec.rb +0 -15
  284. data/spec/unit/axiom/algebra/summarization/hash_spec.rb +0 -16
  285. data/spec/unit/axiom/attribute/hash_spec.rb +0 -21
  286. data/spec/unit/axiom/attribute/numeric/hash_spec.rb +0 -17
  287. data/spec/unit/axiom/attribute/string/hash_spec.rb +0 -25
  288. data/spec/unit/axiom/equalizer/methods/eql_spec.rb +0 -49
  289. data/spec/unit/axiom/equalizer/methods/equality_operator_spec.rb +0 -85
  290. data/spec/unit/axiom/function/binary/invertible/class_methods/included_spec.rb +0 -29
  291. data/spec/unit/axiom/function/predicate/hash_spec.rb +0 -16
  292. data/spec/unit/axiom/function/predicate/inverse_spec.rb +0 -17
  293. data/spec/unit/axiom/function/proposition/hash_spec.rb +0 -14
  294. data/spec/unit/axiom/function/unary/hash_spec.rb +0 -18
  295. data/spec/unit/axiom/function/unary/invertible/class_methods/included_spec.rb +0 -29
  296. data/spec/unit/axiom/operation/binary/hash_spec.rb +0 -16
  297. data/spec/unit/axiom/operation/unary/hash_spec.rb +0 -15
  298. data/spec/unit/axiom/relation/base/hash_spec.rb +0 -16
  299. data/spec/unit/axiom/relation/hash_spec.rb +0 -19
  300. data/spec/unit/axiom/relation/header/hash_spec.rb +0 -15
  301. data/spec/unit/axiom/relation/operation/limit/hash_spec.rb +0 -16
  302. data/spec/unit/axiom/relation/operation/offset/hash_spec.rb +0 -16
  303. data/spec/unit/axiom/relation/operation/order/ascending/class_methods/reverse_spec.rb +0 -11
  304. data/spec/unit/axiom/relation/operation/order/descending/class_methods/reverse_spec.rb +0 -11
  305. data/spec/unit/axiom/relation/operation/order/direction/hash_spec.rb +0 -15
  306. data/spec/unit/axiom/relation/operation/order/direction_set/hash_spec.rb +0 -15
  307. data/spec/unit/axiom/relation/operation/order/hash_spec.rb +0 -15
  308. data/spec/unit/axiom/relation/operation/order/methods/sort_spec.rb +0 -19
  309. data/spec/unit/axiom/relation/proxy/hash_spec.rb +0 -26
  310. data/spec/unit/axiom/relation/proxy/method_missing_spec.rb +0 -24
  311. data/spec/unit/axiom/tuple/hash_spec.rb +0 -15
@@ -5,7 +5,7 @@ module Axiom
5
5
  module Operation
6
6
 
7
7
  # A class representing a reverse sorted relation
8
- class Reverse < Order
8
+ class Reverse < Sorted
9
9
 
10
10
  # Instantiate a new Reverse relation
11
11
  #
@@ -18,27 +18,27 @@ module Axiom
18
18
  #
19
19
  # @api public
20
20
  def self.new(operand)
21
- assert_ordered_operand(operand)
21
+ assert_sorted_operand(operand)
22
22
  super(operand, operand.directions.reverse)
23
23
  end
24
24
 
25
- # Assert the operand is ordered
25
+ # Assert the operand is sorted
26
26
  #
27
27
  # @param [Relation] operand
28
28
  #
29
29
  # @return [undefined]
30
30
  #
31
- # @raise [OrderedRelationRequiredError]
32
- # raise if the operand is unordered
31
+ # @raise [SortededRelationRequiredError]
32
+ # raise if the operand is unsorted
33
33
  #
34
34
  # @api private
35
- def self.assert_ordered_operand(operand)
36
- if operand.header.to_ary.size != operand.directions.to_ary.size
37
- raise OrderedRelationRequiredError, 'can only reverse an ordered operand'
35
+ def self.assert_sorted_operand(operand)
36
+ if operand.header.size != operand.directions.size
37
+ fail SortededRelationRequiredError, 'can only reverse a sorted operand'
38
38
  end
39
39
  end
40
40
 
41
- private_class_method :assert_ordered_operand
41
+ private_class_method :assert_sorted_operand
42
42
 
43
43
  # Iterate over each tuple in the set
44
44
  #
@@ -68,7 +68,7 @@ module Axiom
68
68
  # @api private
69
69
  def assert_equivalent_headers(left, right)
70
70
  if left.header != right.header
71
- raise InvalidHeaderError, 'the headers must be equivalent'
71
+ fail InvalidHeaderError, 'the headers must be equivalent'
72
72
  end
73
73
  end
74
74
 
@@ -5,28 +5,28 @@ module Axiom
5
5
  module Operation
6
6
 
7
7
  # A class representing a sorted relation
8
- class Order < Relation
8
+ class Sorted < Relation
9
9
  include Unary
10
10
  include Equalizer.new(:operand, :directions)
11
11
 
12
12
  # The relation sort order
13
13
  #
14
- # @return [Operation::Order::DirectionSet]
14
+ # @return [Operation::Sorted::DirectionSet]
15
15
  #
16
16
  # @api private
17
17
  attr_reader :directions
18
18
 
19
- # Instantiate a new Order
19
+ # Instantiate a new Sorted
20
20
  #
21
21
  # @example
22
- # order = Order.new(operand, directions)
22
+ # sorted = Sorted.new(operand, directions)
23
23
  #
24
24
  # @param [Relation] operand
25
25
  # the relation to sort
26
26
  # @param [DirectionSet, Header, Array<Direction, Attribute>] directions
27
27
  # the directions to sort tuples in
28
28
  #
29
- # @return [Order]
29
+ # @return [Sorted]
30
30
  #
31
31
  # @api public
32
32
  def self.new(operand, directions)
@@ -34,11 +34,12 @@ module Axiom
34
34
  directions = DirectionSet.coerce(directions) do |direction|
35
35
  header[direction] unless direction.kind_of?(Direction)
36
36
  end
37
- directions |= header - directions.attributes
37
+ new_directions = directions | header - directions.attributes
38
+ directions = new_directions if new_directions != directions
38
39
  super
39
40
  end
40
41
 
41
- # Initialize an Order
42
+ # Initialize an Sorted
42
43
  #
43
44
  # @param [Relation] operand
44
45
  # the relation to sort
@@ -56,8 +57,8 @@ module Axiom
56
57
  # Iterate over each tuple in the set
57
58
  #
58
59
  # @example
59
- # order = Order.new(operand, directions)
60
- # order.each { |tuple| ... }
60
+ # sorted = Sorted.new(operand, directions)
61
+ # sorted.each { |tuple| ... }
61
62
  #
62
63
  # @yield [tuple]
63
64
  #
@@ -73,14 +74,14 @@ module Axiom
73
74
  self
74
75
  end
75
76
 
76
- # Insert a relation into the Order
77
+ # Insert a relation into the Sorted
77
78
  #
78
79
  # @example
79
- # new_relation = order.insert(other)
80
+ # new_relation = sorted.insert(other)
80
81
  #
81
82
  # @param [Relation] other
82
83
  #
83
- # @return [Order]
84
+ # @return [Sorted]
84
85
  #
85
86
  # @api public
86
87
  def insert(other)
@@ -88,14 +89,14 @@ module Axiom
88
89
  operand.insert(other.operand).sort_by(directions)
89
90
  end
90
91
 
91
- # Delete a relation from the Order
92
+ # Delete a relation from the Sorted
92
93
  #
93
94
  # @example
94
- # new_relation = order.delete(other)
95
+ # new_relation = sorted.delete(other)
95
96
  #
96
97
  # @param [Relation] other
97
98
  #
98
- # @return [Order]
99
+ # @return [Sorted]
99
100
  #
100
101
  # @api public
101
102
  def delete(other)
@@ -113,25 +114,25 @@ module Axiom
113
114
  #
114
115
  # @return [undefined]
115
116
  #
116
- # @raise [OrderMismatchError]
117
+ # @raise [SortedMismatchError]
117
118
  # raised when inserting a relation does not have matching directions
118
119
  #
119
120
  # @api private
120
121
  def assert_matching_directions(other, event)
121
- unless other.kind_of?(self.class) && directions.eql?(other.directions)
122
- raise OrderMismatchError, "other relation must have matching directions to be #{event}"
122
+ unless other.respond_to?(:directions) && directions.eql?(other.directions)
123
+ fail SortedMismatchError, "other relation must have matching directions to be #{event}"
123
124
  end
124
125
  end
125
126
 
126
127
  module Methods
127
128
 
128
- # Return an ordered relation
129
+ # Return a sorted relation
129
130
  #
130
131
  # @example with a block
131
- # order = relation.sort_by { |r| [r.a.desc, r.b] }
132
+ # sorted = relation.sort_by { |r| [r.a.desc, r.b] }
132
133
  #
133
134
  # @example with directions
134
- # order = relation.sort_by(directions)
135
+ # sorted = relation.sort_by(directions)
135
136
  #
136
137
  # @param [Array] args
137
138
  # optional arguments
@@ -143,23 +144,23 @@ module Axiom
143
144
  #
144
145
  # @yieldreturn [DirectionSet, Array<Direction>, Header]
145
146
  #
146
- # @return [Order]
147
+ # @return [Sorted]
147
148
  #
148
149
  # @api public
149
150
  def sort_by(*args, &block)
150
- Order.new(self, coerce_to_directions(*args, &block))
151
+ Sorted.new(self, coerce_to_directions(*args, &block))
151
152
  end
152
153
 
153
- # Return an ordered relation
154
+ # Return a sorted relation
154
155
  #
155
156
  # @example
156
- # order = relation.sort
157
+ # sorted = relation.sort
157
158
  #
158
- # @return [Order]
159
+ # @return [Sorted]
159
160
  #
160
161
  # @api public
161
162
  def sort
162
- Order.new(self, EMPTY_ARRAY)
163
+ Sorted.new(self, nil)
163
164
  end
164
165
 
165
166
  private
@@ -191,7 +192,7 @@ module Axiom
191
192
 
192
193
  Relation.class_eval { include Methods }
193
194
 
194
- end # class Order
195
+ end # class Sorted
195
196
  end # module Operation
196
197
  end # class Relation
197
198
  end # module Axiom
@@ -3,7 +3,7 @@
3
3
  module Axiom
4
4
  class Relation
5
5
  module Operation
6
- class Order
6
+ class Sorted
7
7
 
8
8
  # Abstract base class for attribute sorting
9
9
  class Direction
@@ -139,7 +139,7 @@ module Axiom
139
139
  #
140
140
  # @api private
141
141
  def self.call(left, right)
142
- left <=> right
142
+ left <=> right || (1 if left.nil?) || (-1 if right.nil?)
143
143
  end
144
144
 
145
145
  end # class Ascending
@@ -172,11 +172,11 @@ module Axiom
172
172
  #
173
173
  # @api private
174
174
  def self.call(left, right)
175
- right <=> left
175
+ right <=> left || (1 if right.nil?) || (-1 if left.nil?)
176
176
  end
177
177
 
178
178
  end # class Descending
179
- end # class Order
179
+ end # class Sorted
180
180
  end # module Operation
181
181
  end # class Relation
182
182
  end # module Axiom
@@ -3,7 +3,7 @@
3
3
  module Axiom
4
4
  class Relation
5
5
  module Operation
6
- class Order
6
+ class Sorted
7
7
 
8
8
  # A class that represents a tuple sort order for a set of attributes
9
9
  class DirectionSet < Header
@@ -90,7 +90,7 @@ module Axiom
90
90
  # @api private
91
91
  def cmp_tuples(left, right)
92
92
  reduce(0) do |cmp, direction|
93
- break cmp if cmp.nonzero?
93
+ return cmp if cmp.nonzero?
94
94
  direction.call(left, right)
95
95
  end
96
96
  end
@@ -101,7 +101,7 @@ module Axiom
101
101
  EMPTY = new
102
102
 
103
103
  end # class DirectionSet
104
- end # class Order
104
+ end # class Sorted
105
105
  end # module Operation
106
106
  end # class Relation
107
107
  end # module Axiom
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+ module Operation
6
+
7
+ # A class representing an ungrouped relation
8
+ class Ungroup < Relation
9
+ include Unary
10
+ include Equalizer.new(:operand, :attribute)
11
+
12
+ # The grouped attribute
13
+ #
14
+ # @return [Attribute::Relation]
15
+ #
16
+ # @api private
17
+ attr_reader :attribute
18
+
19
+ # Initialize an ungrouped relation
20
+ #
21
+ # @param [Relation] operand
22
+ # @param [#to_sym] name
23
+ #
24
+ # @return [undefined]
25
+ #
26
+ # @api private
27
+ def initialize(operand, name)
28
+ super(operand)
29
+ @attribute = header[name]
30
+ @outer = header - [attribute]
31
+ @header = @outer.extend(attribute.header)
32
+ end
33
+
34
+ # Iterate over each tuple in the set
35
+ #
36
+ # @example
37
+ # ungrouped = Ungroup.new(operand, name)
38
+ # ungrouped.each { |tuple| ... }
39
+ #
40
+ # @yield [tuple]
41
+ #
42
+ # @yieldparam [Tuple] tuple
43
+ # each tuple in the set
44
+ #
45
+ # @return [self]
46
+ #
47
+ # @api public
48
+ def each
49
+ return to_enum unless block_given?
50
+ operand.each do |tuple|
51
+ outer_tuple = tuple.project(@outer)
52
+ tuple[attribute].each do |inner_tuple|
53
+ yield outer_tuple.join(header, inner_tuple)
54
+ end
55
+ end
56
+ self
57
+ end
58
+
59
+ module Methods
60
+
61
+ # Return an ungrouped relation
62
+ #
63
+ # @example
64
+ # ungrouped = relation.ungroup(:location, :names)
65
+ #
66
+ # @param [Enumerable<#to_sym>] names
67
+ #
68
+ # @return [Ungroup]
69
+ #
70
+ # @api public
71
+ def ungroup(*names)
72
+ names.reduce(self, &Ungroup.method(:new))
73
+ end
74
+
75
+ end # module Methods
76
+
77
+ Relation.class_eval { include Methods }
78
+
79
+ end # class Ungroup
80
+ end # module Operation
81
+ end # class Relation
82
+ end # module Axiom
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+ module Operation
6
+
7
+ # A class representing a unwrapped relation
8
+ class Unwrap < Relation
9
+ include Unary
10
+ include Equalizer.new(:operand, :attribute)
11
+
12
+ # The unwrapped attribute
13
+ #
14
+ # @return [Attribute::Relation]
15
+ #
16
+ # @api private
17
+ attr_reader :attribute
18
+
19
+ # Initialize a unwrapped relation
20
+ #
21
+ # @param [Relation] operand
22
+ # @param [#to_sym] name
23
+ # @param [Enumerable<Axiom::Attribute>] attributes
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ def initialize(operand, name)
29
+ super(operand)
30
+ @attribute = header[name]
31
+ @outer = header - [attribute]
32
+ @header = @outer.extend(attribute.header)
33
+ end
34
+
35
+ # Iterate over each tuple in the set
36
+ #
37
+ # @example
38
+ # unwrapped = Unwrap.new(left, right)
39
+ # unwrapped.each { |tuple| ... }
40
+ #
41
+ # @yield [tuple]
42
+ #
43
+ # @yieldparam [Tuple] tuple
44
+ # each tuple in the set
45
+ #
46
+ # @return [self]
47
+ #
48
+ # @api public
49
+ def each
50
+ return to_enum unless block_given?
51
+ operand.each do |tuple|
52
+ yield tuple.project(@outer).join(header, tuple[attribute])
53
+ end
54
+ self
55
+ end
56
+
57
+ module Methods
58
+
59
+ # Return a unwrapped relation
60
+ #
61
+ # @example
62
+ # unwrapped = relation.unwrap(:location, :names)
63
+ #
64
+ # @param [Enumerable<#to_sym>] names
65
+ #
66
+ # @return [Unwrap]
67
+ #
68
+ # @api public
69
+ def unwrap(*names)
70
+ names.reduce(self, &Unwrap.method(:new))
71
+ end
72
+
73
+ end # module Methods
74
+
75
+ Relation.class_eval { include Methods }
76
+
77
+ end # class Unwrap
78
+ end # module Operation
79
+ end # class Relation
80
+ end # module Axiom
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+ module Operation
6
+
7
+ # A class representing a wrapped relation
8
+ class Wrap < Relation
9
+ include Unary
10
+ include Equalizer.new(:operand, :attribute)
11
+
12
+ # The wrapped attribute
13
+ #
14
+ # @return [Attribute::Relation]
15
+ #
16
+ # @api private
17
+ attr_reader :attribute
18
+
19
+ # Initialize a wrapped relation
20
+ #
21
+ # @param [Relation] operand
22
+ # @param [#to_sym] name
23
+ # @param [Enumerable<Axiom::Attribute>] attributes
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ def initialize(operand, name, attributes)
29
+ super(operand)
30
+ inner = header.project(attributes)
31
+ @outer = header - inner
32
+ @attribute = Attribute::Tuple.new(name, header: inner)
33
+ @header = @outer.extend(attribute)
34
+ end
35
+
36
+ # Iterate over each tuple in the set
37
+ #
38
+ # @example
39
+ # wrapped = Wrap.new(operand, name attributes)
40
+ # wrapped.each { |tuple| ... }
41
+ #
42
+ # @yield [tuple]
43
+ #
44
+ # @yieldparam [Tuple] tuple
45
+ # each tuple in the set
46
+ #
47
+ # @return [self]
48
+ #
49
+ # @api public
50
+ def each
51
+ return to_enum unless block_given?
52
+ operand.each do |tuple|
53
+ outer_tuple = tuple.project(@outer)
54
+ inner_tuple = tuple.project(attribute.header)
55
+ yield outer_tuple.extend(header, [inner_tuple])
56
+ end
57
+ self
58
+ end
59
+
60
+ module Methods
61
+
62
+ # Return a wrapped relation
63
+ #
64
+ # @example
65
+ # wrapped = relation.wrap(location: [:latitude, :longitude])
66
+ #
67
+ # @param [Hash{#to_sym => Enumerable<Axiom::Attribute>] wrapping
68
+ #
69
+ # @return [Wrap]
70
+ #
71
+ # @api public
72
+ def wrap(wrapping)
73
+ wrapping.reduce(self) do |operation, pair|
74
+ Wrap.new(operation, *pair)
75
+ end
76
+ end
77
+
78
+ end # module Methods
79
+
80
+ Relation.class_eval { include Methods }
81
+
82
+ end # class Wrap
83
+ end # module Operation
84
+ end # class Relation
85
+ end # module Axiom