From 5c9d75db74572567d66561f6fba6c10350c530ff Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Sep 2010 17:32:44 -0700 Subject: [PATCH] adding locking node to the AST --- lib/arel/nodes.rb | 1 + lib/arel/nodes/lock.rb | 6 ++++++ lib/arel/nodes/select_statement.rb | 3 ++- lib/arel/select_manager.rb | 7 +++++++ lib/arel/table.rb | 4 ++++ lib/arel/visitors/to_sql.rb | 8 +++++++- spec/arel/select_manager_spec.rb | 9 +++++++++ 7 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 lib/arel/nodes/lock.rb diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 8e11760c18..3d73de2f7a 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -4,6 +4,7 @@ require 'arel/nodes/or' require 'arel/nodes/and' require 'arel/nodes/in' +require 'arel/nodes/lock' require 'arel/nodes/function' require 'arel/nodes/count' require 'arel/nodes/sum' diff --git a/lib/arel/nodes/lock.rb b/lib/arel/nodes/lock.rb new file mode 100644 index 0000000000..3c7a72273f --- /dev/null +++ b/lib/arel/nodes/lock.rb @@ -0,0 +1,6 @@ +module Arel + module Nodes + class Lock + end + end +end diff --git a/lib/arel/nodes/select_statement.rb b/lib/arel/nodes/select_statement.rb index b7c59da275..a96c02a545 100644 --- a/lib/arel/nodes/select_statement.rb +++ b/lib/arel/nodes/select_statement.rb @@ -2,12 +2,13 @@ module Arel module Nodes class SelectStatement attr_reader :cores - attr_accessor :limit, :orders + attr_accessor :limit, :orders, :lock def initialize cores = [SelectCore.new] @cores = cores @orders = [] @limit = nil + @lock = nil end def initialize_copy other diff --git a/lib/arel/select_manager.rb b/lib/arel/select_manager.rb index 4ddae13aa4..bcfb1dc4eb 100644 --- a/lib/arel/select_manager.rb +++ b/lib/arel/select_manager.rb @@ -8,6 +8,13 @@ module Arel @ctx = @head.cores.last end + 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? + @head.lock = Nodes::Lock.new + self + end + def on *exprs @ctx.froms.last.constraint = Nodes::On.new(collapse(exprs)) self diff --git a/lib/arel/table.rb b/lib/arel/table.rb index ce21457e60..ac832ed2b3 100644 --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -26,6 +26,10 @@ module Arel SelectManager.new(@engine).from(self) end + def from table + SelectManager.new(@engine).from table + end + def joins manager nil end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 12967d27ad..0f2de092ea 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -48,7 +48,8 @@ module Arel [ o.cores.map { |x| visit x }.join, ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?), - ("LIMIT #{o.limit}" if o.limit) + ("LIMIT #{o.limit}" if o.limit), + (visit(o.lock) if o.lock), ].compact.join ' ' end @@ -66,6 +67,11 @@ module Arel "HAVING #{visit o.expr}" end + # FIXME: this does nothing on SQLLite3, but should do things on other + # databases. + def visit_Arel_Nodes_Lock o + end + def visit_Arel_Nodes_Group o visit o.expr end diff --git a/spec/arel/select_manager_spec.rb b/spec/arel/select_manager_spec.rb index 335d044feb..0b45b8180c 100644 --- a/spec/arel/select_manager_spec.rb +++ b/spec/arel/select_manager_spec.rb @@ -25,6 +25,15 @@ module Arel end describe 'select manager' do + describe 'lock' do + # This should fail on other databases + it 'adds a lock node' do + table = Table.new :users + mgr = table.from table + mgr.lock.to_sql.should be_like %{ SELECT FROM "users" } + end + end + describe 'order' do it 'generates order clauses' do table = Table.new :users