diff options
-rw-r--r-- | lib/arel/nodes.rb | 3 | ||||
-rw-r--r-- | lib/arel/nodes/select_core.rb (renamed from lib/arel/nodes/select.rb) | 2 | ||||
-rw-r--r-- | lib/arel/nodes/select_statement.rb | 13 | ||||
-rw-r--r-- | lib/arel/table.rb | 4 | ||||
-rw-r--r-- | lib/arel/tree_manager.rb | 21 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 9 | ||||
-rw-r--r-- | spec/arel/table_spec.rb | 13 | ||||
-rw-r--r-- | spec/arel/tree_manager.rb | 23 |
8 files changed, 78 insertions, 10 deletions
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 53c17a8cca..5db177d53d 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -1,3 +1,4 @@ require 'arel/nodes/equality' require 'arel/nodes/sql_literal' -require 'arel/nodes/select' +require 'arel/nodes/select_core' +require 'arel/nodes/select_statement' diff --git a/lib/arel/nodes/select.rb b/lib/arel/nodes/select_core.rb index 8f68adbcd5..39145de697 100644 --- a/lib/arel/nodes/select.rb +++ b/lib/arel/nodes/select_core.rb @@ -1,6 +1,6 @@ module Arel module Nodes - class Select + class SelectCore attr_reader :froms, :projections, :wheres def initialize diff --git a/lib/arel/nodes/select_statement.rb b/lib/arel/nodes/select_statement.rb new file mode 100644 index 0000000000..122f6275fe --- /dev/null +++ b/lib/arel/nodes/select_statement.rb @@ -0,0 +1,13 @@ +module Arel + module Nodes + class SelectStatement + attr_reader :cores + attr_accessor :limit + + def initialize cores = [SelectCore.new] + @cores = cores + @limit = nil + end + end + end +end diff --git a/lib/arel/table.rb b/lib/arel/table.rb index 0ab39f134d..7933c8c1a4 100644 --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -10,6 +10,10 @@ module Arel @engine = engine end + def where expression + TreeManager.new(@engine).from(self).where expression + end + def columns @engine.connection.columns(@name, "#{@name} Columns").map do |column| Attributes.for(column).new self, column.name, column diff --git a/lib/arel/tree_manager.rb b/lib/arel/tree_manager.rb index b111ca9557..e92092d6e1 100644 --- a/lib/arel/tree_manager.rb +++ b/lib/arel/tree_manager.rb @@ -1,31 +1,38 @@ module Arel class TreeManager def initialize engine - @engine = engine - @statement_list = [] + @engine = engine + @selects = [] # default to Select - @statement_list << Nodes::Select.new + @stmt = Nodes::SelectStatement.new + @core = @stmt.cores.last + @selects << @stmt end def from table - @statement_list.last.froms << table + @core.froms << table self end def project projection - @statement_list.last.projections << projection + @core.projections << projection self end def where expr - @statement_list.last.wheres << expr + @core.wheres << expr + self + end + + def take limit + @stmt.limit = limit self end def to_sql viz = Visitors::ToSql.new @engine - viz.accept @statement_list.last + viz.accept @stmt end end end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index bb2a4d07e8..44a585698f 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -12,7 +12,14 @@ module Arel end private - def visit_Arel_Nodes_Select o + def visit_Arel_Nodes_SelectStatement o + [ + o.cores.map { |x| visit x }.join, + ("LIMIT #{o.limit}" if o.limit) + ].compact.join ' ' + end + + def visit_Arel_Nodes_SelectCore o [ "SELECT #{o.projections.map { |x| visit x }.join ', '}", "FROM #{o.froms.map { |x| visit x }.join ', ' }", diff --git a/spec/arel/table_spec.rb b/spec/arel/table_spec.rb index be153438c4..b68fdd5a3d 100644 --- a/spec/arel/table_spec.rb +++ b/spec/arel/table_spec.rb @@ -6,6 +6,19 @@ module Arel @relation = Table.new(:users) end + describe 'where' do + it "returns a tree manager" do + manager = @relation.where @relation[:id].eq 1 + manager.project @relation[:id] + manager.should be_kind_of TreeManager + manager.to_sql.should == %{ + SELECT "users"."id" + FROM "users" + WHERE "users"."id" = 1 + }.gsub("\n", '').gsub(/(^\s*|\s*$)/, '').squeeze(' ') + end + end + describe 'columns' do it 'returns a list of columns' do columns = @relation.columns diff --git a/spec/arel/tree_manager.rb b/spec/arel/tree_manager.rb index 513b41e305..44dbb9f727 100644 --- a/spec/arel/tree_manager.rb +++ b/spec/arel/tree_manager.rb @@ -2,6 +2,29 @@ require 'spec_helper' module Arel describe 'tree manager' do + describe 'take' do + it "knows take" do + table = Table.new :users + manager = Arel::TreeManager.new Table.engine + manager.from(table).project(table['id']) + manager.where(table['id'].eq(1)) + manager.take 1 + + manager.to_sql.should == %{ + SELECT "users"."id" + FROM "users" + WHERE "users"."id" = 1 + LIMIT 1 + }.gsub("\n", '').gsub(/(^\s*|\s*$)/, '').squeeze(' ') + end + + it "chains" do + table = Table.new :users + manager = Arel::TreeManager.new Table.engine + manager.take(1).should == manager + end + end + describe 'where' do it "knows where" do table = Table.new :users |