veritas 0.0.5 → 0.0.6
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 +5 -4
- data/Gemfile +16 -14
- data/Guardfile +0 -4
- data/README.md +188 -0
- data/Rakefile +2 -2
- data/TODO +0 -16
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/roodi.yml +4 -4
- data/config/site.reek +7 -3
- data/lib/veritas/aggregate.rb +18 -0
- data/lib/veritas/algebra/extension.rb +2 -29
- data/lib/veritas/algebra/projection.rb +2 -29
- data/lib/veritas/algebra/rename/aliases.rb +4 -32
- data/lib/veritas/algebra/rename.rb +2 -29
- data/lib/veritas/algebra/restriction.rb +2 -29
- data/lib/veritas/algebra/summarization.rb +2 -31
- data/lib/veritas/attribute/time.rb +1 -1
- data/lib/veritas/attribute.rb +20 -40
- data/lib/veritas/function/binary.rb +2 -3
- data/lib/veritas/function/connective/negation.rb +1 -1
- data/lib/veritas/function/predicate/enumerable.rb +19 -0
- data/lib/veritas/function/predicate/exclusion.rb +1 -1
- data/lib/veritas/function/predicate/match.rb +1 -1
- data/lib/veritas/function/unary.rb +5 -3
- data/lib/veritas/function.rb +1 -41
- data/lib/veritas/relation/base.rb +2 -29
- data/lib/veritas/relation/empty.rb +30 -2
- data/lib/veritas/relation/header.rb +17 -31
- data/lib/veritas/relation/materialized.rb +0 -12
- data/lib/veritas/relation/operation/limit.rb +2 -29
- data/lib/veritas/relation/operation/offset.rb +2 -29
- data/lib/veritas/relation/operation/order/direction.rb +3 -29
- data/lib/veritas/relation/operation/order/direction_set.rb +18 -34
- data/lib/veritas/relation/operation/order.rb +4 -56
- data/lib/veritas/relation.rb +8 -36
- data/lib/veritas/support/aliasable.rb +20 -7
- data/lib/veritas/support/comparator.rb +81 -0
- data/lib/veritas/support/evaluator.rb +1 -1
- data/lib/veritas/support/immutable.rb +22 -49
- data/lib/veritas/support/operation/binary.rb +3 -30
- data/lib/veritas/support/operation/unary.rb +3 -29
- data/lib/veritas/tuple.rb +19 -29
- data/lib/veritas/version.rb +1 -1
- data/lib/veritas.rb +1 -0
- data/spec/integration/veritas/relation/efficient_enumerable_spec.rb +3 -3
- data/spec/shared/hash_method_behavior.rb +7 -2
- data/spec/unit/date/pred_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/equal_value_spec.rb +52 -0
- data/spec/unit/veritas/aggregate/hash_spec.rb +15 -0
- data/spec/unit/veritas/aliasable/inheritable_alias_spec.rb +1 -1
- data/spec/unit/veritas/comparator/compare_spec.rb +40 -0
- data/spec/unit/veritas/comparator/methods/eql_spec.rb +48 -0
- data/spec/unit/veritas/evaluator/context/respond_to_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/enumerable/call_spec.rb +36 -0
- data/spec/unit/veritas/function/unary/hash_spec.rb +18 -0
- data/spec/unit/veritas/immutable/freeze_spec.rb +2 -2
- data/spec/unit/veritas/immutable/memoize_spec.rb +13 -0
- data/spec/unit/veritas/immutable/module_methods/memoize_spec.rb +1 -1
- data/spec/unit/veritas/relation/empty/class_methods/new_spec.rb +30 -0
- data/spec/unit/veritas/relation/empty/each_spec.rb +20 -5
- data/spec/unit/veritas/relation/empty/size_spec.rb +11 -0
- data/spec/unit/veritas/relation/header/hash_spec.rb +1 -1
- data/spec/unit/veritas/relation/materialized/empty_spec.rb +0 -10
- data/spec/unit/veritas/relation/operation/order/direction_set/class_methods/coerce_spec.rb +12 -3
- data/tasks/metrics/heckle.rake +2 -3
- data/veritas.gemspec +21 -18
- metadata +36 -33
- data/README.rdoc +0 -143
- data/spec/unit/veritas/function/eql_spec.rb +0 -14
- data/spec/unit/veritas/function/equal_value_spec.rb +0 -14
- data/spec/unit/veritas/function/hash_spec.rb +0 -13
- data/spec/unit/veritas/immutable/memory/element_reference_spec.rb +0 -26
- data/spec/unit/veritas/immutable/memory/element_set_spec.rb +0 -19
- data/spec/unit/veritas/relation/operation/order/methods/order_spec.rb +0 -54
@@ -7,6 +7,8 @@ module Veritas
|
|
7
7
|
class Summarization < Relation
|
8
8
|
include Relation::Operation::Unary
|
9
9
|
|
10
|
+
compare :operand, :summarize_per, :summarizers
|
11
|
+
|
10
12
|
# The relation to summarize with
|
11
13
|
#
|
12
14
|
# @return [Relation]
|
@@ -99,35 +101,6 @@ module Veritas
|
|
99
101
|
self
|
100
102
|
end
|
101
103
|
|
102
|
-
# Compare the Summarization with other relation for equality
|
103
|
-
#
|
104
|
-
# @example
|
105
|
-
# summarization.eql?(other) # => true or false
|
106
|
-
#
|
107
|
-
# @param [Relation] other
|
108
|
-
# the other relation to compare with
|
109
|
-
#
|
110
|
-
# @return [Boolean]
|
111
|
-
#
|
112
|
-
# @api public
|
113
|
-
def eql?(other)
|
114
|
-
super &&
|
115
|
-
summarize_per.eql?(other.summarize_per) &&
|
116
|
-
summarizers.eql?(other.summarizers)
|
117
|
-
end
|
118
|
-
|
119
|
-
# Return the hash of the summarization
|
120
|
-
#
|
121
|
-
# @example
|
122
|
-
# hash = summarization.hash
|
123
|
-
#
|
124
|
-
# @return [Fixnum]
|
125
|
-
#
|
126
|
-
# @api public
|
127
|
-
def hash
|
128
|
-
super ^ summarize_per.hash ^ summarizers.hash
|
129
|
-
end
|
130
|
-
|
131
104
|
private
|
132
105
|
|
133
106
|
# Return the current summaries
|
@@ -209,8 +182,6 @@ module Veritas
|
|
209
182
|
|
210
183
|
Relation.class_eval { include Methods }
|
211
184
|
|
212
|
-
memoize :hash
|
213
|
-
|
214
185
|
end # class Summarization
|
215
186
|
end # module Algebra
|
216
187
|
end # module Veritas
|
data/lib/veritas/attribute.rb
CHANGED
@@ -4,9 +4,11 @@ module Veritas
|
|
4
4
|
|
5
5
|
# Abstract base class representing a type of data in a relation tuple
|
6
6
|
class Attribute
|
7
|
-
extend Aliasable
|
7
|
+
extend Aliasable, Comparator
|
8
8
|
include AbstractClass, Immutable, ::Comparable, Visitable
|
9
9
|
|
10
|
+
compare :name, :options
|
11
|
+
|
10
12
|
# The attribute name
|
11
13
|
#
|
12
14
|
# @return [Symbol]
|
@@ -91,11 +93,11 @@ module Veritas
|
|
91
93
|
# @api private
|
92
94
|
def self.infer_type(operand)
|
93
95
|
case operand
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
when Attribute, Function, Aggregate then operand.type
|
97
|
+
when FalseClass then Boolean
|
98
|
+
else
|
99
|
+
type = operand.class
|
100
|
+
descendants.detect { |descendant| type <= descendant.primitive }
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
@@ -227,38 +229,7 @@ module Veritas
|
|
227
229
|
#
|
228
230
|
# @api public
|
229
231
|
def ==(other)
|
230
|
-
|
231
|
-
name.equal?(other.name) &&
|
232
|
-
options == other.options
|
233
|
-
end
|
234
|
-
|
235
|
-
# Compare the attribute with other attribute for equality
|
236
|
-
#
|
237
|
-
# @example
|
238
|
-
# attribute.eql?(other) # => true or false
|
239
|
-
#
|
240
|
-
# @param [Attribute] other
|
241
|
-
# the other attribute to compare with
|
242
|
-
#
|
243
|
-
# @return [Boolean]
|
244
|
-
#
|
245
|
-
# @api public
|
246
|
-
def eql?(other)
|
247
|
-
instance_of?(other.class) &&
|
248
|
-
name.equal?(other.name) &&
|
249
|
-
options.eql?(other.options)
|
250
|
-
end
|
251
|
-
|
252
|
-
# Return the hash of the attribute
|
253
|
-
#
|
254
|
-
# @example
|
255
|
-
# hash = attribute.hash
|
256
|
-
#
|
257
|
-
# @return [Fixnum]
|
258
|
-
#
|
259
|
-
# @api public
|
260
|
-
def hash
|
261
|
-
self.class.hash ^ name.hash ^ options.hash
|
232
|
+
cmp?(__method__, coerce(other))
|
262
233
|
end
|
263
234
|
|
264
235
|
# Return a string representing the attribute
|
@@ -286,10 +257,19 @@ module Veritas
|
|
286
257
|
#
|
287
258
|
# @api private
|
288
259
|
def valid_or_optional?(value)
|
289
|
-
value.nil? ? !required? : yield
|
260
|
+
value.nil? ? ! required? : yield
|
290
261
|
end
|
291
262
|
|
292
|
-
|
263
|
+
# Coerce the object into an Attribute
|
264
|
+
#
|
265
|
+
# @param [Attribute, Array] object
|
266
|
+
#
|
267
|
+
# @return [Attribute]
|
268
|
+
#
|
269
|
+
# @api private
|
270
|
+
def coerce(object)
|
271
|
+
Attribute.coerce(object)
|
272
|
+
end
|
293
273
|
|
294
274
|
end # class Attribute
|
295
275
|
end # module Veritas
|
@@ -7,7 +7,7 @@ module Veritas
|
|
7
7
|
module Binary
|
8
8
|
include Operation::Binary
|
9
9
|
|
10
|
-
# Evaluate the binary
|
10
|
+
# Evaluate the binary function using the tuple
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# binary.call(tuple) # => true or false
|
@@ -98,8 +98,7 @@ module Veritas
|
|
98
98
|
#
|
99
99
|
# @api public
|
100
100
|
def inverse
|
101
|
-
self.class.inverse.new(left, right).
|
102
|
-
memoize(:inverse, self)
|
101
|
+
self.class.inverse.new(left, right).memoize(:inverse, self)
|
103
102
|
end
|
104
103
|
|
105
104
|
end # module Invertible
|
@@ -32,6 +32,25 @@ module Veritas
|
|
32
32
|
super(left, Immutable.freeze_object(right))
|
33
33
|
end
|
34
34
|
|
35
|
+
# Evaluate the enumerable function using the tuple
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# enumerable.call(tuple) # => true or false
|
39
|
+
#
|
40
|
+
# @param [Tuple] tuple
|
41
|
+
# the tuple to pass to #call in the left and right operands
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def call(tuple)
|
47
|
+
util = self.class
|
48
|
+
util.call(
|
49
|
+
util.extract_value(left, tuple),
|
50
|
+
right.map { |entry| util.extract_value(entry, tuple) }
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
35
54
|
end # module Enumerable
|
36
55
|
end # class Predicate
|
37
56
|
end # class Function
|
@@ -5,8 +5,11 @@ module Veritas
|
|
5
5
|
|
6
6
|
# Mixin for unary functions
|
7
7
|
module Unary
|
8
|
+
extend Comparator
|
8
9
|
include Operation::Unary
|
9
10
|
|
11
|
+
compare :operand
|
12
|
+
|
10
13
|
# Evaluate the unary connective using the tuple
|
11
14
|
#
|
12
15
|
# @example
|
@@ -64,7 +67,7 @@ module Veritas
|
|
64
67
|
# @api public
|
65
68
|
def ==(other)
|
66
69
|
(kind_of?(other.class) || other.kind_of?(self.class)) &&
|
67
|
-
|
70
|
+
cmp?(__method__, other)
|
68
71
|
end
|
69
72
|
|
70
73
|
# Mixin for invertable unary functions
|
@@ -94,8 +97,7 @@ module Veritas
|
|
94
97
|
#
|
95
98
|
# @api public
|
96
99
|
def inverse
|
97
|
-
self.class.inverse.new(operand).
|
98
|
-
memoize(:inverse, self)
|
100
|
+
self.class.inverse.new(operand).memoize(:inverse, self)
|
99
101
|
end
|
100
102
|
|
101
103
|
end # module Invertible
|
data/lib/veritas/function.rb
CHANGED
@@ -18,7 +18,7 @@ module Veritas
|
|
18
18
|
#
|
19
19
|
# @api private
|
20
20
|
def self.rename_attributes(operand, aliases)
|
21
|
-
if operand.respond_to?(:rename) && !operand.kind_of?(Attribute)
|
21
|
+
if operand.respond_to?(:rename) && ! operand.kind_of?(Attribute)
|
22
22
|
operand.rename(aliases)
|
23
23
|
else
|
24
24
|
aliases[operand]
|
@@ -75,46 +75,6 @@ module Veritas
|
|
75
75
|
raise NotImplementedError, "#{self.class}#type must be implemented"
|
76
76
|
end
|
77
77
|
|
78
|
-
# Compare the function with other function for equivalency
|
79
|
-
#
|
80
|
-
# @example
|
81
|
-
# function == other # => true or false
|
82
|
-
#
|
83
|
-
# @param [Function] other
|
84
|
-
#
|
85
|
-
# @return [Boolean]
|
86
|
-
#
|
87
|
-
# @api public
|
88
|
-
def ==(other)
|
89
|
-
raise NotImplementedError, "#{self.class}#== must be implemented"
|
90
|
-
end
|
91
|
-
|
92
|
-
# Compare the function with other function for equality
|
93
|
-
#
|
94
|
-
# @example
|
95
|
-
# function.eql?(other) # => true or false
|
96
|
-
#
|
97
|
-
# @param [Function] other
|
98
|
-
#
|
99
|
-
# @return [Boolean]
|
100
|
-
#
|
101
|
-
# @api public
|
102
|
-
def eql?(other)
|
103
|
-
raise NotImplementedError, "#{self.class}#eql? must be implemented"
|
104
|
-
end
|
105
|
-
|
106
|
-
# Return the hash of the function
|
107
|
-
#
|
108
|
-
# @example
|
109
|
-
# hash = function.hash
|
110
|
-
#
|
111
|
-
# @return [Fixnum]
|
112
|
-
#
|
113
|
-
# @api public
|
114
|
-
def hash
|
115
|
-
raise NotImplementedError, "#{self.class}#hash must be implemented"
|
116
|
-
end
|
117
|
-
|
118
78
|
# Return a string representing the function
|
119
79
|
#
|
120
80
|
# @example
|
@@ -6,6 +6,8 @@ module Veritas
|
|
6
6
|
# A class that represents a base relation
|
7
7
|
class Base < Relation
|
8
8
|
|
9
|
+
compare :header, :to_set, :name
|
10
|
+
|
9
11
|
# The base relation name
|
10
12
|
#
|
11
13
|
# @example
|
@@ -33,35 +35,6 @@ module Veritas
|
|
33
35
|
@name = Immutable.freeze_object(name.to_s)
|
34
36
|
end
|
35
37
|
|
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
|
-
|
65
38
|
end # class Base
|
66
39
|
end # class Relation
|
67
40
|
end # module Veritas
|
@@ -11,12 +11,40 @@ module Veritas
|
|
11
11
|
#
|
12
12
|
# @param [Header] header
|
13
13
|
# the header for the empty relation
|
14
|
+
# @param [#each] tuples
|
15
|
+
# optional original tuples
|
14
16
|
#
|
15
17
|
# @return [undefined]
|
16
18
|
#
|
17
19
|
# @api public
|
18
|
-
def initialize(header)
|
19
|
-
super
|
20
|
+
def initialize(header, tuples = ZERO_TUPLE)
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
# Noop #each method
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# empty = Empty.new(header)
|
28
|
+
# empty.each { ... }
|
29
|
+
#
|
30
|
+
# @return [self]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def each
|
34
|
+
return to_enum unless block_given?
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the number of tuples
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# empty.size # => 0
|
42
|
+
#
|
43
|
+
# @return [0]
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def size
|
47
|
+
0
|
20
48
|
end
|
21
49
|
|
22
50
|
end # class Empty
|
@@ -5,9 +5,11 @@ module Veritas
|
|
5
5
|
|
6
6
|
# A set of attributes that correspond to values in each tuple
|
7
7
|
class Header
|
8
|
-
extend Aliasable
|
8
|
+
extend Aliasable, Comparator
|
9
9
|
include Enumerable, Immutable
|
10
10
|
|
11
|
+
compare :to_set
|
12
|
+
|
11
13
|
inheritable_alias(
|
12
14
|
:& => :intersect,
|
13
15
|
:| => :union,
|
@@ -217,35 +219,7 @@ module Veritas
|
|
217
219
|
#
|
218
220
|
# @api public
|
219
221
|
def ==(other)
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
|
-
# Compare the header with other header for equality
|
224
|
-
#
|
225
|
-
# @example
|
226
|
-
# header.eql?(other) # => true or false
|
227
|
-
#
|
228
|
-
# @param [Header] other
|
229
|
-
# the other header to compare with
|
230
|
-
#
|
231
|
-
# @return [Boolean]
|
232
|
-
#
|
233
|
-
# @api public
|
234
|
-
def eql?(other)
|
235
|
-
instance_of?(other.class) &&
|
236
|
-
to_set == other.to_set
|
237
|
-
end
|
238
|
-
|
239
|
-
# Return the hash of the header
|
240
|
-
#
|
241
|
-
# @example
|
242
|
-
# hash = header.hash
|
243
|
-
#
|
244
|
-
# @return [Fixnum]
|
245
|
-
#
|
246
|
-
# @api public
|
247
|
-
def hash
|
248
|
-
self.class.hash ^ @attributes.hash
|
222
|
+
cmp?(__method__, coerce(other))
|
249
223
|
end
|
250
224
|
|
251
225
|
# Test if there are no attributes
|
@@ -286,6 +260,18 @@ module Veritas
|
|
286
260
|
self.class.new(attributes)
|
287
261
|
end
|
288
262
|
|
263
|
+
# Coerce the object into a Header
|
264
|
+
#
|
265
|
+
# @param [Header, #to_ary]
|
266
|
+
# the header or attributes
|
267
|
+
#
|
268
|
+
# @return [Header]
|
269
|
+
#
|
270
|
+
# @api private
|
271
|
+
def coerce(object)
|
272
|
+
self.class.coerce(object)
|
273
|
+
end
|
274
|
+
|
289
275
|
# Coerce an Array-like object into a Header
|
290
276
|
#
|
291
277
|
# @param [Header, #to_ary]
|
@@ -298,7 +284,7 @@ module Veritas
|
|
298
284
|
object.kind_of?(Header) ? object : new(object)
|
299
285
|
end
|
300
286
|
|
301
|
-
memoize :
|
287
|
+
memoize :to_ary
|
302
288
|
|
303
289
|
end # class Header
|
304
290
|
end # class Relation
|
@@ -54,18 +54,6 @@ module Veritas
|
|
54
54
|
true
|
55
55
|
end
|
56
56
|
|
57
|
-
# Test if there are no tuples
|
58
|
-
#
|
59
|
-
# @example
|
60
|
-
# materialized.empty? # => true or false
|
61
|
-
#
|
62
|
-
# @return [Boolean]
|
63
|
-
#
|
64
|
-
# @api public
|
65
|
-
def empty?
|
66
|
-
tuples.empty?
|
67
|
-
end
|
68
|
-
|
69
57
|
# Return the number of tuples
|
70
58
|
#
|
71
59
|
# @example
|
@@ -8,6 +8,8 @@ module Veritas
|
|
8
8
|
class Limit < Relation
|
9
9
|
include Unary
|
10
10
|
|
11
|
+
compare :operand, :limit
|
12
|
+
|
11
13
|
# Return the limit
|
12
14
|
#
|
13
15
|
# @example
|
@@ -117,33 +119,6 @@ module Veritas
|
|
117
119
|
self
|
118
120
|
end
|
119
121
|
|
120
|
-
# Compare the Limit with other relation for equality
|
121
|
-
#
|
122
|
-
# @example
|
123
|
-
# limited_relation.eql?(other) # => true or false
|
124
|
-
#
|
125
|
-
# @param [Relation] other
|
126
|
-
# the other relation to compare with
|
127
|
-
#
|
128
|
-
# @return [Boolean]
|
129
|
-
#
|
130
|
-
# @api public
|
131
|
-
def eql?(other)
|
132
|
-
super && limit.eql?(other.limit)
|
133
|
-
end
|
134
|
-
|
135
|
-
# Return the hash of the limit
|
136
|
-
#
|
137
|
-
# @example
|
138
|
-
# hash = limit.hash
|
139
|
-
#
|
140
|
-
# @return [Fixnum]
|
141
|
-
#
|
142
|
-
# @api public
|
143
|
-
def hash
|
144
|
-
super ^ limit.hash
|
145
|
-
end
|
146
|
-
|
147
122
|
module Methods
|
148
123
|
|
149
124
|
# Return a relation with n tuples
|
@@ -201,8 +176,6 @@ module Veritas
|
|
201
176
|
|
202
177
|
Relation.class_eval { include Methods }
|
203
178
|
|
204
|
-
memoize :hash
|
205
|
-
|
206
179
|
end # class Limit
|
207
180
|
end # module Operation
|
208
181
|
end # class Relation
|
@@ -8,6 +8,8 @@ module Veritas
|
|
8
8
|
class Offset < Relation
|
9
9
|
include Unary
|
10
10
|
|
11
|
+
compare :operand, :offset
|
12
|
+
|
11
13
|
# Return the offset
|
12
14
|
#
|
13
15
|
# @example
|
@@ -116,33 +118,6 @@ module Veritas
|
|
116
118
|
self
|
117
119
|
end
|
118
120
|
|
119
|
-
# Compare the Offset with other relation for equality
|
120
|
-
#
|
121
|
-
# @example
|
122
|
-
# offset_relation.eql?(other) # => true or false
|
123
|
-
#
|
124
|
-
# @param [Relation] other
|
125
|
-
# the other relation to compare with
|
126
|
-
#
|
127
|
-
# @return [Boolean]
|
128
|
-
#
|
129
|
-
# @api public
|
130
|
-
def eql?(other)
|
131
|
-
super && offset.eql?(other.offset)
|
132
|
-
end
|
133
|
-
|
134
|
-
# Return the hash of the offset
|
135
|
-
#
|
136
|
-
# @example
|
137
|
-
# hash = offset.hash
|
138
|
-
#
|
139
|
-
# @return [Fixnum]
|
140
|
-
#
|
141
|
-
# @api public
|
142
|
-
def hash
|
143
|
-
super ^ offset.hash
|
144
|
-
end
|
145
|
-
|
146
121
|
module Methods
|
147
122
|
|
148
123
|
# Return a relation with n tuples
|
@@ -164,8 +139,6 @@ module Veritas
|
|
164
139
|
|
165
140
|
Relation.class_eval { include Methods }
|
166
141
|
|
167
|
-
memoize :hash
|
168
|
-
|
169
142
|
end # class Offset
|
170
143
|
end # module Operation
|
171
144
|
end # class Relation
|
@@ -7,8 +7,11 @@ module Veritas
|
|
7
7
|
|
8
8
|
# Abstract base class for attribute sorting
|
9
9
|
class Direction
|
10
|
+
extend Comparator
|
10
11
|
include AbstractClass, Immutable
|
11
12
|
|
13
|
+
compare :attribute
|
14
|
+
|
12
15
|
# The attribute to sort on
|
13
16
|
#
|
14
17
|
# @return [Attribute]
|
@@ -97,33 +100,6 @@ module Veritas
|
|
97
100
|
eql?(other)
|
98
101
|
end
|
99
102
|
|
100
|
-
# Compare the direction with other direction for equality
|
101
|
-
#
|
102
|
-
# @example
|
103
|
-
# direction.eql?(other) # => true or false
|
104
|
-
#
|
105
|
-
# @param [Direction] other
|
106
|
-
#
|
107
|
-
# @return [Boolean]
|
108
|
-
#
|
109
|
-
# @api public
|
110
|
-
def eql?(other)
|
111
|
-
instance_of?(other.class) &&
|
112
|
-
attribute.eql?(other.attribute)
|
113
|
-
end
|
114
|
-
|
115
|
-
# Return the hash of the direction
|
116
|
-
#
|
117
|
-
# @example
|
118
|
-
# hash = direction.hash
|
119
|
-
#
|
120
|
-
# @return [Fixnum]
|
121
|
-
#
|
122
|
-
# @api public
|
123
|
-
def hash
|
124
|
-
self.class.hash ^ attribute.hash
|
125
|
-
end
|
126
|
-
|
127
103
|
# Coerce an object into a Direction
|
128
104
|
#
|
129
105
|
# @param [Attribute, Direction] object
|
@@ -136,8 +112,6 @@ module Veritas
|
|
136
112
|
object.kind_of?(Direction) ? object : new(object)
|
137
113
|
end
|
138
114
|
|
139
|
-
memoize :hash
|
140
|
-
|
141
115
|
end # class Direction
|
142
116
|
|
143
117
|
# Represent an attribute sorted ascending
|