arel-compat 0.4.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 (164) hide show
  1. data/History.txt +25 -0
  2. data/README.markdown +182 -0
  3. data/lib/arel.rb +13 -0
  4. data/lib/arel/algebra.rb +10 -0
  5. data/lib/arel/algebra/attributes.rb +7 -0
  6. data/lib/arel/algebra/attributes/attribute.rb +270 -0
  7. data/lib/arel/algebra/attributes/boolean.rb +21 -0
  8. data/lib/arel/algebra/attributes/decimal.rb +9 -0
  9. data/lib/arel/algebra/attributes/float.rb +9 -0
  10. data/lib/arel/algebra/attributes/integer.rb +10 -0
  11. data/lib/arel/algebra/attributes/string.rb +10 -0
  12. data/lib/arel/algebra/attributes/time.rb +6 -0
  13. data/lib/arel/algebra/core_extensions.rb +4 -0
  14. data/lib/arel/algebra/core_extensions/class.rb +32 -0
  15. data/lib/arel/algebra/core_extensions/hash.rb +11 -0
  16. data/lib/arel/algebra/core_extensions/object.rb +30 -0
  17. data/lib/arel/algebra/core_extensions/symbol.rb +9 -0
  18. data/lib/arel/algebra/expression.rb +43 -0
  19. data/lib/arel/algebra/header.rb +67 -0
  20. data/lib/arel/algebra/ordering.rb +23 -0
  21. data/lib/arel/algebra/predicates.rb +190 -0
  22. data/lib/arel/algebra/relations.rb +17 -0
  23. data/lib/arel/algebra/relations/operations/alias.rb +7 -0
  24. data/lib/arel/algebra/relations/operations/from.rb +6 -0
  25. data/lib/arel/algebra/relations/operations/group.rb +12 -0
  26. data/lib/arel/algebra/relations/operations/having.rb +17 -0
  27. data/lib/arel/algebra/relations/operations/join.rb +69 -0
  28. data/lib/arel/algebra/relations/operations/lock.rb +12 -0
  29. data/lib/arel/algebra/relations/operations/order.rb +19 -0
  30. data/lib/arel/algebra/relations/operations/project.rb +20 -0
  31. data/lib/arel/algebra/relations/operations/skip.rb +7 -0
  32. data/lib/arel/algebra/relations/operations/take.rb +11 -0
  33. data/lib/arel/algebra/relations/operations/where.rb +17 -0
  34. data/lib/arel/algebra/relations/relation.rb +136 -0
  35. data/lib/arel/algebra/relations/row.rb +26 -0
  36. data/lib/arel/algebra/relations/utilities/compound.rb +54 -0
  37. data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
  38. data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
  39. data/lib/arel/algebra/relations/writes.rb +36 -0
  40. data/lib/arel/algebra/value.rb +14 -0
  41. data/lib/arel/engines.rb +2 -0
  42. data/lib/arel/engines/memory.rb +4 -0
  43. data/lib/arel/engines/memory/engine.rb +16 -0
  44. data/lib/arel/engines/memory/predicates.rb +99 -0
  45. data/lib/arel/engines/memory/primitives.rb +27 -0
  46. data/lib/arel/engines/memory/relations.rb +5 -0
  47. data/lib/arel/engines/memory/relations/array.rb +35 -0
  48. data/lib/arel/engines/memory/relations/compound.rb +9 -0
  49. data/lib/arel/engines/memory/relations/operations.rb +67 -0
  50. data/lib/arel/engines/memory/relations/writes.rb +7 -0
  51. data/lib/arel/engines/sql.rb +8 -0
  52. data/lib/arel/engines/sql/attributes.rb +40 -0
  53. data/lib/arel/engines/sql/christener.rb +14 -0
  54. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +48 -0
  55. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
  56. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
  57. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
  58. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
  59. data/lib/arel/engines/sql/core_extensions.rb +4 -0
  60. data/lib/arel/engines/sql/core_extensions/array.rb +24 -0
  61. data/lib/arel/engines/sql/core_extensions/nil_class.rb +15 -0
  62. data/lib/arel/engines/sql/core_extensions/object.rb +19 -0
  63. data/lib/arel/engines/sql/core_extensions/range.rb +19 -0
  64. data/lib/arel/engines/sql/engine.rb +55 -0
  65. data/lib/arel/engines/sql/formatters.rb +122 -0
  66. data/lib/arel/engines/sql/predicates.rb +103 -0
  67. data/lib/arel/engines/sql/primitives.rb +97 -0
  68. data/lib/arel/engines/sql/relations.rb +10 -0
  69. data/lib/arel/engines/sql/relations/compiler.rb +118 -0
  70. data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
  71. data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
  72. data/lib/arel/engines/sql/relations/relation.rb +65 -0
  73. data/lib/arel/engines/sql/relations/table.rb +88 -0
  74. data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
  75. data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
  76. data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
  77. data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
  78. data/lib/arel/engines/sql/relations/writes.rb +19 -0
  79. data/lib/arel/session.rb +51 -0
  80. data/lib/arel/version.rb +3 -0
  81. data/spec/algebra/unit/predicates/binary_spec.rb +35 -0
  82. data/spec/algebra/unit/predicates/equality_spec.rb +29 -0
  83. data/spec/algebra/unit/predicates/in_spec.rb +12 -0
  84. data/spec/algebra/unit/primitives/attribute_spec.rb +181 -0
  85. data/spec/algebra/unit/primitives/expression_spec.rb +45 -0
  86. data/spec/algebra/unit/primitives/value_spec.rb +15 -0
  87. data/spec/algebra/unit/relations/alias_spec.rb +16 -0
  88. data/spec/algebra/unit/relations/delete_spec.rb +9 -0
  89. data/spec/algebra/unit/relations/group_spec.rb +10 -0
  90. data/spec/algebra/unit/relations/insert_spec.rb +9 -0
  91. data/spec/algebra/unit/relations/join_spec.rb +25 -0
  92. data/spec/algebra/unit/relations/order_spec.rb +21 -0
  93. data/spec/algebra/unit/relations/project_spec.rb +34 -0
  94. data/spec/algebra/unit/relations/relation_spec.rb +187 -0
  95. data/spec/algebra/unit/relations/skip_spec.rb +10 -0
  96. data/spec/algebra/unit/relations/table_spec.rb +38 -0
  97. data/spec/algebra/unit/relations/take_spec.rb +10 -0
  98. data/spec/algebra/unit/relations/update_spec.rb +9 -0
  99. data/spec/algebra/unit/relations/where_spec.rb +19 -0
  100. data/spec/algebra/unit/session/session_spec.rb +84 -0
  101. data/spec/attributes/boolean_spec.rb +57 -0
  102. data/spec/attributes/float_spec.rb +119 -0
  103. data/spec/attributes/header_spec.rb +42 -0
  104. data/spec/attributes/integer_spec.rb +119 -0
  105. data/spec/attributes/string_spec.rb +43 -0
  106. data/spec/attributes/time_spec.rb +24 -0
  107. data/spec/engines/memory/integration/joins/cross_engine_spec.rb +51 -0
  108. data/spec/engines/memory/unit/relations/array_spec.rb +32 -0
  109. data/spec/engines/memory/unit/relations/insert_spec.rb +28 -0
  110. data/spec/engines/memory/unit/relations/join_spec.rb +31 -0
  111. data/spec/engines/memory/unit/relations/order_spec.rb +27 -0
  112. data/spec/engines/memory/unit/relations/project_spec.rb +27 -0
  113. data/spec/engines/memory/unit/relations/skip_spec.rb +26 -0
  114. data/spec/engines/memory/unit/relations/take_spec.rb +26 -0
  115. data/spec/engines/memory/unit/relations/where_spec.rb +39 -0
  116. data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +258 -0
  117. data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +221 -0
  118. data/spec/engines/sql/integration/joins/with_compounds_spec.rb +137 -0
  119. data/spec/engines/sql/unit/engine_spec.rb +45 -0
  120. data/spec/engines/sql/unit/predicates/binary_spec.rb +140 -0
  121. data/spec/engines/sql/unit/predicates/equality_spec.rb +75 -0
  122. data/spec/engines/sql/unit/predicates/in_spec.rb +179 -0
  123. data/spec/engines/sql/unit/predicates/noteq_spec.rb +75 -0
  124. data/spec/engines/sql/unit/predicates/predicates_spec.rb +79 -0
  125. data/spec/engines/sql/unit/primitives/attribute_spec.rb +36 -0
  126. data/spec/engines/sql/unit/primitives/expression_spec.rb +28 -0
  127. data/spec/engines/sql/unit/primitives/literal_spec.rb +43 -0
  128. data/spec/engines/sql/unit/primitives/value_spec.rb +29 -0
  129. data/spec/engines/sql/unit/relations/alias_spec.rb +53 -0
  130. data/spec/engines/sql/unit/relations/delete_spec.rb +83 -0
  131. data/spec/engines/sql/unit/relations/from_spec.rb +64 -0
  132. data/spec/engines/sql/unit/relations/group_spec.rb +72 -0
  133. data/spec/engines/sql/unit/relations/having_spec.rb +78 -0
  134. data/spec/engines/sql/unit/relations/insert_spec.rb +143 -0
  135. data/spec/engines/sql/unit/relations/join_spec.rb +180 -0
  136. data/spec/engines/sql/unit/relations/lock_spec.rb +86 -0
  137. data/spec/engines/sql/unit/relations/order_spec.rb +161 -0
  138. data/spec/engines/sql/unit/relations/project_spec.rb +143 -0
  139. data/spec/engines/sql/unit/relations/skip_spec.rb +41 -0
  140. data/spec/engines/sql/unit/relations/table_spec.rb +129 -0
  141. data/spec/engines/sql/unit/relations/take_spec.rb +49 -0
  142. data/spec/engines/sql/unit/relations/update_spec.rb +203 -0
  143. data/spec/engines/sql/unit/relations/where_spec.rb +72 -0
  144. data/spec/relations/join_spec.rb +42 -0
  145. data/spec/relations/relation_spec.rb +31 -0
  146. data/spec/shared/relation_spec.rb +255 -0
  147. data/spec/spec_helper.rb +36 -0
  148. data/spec/support/check.rb +6 -0
  149. data/spec/support/connections/mysql_connection.rb +14 -0
  150. data/spec/support/connections/oracle_connection.rb +17 -0
  151. data/spec/support/connections/postgresql_connection.rb +13 -0
  152. data/spec/support/connections/sqlite3_connection.rb +24 -0
  153. data/spec/support/guards.rb +28 -0
  154. data/spec/support/matchers.rb +4 -0
  155. data/spec/support/matchers/be_like.rb +24 -0
  156. data/spec/support/matchers/disambiguate_attributes.rb +28 -0
  157. data/spec/support/matchers/hash_the_same_as.rb +26 -0
  158. data/spec/support/matchers/have_rows.rb +18 -0
  159. data/spec/support/model.rb +62 -0
  160. data/spec/support/schemas/mysql_schema.rb +26 -0
  161. data/spec/support/schemas/oracle_schema.rb +20 -0
  162. data/spec/support/schemas/postgresql_schema.rb +26 -0
  163. data/spec/support/schemas/sqlite3_schema.rb +26 -0
  164. metadata +258 -0
@@ -0,0 +1,17 @@
1
+ require 'arel/algebra/relations/relation'
2
+ require 'arel/algebra/relations/utilities/compound'
3
+ require 'arel/algebra/relations/utilities/nil'
4
+ require 'arel/algebra/relations/utilities/externalization'
5
+ require 'arel/algebra/relations/row'
6
+ require 'arel/algebra/relations/writes'
7
+ require 'arel/algebra/relations/operations/alias'
8
+ require 'arel/algebra/relations/operations/from'
9
+ require 'arel/algebra/relations/operations/group'
10
+ require 'arel/algebra/relations/operations/having'
11
+ require 'arel/algebra/relations/operations/join'
12
+ require 'arel/algebra/relations/operations/order'
13
+ require 'arel/algebra/relations/operations/project'
14
+ require 'arel/algebra/relations/operations/where'
15
+ require 'arel/algebra/relations/operations/skip'
16
+ require 'arel/algebra/relations/operations/take'
17
+ require 'arel/algebra/relations/operations/lock'
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ class Alias < Compound
3
+ attributes :relation
4
+ deriving :initialize
5
+ alias_method :==, :equal?
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ class From < Compound
3
+ attributes :relation, :sources
4
+ deriving :initialize, :==
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ module Arel
2
+ class Group < Compound
3
+ attributes :relation, :groupings
4
+ deriving :==
5
+
6
+ def initialize(relation, *groupings, &block)
7
+ @relation = relation
8
+ @groupings = (groupings + arguments_from_block(relation, &block)) \
9
+ .collect { |g| g.bind(relation) }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Arel
2
+ class Having < Compound
3
+ attributes :relation, :predicates
4
+ deriving :==
5
+ requires :restricting
6
+
7
+ def initialize(relation, *predicates, &block)
8
+ predicates = [yield(relation)] + predicates if block_given?
9
+ @predicates = predicates.map { |p| p.bind(relation) }
10
+ @relation = relation
11
+ end
12
+
13
+ def havings
14
+ @havings ||= relation.havings + predicates
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ module Arel
2
+ class Join
3
+ include Relation
4
+
5
+ attributes :relation1, :relation2, :predicates
6
+ deriving :==
7
+ delegate :name, :to => :relation1
8
+
9
+ def initialize(relation1, relation2 = Nil.instance, *predicates)
10
+ @relation1, @relation2, @predicates = relation1, relation2, predicates
11
+ end
12
+
13
+ def hash
14
+ @hash ||= :relation1.hash
15
+ end
16
+
17
+ def eql?(other)
18
+ self == other
19
+ end
20
+
21
+ def attributes
22
+ @attributes ||= (relation1.externalize.attributes | relation2.externalize.attributes).bind(self)
23
+ end
24
+
25
+ def wheres
26
+ # TESTME bind to self?
27
+ relation1.externalize.wheres
28
+ end
29
+
30
+ def ons
31
+ @ons ||= @predicates.collect { |p| p.bind(self) }
32
+ end
33
+
34
+ # TESTME
35
+ def externalizable?
36
+ relation1.externalizable? or relation2.externalizable?
37
+ end
38
+
39
+ def join?
40
+ true
41
+ end
42
+
43
+ def engine
44
+ relation1.engine != relation2.engine ? Memory::Engine.new : relation1.engine
45
+ end
46
+ end
47
+
48
+ class InnerJoin < Join; end
49
+ class OuterJoin < Join; end
50
+ class StringJoin < Join
51
+ def externalizable?
52
+ relation1.externalizable?
53
+ end
54
+
55
+ def attributes
56
+ relation1.externalize.attributes
57
+ end
58
+
59
+ def engine
60
+ relation1.engine
61
+ end
62
+ end
63
+
64
+ module Relation
65
+ def join?
66
+ false
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,12 @@
1
+ module Arel
2
+ class Lock < Compound
3
+ attributes :relation, :locked
4
+ deriving :initialize, :==
5
+
6
+ def initialize(relation, locked, &block)
7
+ @relation = relation
8
+ @locked = locked.blank? ? " FOR UPDATE" : locked
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,19 @@
1
+ module Arel
2
+ class Order < Compound
3
+ attributes :relation, :orderings
4
+ deriving :==
5
+ requires :ordering
6
+
7
+ def initialize(relation, *orderings, &block)
8
+ @relation = relation
9
+ @orderings = (orderings + arguments_from_block(relation, &block)) \
10
+ .collect { |o| o.bind(relation) }
11
+ end
12
+
13
+ # TESTME
14
+ def orders
15
+ # QUESTION - do we still need relation.orders ?
16
+ (orderings + relation.orders).collect { |o| o.bind(self) }.collect { |o| o.to_ordering }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Arel
2
+ class Project < Compound
3
+ attributes :relation, :projections
4
+ deriving :==
5
+
6
+ def initialize(relation, *projections, &block)
7
+ @relation = relation
8
+ @projections = (projections + arguments_from_block(relation, &block)) \
9
+ .collect { |p| p.bind(relation) }
10
+ end
11
+
12
+ def attributes
13
+ @attributes ||= Header.new(projections).bind(self)
14
+ end
15
+
16
+ def externalizable?
17
+ attributes.any? { |a| a.respond_to?(:aggregation?) && a.aggregation? } || relation.externalizable?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ class Skip < Compound
3
+ attributes :relation, :skipped
4
+ deriving :initialize, :==
5
+ requires :skipping
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ class Take < Compound
3
+ attributes :relation, :taken
4
+ deriving :initialize, :==
5
+ requires :limiting
6
+
7
+ def externalizable?
8
+ true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Arel
2
+ class Where < Compound
3
+ attributes :relation, :predicates
4
+ deriving :==
5
+ requires :restricting
6
+
7
+ def initialize(relation, *predicates, &block)
8
+ predicates = [yield(relation)] + predicates if block_given?
9
+ @predicates = predicates.map { |p| p.bind(relation) }
10
+ @relation = relation
11
+ end
12
+
13
+ def wheres
14
+ @wheres ||= relation.wheres + predicates
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,136 @@
1
+ module Arel
2
+ module Relation
3
+ attr_reader :count
4
+
5
+ def session
6
+ Session.new
7
+ end
8
+
9
+ def call
10
+ engine.read(self)
11
+ end
12
+
13
+ def bind(relation)
14
+ self
15
+ end
16
+
17
+ module Enumerable
18
+ include ::Enumerable
19
+
20
+ def each(&block)
21
+ session.read(self).each(&block)
22
+ end
23
+
24
+ def first
25
+ session.read(self).first
26
+ end
27
+ end
28
+ include Enumerable
29
+
30
+ module Operable
31
+ def join(other_relation = nil, join_class = InnerJoin)
32
+ case other_relation
33
+ when String
34
+ StringJoin.new(self, other_relation)
35
+ when Relation
36
+ JoinOperation.new(join_class, self, other_relation)
37
+ else
38
+ self
39
+ end
40
+ end
41
+
42
+ def outer_join(other_relation = nil)
43
+ join(other_relation, OuterJoin)
44
+ end
45
+
46
+ [:where, :project, :order, :take, :skip, :group, :from, :having].each do |operation_name|
47
+ class_eval <<-OPERATION, __FILE__, __LINE__
48
+ def #{operation_name}(*arguments, &block)
49
+ arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block)
50
+ end
51
+ OPERATION
52
+ end
53
+
54
+ def lock(locking = nil)
55
+ Lock.new(self, locking)
56
+ end
57
+
58
+ def alias
59
+ Alias.new(self)
60
+ end
61
+
62
+ module Writable
63
+ def insert(record)
64
+ session.create Insert.new(self, record)
65
+ end
66
+
67
+ def update(assignments)
68
+ session.update Update.new(self, assignments)
69
+ end
70
+
71
+ def delete
72
+ session.delete Deletion.new(self)
73
+ end
74
+ end
75
+ include Writable
76
+
77
+ JoinOperation = Struct.new(:join_class, :relation1, :relation2) do
78
+ def on(*predicates)
79
+ join_class.new(relation1, relation2, *predicates)
80
+ end
81
+ end
82
+ end
83
+ include Operable
84
+
85
+ module AttributeAccessable
86
+ def [](index)
87
+ attributes[index]
88
+ end
89
+
90
+ def find_attribute_matching_name(name)
91
+ attributes.detect { |a| a.named?(name) } || Attribute.new(self, name)
92
+ end
93
+
94
+ def find_attribute_matching_attribute(attribute)
95
+ matching_attributes(attribute).max do |a1, a2|
96
+ (a1.original_attribute / attribute) <=> (a2.original_attribute / attribute)
97
+ end
98
+ end
99
+
100
+ def position_of(attribute)
101
+ (@position_of ||= Hash.new do |h, attribute|
102
+ h[attribute] = attributes.index(self[attribute])
103
+ end)[attribute]
104
+ end
105
+
106
+ private
107
+ def matching_attributes(attribute)
108
+ (@matching_attributes ||= attributes.inject({}) do |hash, a|
109
+ (hash[a.is_a?(Value) ? a.value : a.root] ||= []) << a
110
+ hash
111
+ end)[attribute.root] || []
112
+ end
113
+
114
+ def has_attribute?(attribute)
115
+ !matching_attributes(attribute).empty?
116
+ end
117
+ end
118
+ include AttributeAccessable
119
+
120
+ module DefaultOperations
121
+ def attributes; Header.new end
122
+ def projections; [] end
123
+ def wheres; [] end
124
+ def orders; [] end
125
+ def inserts; [] end
126
+ def groupings; [] end
127
+ def havings; [] end
128
+ def joins(formatter = nil); nil end # FIXME
129
+ def taken; nil end
130
+ def skipped; nil end
131
+ def sources; [] end
132
+ def locked; [] end
133
+ end
134
+ include DefaultOperations
135
+ end
136
+ end
@@ -0,0 +1,26 @@
1
+ module Arel
2
+ class Row
3
+ attributes :relation, :tuple
4
+ deriving :==, :initialize
5
+
6
+ def [](attribute)
7
+ attribute.type_cast(tuple[relation.position_of(attribute)])
8
+ end
9
+
10
+ def slice(*attributes)
11
+ Row.new(relation, attributes.inject([]) do |cheese, attribute|
12
+ # FIXME TESTME method chaining
13
+ cheese << tuple[relation.relation.position_of(attribute)]
14
+ cheese
15
+ end)
16
+ end
17
+
18
+ def bind(relation)
19
+ Row.new(relation, tuple)
20
+ end
21
+
22
+ def combine(other, relation)
23
+ Row.new(relation, tuple + other.tuple)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ module Arel
2
+ class Compound
3
+ include Relation
4
+
5
+ attr_reader :relation
6
+ delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?,
7
+ :column_for, :engine, :sources, :locked, :table_alias,
8
+ :to => :relation
9
+
10
+ def self.requires(feature = nil)
11
+ @requires ||= nil
12
+ @requires = feature if feature
13
+ @requires
14
+ end
15
+
16
+ [:wheres, :groupings, :orders, :havings, :projections].each do |operation_name|
17
+ class_eval <<-OPERATION, __FILE__, __LINE__
18
+ def #{operation_name}
19
+ @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) }
20
+ end
21
+ OPERATION
22
+ end
23
+
24
+ def attributes
25
+ @attributes ||= relation.attributes.bind(self)
26
+ end
27
+
28
+ def hash
29
+ @hash ||= :relation.hash
30
+ end
31
+
32
+ def eql?(other)
33
+ self == other
34
+ end
35
+
36
+ def engine
37
+ requires = self.class.requires
38
+ engine = relation.engine
39
+
40
+ # Temporary check of whether or not the engine supports where.
41
+ if requires && engine.respond_to?(:supports) && !engine.supports(requires)
42
+ Memory::Engine.new
43
+ else
44
+ engine
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def arguments_from_block(relation, &block)
51
+ block_given?? [yield(relation)] : []
52
+ end
53
+ end
54
+ end