alf-sequel 0.13.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 (63) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/Gemfile +19 -0
  3. data/Gemfile.lock +38 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +12 -0
  6. data/README.md +11 -0
  7. data/Rakefile +11 -0
  8. data/lib/alf/sequel/adapter.rb +57 -0
  9. data/lib/alf/sequel/cog.rb +92 -0
  10. data/lib/alf/sequel/compiler/predicate.rb +76 -0
  11. data/lib/alf/sequel/compiler.rb +168 -0
  12. data/lib/alf/sequel/connection/connection_methods.rb +46 -0
  13. data/lib/alf/sequel/connection/schema_methods.rb +76 -0
  14. data/lib/alf/sequel/connection/update_methods.rb +63 -0
  15. data/lib/alf/sequel/connection.rb +23 -0
  16. data/lib/alf/sequel/loader.rb +2 -0
  17. data/lib/alf/sequel/unit_of_work/atomic.rb +35 -0
  18. data/lib/alf/sequel/unit_of_work/delete.rb +24 -0
  19. data/lib/alf/sequel/unit_of_work/insert.rb +60 -0
  20. data/lib/alf/sequel/unit_of_work/update.rb +60 -0
  21. data/lib/alf/sequel/unit_of_work.rb +11 -0
  22. data/lib/alf/sequel/version.rb +16 -0
  23. data/lib/alf/sequel.rb +7 -0
  24. data/lib/alf-sequel.rb +1 -0
  25. data/spec/adapter/test_recognize.rb +50 -0
  26. data/spec/alf.db +0 -0
  27. data/spec/compiler/test_clip.rb +40 -0
  28. data/spec/compiler/test_compact.rb +18 -0
  29. data/spec/compiler/test_extend.rb +16 -0
  30. data/spec/compiler/test_intersect.rb +18 -0
  31. data/spec/compiler/test_join.rb +18 -0
  32. data/spec/compiler/test_leaf_operand.rb +24 -0
  33. data/spec/compiler/test_matching.rb +34 -0
  34. data/spec/compiler/test_not_matching.rb +34 -0
  35. data/spec/compiler/test_predicate.rb +141 -0
  36. data/spec/compiler/test_project.rb +64 -0
  37. data/spec/compiler/test_rename.rb +26 -0
  38. data/spec/compiler/test_restrict.rb +48 -0
  39. data/spec/compiler/test_sort.rb +18 -0
  40. data/spec/compiler/test_union.rb +18 -0
  41. data/spec/compiler_helper.rb +34 -0
  42. data/spec/connection/test_connection_uri.rb +54 -0
  43. data/spec/connection/test_delete.rb +20 -0
  44. data/spec/connection/test_heading.rb +16 -0
  45. data/spec/connection/test_insert.rb +24 -0
  46. data/spec/connection/test_keys.rb +24 -0
  47. data/spec/connection/test_lock.rb +15 -0
  48. data/spec/connection/test_ping.rb +26 -0
  49. data/spec/connection/test_relvar.rb +16 -0
  50. data/spec/connection/test_update.rb +20 -0
  51. data/spec/fixtures/sap.db +0 -0
  52. data/spec/fixtures/sap.rb +43 -0
  53. data/spec/spec_helper.rb +35 -0
  54. data/spec/test_assumptions.rb +14 -0
  55. data/spec/test_sequel.rb +10 -0
  56. data/spec/unit_of_work/atomic/test_run.rb +72 -0
  57. data/spec/unit_of_work/delete/test_delete.rb +39 -0
  58. data/spec/unit_of_work/insert/test_run.rb +71 -0
  59. data/spec/unit_of_work/update/test_run.rb +39 -0
  60. data/tasks/fixtures.rake +12 -0
  61. data/tasks/gem.rake +8 -0
  62. data/tasks/test.rake +6 -0
  63. metadata +174 -0
@@ -0,0 +1,64 @@
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
@@ -0,0 +1,26 @@
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
@@ -0,0 +1,48 @@
1
+ require 'compiler_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Compiler, "restrict" do
5
+
6
+ subject{ compile(expr) }
7
+
8
+ context 'with a native predicate' do
9
+ let(:expr){ restrict(suppliers, proc{ status > 20 }) }
10
+
11
+ it{ should be_a(Engine::Filter) }
12
+ end
13
+
14
+ context 'when the operand is fully compilable' do
15
+ let(:expr){ restrict(suppliers, :name => "Jones") }
16
+
17
+ specify{
18
+ subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (`t1`.`name` = 'Jones')")
19
+ }
20
+ end
21
+
22
+ context 'when the operand is a IN (values)' do
23
+ let(:expr){ restrict(suppliers, Predicate.in(:city, ["London", "Paris"])) }
24
+
25
+ specify{
26
+ subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (`t1`.`city` IN ('London', 'Paris'))")
27
+ }
28
+ end
29
+
30
+ context 'when the operand is a NOT IN (values)' do
31
+ let(:expr){ restrict(suppliers, !Predicate.in(:city, ["London", "Paris"])) }
32
+
33
+ specify{
34
+ subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' WHERE (`t1`.`city` NOT IN ('London', 'Paris'))")
35
+ }
36
+ end
37
+
38
+ context 'when the operand is a renaming' do
39
+ let(:expr){ restrict(rename(suppliers, :name => :sname), :sname => "Jones") }
40
+
41
+ specify{
42
+ subject.sql.should eq("SELECT * FROM (SELECT `t1`.`name` AS 'sname', `t1`.`sid` AS 'sid', `t1`.`status` AS 'status', `t1`.`city` AS 'city' FROM `suppliers` AS 't1') AS 't2' WHERE (`t2`.`sname` = 'Jones')")
43
+ }
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ require 'compiler_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Compiler, "sort" do
5
+
6
+ subject{ compile(expr) }
7
+
8
+ context 'when the operand is fully compilable' do
9
+ let(:expr){ sort(suppliers, [ [:name, :asc], [:status, :desc] ]) }
10
+
11
+ specify{
12
+ subject.sql.should eq("SELECT * FROM `suppliers` AS 't1' ORDER BY `t1`.`name` ASC, `t1`.`status` DESC")
13
+ }
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'compiler_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Compiler, "union" do
5
+
6
+ subject{ compile(expr) }
7
+
8
+ context 'when the operand is fully compilable' do
9
+ let(:expr){ union(suppliers, supplies) }
10
+
11
+ specify do
12
+ subject.sql.should eq("SELECT * FROM (SELECT * FROM `suppliers` AS 't1' UNION SELECT * FROM `supplies` AS 't2') AS 't3'")
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'spec_helper'
2
+
3
+ module CompilerHelpers
4
+ include Alf::Lang::Functional
5
+
6
+ def suppliers
7
+ Alf::Algebra.named_operand(:suppliers, sap)
8
+ end
9
+
10
+ def supplies
11
+ Alf::Algebra.named_operand(:supplies, sap)
12
+ end
13
+
14
+ def parts
15
+ Alf::Algebra.named_operand(:parts, sap)
16
+ end
17
+
18
+ def _context
19
+ sap
20
+ end
21
+
22
+ def an_operand
23
+ Alf::Algebra::Operand::Fake.new(sap)
24
+ end
25
+
26
+ def compile(expr)
27
+ Alf::Sequel::Compiler.new.call(expr)
28
+ end
29
+
30
+ end
31
+
32
+ RSpec.configure do |c|
33
+ c.include CompilerHelpers
34
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'connection_uri' do
5
+
6
+ subject{ conn.connection_uri(with_password) }
7
+
8
+ let(:with_password){ false }
9
+
10
+ context 'when build with an uri' do
11
+ let(:conn){ Connection.new("somewhere/to/db.sqlite3") }
12
+
13
+ it{ should eq("somewhere/to/db.sqlite3") }
14
+ end
15
+
16
+ context 'when build with no host on sqlite' do
17
+ let(:conn){ Connection.new({:adapter => "sqlite", :database => "sap.db"}) }
18
+
19
+ it{ should eq("sqlite://sap.db") }
20
+ end
21
+
22
+ context 'when build with no host on postgres' do
23
+ let(:conn){ Connection.new({:adapter => "postgres", :database => "sap"}) }
24
+
25
+ it{ should eq("postgres://localhost/sap") }
26
+ end
27
+
28
+ context 'when build with a host but no port' do
29
+ let(:conn){ Connection.new({:adapter => "postgres", :host => "athena", :database => "sap"}) }
30
+
31
+ it{ should eq("postgres://athena/sap") }
32
+ end
33
+
34
+ context 'when build with a host and a no port' do
35
+ let(:conn){ Connection.new({:adapter => "postgres", :host => "athena", :port => 1234, :database => "sap"}) }
36
+
37
+ it{ should eq("postgres://athena:1234/sap") }
38
+ end
39
+
40
+ context 'when build with a user/pass and with_password=false' do
41
+ let(:conn){ Connection.new({:adapter => "postgres", :host => "athena", :user => "buly", :password => "pass", :database => "sap"}) }
42
+
43
+ it{ should eq("postgres://buly@athena/sap") }
44
+ end
45
+
46
+ context 'when build with a user/pass and with_password=true' do
47
+ let(:conn){ Connection.new({:adapter => "postgres", :host => "athena", :user => "buly", :password => "pass", :database => "sap"}) }
48
+ let(:with_password){ true }
49
+
50
+ it{ should eq("postgres://buly:pass@athena/sap") }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'delete' do
5
+
6
+ let(:conn){ sap_memory }
7
+
8
+ subject{ conn.delete(:suppliers, Predicate.tautology) }
9
+
10
+ it 'returns a UnitOfWork::Delete' do
11
+ subject.should be_a(UnitOfWork::Delete)
12
+ end
13
+
14
+ it 'is ran' do
15
+ subject.should be_ran
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'heading' do
5
+
6
+ subject{ sap.heading(:suppliers) }
7
+
8
+ let(:expected){
9
+ Heading[:sid => Integer, :name => String, :status => Integer, :city => String]
10
+ }
11
+
12
+ it{ should eq(expected) }
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'insert' do
5
+
6
+ let(:conn){ sap_memory }
7
+
8
+ subject{ conn.insert(:suppliers, suppliers) }
9
+
10
+ let(:suppliers){[
11
+ {sid: 10, name: "Marcus", status: 20, city: "Ouagadougou"}
12
+ ]}
13
+
14
+ it 'returns a UnitOfWork::Insert' do
15
+ subject.should be_a(UnitOfWork::Insert)
16
+ end
17
+
18
+ it 'is ran' do
19
+ subject.should be_ran
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'keys' do
5
+
6
+ context "when only a primary key" do
7
+ subject{ sap.keys(:parts) }
8
+
9
+ let(:expected){ Keys[ [:pid] ] }
10
+
11
+ it{ should eq(expected) }
12
+ end
13
+
14
+ context "when both primary key and unique index" do
15
+ subject{ sap.keys(:suppliers) }
16
+
17
+ let(:expected){ Keys[ [:sid], [:name] ] }
18
+
19
+ it{ should eq(expected) }
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'lock' do
5
+
6
+ subject{ sap.lock(:suppliers, :exclusive){ @seen = true } }
7
+
8
+ it 'yields the block' do
9
+ subject
10
+ @seen.should be_true
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, "ping" do
5
+
6
+ it "returns true on a file" do
7
+ Connection.new("#{sequel_database_path}").ping.should be_true
8
+ end
9
+
10
+ it "returns true on an uri" do
11
+ Connection.new(sequel_database_uri).ping.should be_true
12
+ end
13
+
14
+ it "returns true on a Path" do
15
+ Connection.new(sequel_database_path).ping.should be_true
16
+ end
17
+
18
+ it "raises on non existing" do
19
+ lambda {
20
+ Connection.new("postgres://non-existing.sqlite3").ping
21
+ }.should raise_error
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'relvar' do
5
+
6
+ it "should serve relvars" do
7
+ sap.relvar(:suppliers).should be_a(Alf::Relvar)
8
+ end
9
+
10
+ it "should be the correct relation" do
11
+ sap.relvar(:suppliers).value.size.should eq(5)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Sequel
4
+ describe Connection, 'update' do
5
+
6
+ let(:conn){ sap_memory }
7
+
8
+ subject{ conn.update(:suppliers, {status: 10}, Predicate.tautology) }
9
+
10
+ it 'returns a UnitOfWork::Update' do
11
+ subject.should be_a(UnitOfWork::Update)
12
+ end
13
+
14
+ it 'is ran' do
15
+ subject.should be_ran
16
+ end
17
+
18
+ end
19
+ end
20
+ end
Binary file
@@ -0,0 +1,43 @@
1
+ class SAP
2
+
3
+ def self.create!(sequel_db)
4
+ sequel_db = ::Sequel.connect(sequel_db) unless sequel_db.is_a?(::Sequel::Database)
5
+ sequel_db.tap do |db|
6
+ db.create_table(:suppliers) do
7
+ primary_key :sid
8
+ String :name
9
+ Integer :status
10
+ String :city
11
+ index :name, :unique => true
12
+ end
13
+ db.create_table(:parts) do
14
+ primary_key :pid
15
+ String :name
16
+ String :color
17
+ Float :weight
18
+ String :city
19
+ end
20
+ db.create_table(:supplies) do
21
+ Integer :sid
22
+ Integer :pid
23
+ Integer :qty
24
+ primary_key [:sid, :pid]
25
+ end
26
+ end
27
+ Alf.connect(sequel_db) do |alf_db|
28
+ ex = Alf.examples
29
+ alf_db.relvar(:suppliers).affect ex.query{
30
+ (extend suppliers, :sid => lambda{ (sid.match /\d+/)[0].to_i })
31
+ }
32
+ alf_db.relvar(:parts).affect ex.query{
33
+ (extend parts, :pid => lambda{ (pid.match /\d+/)[0].to_i })
34
+ }
35
+ alf_db.relvar(:supplies).affect ex.query{
36
+ (extend supplies, :sid => lambda{ (sid.match /\d+/)[0].to_i },
37
+ :pid => lambda{ (pid.match /\d+/)[0].to_i })
38
+ }
39
+ end
40
+ sequel_db
41
+ end
42
+
43
+ end
@@ -0,0 +1,35 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'alf-sequel'
3
+ require "rspec"
4
+ require 'path'
5
+ require_relative 'fixtures/sap.rb'
6
+
7
+ module Helpers
8
+
9
+ def sequel_database_path
10
+ Path.dir/'alf.db'
11
+ end
12
+
13
+ def sequel_database_uri
14
+ "#{Alf::Sequel::Adapter.sqlite_protocol}://#{sequel_database_path}"
15
+ end
16
+
17
+ def sequel_database_memory
18
+ "#{Alf::Sequel::Adapter.sqlite_protocol}::memory:"
19
+ end
20
+
21
+ def sap
22
+ @sap ||= Alf.connect Path.relative("fixtures/sap.db")
23
+ end
24
+
25
+ def sap_memory
26
+ Alf.connect(SAP.create!(sequel_database_memory), schema_cache: false)
27
+ end
28
+
29
+ end
30
+
31
+ RSpec.configure do |c|
32
+ c.include Helpers
33
+ c.extend Helpers
34
+ c.filter_run_excluding :ruby19 => (RUBY_VERSION < "1.9")
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ describe "assumptions" do
3
+
4
+ context 'sqlite://memory' do
5
+ let(:db1){ ::Sequel.connect(sequel_database_memory) }
6
+ let(:db2){ ::Sequel.connect(sequel_database_memory) }
7
+
8
+ it 'leads to two different databases' do
9
+ db1.create_table(:blah){ primary_key :id }
10
+ db2.create_table(:blah){ primary_key :id }
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ describe Sequel do
4
+
5
+ it "should have a version number" do
6
+ Sequel.const_defined?(:VERSION).should be_true
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+ module Alf
3
+ module Sequel
4
+ module UnitOfWork
5
+ describe Atomic, "run" do
6
+
7
+ def build_uow(&bl)
8
+ Object.new.tap{|uow|
9
+ uow.extend(Atomic)
10
+ uow.singleton_class.send(:define_method, :_run, &bl)
11
+ }
12
+ end
13
+
14
+ subject{ uow.run }
15
+
16
+ context 'when the block succeeds' do
17
+ let(:uow){ build_uow{ true } }
18
+
19
+ it 'returns itself' do
20
+ subject.should be(uow)
21
+ end
22
+
23
+ it 'sets ran? to true' do
24
+ subject.should be_ran
25
+ end
26
+
27
+ it 'sets failed? to false' do
28
+ subject.should_not be_failed
29
+ end
30
+ end
31
+
32
+ context 'when the block fails' do
33
+ let(:uow){ build_uow{ raise ArgumentError, "failed" } }
34
+
35
+ it 'raise the error' do
36
+ lambda{
37
+ subject
38
+ }.should raise_error(ArgumentError, "failed")
39
+ end
40
+
41
+ it 'sets ran? to true' do
42
+ lambda{ subject }.should raise_error
43
+ uow.should be_ran
44
+ end
45
+
46
+ it 'sets failed? to false' do
47
+ lambda{ subject }.should raise_error
48
+ uow.should be_failed
49
+ end
50
+
51
+ it 'sets failure to the error' do
52
+ lambda{ subject }.should raise_error
53
+ uow.failure.should be_a(ArgumentError)
54
+ end
55
+ end
56
+
57
+ context 'when already ran' do
58
+ let(:uow){ build_uow{ true } }
59
+
60
+ before{ uow.run }
61
+
62
+ it 'raises an Alf::IllegalStateError' do
63
+ lambda{
64
+ subject
65
+ }.should raise_error(IllegalStateError, /already ran/)
66
+ end
67
+ end
68
+
69
+ end
70
+ end # module UnitOfWork
71
+ end # module Sequel
72
+ end # module Alf
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+ module Alf
3
+ module Sequel
4
+ module UnitOfWork
5
+ describe Delete, "run" do
6
+
7
+ let(:conn){ sap_memory.adapter_connection }
8
+ let(:uow){
9
+ UnitOfWork::Delete.new(conn, relvar_name, predicate)
10
+ }
11
+ subject{ uow.run }
12
+
13
+ before do
14
+ subject.should be(uow)
15
+ end
16
+
17
+ context 'when predicate is a tautology' do
18
+ let(:relvar_name){ :suppliers }
19
+ let(:predicate){ Predicate.tautology }
20
+
21
+ it 'removes all tuples' do
22
+ conn.dataset(relvar_name).should be_empty
23
+ end
24
+ end
25
+
26
+ context 'when predicate is not a tautology' do
27
+ let(:relvar_name){ :suppliers }
28
+ let(:predicate){ Predicate.eq(sid: 1) }
29
+
30
+ it 'removes only targetted tuples' do
31
+ conn.dataset(relvar_name).should_not be_empty
32
+ conn.dataset(relvar_name).where(sid: 1).should be_empty
33
+ end
34
+ end
35
+
36
+ end
37
+ end # module UnitOfWork
38
+ end # module Sequel
39
+ end # module Alf