alf-sequel 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Gemfile +10 -7
  2. data/Gemfile.lock +26 -14
  3. data/README.md +45 -3
  4. data/lib/alf/sequel.rb +1 -0
  5. data/lib/alf/sequel/cog.rb +23 -75
  6. data/lib/alf/sequel/compiler.rb +8 -198
  7. data/lib/alf/sequel/connection.rb +5 -1
  8. data/lib/alf/sequel/connection/connection_methods.rb +4 -2
  9. data/lib/alf/sequel/connection/schema_methods.rb +2 -6
  10. data/lib/alf/sequel/connection/update_methods.rb +1 -1
  11. data/lib/alf/sequel/loader.rb +1 -0
  12. data/lib/alf/sequel/translator.rb +198 -0
  13. data/lib/alf/sequel/unit_of_work/insert.rb +10 -4
  14. data/lib/alf/sequel/unit_of_work/update.rb +3 -3
  15. data/lib/alf/sequel/version.rb +1 -1
  16. data/spec/connection/test_heading.rb +1 -1
  17. data/spec/{fixtures/sap.db → sap.db} +0 -0
  18. data/spec/spec_helper.rb +48 -6
  19. data/spec/unit_of_work/delete/test_delete.rb +2 -2
  20. data/spec/unit_of_work/insert/test_run.rb +12 -14
  21. data/spec/unit_of_work/update/test_run.rb +1 -1
  22. data/tasks/bench.rake +40 -0
  23. data/tasks/test.rake +3 -3
  24. metadata +29 -29
  25. data/lib/alf/sequel/compiler/predicate.rb +0 -76
  26. data/spec/alf.db +0 -0
  27. data/spec/compiler/test_clip.rb +0 -40
  28. data/spec/compiler/test_compact.rb +0 -18
  29. data/spec/compiler/test_extend.rb +0 -16
  30. data/spec/compiler/test_frame.rb +0 -89
  31. data/spec/compiler/test_intersect.rb +0 -18
  32. data/spec/compiler/test_join.rb +0 -26
  33. data/spec/compiler/test_leaf_operand.rb +0 -24
  34. data/spec/compiler/test_matching.rb +0 -34
  35. data/spec/compiler/test_not_matching.rb +0 -34
  36. data/spec/compiler/test_page.rb +0 -86
  37. data/spec/compiler/test_predicate.rb +0 -141
  38. data/spec/compiler/test_project.rb +0 -64
  39. data/spec/compiler/test_rename.rb +0 -26
  40. data/spec/compiler/test_restrict.rb +0 -48
  41. data/spec/compiler/test_sort.rb +0 -18
  42. data/spec/compiler/test_union.rb +0 -18
  43. data/spec/compiler_helper.rb +0 -34
  44. data/spec/fixtures/sap.rb +0 -43
  45. data/tasks/fixtures.rake +0 -12
@@ -1,18 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "intersect" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when the operand is fully compilable' do
9
- let(:expr){ intersect(suppliers, supplies) }
10
-
11
- specify do
12
- subject.sql.should eq("SELECT * FROM (SELECT * FROM `suppliers` AS 't1' INTERSECT SELECT * FROM `supplies` AS 't2') AS 't3'")
13
- end
14
- end
15
-
16
- end
17
- end
18
- end
@@ -1,26 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "join" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when the operand is fully compilable' do
9
- let(:expr){ join(suppliers, supplies) }
10
-
11
- specify do
12
- subject.sql.should eq("SELECT * FROM (SELECT * FROM (SELECT * FROM `suppliers` AS 't1') AS 't1' INNER JOIN (SELECT * FROM `supplies` AS 't2') AS 't3' USING (`sid`)) AS 't3'")
13
- end
14
- end
15
-
16
- context 'when the left operand is a projection' do
17
- let(:expr){ join(project(suppliers, [:sid]), supplies) }
18
-
19
- specify do
20
- subject.sql.should eq("SELECT * FROM (SELECT * FROM (SELECT `t1`.`sid` FROM `suppliers` AS 't1') AS 't1' INNER JOIN (SELECT * FROM `supplies` AS 't2') AS 't3' USING (`sid`)) AS 't3'")
21
- end
22
- end
23
-
24
- end
25
- end
26
- end
@@ -1,24 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "leaf_operand" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'on the proper context' do
9
- let(:expr){ suppliers }
10
-
11
- it{ should be_a(Cog) }
12
- end
13
-
14
- context 'on another context' do
15
- let(:expr){ Algebra.named_operand(:suppliers, self) }
16
-
17
- pending "support for multiple context is needed" do
18
- it{ should_not be_a(Cog) }
19
- end
20
- end
21
-
22
- end
23
- end
24
- end
@@ -1,34 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "matching" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when no common attributes' do
9
- let(:expr){ matching(suppliers, project(supplies, [:part_id])) }
10
-
11
- specify do
12
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (EXISTS (SELECT DISTINCT `t2`.`part_id` FROM `supplies` AS 't2'))")
13
- end
14
- end
15
-
16
- context 'when only one common attributes' do
17
- let(:expr){ matching(suppliers, supplies) }
18
-
19
- specify do
20
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (`t1`.`sid` IN (SELECT `t2`.`sid` FROM `supplies` AS 't2'))")
21
- end
22
- end
23
-
24
- context 'when many common attributes' do
25
- let(:expr){ matching(suppliers, parts) }
26
-
27
- specify do
28
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (EXISTS (SELECT * FROM `parts` AS 't2' WHERE ((`t1`.`name` = `t2`.`name`) AND (`t1`.`city` = `t2`.`city`))))")
29
- end
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,34 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "not_matching" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when no common attributes' do
9
- let(:expr){ not_matching(suppliers, project(supplies, [:part_id])) }
10
-
11
- specify do
12
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE NOT (EXISTS (SELECT DISTINCT `t2`.`part_id` FROM `supplies` AS 't2'))")
13
- end
14
- end
15
-
16
- context 'when only one common attributes' do
17
- let(:expr){ not_matching(suppliers, supplies) }
18
-
19
- specify do
20
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (`t1`.`sid` NOT IN (SELECT `t2`.`sid` FROM `supplies` AS 't2'))")
21
- end
22
- end
23
-
24
- context 'when many common attributes' do
25
- let(:expr){ not_matching(suppliers, parts) }
26
-
27
- specify do
28
- subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE NOT (EXISTS (SELECT * FROM `parts` AS 't2' WHERE ((`t1`.`name` = `t2`.`name`) AND (`t1`.`city` = `t2`.`city`))))")
29
- end
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,86 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "page" do
5
-
6
- subject{ compile(expr) }
7
-
8
- let(:expr){
9
- page(operand, ordering, page_index, page_size: 8)
10
- }
11
-
12
- context 'when fully compilable' do
13
- let(:operand){ suppliers }
14
-
15
- [
16
- [ [[:name, :asc]], 2, "SELECT * FROM `suppliers` AS 't1' ORDER BY `t1`.`name` ASC LIMIT 8 OFFSET 8" ],
17
- [ [[:name, :asc]], -2, "SELECT * FROM `suppliers` AS 't1' ORDER BY `t1`.`name` DESC LIMIT 8 OFFSET 8" ],
18
- [ [[:city, :asc]], 2, "SELECT * FROM `suppliers` AS 't1' ORDER BY `t1`.`city` ASC, `t1`.`sid` ASC LIMIT 8 OFFSET 8" ],
19
- [ [[:city, :asc]], -2, "SELECT * FROM `suppliers` AS 't1' ORDER BY `t1`.`city` DESC, `t1`.`sid` DESC LIMIT 8 OFFSET 8" ],
20
- ].each do |(ordering,page_index,expected)|
21
-
22
- context "page(#{ordering}, #{page_index})" do
23
- let(:ordering) { ordering }
24
- let(:page_index){ page_index }
25
-
26
- it 'should compile as expected' do
27
- subject.sql.should eq(expected)
28
- end
29
- end
30
-
31
- end
32
- end # fully compilable
33
-
34
- context 'when immediately uncompilable yet known keys' do
35
- let(:operand){
36
- Algebra::Operand::Fake.new.with_keys([:sid], [:name])
37
- }
38
-
39
- [
40
- [ [[:name, :asc]], 2, [[:name, :asc]] ],
41
- [ [[:city, :asc]], 2, [[:city, :asc], [:sid, :asc]] ]
42
- ].each do |ordering, page_index, expected|
43
-
44
- context "page(#{ordering}, #{page_index})" do
45
- let(:ordering) { ordering }
46
- let(:page_index){ page_index }
47
-
48
- it{ should be_a(Engine::Take) }
49
-
50
- it 'should have sort with good ordering' do
51
- subject.operand.should be_a(Engine::Sort)
52
- subject.operand.ordering.should eq(Ordering.new(expected))
53
- end
54
- end
55
-
56
- end
57
- end
58
-
59
- context 'when immediately uncompilable yet unknown keys' do
60
- let(:operand){
61
- Algebra::Operand::Fake.new
62
- }
63
-
64
- [
65
- [ [[:name, :asc]], 2, [[:name, :asc]] ],
66
- [ [[:city, :asc]], 2, [[:city, :asc]] ]
67
- ].each do |ordering, page_index, expected|
68
-
69
- context "page(#{ordering}, #{page_index})" do
70
- let(:ordering) { ordering }
71
- let(:page_index){ page_index }
72
-
73
- it{ should be_a(Engine::Take) }
74
-
75
- it 'should have sort with good ordering' do
76
- subject.operand.should be_a(Engine::Sort)
77
- subject.operand.ordering.should eq(Ordering.new(expected))
78
- end
79
- end
80
-
81
- end
82
- end
83
-
84
- end
85
- end
86
- end
@@ -1,141 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- class Compiler
5
- describe Predicate do
6
-
7
- let(:p) { Alf::Predicate }
8
- let(:compiler) { Predicate.new }
9
- let(:dataset) { sap.cog(:suppliers).dataset }
10
- let(:compiled) { compiler.call(expr) }
11
-
12
- subject{ dataset.literal(compiled) }
13
-
14
- context 'tautology' do
15
- let(:expr){ p.tautology }
16
-
17
- it{ should eq("(1 = 1)") }
18
- end
19
-
20
- context 'contradiction' do
21
- let(:expr){ p.contradiction }
22
-
23
- it{ should eq("(1 = 0)") }
24
- end
25
-
26
- context 'var_ref' do
27
- let(:expr){ p.var_ref(:x) }
28
-
29
- it{ should eq("`x`") }
30
- end
31
-
32
- context 'literal' do
33
- let(:expr){ p.literal(12) }
34
-
35
- it{ should eq("12") }
36
- end
37
-
38
- context 'eq(var, literal)' do
39
- let(:expr){ p.eq(:x, 12) }
40
-
41
- it{ should eq("(`x` = 12)") }
42
- end
43
-
44
- context 'neq(var, literal)' do
45
- let(:expr){ p.neq(:x, 12) }
46
-
47
- it{ should eq("(`x` != 12)") }
48
- end
49
-
50
- context 'eq(var, nil)' do
51
- let(:expr){ p.eq(:x, nil) }
52
-
53
- it{ should eq("(`x` IS NULL)") }
54
- end
55
-
56
- context 'eq(var, var)' do
57
- let(:expr){ p.eq(:x, :y) }
58
-
59
- it{ should eq("(`x` = `y`)") }
60
- end
61
-
62
- context 'lt(var, literal)' do
63
- let(:expr){ p.lt(:x, 2) }
64
-
65
- it{ should eq("(`x` < 2)") }
66
- end
67
-
68
- context 'lte(var, literal)' do
69
- let(:expr){ p.lte(:x, 2) }
70
-
71
- it{ should eq("(`x` <= 2)") }
72
- end
73
-
74
- context 'gt(var, literal)' do
75
- let(:expr){ p.gt(:x, 2) }
76
-
77
- it{ should eq("(`x` > 2)") }
78
- end
79
-
80
- context 'gte(var, literal)' do
81
- let(:expr){ p.gte(:x, 2) }
82
-
83
- it{ should eq("(`x` >= 2)") }
84
- end
85
-
86
- context 'not(var)' do
87
- let(:expr){ p.not(:x) }
88
-
89
- it{ should eq("NOT `x`") }
90
- end
91
-
92
- context 'not(tautology)' do
93
- let(:expr){ p.not(true) }
94
-
95
- it{ should eq("(1 = 0)") }
96
- end
97
-
98
- context 'and' do
99
- let(:expr){ p.eq(:x, 2) & p.eq(:y, 3) }
100
-
101
- it{ should eq("((`x` = 2) AND (`y` = 3))") }
102
- end
103
-
104
- context 'or' do
105
- let(:expr){ p.eq(:x, 2) | p.eq(:y, 3) }
106
-
107
- it{ should eq("((`x` = 2) OR (`y` = 3))") }
108
- end
109
-
110
- context 'comp' do
111
- let(:expr){ p.comp(:lt, :x => 2, :y => 3) }
112
-
113
- it{ should eq("((`x` < 2) AND (`y` < 3))") }
114
- end
115
-
116
- context 'in' do
117
- let(:expr){ p.in(:x, [2, 3]) }
118
-
119
- it{ should eq("(`x` IN (2, 3))") }
120
- end
121
-
122
- context 'in with a dataset at right' do
123
- let(:expr){ p.in(:x, dataset) }
124
-
125
- it{ should eq("(`x` IN (SELECT * FROM `suppliers`))") }
126
- end
127
-
128
- context 'native' do
129
- let(:expr){ p.native(lambda{}) }
130
-
131
- specify{
132
- lambda{
133
- subject
134
- }.should throw_symbol(:pass)
135
- }
136
- end
137
-
138
- end
139
- end
140
- end
141
- end
@@ -1,64 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "project" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when the operand is fully compilable' do
9
- let(:expr){ project(suppliers, [:sid, :name]) }
10
-
11
- specify{
12
- subject.sql.should eq("SELECT `t1`.`sid`, `t1`.`name` FROM `suppliers` AS 't1'")
13
- }
14
- end
15
-
16
- context 'when the operand is fully compilable (distinct needed)' do
17
- let(:expr){ project(suppliers, [:city]) }
18
-
19
- specify{
20
- subject.sql.should eq("SELECT DISTINCT `t1`.`city` FROM `suppliers` AS 't1'")
21
- }
22
- end
23
-
24
- context 'when the operand is a restriction on a key part' do
25
- let(:expr){ project(restrict(supplies, Predicate.eq(:sid, 1)), [:pid]) }
26
-
27
- specify{
28
- subject.sql.should eq("SELECT `t1`.`pid` FROM `supplies` AS 't1' WHERE (`t1`.`sid` = 1)")
29
- }
30
- end
31
-
32
- context 'when the operand is a restriction on the key' do
33
- let(:expr){ project(restrict(suppliers, Predicate.eq(:sid, 1)), [:sid]) }
34
-
35
- specify{
36
- subject.sql.should eq("SELECT `t1`.`sid` FROM `suppliers` AS 't1' WHERE (`t1`.`sid` = 1)")
37
- }
38
- end
39
-
40
- context 'when the operand is fully compilable (allbut, distinct)' do
41
- let(:expr){ project(suppliers, [:sid, :name, :status], :allbut => true) }
42
-
43
- specify{
44
- subject.sql.should eq("SELECT DISTINCT `t1`.`city` FROM `suppliers` AS 't1'")
45
- }
46
- end
47
-
48
- context 'when the operand is a renaming' do
49
- let(:expr){ project(rename(suppliers, :sid => :supplier_id), [:supplier_id]) }
50
-
51
- specify{
52
- subject.sql.should eq("SELECT `t2`.`supplier_id` AS 'supplier_id' FROM (SELECT `t1`.`sid` AS 'supplier_id', `t1`.`name` AS 'name', `t1`.`status` AS 'status', `t1`.`city` AS 'city' FROM `suppliers` AS 't1') AS 't2'")
53
- }
54
- end
55
-
56
- context 'when the operand is not compilable' do
57
- let(:expr){ project(an_operand, [:sid, :name]) }
58
-
59
- it{ should be_a(Engine::Cog) }
60
- end
61
-
62
- end
63
- end
64
- end
@@ -1,26 +0,0 @@
1
- require 'compiler_helper'
2
- module Alf
3
- module Sequel
4
- describe Compiler, "rename" do
5
-
6
- subject{ compile(expr) }
7
-
8
- context 'when the operand is fully compilable' do
9
- let(:expr){ rename(suppliers, :sid => :id) }
10
-
11
- specify{
12
- subject.sql.should eq("SELECT * FROM (SELECT `t1`.`sid` AS 'id', `t1`.`name` AS 'name', `t1`.`status` AS 'status', `t1`.`city` AS 'city' FROM `suppliers` AS 't1') AS 't2'")
13
- }
14
- end
15
-
16
- context 'when the operand is another renaming' do
17
- let(:expr){ rename(rename(suppliers, :sid => :id), :id => :foo) }
18
-
19
- specify{
20
- subject.sql.should eq("SELECT * FROM (SELECT `t2`.`id` AS 'foo', `t2`.`name` AS 'name', `t2`.`status` AS 'status', `t2`.`city` AS 'city' FROM (SELECT `t1`.`sid` AS 'id', `t1`.`name` AS 'name', `t1`.`status` AS 'status', `t1`.`city` AS 'city' FROM `suppliers` AS 't1') AS 't2') AS 't3'")
21
- }
22
- end
23
-
24
- end
25
- end
26
- end