1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow database specific locking clauses to be used

This commit is contained in:
Jesse Storimer 2011-01-20 00:37:05 -05:00
parent dae7a245f8
commit 6c65b01762
6 changed files with 38 additions and 12 deletions

View file

@ -1,6 +1,10 @@
module Arel
module Nodes
class Lock < Arel::Nodes::Node
attr_reader :locking
def initialize locking = true
@locking = locking
end
end
end
end

View file

@ -40,7 +40,7 @@ module Arel
def lock locking = true
# FIXME: do we even need to store this? If locking is +false+ shouldn't
# we just remove the node from the AST?
@ast.lock = Nodes::Lock.new
@ast.lock = Nodes::Lock.new(locking)
self
end

View file

@ -3,8 +3,12 @@ module Arel
class MySQL < Arel::Visitors::ToSql
private
def visit_Arel_Nodes_Lock o
if o.locking.is_a?(String)
o.locking
else
"FOR UPDATE"
end
end
###
# :'(

View file

@ -3,8 +3,12 @@ module Arel
class PostgreSQL < Arel::Visitors::ToSql
private
def visit_Arel_Nodes_Lock o
if o.locking.is_a?(String)
o.locking
else
"FOR UPDATE"
end
end
def visit_Arel_Nodes_SelectStatement o
if !o.orders.empty? && using_distinct_on?(o)

View file

@ -29,11 +29,16 @@ module Arel
sql.must_be_like "SELECT FROM DUAL"
end
it 'uses FOR UPDATE when locking' do
stmt = Nodes::SelectStatement.new
stmt.lock = Nodes::Lock.new
sql = @visitor.accept(stmt)
sql.must_be_like "SELECT FROM DUAL FOR UPDATE"
describe 'locking' do
it 'defaults to FOR UPDATE when locking' do
node = Nodes::Lock.new
@visitor.accept(node).must_be_like "FOR UPDATE"
end
it 'allows a custom string to be used as a lock' do
node = Nodes::Lock.new('LOCK IN SHARE MODE')
@visitor.accept(node).must_be_like "LOCK IN SHARE MODE"
end
end
end
end

View file

@ -7,12 +7,21 @@ module Arel
@visitor = PostgreSQL.new Table.engine
end
it 'should produce a lock value' do
describe 'locking' do
it 'defaults to FOR UPDATE' do
@visitor.accept(Nodes::Lock.new).must_be_like %{
FOR UPDATE
}
end
it 'allows a custom string to be used as a lock' do
node = Nodes::Lock.new('FOR SHARE')
@visitor.accept(node).must_be_like %{
FOR SHARE
}
end
end
it "should escape LIMIT" do
sc = Arel::Nodes::SelectStatement.new
sc.limit = Nodes::Limit.new("omg")