1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
require_relative "spec_helper"
describe "MSSSQL optimistic locking plugin" do
before do
@db = Sequel.mock(:host=>'mssql')
@ds = @db[:items].with_quote_identifiers(false).with_extend{private; def input_identifier(v); v.to_s end}
@c = Class.new(Sequel::Model(@ds))
@c.columns :id, :name, :timestamp
@c.plugin :mssql_optimistic_locking
@o = @c.load(:id=>1, :name=>'a', :timestamp=>'1234')
@db.sqls
end
it "should not include the lock column when updating" do
@db.fetch = [[{:timestamp=>'2345'}]]
@o.save
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x31323334))"]
end
it "should include the primary key column when updating if it has changed" do
@db.fetch = [[{:timestamp=>'2345'}]]
@o.id = 2
@o.save
@db.sqls.must_equal ["UPDATE TOP (1) items SET id = 2, name = 'a' OUTPUT inserted.timestamp WHERE ((id = 2) AND (timestamp = 0x31323334))"]
end
it "should automatically update lock column using new value from database" do
@db.fetch = [[{:timestamp=>'2345'}]]
@o.save
@o.timestamp.must_equal '2345'
end
it "should raise error when updating stale object" do
@db.fetch = []
@o.timestamp = '2345'
proc{@o.save}.must_raise(Sequel::NoExistingObject)
@o.timestamp.must_equal '2345'
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x32333435))"]
end
it "should raise error when destroying stale object" do
@db.numrows = 0
@o.timestamp = '2345'
proc{@o.destroy}.must_raise(Sequel::NoExistingObject)
@db.sqls.must_equal ["DELETE TOP (1) FROM items WHERE ((id = 1) AND (timestamp = 0x32333435))"]
end
it "should allow refresh after failed save" do
@db.fetch = []
@o.timestamp = '2345'
proc{@o.save}.must_raise(Sequel::NoExistingObject)
@db.fetch = {:id=>1, :name=>'a', :timestamp=>'2345'}
@o.refresh
@db.sqls
@o.save
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x32333435))"]
end
it "should allow changing the lock column via model.lock_column=" do
@c = Class.new(Sequel::Model(@ds))
@c.columns :id, :name, :lv
@c.plugin :mssql_optimistic_locking
@c.lock_column = :lv
@o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
@db.sqls
@db.fetch = []
proc{@o.save}.must_raise(Sequel::NoExistingObject)
@o.lv.must_equal '1234'
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.lv WHERE ((id = 1) AND (lv = 0x31323334))"]
@o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
@db.fetch = {:lv=>'2345'}
@o.save
@o.lv.must_equal '2345'
end
it "should allow changing the lock column via plugin option" do
@c = Class.new(Sequel::Model(@ds))
@c.columns :id, :name, :lv
@c.plugin :mssql_optimistic_locking, :lock_column=>:lv
@o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
@db.sqls
@db.fetch = []
proc{@o.save}.must_raise(Sequel::NoExistingObject)
@o.lv.must_equal '1234'
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.lv WHERE ((id = 1) AND (lv = 0x31323334))"]
@o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
@db.fetch = {:lv=>'2345'}
@o.save
@o.lv.must_equal '2345'
end
it "should work when subclassing" do
c = Class.new(@c)
o = c.load(:id=>1, :name=>'a', :timestamp=>'1234')
@db.fetch = [[{:timestamp=>'2345'}]]
o.save
@db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x31323334))"]
end
end
|