aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-08-12 21:21:20 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2010-08-12 21:21:20 -0700
commite573a9ea468d748cf0ebd1a70521c1589efda23e (patch)
tree0d92325a54370b1412b47e247efe4bd4d86efdc7
parent16e7273245473bb6466a79a38702a52387bab44d (diff)
downloadrails-e573a9ea468d748cf0ebd1a70521c1589efda23e.tar.gz
rails-e573a9ea468d748cf0ebd1a70521c1589efda23e.tar.bz2
rails-e573a9ea468d748cf0ebd1a70521c1589efda23e.zip
limits are added
-rw-r--r--lib/arel/nodes.rb3
-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.rb13
-rw-r--r--lib/arel/table.rb4
-rw-r--r--lib/arel/tree_manager.rb21
-rw-r--r--lib/arel/visitors/to_sql.rb9
-rw-r--r--spec/arel/table_spec.rb13
-rw-r--r--spec/arel/tree_manager.rb23
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