veritas 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|