arel 0.4.0 → 1.0.0.rc1
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/README.markdown +24 -0
- data/lib/arel.rb +3 -1
- data/lib/arel/algebra/attributes/attribute.rb +175 -141
- data/lib/arel/algebra/core_extensions.rb +0 -1
- data/lib/arel/algebra/core_extensions/hash.rb +5 -9
- data/lib/arel/algebra/core_extensions/object.rb +0 -4
- data/lib/arel/algebra/expression.rb +37 -24
- data/lib/arel/algebra/header.rb +5 -6
- data/lib/arel/algebra/ordering.rb +13 -5
- data/lib/arel/algebra/predicates.rb +143 -27
- data/lib/arel/algebra/relations.rb +0 -1
- data/lib/arel/algebra/relations/operations/from.rb +10 -2
- data/lib/arel/algebra/relations/operations/group.rb +8 -6
- data/lib/arel/algebra/relations/operations/having.rb +3 -6
- data/lib/arel/algebra/relations/operations/join.rb +52 -18
- data/lib/arel/algebra/relations/operations/lock.rb +4 -6
- data/lib/arel/algebra/relations/operations/order.rb +11 -7
- data/lib/arel/algebra/relations/operations/project.rb +10 -10
- data/lib/arel/algebra/relations/operations/skip.rb +10 -3
- data/lib/arel/algebra/relations/operations/take.rb +10 -3
- data/lib/arel/algebra/relations/operations/where.rb +12 -6
- data/lib/arel/algebra/relations/relation.rb +161 -92
- data/lib/arel/algebra/relations/row.rb +8 -5
- data/lib/arel/algebra/relations/utilities/compound.rb +34 -33
- data/lib/arel/algebra/relations/utilities/externalization.rb +10 -8
- data/lib/arel/algebra/relations/writes.rb +24 -13
- data/lib/arel/algebra/value.rb +41 -2
- data/lib/arel/engines/memory.rb +0 -2
- data/lib/arel/engines/memory/engine.rb +3 -9
- data/lib/arel/engines/memory/relations.rb +0 -3
- data/lib/arel/engines/memory/relations/array.rb +5 -3
- data/lib/arel/engines/memory/relations/operations.rb +2 -60
- data/lib/arel/engines/sql.rb +0 -2
- data/lib/arel/engines/sql/christener.rb +12 -6
- data/lib/arel/engines/sql/compilers/oracle_compiler.rb +34 -23
- data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +23 -15
- data/lib/arel/engines/sql/engine.rb +19 -27
- data/lib/arel/engines/sql/formatters.rb +26 -10
- data/lib/arel/engines/sql/relations.rb +0 -7
- data/lib/arel/engines/sql/relations/compiler.rb +70 -35
- data/lib/arel/engines/sql/relations/table.rb +44 -32
- data/lib/arel/{engines/sql/relations/utilities/recursion.rb → recursion/base_case.rb} +0 -0
- data/lib/arel/session.rb +24 -40
- data/lib/arel/sql_literal.rb +13 -0
- data/lib/arel/version.rb +1 -1
- data/spec/algebra/unit/predicates/inequality_spec.rb +32 -0
- data/spec/algebra/unit/predicates/predicate_spec.rb +22 -0
- data/spec/algebra/unit/primitives/attribute_spec.rb +3 -9
- data/spec/algebra/unit/primitives/expression_spec.rb +1 -7
- data/spec/algebra/unit/relations/join_spec.rb +0 -7
- data/spec/algebra/unit/relations/project_spec.rb +3 -3
- data/spec/algebra/unit/relations/relation_spec.rb +74 -25
- data/spec/algebra/unit/session/session_spec.rb +7 -7
- data/spec/engines/memory/integration/joins/cross_engine_spec.rb +20 -10
- data/spec/engines/memory/unit/relations/array_spec.rb +6 -5
- data/spec/engines/memory/unit/relations/join_spec.rb +7 -6
- data/spec/engines/memory/unit/relations/order_spec.rb +7 -6
- data/spec/engines/memory/unit/relations/project_spec.rb +6 -6
- data/spec/engines/memory/unit/relations/skip_spec.rb +10 -5
- data/spec/engines/memory/unit/relations/take_spec.rb +7 -5
- data/spec/engines/memory/unit/relations/where_spec.rb +13 -9
- data/spec/engines/sql/unit/engine_spec.rb +20 -0
- data/spec/engines/sql/unit/relations/group_spec.rb +2 -2
- data/spec/engines/sql/unit/relations/order_spec.rb +5 -5
- data/spec/engines/sql/unit/relations/project_spec.rb +4 -4
- data/spec/engines/sql/unit/relations/table_spec.rb +0 -7
- data/spec/engines/sql/unit/relations/take_spec.rb +26 -0
- data/spec/engines/sql/unit/relations/where_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -4
- data/spec/sql/christener_spec.rb +70 -0
- data/spec/support/model.rb +7 -2
- metadata +109 -23
- data/lib/arel/algebra/core_extensions/class.rb +0 -32
- data/lib/arel/algebra/relations/operations/alias.rb +0 -7
- data/lib/arel/engines/memory/predicates.rb +0 -99
- data/lib/arel/engines/memory/primitives.rb +0 -27
- data/lib/arel/engines/memory/relations/compound.rb +0 -9
- data/lib/arel/engines/memory/relations/writes.rb +0 -7
- data/lib/arel/engines/sql/predicates.rb +0 -103
- data/lib/arel/engines/sql/primitives.rb +0 -97
- data/lib/arel/engines/sql/relations/operations/alias.rb +0 -5
- data/lib/arel/engines/sql/relations/operations/join.rb +0 -33
- data/lib/arel/engines/sql/relations/relation.rb +0 -65
- data/lib/arel/engines/sql/relations/utilities/compound.rb +0 -10
- data/lib/arel/engines/sql/relations/utilities/externalization.rb +0 -14
- data/lib/arel/engines/sql/relations/writes.rb +0 -19
File without changes
|
data/lib/arel/session.rb
CHANGED
@@ -1,51 +1,35 @@
|
|
1
1
|
module Arel
|
2
2
|
class Session
|
3
|
-
|
4
|
-
attr_accessor :instance
|
5
|
-
alias_method :manufacture, :new
|
3
|
+
@instance = nil
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
yield
|
10
|
-
else
|
11
|
-
begin
|
12
|
-
@started = true
|
13
|
-
@instance = manufacture
|
14
|
-
singleton_class.class_eval do
|
15
|
-
undef :new
|
16
|
-
alias_method :new, :instance
|
17
|
-
end
|
18
|
-
yield
|
19
|
-
ensure
|
20
|
-
singleton_class.class_eval do
|
21
|
-
undef :new
|
22
|
-
alias_method :new, :manufacture
|
23
|
-
end
|
24
|
-
@started = false
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
5
|
+
def self.instance
|
6
|
+
@instance || new
|
28
7
|
end
|
29
8
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
9
|
+
def self.start
|
10
|
+
@instance ||= new
|
11
|
+
yield @instance
|
12
|
+
ensure
|
13
|
+
@instance = nil
|
14
|
+
end
|
34
15
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end)[select]
|
39
|
-
end
|
16
|
+
def create(insert)
|
17
|
+
insert.call
|
18
|
+
end
|
40
19
|
|
41
|
-
|
42
|
-
|
43
|
-
|
20
|
+
def read(select)
|
21
|
+
@read ||= {}
|
22
|
+
key = select.object_id
|
23
|
+
return @read[key] if @read.key? key
|
24
|
+
@read[key] = select.call
|
25
|
+
end
|
26
|
+
|
27
|
+
def update(update)
|
28
|
+
update.call
|
29
|
+
end
|
44
30
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
31
|
+
def delete(delete)
|
32
|
+
delete.call
|
48
33
|
end
|
49
|
-
include CRUD
|
50
34
|
end
|
51
35
|
end
|
data/lib/arel/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Predicates
|
5
|
+
describe Inequality do
|
6
|
+
before do
|
7
|
+
relation1 = Arel::Table.new(:users)
|
8
|
+
relation2 = Arel::Table.new(:photos)
|
9
|
+
left = relation1[:id]
|
10
|
+
right = relation2[:user_id]
|
11
|
+
@a = Inequality.new(left, right)
|
12
|
+
@b = Inequality.new(right, left)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'operator' do
|
16
|
+
it "should have one" do
|
17
|
+
@a.operator.should == :"!="
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '==' do
|
22
|
+
it "is equal to itself" do
|
23
|
+
@a.should == @a
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should not care abount children order" do
|
27
|
+
@a.should == @b
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Predicates
|
5
|
+
describe Polyadic do
|
6
|
+
before do
|
7
|
+
@relation1 = Arel::Table.new(:users)
|
8
|
+
@relation2 = Arel::Table.new(:photos)
|
9
|
+
@a = @relation1[:id]
|
10
|
+
@b = @relation2[:user_id]
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '==' do
|
14
|
+
left = Polyadic.new @a, @b
|
15
|
+
right = Polyadic.new @b, @a
|
16
|
+
|
17
|
+
left.should != right
|
18
|
+
left.should == right
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -7,13 +7,7 @@ module Arel
|
|
7
7
|
@attribute = @relation[:id]
|
8
8
|
end
|
9
9
|
|
10
|
-
describe
|
11
|
-
it "returns a simple, short inspect string" do
|
12
|
-
@attribute.inspect.should == "<Attribute id>"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe Attribute::Transformations do
|
10
|
+
describe 'Attribute::Transformations' do
|
17
11
|
describe '#as' do
|
18
12
|
it "manufactures an aliased attributed" do
|
19
13
|
@attribute.as(:alias).should == Attribute.new(@relation, @attribute.name, :alias => :alias, :ancestor => @attribute)
|
@@ -58,7 +52,7 @@ module Arel
|
|
58
52
|
end
|
59
53
|
end
|
60
54
|
|
61
|
-
describe Attribute::Congruence do
|
55
|
+
describe 'Attribute::Congruence' do
|
62
56
|
describe '/' do
|
63
57
|
before do
|
64
58
|
@aliased_relation = @relation.alias
|
@@ -80,7 +74,7 @@ module Arel
|
|
80
74
|
end
|
81
75
|
end
|
82
76
|
|
83
|
-
describe Attribute::Predications do
|
77
|
+
describe 'Attribute::Predications' do
|
84
78
|
before do
|
85
79
|
@attribute = Attribute.new(@relation, :name)
|
86
80
|
end
|
@@ -7,13 +7,7 @@ module Arel
|
|
7
7
|
@attribute = @relation[:id]
|
8
8
|
end
|
9
9
|
|
10
|
-
describe
|
11
|
-
it "returns a simple, short inspect string" do
|
12
|
-
@attribute.count.inspect.should == "<Arel::Count <Attribute id>>"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe Expression::Transformations do
|
10
|
+
describe 'Expression::Transformations' do
|
17
11
|
before do
|
18
12
|
@expression = Count.new(@attribute)
|
19
13
|
end
|
@@ -8,13 +8,6 @@ module Arel
|
|
8
8
|
@predicate = @relation1[:id].eq(@relation2[:user_id])
|
9
9
|
end
|
10
10
|
|
11
|
-
describe 'hashing' do
|
12
|
-
it 'implements hash equality' do
|
13
|
-
InnerJoin.new(@relation1, @relation2, @predicate) \
|
14
|
-
.should hash_the_same_as(InnerJoin.new(@relation1, @relation2, @predicate))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
11
|
describe '#attributes' do
|
19
12
|
it 'combines the attributes of the two relations' do
|
20
13
|
join = InnerJoin.new(@relation1, @relation2, @predicate)
|
@@ -9,7 +9,7 @@ module Arel
|
|
9
9
|
|
10
10
|
describe '#attributes' do
|
11
11
|
before do
|
12
|
-
@projection = Project.new(@relation, @attribute)
|
12
|
+
@projection = Project.new(@relation, [@attribute])
|
13
13
|
end
|
14
14
|
|
15
15
|
it "manufactures attributes associated with the projection relation" do
|
@@ -20,13 +20,13 @@ module Arel
|
|
20
20
|
describe '#externalizable?' do
|
21
21
|
describe 'when the projections are attributes' do
|
22
22
|
it 'returns false' do
|
23
|
-
Project.new(@relation, @attribute).should_not be_externalizable
|
23
|
+
Project.new(@relation, [@attribute]).should_not be_externalizable
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
describe 'when the projections include an aggregation' do
|
28
28
|
it "obtains" do
|
29
|
-
Project.new(@relation, @attribute.sum).should be_externalizable
|
29
|
+
Project.new(@relation, [@attribute.sum]).should be_externalizable
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -23,7 +23,7 @@ module Arel
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
describe Relation::Operable do
|
26
|
+
describe 'Relation::Operable' do
|
27
27
|
describe 'joins' do
|
28
28
|
before do
|
29
29
|
@predicate = @relation[:id].eq(@relation[:id])
|
@@ -32,14 +32,23 @@ module Arel
|
|
32
32
|
describe '#join' do
|
33
33
|
describe 'when given a relation' do
|
34
34
|
it "manufactures an inner join operation between those two relations" do
|
35
|
-
@relation.join(@relation).on(@predicate)
|
36
|
-
|
35
|
+
join = @relation.join(@relation).on(@predicate)
|
36
|
+
join.relation1.should == @relation
|
37
|
+
join.relation2.should == @relation
|
38
|
+
join.predicates.should == [@predicate]
|
39
|
+
join.should be_kind_of(InnerJoin)
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
40
43
|
describe "when given a string" do
|
41
44
|
it "manufactures a join operation with the string passed through" do
|
42
|
-
|
45
|
+
arbitrary_string = "ASDF"
|
46
|
+
|
47
|
+
join = @relation.join(arbitrary_string)
|
48
|
+
join.relation1.should == @relation
|
49
|
+
join.relation2.should == arbitrary_string
|
50
|
+
join.predicates.should == []
|
51
|
+
join.should be_kind_of StringJoin
|
43
52
|
end
|
44
53
|
end
|
45
54
|
|
@@ -52,16 +61,21 @@ module Arel
|
|
52
61
|
|
53
62
|
describe '#outer_join' do
|
54
63
|
it "manufactures a left outer join operation between those two relations" do
|
55
|
-
@relation.outer_join(@relation).on(@predicate)
|
56
|
-
|
64
|
+
join = @relation.outer_join(@relation).on(@predicate)
|
65
|
+
join.relation1.should == @relation
|
66
|
+
join.relation2.should == @relation
|
67
|
+
join.predicates.should == [@predicate]
|
68
|
+
join.should be_kind_of OuterJoin
|
57
69
|
end
|
58
70
|
end
|
59
71
|
end
|
60
72
|
|
61
73
|
describe '#project' do
|
62
74
|
it "manufactures a projection relation" do
|
63
|
-
@relation.project(@attribute1, @attribute2)
|
64
|
-
|
75
|
+
project = @relation.project(@attribute1, @attribute2)
|
76
|
+
project.relation.should == @relation
|
77
|
+
project.projections.should == [@attribute1, @attribute2]
|
78
|
+
project.should be_kind_of Project
|
65
79
|
end
|
66
80
|
|
67
81
|
describe "when given blank attributes" do
|
@@ -83,11 +97,20 @@ module Arel
|
|
83
97
|
end
|
84
98
|
|
85
99
|
it "manufactures a where relation" do
|
86
|
-
@relation.where(@predicate)
|
100
|
+
where = @relation.where(@predicate)
|
101
|
+
where.relation.should == @relation
|
102
|
+
where.predicates.should == [@predicate]
|
103
|
+
where.should be_kind_of Where
|
87
104
|
end
|
88
105
|
|
89
106
|
it "accepts arbitrary strings" do
|
90
|
-
@relation.where("arbitrary")
|
107
|
+
where = @relation.where("arbitrary")
|
108
|
+
where.relation.should == @relation
|
109
|
+
|
110
|
+
where.predicates.length.should == 1
|
111
|
+
where.predicates.first.value.should == "arbitrary"
|
112
|
+
|
113
|
+
where.should be_kind_of Where
|
91
114
|
end
|
92
115
|
|
93
116
|
describe 'when given a blank predicate' do
|
@@ -99,7 +122,10 @@ module Arel
|
|
99
122
|
|
100
123
|
describe '#order' do
|
101
124
|
it "manufactures an order relation" do
|
102
|
-
@relation.order(@attribute1, @attribute2)
|
125
|
+
order = @relation.order(@attribute1, @attribute2)
|
126
|
+
order.relation.should == @relation
|
127
|
+
order.orderings.should == [@attribute1, @attribute2]
|
128
|
+
order.should be_kind_of Order
|
103
129
|
end
|
104
130
|
|
105
131
|
describe 'when given a blank ordering' do
|
@@ -111,19 +137,24 @@ module Arel
|
|
111
137
|
|
112
138
|
describe '#take' do
|
113
139
|
it "manufactures a take relation" do
|
114
|
-
@relation.take(5)
|
140
|
+
take = @relation.take(5)
|
141
|
+
take.relation.should == @relation
|
142
|
+
take.taken.should == 5
|
115
143
|
end
|
116
144
|
|
117
145
|
describe 'when given a blank number of items' do
|
118
|
-
it '
|
119
|
-
@relation.take.should
|
146
|
+
it 'raises error' do
|
147
|
+
lambda { @relation.take }.should raise_exception
|
120
148
|
end
|
121
149
|
end
|
122
150
|
end
|
123
151
|
|
124
152
|
describe '#skip' do
|
125
153
|
it "manufactures a skip relation" do
|
126
|
-
@relation.skip(4)
|
154
|
+
skip = @relation.skip(4)
|
155
|
+
skip.relation.should == @relation
|
156
|
+
skip.skipped.should == 4
|
157
|
+
skip.should be_kind_of Skip
|
127
158
|
end
|
128
159
|
|
129
160
|
describe 'when given a blank number of items' do
|
@@ -135,7 +166,12 @@ module Arel
|
|
135
166
|
|
136
167
|
describe '#group' do
|
137
168
|
it 'manufactures a group relation' do
|
138
|
-
@relation.group(@attribute1, @attribute2)
|
169
|
+
group = @relation.group(@attribute1, @attribute2)
|
170
|
+
group.relation.should == @relation
|
171
|
+
group.groupings.should == [@attribute1, @attribute2]
|
172
|
+
group.should be_kind_of Group
|
173
|
+
sql = group.to_sql
|
174
|
+
sql.should =~ /GROUP BY/
|
139
175
|
end
|
140
176
|
|
141
177
|
describe 'when given blank groupings' do
|
@@ -145,11 +181,14 @@ module Arel
|
|
145
181
|
end
|
146
182
|
end
|
147
183
|
|
148
|
-
describe
|
184
|
+
describe 'relation is writable' do
|
149
185
|
describe '#delete' do
|
150
186
|
it 'manufactures a deletion relation' do
|
151
|
-
Session.start do
|
152
|
-
|
187
|
+
Session.start do |s|
|
188
|
+
s.should_receive(:delete) do |delete|
|
189
|
+
delete.relation.should == @relation
|
190
|
+
delete.should be_kind_of Deletion
|
191
|
+
end
|
153
192
|
@relation.delete
|
154
193
|
end
|
155
194
|
end
|
@@ -157,9 +196,14 @@ module Arel
|
|
157
196
|
|
158
197
|
describe '#insert' do
|
159
198
|
it 'manufactures an insertion relation' do
|
160
|
-
Session.start do
|
161
|
-
record = { @relation[:name] => 'carl' }
|
162
|
-
|
199
|
+
Session.start do |s|
|
200
|
+
record = { @relation[:name] => Value.new('carl', @relation) }
|
201
|
+
s.should_receive(:create) do |insert|
|
202
|
+
insert.relation.should == @relation
|
203
|
+
insert.record.should == record
|
204
|
+
insert.should be_kind_of Insert
|
205
|
+
insert
|
206
|
+
end
|
163
207
|
@relation.insert(record)
|
164
208
|
end
|
165
209
|
end
|
@@ -167,9 +211,14 @@ module Arel
|
|
167
211
|
|
168
212
|
describe '#update' do
|
169
213
|
it 'manufactures an update relation' do
|
170
|
-
Session.start do
|
214
|
+
Session.start do |s|
|
171
215
|
assignments = { @relation[:name] => Value.new('bob', @relation) }
|
172
|
-
|
216
|
+
s.should_receive(:update) do |update|
|
217
|
+
update.relation.should == @relation
|
218
|
+
update.assignments.should == assignments
|
219
|
+
update.should be_kind_of Update
|
220
|
+
update
|
221
|
+
end
|
173
222
|
@relation.update(assignments)
|
174
223
|
end
|
175
224
|
end
|
@@ -177,7 +226,7 @@ module Arel
|
|
177
226
|
end
|
178
227
|
end
|
179
228
|
|
180
|
-
describe
|
229
|
+
describe 'is enumerable' do
|
181
230
|
it "implements enumerable" do
|
182
231
|
@relation.map { |value| value }.should ==
|
183
232
|
@relation.session.read(@relation).map { |value| value }
|
@@ -10,16 +10,16 @@ module Arel
|
|
10
10
|
describe '::start' do
|
11
11
|
describe '::instance' do
|
12
12
|
it "it is a singleton within the started session" do
|
13
|
-
Session.start do
|
14
|
-
Session.
|
13
|
+
Session.start do |session|
|
14
|
+
Session.instance.should == session
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
it "is a singleton across nested sessions" do
|
19
|
-
Session.start do
|
20
|
-
outside = Session.
|
21
|
-
Session.start do
|
22
|
-
Session.
|
19
|
+
Session.start do |s1|
|
20
|
+
outside = Session.instance
|
21
|
+
Session.start do |s2|
|
22
|
+
Session.instance.should == outside
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -30,7 +30,7 @@ module Arel
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
describe
|
33
|
+
describe 'session crud' do
|
34
34
|
before do
|
35
35
|
@insert = Insert.new(@relation, @relation[:name] => 'nick')
|
36
36
|
@update = Update.new(@relation, @relation[:name] => 'nick')
|