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

Added lock to Arel, allowing a locking read if required.

This commit is contained in:
Emilio Tagua 2009-12-27 18:04:35 -03:00
parent 3ea68bc6bd
commit b339caca2f
6 changed files with 70 additions and 3 deletions

View file

@ -13,3 +13,4 @@ require 'arel/algebra/relations/operations/project'
require 'arel/algebra/relations/operations/where'
require 'arel/algebra/relations/operations/skip'
require 'arel/algebra/relations/operations/take'
require 'arel/algebra/relations/operations/lock'

View file

@ -0,0 +1,12 @@
module Arel
class Lock < Compound
attributes :relation, :locked
deriving :initialize, :==
def initialize(relation, locked, &block)
@relation = relation
@locked = locked.blank? ? " FOR UPDATE" : locked
end
end
end

View file

@ -51,6 +51,10 @@ module Arel
OPERATION
end
def lock(locking = nil)
Lock.new(self, locking)
end
def alias
Alias.new(self)
end
@ -131,6 +135,7 @@ module Arel
def taken; nil end
def skipped; nil end
def sources; [] end
def locked; [] end
end
include DefaultOperations
end

View file

@ -2,7 +2,7 @@ module Arel
class Compound < Relation
attr_reader :relation
delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?,
:column_for, :engine, :sources,
:column_for, :engine, :sources, :locked,
:to => :relation
[:attributes, :wheres, :groupings, :orders].each do |operation_name|

View file

@ -16,7 +16,8 @@ module Arel
"FROM #{from_clauses}",
(joins(self) unless joins(self).blank? ),
("WHERE #{where_clauses.join("\n\tAND ")}" unless wheres.blank? ),
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? )
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
("#{locked}" unless locked.blank? )
build_query \
"SELECT * FROM (#{query}) AS id_list",
@ -33,7 +34,8 @@ module Arel
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? ),
("LIMIT #{taken}" unless taken.blank? ),
("OFFSET #{skipped}" unless skipped.blank? )
("OFFSET #{skipped}" unless skipped.blank? ),
("#{locked}" unless locked.blank? )
end
end

View file

@ -0,0 +1,47 @@
require 'spec_helper'
module Arel
describe Lock do
before do
@relation = Table.new(:users)
end
describe '#to_sql' do
it "manufactures a simple select query lock" do
sql = @relation.lock.to_sql
adapter_is :mysql do
sql.should be_like(%Q{
SELECT `users`.`id`, `users`.`name`
FROM `users` FOR UPDATE
})
end
adapter_is_not :mysql do
sql.should be_like(%Q{
SELECT "users"."id", "users"."name"
FROM "users" FOR UPDATE
})
end
end
it "manufactures a select query locking with a given lock" do
sql = @relation.lock("LOCK IN SHARE MODE").to_sql
adapter_is :mysql do
sql.should be_like(%Q{
SELECT `users`.`id`, `users`.`name`
FROM `users` LOCK IN SHARE MODE
})
end
adapter_is_not :mysql do
sql.should be_like(%Q{
SELECT "users"."id", "users"."name"
FROM "users" LOCK IN SHARE MODE
})
end
end
end
end
end