veritas 0.0.4 → 0.0.5
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.
- data/.travis.yml +4 -2
- data/Gemfile +7 -8
- data/README.rdoc +17 -18
- data/Rakefile +2 -2
- data/TODO +18 -14
- data/benchmarks/memory.rb +8 -7
- data/benchmarks/speed.rb +4 -3
- data/config/flay.yml +1 -1
- data/lib/veritas/aggregate.rb +3 -0
- data/lib/veritas/algebra/join.rb +11 -4
- data/lib/veritas/algebra/product.rb +2 -1
- data/lib/veritas/algebra/restriction.rb +3 -2
- data/lib/veritas/algebra/summarization.rb +8 -3
- data/lib/veritas/attribute/string.rb +3 -1
- data/lib/veritas/attribute.rb +1 -1
- data/lib/veritas/function/binary.rb +1 -0
- data/lib/veritas/function/comparable.rb +1 -0
- data/lib/veritas/function/connective/negation.rb +2 -0
- data/lib/veritas/function/proposition.rb +5 -1
- data/lib/veritas/function/unary.rb +1 -0
- data/lib/veritas/function.rb +3 -0
- data/lib/veritas/relation/base.rb +32 -3
- data/lib/veritas/relation/header.rb +2 -2
- data/lib/veritas/relation/materialized.rb +12 -0
- data/lib/veritas/relation/operation/binary.rb +1 -0
- data/lib/veritas/relation/operation/limit.rb +1 -1
- data/lib/veritas/relation/operation/offset.rb +1 -1
- data/lib/veritas/relation/operation/order/direction_set.rb +67 -5
- data/lib/veritas/relation/operation/order.rb +25 -3
- data/lib/veritas/relation/operation/set.rb +1 -0
- data/lib/veritas/relation.rb +20 -7
- data/lib/veritas/support/abstract_class.rb +1 -0
- data/lib/veritas/support/evaluator.rb +49 -3
- data/lib/veritas/support/immutable.rb +2 -1
- data/lib/veritas/tuple.rb +28 -14
- data/lib/veritas/version.rb +1 -1
- data/lib/veritas.rb +6 -3
- data/spec/integration/veritas/algebra/projection_spec.rb +4 -4
- data/spec/integration/veritas/relation/efficient_enumerable_spec.rb +1 -1
- data/spec/shared/each_method_behaviour.rb +2 -2
- data/spec/shared/hash_method_behavior.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/date/pred_spec.rb +3 -3
- data/spec/unit/range/overlaps_spec.rb +14 -14
- data/spec/unit/range/to_inclusive_spec.rb +2 -2
- data/spec/unit/time/pred_spec.rb +3 -3
- data/spec/unit/veritas/abstract_class/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/count/class_methods/call_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/count/methods/count_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/maximum/methods/maximum_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/mean/class_methods/call_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/mean/methods/mean_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/minimum/methods/minimum_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/standard_deviation/methods/standard_deviation_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/sum/class_methods/call_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/sum/methods/sum_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/variance/class_methods/call_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/variance/methods/variance_spec.rb +1 -1
- data/spec/unit/veritas/algebra/difference/methods/difference_spec.rb +2 -2
- data/spec/unit/veritas/algebra/extension/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/algebra/extension/eql_spec.rb +5 -5
- data/spec/unit/veritas/algebra/extension/header_spec.rb +1 -1
- data/spec/unit/veritas/algebra/extension/methods/extend_spec.rb +1 -1
- data/spec/unit/veritas/algebra/intersection/methods/intersect_spec.rb +2 -2
- data/spec/unit/veritas/algebra/join/class_methods/new_spec.rb +2 -2
- data/spec/unit/veritas/algebra/join/join_header_spec.rb +17 -0
- data/spec/unit/veritas/algebra/join/methods/join_spec.rb +2 -2
- data/spec/unit/veritas/algebra/product/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/algebra/product/methods/product_spec.rb +1 -1
- data/spec/unit/veritas/algebra/projection/eql_spec.rb +5 -5
- data/spec/unit/veritas/algebra/projection/header_spec.rb +1 -1
- data/spec/unit/veritas/algebra/projection/methods/project_spec.rb +1 -1
- data/spec/unit/veritas/algebra/projection/methods/remove_spec.rb +1 -1
- data/spec/unit/veritas/algebra/rename/aliases/class_methods/coerce_spec.rb +4 -4
- data/spec/unit/veritas/algebra/rename/aliases/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/algebra/rename/aliases/eql_spec.rb +4 -4
- data/spec/unit/veritas/algebra/rename/aliases/equal_value_spec.rb +4 -4
- data/spec/unit/veritas/algebra/rename/aliases/to_hash_spec.rb +1 -1
- data/spec/unit/veritas/algebra/rename/aliases/union_spec.rb +10 -10
- data/spec/unit/veritas/algebra/rename/directions_spec.rb +3 -3
- data/spec/unit/veritas/algebra/rename/eql_spec.rb +5 -5
- data/spec/unit/veritas/algebra/rename/header_spec.rb +1 -1
- data/spec/unit/veritas/algebra/rename/methods/rename_spec.rb +1 -1
- data/spec/unit/veritas/algebra/restriction/eql_spec.rb +5 -5
- data/spec/unit/veritas/algebra/restriction/methods/restrict_spec.rb +1 -1
- data/spec/unit/veritas/algebra/summarization/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/algebra/summarization/eql_spec.rb +7 -7
- data/spec/unit/veritas/algebra/summarization/header_spec.rb +1 -1
- data/spec/unit/veritas/algebra/summarization/methods/summarize_spec.rb +18 -8
- data/spec/unit/veritas/algebra/summarization/summaries/summarize_by_spec.rb +3 -3
- data/spec/unit/veritas/algebra/summarization/summaries/to_hash_spec.rb +2 -2
- data/spec/unit/veritas/algebra/summarization/summary/summarize_by_spec.rb +1 -1
- data/spec/unit/veritas/algebra/union/methods/union_spec.rb +2 -2
- data/spec/unit/veritas/aliasable/inheritable_alias_spec.rb +2 -2
- data/spec/unit/veritas/attribute/class_methods/coerce_spec.rb +4 -4
- data/spec/unit/veritas/attribute/class_methods/descendants_spec.rb +2 -6
- data/spec/unit/veritas/attribute/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/attribute/comparable/comparable_spec.rb +3 -3
- data/spec/unit/veritas/attribute/eql_spec.rb +4 -4
- data/spec/unit/veritas/attribute/equal_value_spec.rb +4 -4
- data/spec/unit/veritas/attribute/inspect_spec.rb +1 -1
- data/spec/unit/veritas/attribute/joinable_spec.rb +4 -4
- data/spec/unit/veritas/attribute/numeric/joinable_spec.rb +3 -3
- data/spec/unit/veritas/attribute/options_spec.rb +2 -2
- data/spec/unit/veritas/attribute/orderable/asc_spec.rb +1 -1
- data/spec/unit/veritas/attribute/orderable/desc_spec.rb +1 -1
- data/spec/unit/veritas/attribute/rename_spec.rb +1 -1
- data/spec/unit/veritas/attribute/string/joinable_spec.rb +14 -4
- data/spec/unit/veritas/evaluator/context/method_missing_spec.rb +29 -0
- data/spec/unit/veritas/evaluator/context/respond_to_spec.rb +39 -0
- data/spec/unit/veritas/evaluator/context/send_spec.rb +28 -0
- data/spec/unit/veritas/evaluator/context/yield_spec.rb +14 -0
- data/spec/unit/veritas/function/binary/equal_value_spec.rb +5 -5
- data/spec/unit/veritas/function/binary/invertible/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/binary/rename_spec.rb +3 -3
- data/spec/unit/veritas/function/connective/conjunction/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/connective/disjunction/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/connective/negation/methods/not_spec.rb +2 -2
- data/spec/unit/veritas/function/numeric/absolute/methods/absolute_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/addition/methods/add_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/division/methods/divide_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/exponentiation/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/exponentiation/methods/exponent_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/modulo/methods/modulo_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/multiplication/methods/multiply_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/square_root/methods/square_root_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/subtraction/methods/subtract_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/unary_minus/methods/unary_minus_spec.rb +1 -1
- data/spec/unit/veritas/function/numeric/unary_plus/methods/unary_plus_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/eql_spec.rb +5 -5
- data/spec/unit/veritas/function/predicate/equality/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/equality/methods/eq_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/exclusion/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/exclusion/methods/exclude_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/greater_than/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/greater_than/methods/gt_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/greater_than_or_equal_to/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/greater_than_or_equal_to/methods/gte_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/inclusion/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/inclusion/methods/include_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/inequality/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/inequality/methods/ne_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/less_than/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/less_than/methods/lt_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/less_than_or_equal_to/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/less_than_or_equal_to/methods/lte_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/match/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/match/methods/match_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/no_match/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/no_match/methods/no_match_spec.rb +1 -1
- data/spec/unit/veritas/function/proposition/eql_spec.rb +3 -3
- data/spec/unit/veritas/function/proposition/equal_value_spec.rb +3 -3
- data/spec/unit/veritas/function/string/length/methods/length_spec.rb +1 -1
- data/spec/unit/veritas/function/unary/equal_value_spec.rb +4 -4
- data/spec/unit/veritas/function/unary/invertible/inverse_spec.rb +1 -1
- data/spec/unit/veritas/function/unary/rename_spec.rb +1 -1
- data/spec/unit/veritas/immutable/class_methods/freeze_object_spec.rb +7 -1
- data/spec/unit/veritas/immutable/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/immutable/freeze_spec.rb +2 -2
- data/spec/unit/veritas/immutable/module_methods/memoize_spec.rb +2 -2
- data/spec/unit/veritas/operation/binary/eql_spec.rb +5 -5
- data/spec/unit/veritas/operation/unary/eql_spec.rb +4 -4
- data/spec/unit/veritas/relation/base/class_methods/new_spec.rb +35 -0
- data/spec/unit/veritas/relation/base/eql_spec.rb +100 -0
- data/spec/unit/veritas/relation/base/hash_spec.rb +16 -0
- data/spec/unit/veritas/relation/class_methods/new_spec.rb +2 -2
- data/spec/unit/veritas/relation/directions_spec.rb +1 -1
- data/spec/unit/veritas/relation/eql_spec.rb +15 -15
- data/spec/unit/veritas/relation/equal_value_spec.rb +16 -16
- data/spec/unit/veritas/relation/header/class_methods/coerce_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/class_methods/new_spec.rb +2 -2
- data/spec/unit/veritas/relation/header/difference_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/eql_spec.rb +5 -5
- data/spec/unit/veritas/relation/header/equal_value_spec.rb +7 -7
- data/spec/unit/veritas/relation/header/inspect_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/intersect_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/project_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/rename_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/to_ary_spec.rb +1 -1
- data/spec/unit/veritas/relation/header/union_spec.rb +1 -1
- data/spec/unit/veritas/relation/materialize_spec.rb +3 -3
- data/spec/unit/veritas/relation/materialized/class_methods/new_spec.rb +2 -2
- data/spec/unit/veritas/relation/materialized/materialized_spec.rb +15 -0
- data/spec/unit/veritas/relation/materialized_spec.rb +15 -0
- data/spec/unit/veritas/relation/operation/binary/class_methods/new_spec.rb +6 -6
- data/spec/unit/veritas/relation/operation/binary/header_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/combination/header_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/limit/class_methods/new_spec.rb +12 -5
- data/spec/unit/veritas/relation/operation/limit/directions_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/limit/each_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/limit/eql_spec.rb +11 -11
- data/spec/unit/veritas/relation/operation/limit/hash_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/limit/limit_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/limit/methods/first_spec.rb +3 -3
- data/spec/unit/veritas/relation/operation/limit/methods/last_spec.rb +3 -3
- data/spec/unit/veritas/relation/operation/limit/methods/take_spec.rb +2 -2
- data/spec/unit/veritas/relation/operation/offset/class_methods/new_spec.rb +12 -5
- data/spec/unit/veritas/relation/operation/offset/directions_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/offset/each_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/offset/eql_spec.rb +11 -11
- data/spec/unit/veritas/relation/operation/offset/hash_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/offset/methods/drop_spec.rb +2 -2
- data/spec/unit/veritas/relation/operation/offset/offset_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/ascending/reverse_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/class_methods/new_spec.rb +3 -7
- data/spec/unit/veritas/relation/operation/order/descending/reverse_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction/class_methods/coerce_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction/eql_spec.rb +4 -4
- data/spec/unit/veritas/relation/operation/order/direction/rename_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction_set/attributes_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction_set/class_methods/coerce_spec.rb +4 -4
- data/spec/unit/veritas/relation/operation/order/direction_set/class_methods/new_spec.rb +32 -0
- data/spec/unit/veritas/relation/operation/order/direction_set/eql_spec.rb +4 -4
- data/spec/unit/veritas/relation/operation/order/direction_set/equal_value_spec.rb +6 -6
- data/spec/unit/veritas/relation/operation/order/direction_set/project_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction_set/rename_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction_set/reverse_spec.rb +2 -2
- data/spec/unit/veritas/relation/operation/order/direction_set/sort_tuples_spec.rb +4 -4
- data/spec/unit/veritas/relation/operation/order/direction_set/to_ary_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/direction_set/union_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/order/eql_spec.rb +5 -5
- data/spec/unit/veritas/relation/operation/order/methods/order_spec.rb +24 -4
- data/spec/unit/veritas/relation/operation/order/methods/sort_by_spec.rb +28 -0
- data/spec/unit/veritas/relation/operation/reverse/class_methods/new_spec.rb +6 -6
- data/spec/unit/veritas/relation/operation/reverse/directions_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/reverse/each_spec.rb +1 -1
- data/spec/unit/veritas/relation/operation/reverse/methods/reverse_spec.rb +2 -2
- data/spec/unit/veritas/relation/operation/set/class_methods/new_spec.rb +1 -1
- data/spec/unit/veritas/tuple/class_methods/coerce_spec.rb +1 -1
- data/spec/unit/veritas/tuple/data_spec.rb +16 -0
- data/spec/unit/veritas/tuple/element_reference_spec.rb +1 -1
- data/spec/unit/veritas/tuple/eql_spec.rb +5 -5
- data/spec/unit/veritas/tuple/equal_value_spec.rb +7 -7
- data/spec/unit/veritas/tuple/extend_spec.rb +3 -3
- data/spec/unit/veritas/tuple/hash_spec.rb +1 -1
- data/spec/unit/veritas/tuple/inspect_spec.rb +2 -2
- data/spec/unit/veritas/tuple/join_spec.rb +1 -1
- data/spec/unit/veritas/tuple/predicate_spec.rb +44 -0
- data/spec/unit/veritas/tuple/project_spec.rb +1 -1
- data/spec/unit/veritas/tuple/to_ary_spec.rb +3 -1
- data/tasks/metrics/heckle.rake +1 -0
- data/veritas.gemspec +28 -14
- metadata +31 -17
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -3,19 +3,18 @@
|
|
|
3
3
|
source :rubygems
|
|
4
4
|
|
|
5
5
|
group :development do
|
|
6
|
-
gem 'backports', '~> 2.
|
|
7
|
-
gem 'jeweler', '~> 1.6.
|
|
8
|
-
gem 'rake', '~> 0.9.
|
|
6
|
+
gem 'backports', '~> 2.3.0'
|
|
7
|
+
gem 'jeweler', '~> 1.6.4'
|
|
8
|
+
gem 'rake', '~> 0.9.2'
|
|
9
9
|
gem 'rspec', '~> 1.3.2'
|
|
10
|
-
gem 'yard', '~> 0.7.
|
|
10
|
+
gem 'yard', '~> 0.7.2'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
group :guard do
|
|
14
|
-
gem '
|
|
15
|
-
gem 'guard', '~> 0.3.4'
|
|
14
|
+
gem 'guard', '~> 0.5.1'
|
|
16
15
|
gem 'guard-bundler', '~> 0.1.3'
|
|
17
16
|
gem 'guard-ego', '~> 0.0.1'
|
|
18
|
-
gem 'guard-rspec', '~> 0.
|
|
17
|
+
gem 'guard-rspec', '~> 0.4.0'
|
|
19
18
|
end
|
|
20
19
|
|
|
21
20
|
group :benchmarks do
|
|
@@ -33,7 +32,7 @@ platforms :mri_18 do
|
|
|
33
32
|
gem 'flay', '~> 1.4.2'
|
|
34
33
|
gem 'flog', '~> 2.5.1'
|
|
35
34
|
gem 'heckle', '~> 1.4.3'
|
|
36
|
-
gem 'json', '~> 1.5.
|
|
35
|
+
gem 'json', '~> 1.5.3'
|
|
37
36
|
gem 'metric_fu', '~> 2.1.1'
|
|
38
37
|
gem 'mspec', '~> 1.5.17'
|
|
39
38
|
gem 'rcov', '~> 0.9.9'
|
data/README.rdoc
CHANGED
|
@@ -36,19 +36,19 @@ http://travis-ci.org/dkubb/veritas.png
|
|
|
36
36
|
new_relation = relation.difference(other) # OR relation - other
|
|
37
37
|
|
|
38
38
|
# restriction
|
|
39
|
-
new_relation = relation.restrict { |r| r
|
|
39
|
+
new_relation = relation.restrict { |r| r.a.eq('other').and(r.b.gte(42)) }
|
|
40
40
|
|
|
41
41
|
# theta-join
|
|
42
|
-
new_relation = relation.join(other) { |r| r
|
|
42
|
+
new_relation = relation.join(other) { |r| r.a.gte(r.b) }
|
|
43
43
|
|
|
44
44
|
# NOTE: theta-join is effectively restricting a product of the relations
|
|
45
45
|
|
|
46
46
|
# extend
|
|
47
|
-
new_relation = relation.extend { |r| r.add(:total, r
|
|
47
|
+
new_relation = relation.extend { |r| r.add(:total, r.unit_price * r.quantity) }
|
|
48
48
|
new_relation = relation.extend { |r| r.add(:total) { |t| t[:unit_price] * t[:quantity] } }
|
|
49
49
|
|
|
50
50
|
# summarize
|
|
51
|
-
new_relation = relation.summarize(relation.project([ :name ])) { |r| r.add(:count, r
|
|
51
|
+
new_relation = relation.summarize(relation.project([ :name ])) { |r| r.add(:count, r.name.count) }
|
|
52
52
|
new_relation = relation.summarize(relation.project([ :name ])) { |r| r.add(:count) { |acc, t| acc.to_i + 1 } }
|
|
53
53
|
|
|
54
54
|
# Non-Relational Operators
|
|
@@ -57,14 +57,11 @@ http://travis-ci.org/dkubb/veritas.png
|
|
|
57
57
|
# returns a set that represents the relation header
|
|
58
58
|
header = relation.header
|
|
59
59
|
|
|
60
|
-
# simplifies and normalizes the relation operations
|
|
61
|
-
optimized_relation = relation.optimize
|
|
62
|
-
|
|
63
60
|
# a relation is Enumerable
|
|
64
61
|
relation = relation.each { |tuple| ... }
|
|
65
62
|
|
|
66
63
|
# order by attribute and direction
|
|
67
|
-
new_relation = relation.
|
|
64
|
+
new_relation = relation.sort_by { |r| [ r.a.desc, r.b ] }
|
|
68
65
|
|
|
69
66
|
# reverse the relation (only allowed if ordered)
|
|
70
67
|
new_relation = relation.reverse
|
|
@@ -83,14 +80,6 @@ http://travis-ci.org/dkubb/veritas.png
|
|
|
83
80
|
new_relation = relation.last # default is 1
|
|
84
81
|
new_relation = relation.last(5)
|
|
85
82
|
|
|
86
|
-
# CRUD Operators
|
|
87
|
-
# --------------
|
|
88
|
-
|
|
89
|
-
# can only modify relations that project all candidate keys for the base relations
|
|
90
|
-
new_relation = relation.create(a: 'test', b: 'other', c: 'yet another')
|
|
91
|
-
new_relation = relation.update(a: 'test', b: 'other', c: 'yet another')
|
|
92
|
-
new_relation = relation.delete
|
|
93
|
-
|
|
94
83
|
== Goals
|
|
95
84
|
|
|
96
85
|
The purpose of this project is to expand my knowledge of relational algebra by attempting to implement a simple query system using the primitive operations defined in relational algebra.
|
|
@@ -107,18 +96,28 @@ Not only does this work nicely with associations, but it will allow DataMapper t
|
|
|
107
96
|
|
|
108
97
|
The first phase of this project will be to implement all the operations listed below using in-memory data structures. I'm focusing on the API, and making sure the specs ensure the desired results are obtained from each operation.
|
|
109
98
|
|
|
110
|
-
This is 100% complete
|
|
99
|
+
This is 100% complete.
|
|
111
100
|
|
|
112
101
|
=== Phase 2: RDBMS Engines
|
|
113
102
|
|
|
114
103
|
The second phase of this project will be to add a RDBMS based engine, and move the in-memory matching to it's own engine. I'll also be working on a system where if the primary engine cannot carry out some operation, that it first look at alternate forms (eg. using a join instead of an intersection), and then fall-back to in-memory matching. I also want to look at re-arranging queries so that all the operations that can be performed natively are "pushed down" the hierarchy and then the in-memory matching is performed last.
|
|
115
104
|
|
|
116
|
-
This is
|
|
105
|
+
This is 95% complete. I have completed a first pass on veritas-sql-generator[https://github.com/dkubb/veritas-sql-generator] which is a visitor that walks the AST and produces SQL for every operatione. More work is needed to write adapters that use the veritas-sql-generator and manage database connections/execution.
|
|
117
106
|
|
|
118
107
|
=== Phase 3: DataMapper Integration
|
|
119
108
|
|
|
120
109
|
The third phase of this project will be to add a few NoSQL engines (like MongoDB[http://www.mongodb.org/] and CouchDB[http://couchdb.org/]) and then look at writing a DataMapper adapter that translates Query objects into Veritas relations. I want to make sure all the DM specs pass with this adapter and each engine, and if everything goes well I will look at updating DM to work directly on top of Veritas.
|
|
121
110
|
|
|
111
|
+
== Related Projects
|
|
112
|
+
|
|
113
|
+
* veritas-optimizer[https://github.com/dkubb/veritas-optimizer]
|
|
114
|
+
|
|
115
|
+
This is an optimizer that takes a veritas relation, scalar or aggregate function and will transform it into something equivalent but simpler in structure to the original.
|
|
116
|
+
|
|
117
|
+
* veritas-sql-generator[https://github.com/dkubb/veritas-sql-generator]
|
|
118
|
+
|
|
119
|
+
This is a visitor class that takes a veritas relation and generates valid SQL from it.
|
|
120
|
+
|
|
122
121
|
== Note on Patches/Pull Requests
|
|
123
122
|
|
|
124
123
|
* If you want your code merged into the mainline, please discuss
|
data/Rakefile
CHANGED
|
@@ -5,7 +5,7 @@ require 'rake'
|
|
|
5
5
|
require File.expand_path('../lib/veritas/version', __FILE__)
|
|
6
6
|
|
|
7
7
|
begin
|
|
8
|
-
gem('jeweler', '~> 1.6.
|
|
8
|
+
gem('jeweler', '~> 1.6.2') if respond_to?(:gem, true)
|
|
9
9
|
require 'jeweler'
|
|
10
10
|
|
|
11
11
|
Jeweler::Tasks.new do |gem|
|
|
@@ -23,5 +23,5 @@ begin
|
|
|
23
23
|
|
|
24
24
|
FileList['tasks/**/*.rake'].each { |task| import task }
|
|
25
25
|
rescue LoadError
|
|
26
|
-
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler -v 1.6.
|
|
26
|
+
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler -v 1.6.2'
|
|
27
27
|
end
|
data/TODO
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
* Materialized relations need to hold a reference to the original relation.
|
|
2
|
+
* Especially "empty" relations should hold a reference to the original
|
|
3
|
+
relation so that insert/update can be performed on them if they are
|
|
4
|
+
empty not because they are valid, but because the source object is empty
|
|
5
|
+
|
|
1
6
|
* Remove Order, Reverse, Limit and Offset from the Relation inheritance chain
|
|
2
7
|
* Instead make it so they are proxy classes that wrap Relations, but
|
|
3
8
|
proxy method calls to the Relation methods, and then wrap the return
|
|
@@ -12,7 +17,7 @@
|
|
|
12
17
|
and instead wrap materialized relations in the Order object
|
|
13
18
|
if any.
|
|
14
19
|
|
|
15
|
-
* Add Relation#
|
|
20
|
+
* Add Relation#group and Relation#ungroup
|
|
16
21
|
|
|
17
22
|
* Update Attributes so that constraints are modelled using predicates,
|
|
18
23
|
so that when "join-ability" is tested, the predicates can just be
|
|
@@ -40,16 +45,15 @@
|
|
|
40
45
|
* The #call method should propagate the Tuple down to each callable entry
|
|
41
46
|
in the Enumerable.
|
|
42
47
|
|
|
43
|
-
*
|
|
44
|
-
to
|
|
45
|
-
*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
* Alias #@- to #desc
|
|
48
|
+
* Within the restriction context, make sure the attributes have aliases for:
|
|
49
|
+
* Alias #== to #eq (may break alot)
|
|
50
|
+
* Alias #!= to #ne (in 1.9 only)
|
|
51
|
+
* Alias #>= to #gte
|
|
52
|
+
* Alias #> to #gt
|
|
53
|
+
* Alias #<= to #lte
|
|
54
|
+
* Alias #< to #lt
|
|
55
|
+
* Alias #=~ to #match
|
|
56
|
+
|
|
57
|
+
* Within the sort_by context, make sure the attributes have aliases for:
|
|
58
|
+
* Alias #@+ to #asc
|
|
59
|
+
* Alias #@- to #desc
|
data/benchmarks/memory.rb
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
8
8
|
|
|
9
9
|
require 'backports'
|
|
10
|
+
require 'backports/basic_object'
|
|
10
11
|
|
|
11
12
|
unless GC.respond_to?(:enable_stats)
|
|
12
13
|
puts 'Error: benchmark works on ree, or ruby with Railsbench GC patch only'
|
|
@@ -94,7 +95,7 @@ end
|
|
|
94
95
|
|
|
95
96
|
each_count do |array, relation, count|
|
|
96
97
|
gc_statistics "restriction (#{count} tuples)" do
|
|
97
|
-
relation.restrict { |r| r
|
|
98
|
+
relation.restrict { |r| r.id.gte(1) }.each {}
|
|
98
99
|
end
|
|
99
100
|
end
|
|
100
101
|
|
|
@@ -130,12 +131,12 @@ end
|
|
|
130
131
|
|
|
131
132
|
each_count do |array, relation, count|
|
|
132
133
|
gc_statistics "order (#{count} tuples)" do
|
|
133
|
-
relation.
|
|
134
|
+
relation.sort_by { |r| [ r.id.desc, r.name ] }.each {}
|
|
134
135
|
end
|
|
135
136
|
end
|
|
136
137
|
|
|
137
138
|
each_count do |array, relation, count|
|
|
138
|
-
relation = relation.
|
|
139
|
+
relation = relation.sort_by { |r| [ r.id, r.name ] }
|
|
139
140
|
|
|
140
141
|
gc_statistics "take (#{count} tuples)" do
|
|
141
142
|
relation.take(count).each {}
|
|
@@ -143,7 +144,7 @@ each_count do |array, relation, count|
|
|
|
143
144
|
end
|
|
144
145
|
|
|
145
146
|
each_count do |array, relation, count|
|
|
146
|
-
relation = relation.
|
|
147
|
+
relation = relation.sort_by { |r| [ r.id, r.name ] }
|
|
147
148
|
|
|
148
149
|
gc_statistics "drop (#{count} tuples)" do
|
|
149
150
|
relation.drop(1).each {}
|
|
@@ -151,7 +152,7 @@ each_count do |array, relation, count|
|
|
|
151
152
|
end
|
|
152
153
|
|
|
153
154
|
each_count do |array, relation, count|
|
|
154
|
-
relation = relation.
|
|
155
|
+
relation = relation.sort_by { |r| [ r.id, r.name ] }
|
|
155
156
|
|
|
156
157
|
gc_statistics "first (#{count} tuples)" do
|
|
157
158
|
relation.first(count).each {}
|
|
@@ -159,7 +160,7 @@ each_count do |array, relation, count|
|
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
each_count do |array, relation, count|
|
|
162
|
-
relation = relation.
|
|
163
|
+
relation = relation.sort_by { |r| [ r.id, r.name ] }
|
|
163
164
|
|
|
164
165
|
gc_statistics "last (#{count} tuples)" do
|
|
165
166
|
relation.last(count).each {}
|
|
@@ -167,7 +168,7 @@ each_count do |array, relation, count|
|
|
|
167
168
|
end
|
|
168
169
|
|
|
169
170
|
each_count do |array, relation, count|
|
|
170
|
-
relation = relation.
|
|
171
|
+
relation = relation.sort_by { |r| [ r.id, r.name ] }
|
|
171
172
|
|
|
172
173
|
gc_statistics "reverse (#{count} tuples)" do
|
|
173
174
|
relation.reverse.each {}
|
data/benchmarks/speed.rb
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
8
8
|
|
|
9
9
|
require 'backports'
|
|
10
|
+
require 'backports/basic_object'
|
|
10
11
|
require 'rbench'
|
|
11
12
|
require 'veritas'
|
|
12
13
|
include Veritas
|
|
@@ -18,7 +19,7 @@ array = (1..100).map { |n| Tuple.new(header, [ n, 'Dan Kubb' ]) }
|
|
|
18
19
|
relation = Relation.new(header, array)
|
|
19
20
|
join = Relation.new([ [ :id, Integer, ], [ :age, Integer ] ], [ [ 1, 35 ] ])
|
|
20
21
|
product = Relation.new([ [ :age, Integer ] ], [ [ 35 ] ])
|
|
21
|
-
ordered = relation.
|
|
22
|
+
ordered = relation.sort_by { |r| [ r.id, r.name ] }
|
|
22
23
|
|
|
23
24
|
RBench.run(TIMES) do
|
|
24
25
|
column :ruby, :title => 'Ruby'
|
|
@@ -42,7 +43,7 @@ RBench.run(TIMES) do
|
|
|
42
43
|
|
|
43
44
|
report 'restriction' do
|
|
44
45
|
ruby { array.select { |tuple| tuple[:id] >= 1 }.each {} }
|
|
45
|
-
veritas { relation.restrict { |r| r
|
|
46
|
+
veritas { relation.restrict { |r| r.id.gte(1) }.each {} }
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
report 'join' do
|
|
@@ -71,7 +72,7 @@ RBench.run(TIMES) do
|
|
|
71
72
|
|
|
72
73
|
report 'order' do
|
|
73
74
|
ruby { array.sort_by { |tuple| [ -tuple[:id], tuple[:name] ] }.each {} }
|
|
74
|
-
veritas { relation.
|
|
75
|
+
veritas { relation.sort_by { |r| [ r.id.desc, r.name ] }.each {} }
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
report 'take' do
|
data/config/flay.yml
CHANGED
data/lib/veritas/aggregate.rb
CHANGED
data/lib/veritas/algebra/join.rb
CHANGED
|
@@ -7,6 +7,13 @@ module Veritas
|
|
|
7
7
|
class Join < Relation
|
|
8
8
|
include Relation::Operation::Combination
|
|
9
9
|
|
|
10
|
+
# The common headers between the operands
|
|
11
|
+
#
|
|
12
|
+
# @return [Header]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
attr_reader :join_header
|
|
16
|
+
|
|
10
17
|
# Instantiate a new Join
|
|
11
18
|
#
|
|
12
19
|
# @example
|
|
@@ -54,7 +61,7 @@ module Veritas
|
|
|
54
61
|
super
|
|
55
62
|
right_header = right.header
|
|
56
63
|
@join_header = left.header & right_header
|
|
57
|
-
@remainder_header = right_header -
|
|
64
|
+
@remainder_header = right_header - join_header
|
|
58
65
|
end
|
|
59
66
|
|
|
60
67
|
# Iterate over each tuple in the set
|
|
@@ -73,8 +80,8 @@ module Veritas
|
|
|
73
80
|
# @api public
|
|
74
81
|
def each(&block)
|
|
75
82
|
return to_enum unless block_given?
|
|
76
|
-
index = build_index
|
|
77
83
|
util = Relation::Operation::Combination
|
|
84
|
+
index = build_index
|
|
78
85
|
|
|
79
86
|
left.each do |left_tuple|
|
|
80
87
|
right_tuples = index[join_tuple(left_tuple)]
|
|
@@ -109,7 +116,7 @@ module Veritas
|
|
|
109
116
|
#
|
|
110
117
|
# @api private
|
|
111
118
|
def join_tuple(tuple)
|
|
112
|
-
tuple.project(
|
|
119
|
+
tuple.project(join_header)
|
|
113
120
|
end
|
|
114
121
|
|
|
115
122
|
# Generate a tuple with the disjoint attributes to use in the join
|
|
@@ -132,7 +139,7 @@ module Veritas
|
|
|
132
139
|
# join = relation.join(other)
|
|
133
140
|
#
|
|
134
141
|
# @example theta-join using a block
|
|
135
|
-
# join = relation.join(other) { |r| r
|
|
142
|
+
# join = relation.join(other) { |r| r.a.gte(r.b) }
|
|
136
143
|
#
|
|
137
144
|
# @param [Relation] other
|
|
138
145
|
# the other relation to join
|
|
@@ -58,8 +58,9 @@ module Veritas
|
|
|
58
58
|
# @api public
|
|
59
59
|
def each(&block)
|
|
60
60
|
return to_enum unless block_given?
|
|
61
|
+
right_tuples = right.to_a
|
|
61
62
|
left.each do |left_tuple|
|
|
62
|
-
Relation::Operation::Combination.combine_tuples(header, left_tuple,
|
|
63
|
+
Relation::Operation::Combination.combine_tuples(header, left_tuple, right_tuples, &block)
|
|
63
64
|
end
|
|
64
65
|
self
|
|
65
66
|
end
|
|
@@ -83,7 +83,7 @@ module Veritas
|
|
|
83
83
|
# Return a relation with restricted tuples
|
|
84
84
|
#
|
|
85
85
|
# @example restriction using a block
|
|
86
|
-
# restriction = relation.restrict { |r| r
|
|
86
|
+
# restriction = relation.restrict { |r| r.a.eq('other').and(r.b.gte(42)) }
|
|
87
87
|
#
|
|
88
88
|
# @yield [relation]
|
|
89
89
|
# optional block to restrict the tuples with
|
|
@@ -98,7 +98,8 @@ module Veritas
|
|
|
98
98
|
#
|
|
99
99
|
# @api public
|
|
100
100
|
def restrict
|
|
101
|
-
|
|
101
|
+
context = Evaluator::Context.new(header) { |context| yield context }
|
|
102
|
+
Restriction.new(self, context.yield)
|
|
102
103
|
end
|
|
103
104
|
|
|
104
105
|
end # module Methods
|
|
@@ -155,14 +155,19 @@ module Veritas
|
|
|
155
155
|
|
|
156
156
|
# Return a summarized relation
|
|
157
157
|
#
|
|
158
|
+
# @example with no arguments
|
|
159
|
+
# summarization = relation.summarize do |context|
|
|
160
|
+
# context.add(:count, context[:id].count)
|
|
161
|
+
# end
|
|
162
|
+
#
|
|
158
163
|
# @example with a relation
|
|
159
164
|
# summarization = relation.summarize(relation.project([ :name ])) do |context|
|
|
160
|
-
# context.add(:count, context[:
|
|
165
|
+
# context.add(:count, context[:id].count)
|
|
161
166
|
# end
|
|
162
167
|
#
|
|
163
168
|
# @example with a header
|
|
164
169
|
# summarization = relation.summarize([ :name ]) do |context|
|
|
165
|
-
# context.add(:count, context[:
|
|
170
|
+
# context.add(:count, context[:id].count)
|
|
166
171
|
# end
|
|
167
172
|
#
|
|
168
173
|
# @param [Relation, Header, #to_ary] summarize_with
|
|
@@ -176,7 +181,7 @@ module Veritas
|
|
|
176
181
|
# @return [Summarization]
|
|
177
182
|
#
|
|
178
183
|
# @api public
|
|
179
|
-
def summarize(summarize_with)
|
|
184
|
+
def summarize(summarize_with = TABLE_DEE)
|
|
180
185
|
summarize_per = coerce_to_relation(summarize_with)
|
|
181
186
|
context = Evaluator::Context.new(header - summarize_per.header) { |context| yield context }
|
|
182
187
|
Summarization.new(self, summarize_per, context.functions)
|
data/lib/veritas/attribute.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Veritas
|
|
|
31
31
|
# @api private
|
|
32
32
|
def self.inherited(descendant)
|
|
33
33
|
superclass = self.superclass
|
|
34
|
-
superclass.inherited(descendant)
|
|
34
|
+
superclass.inherited(descendant) if superclass.respond_to?(:descendants)
|
|
35
35
|
descendants.unshift(descendant)
|
|
36
36
|
self
|
|
37
37
|
end
|
|
@@ -5,7 +5,11 @@ module Veritas
|
|
|
5
5
|
|
|
6
6
|
# Abstract base class for logical propositions
|
|
7
7
|
class Proposition < Function
|
|
8
|
-
include AbstractClass,
|
|
8
|
+
include AbstractClass,
|
|
9
|
+
Singleton,
|
|
10
|
+
Function::Connective::Conjunction::Methods,
|
|
11
|
+
Function::Connective::Disjunction::Methods,
|
|
12
|
+
Function::Connective::Negation::Methods
|
|
9
13
|
|
|
10
14
|
# Instantiate a new Proposition
|
|
11
15
|
#
|
data/lib/veritas/function.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Veritas
|
|
|
9
9
|
# The base relation name
|
|
10
10
|
#
|
|
11
11
|
# @example
|
|
12
|
-
# name =
|
|
12
|
+
# name = base.name
|
|
13
13
|
#
|
|
14
14
|
# @return [#to_s]
|
|
15
15
|
#
|
|
@@ -28,11 +28,40 @@ module Veritas
|
|
|
28
28
|
# @return [undefined]
|
|
29
29
|
#
|
|
30
30
|
# @api private
|
|
31
|
-
def initialize(name,
|
|
32
|
-
super(
|
|
31
|
+
def initialize(name, header, tuples = Empty::ZERO_TUPLE)
|
|
32
|
+
super(header, tuples)
|
|
33
33
|
@name = Immutable.freeze_object(name.to_s)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# Compare the base relation with other relation for equality
|
|
37
|
+
#
|
|
38
|
+
# @example
|
|
39
|
+
# base.eql?(other) # => true or false
|
|
40
|
+
#
|
|
41
|
+
# @param [Relation] other
|
|
42
|
+
# the other relation to compare with
|
|
43
|
+
#
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
#
|
|
46
|
+
# @api public
|
|
47
|
+
def eql?(other)
|
|
48
|
+
super && name.eql?(other.name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Return the hash of the base relation
|
|
52
|
+
#
|
|
53
|
+
# @example
|
|
54
|
+
# hash = base.hash
|
|
55
|
+
#
|
|
56
|
+
# @return [Fixnum]
|
|
57
|
+
#
|
|
58
|
+
# @api public
|
|
59
|
+
def hash
|
|
60
|
+
super ^ name.hash
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
memoize :hash
|
|
64
|
+
|
|
36
65
|
end # class Base
|
|
37
66
|
end # class Relation
|
|
38
67
|
end # module Veritas
|
|
@@ -26,7 +26,7 @@ module Veritas
|
|
|
26
26
|
#
|
|
27
27
|
# @api public
|
|
28
28
|
def self.new(attributes = [])
|
|
29
|
-
attributes = coerce_attributes(attributes)
|
|
29
|
+
attributes = coerce_attributes(attributes.to_ary)
|
|
30
30
|
assert_unique_attributes(attributes)
|
|
31
31
|
super
|
|
32
32
|
end
|
|
@@ -39,7 +39,7 @@ module Veritas
|
|
|
39
39
|
#
|
|
40
40
|
# @api private
|
|
41
41
|
def self.coerce_attributes(attributes)
|
|
42
|
-
attributes.
|
|
42
|
+
attributes.map { |attribute| Attribute.coerce(attribute) }
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
# Assert the attributes are unique
|
|
@@ -42,6 +42,18 @@ module Veritas
|
|
|
42
42
|
self
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
# Return true for a Materialized relation
|
|
46
|
+
#
|
|
47
|
+
# @example
|
|
48
|
+
# relation.materialized? # => true
|
|
49
|
+
#
|
|
50
|
+
# @return [true]
|
|
51
|
+
#
|
|
52
|
+
# @api public
|
|
53
|
+
def materialized?
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
|
|
45
57
|
# Test if there are no tuples
|
|
46
58
|
#
|
|
47
59
|
# @example
|