aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/arel.rb1
-rw-r--r--lib/arel/nodes.rb1
-rw-r--r--lib/arel/nodes/select.rb13
-rw-r--r--lib/arel/tree_manager.rb31
-rw-r--r--lib/arel/visitors/to_sql.rb12
-rw-r--r--spec/arel/tree_manager.rb44
6 files changed, 102 insertions, 0 deletions
diff --git a/lib/arel.rb b/lib/arel.rb
index ea9a462d1f..e1d34d4561 100644
--- a/lib/arel.rb
+++ b/lib/arel.rb
@@ -1,6 +1,7 @@
require 'arel/version'
require 'arel/table'
require 'arel/attributes'
+require 'arel/tree_manager'
require 'arel/nodes'
require 'arel/visitors/to_sql'
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index 07a687405f..53c17a8cca 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -1,2 +1,3 @@
require 'arel/nodes/equality'
require 'arel/nodes/sql_literal'
+require 'arel/nodes/select'
diff --git a/lib/arel/nodes/select.rb b/lib/arel/nodes/select.rb
new file mode 100644
index 0000000000..8f68adbcd5
--- /dev/null
+++ b/lib/arel/nodes/select.rb
@@ -0,0 +1,13 @@
+module Arel
+ module Nodes
+ class Select
+ attr_reader :froms, :projections, :wheres
+
+ def initialize
+ @froms = []
+ @projections = []
+ @wheres = []
+ end
+ end
+ end
+end
diff --git a/lib/arel/tree_manager.rb b/lib/arel/tree_manager.rb
new file mode 100644
index 0000000000..b111ca9557
--- /dev/null
+++ b/lib/arel/tree_manager.rb
@@ -0,0 +1,31 @@
+module Arel
+ class TreeManager
+ def initialize engine
+ @engine = engine
+ @statement_list = []
+
+ # default to Select
+ @statement_list << Nodes::Select.new
+ end
+
+ def from table
+ @statement_list.last.froms << table
+ self
+ end
+
+ def project projection
+ @statement_list.last.projections << projection
+ self
+ end
+
+ def where expr
+ @statement_list.last.wheres << expr
+ self
+ end
+
+ def to_sql
+ viz = Visitors::ToSql.new @engine
+ viz.accept @statement_list.last
+ end
+ end
+end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index ba92ca7ef1..bb2a4d07e8 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -12,6 +12,18 @@ module Arel
end
private
+ def visit_Arel_Nodes_Select o
+ [
+ "SELECT #{o.projections.map { |x| visit x }.join ', '}",
+ "FROM #{o.froms.map { |x| visit x }.join ', ' }",
+ ("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.blank?)
+ ].compact.join ' '
+ end
+
+ def visit_Arel_Table o
+ quote_table_name o.name
+ end
+
def visit_Arel_Nodes_Equality o
"#{visit o.left} = #{visit o.right}"
end
diff --git a/spec/arel/tree_manager.rb b/spec/arel/tree_manager.rb
new file mode 100644
index 0000000000..513b41e305
--- /dev/null
+++ b/spec/arel/tree_manager.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+module Arel
+ describe 'tree manager' do
+ describe 'where' do
+ it "knows where" do
+ table = Table.new :users
+ manager = Arel::TreeManager.new Table.engine
+ manager.from(table).project(table['id'])
+ manager.where(table['id'].eq(1))
+ manager.to_sql.should == %{
+ SELECT "users"."id"
+ FROM "users"
+ WHERE "users"."id" = 1
+ }.gsub("\n", '').gsub(/(^\s*|\s*$)/, '').squeeze(' ')
+ end
+
+ it "chains" do
+ table = Table.new :users
+ manager = Arel::TreeManager.new Table.engine
+ manager.from(table)
+ manager.project(table['id']).where(table['id'].eq 1).should == manager
+ end
+ end
+
+ describe 'from' do
+ it "makes sql" do
+ table = Table.new :users
+ manager = Arel::TreeManager.new Table.engine
+
+ manager.from table
+ manager.project table['id']
+ manager.to_sql.should == 'SELECT "users"."id" FROM "users"'
+ end
+
+ it "chains" do
+ table = Table.new :users
+ manager = Arel::TreeManager.new Table.engine
+ manager.from(table).project(table['id']).should == manager
+ manager.to_sql.should == 'SELECT "users"."id" FROM "users"'
+ end
+ end
+ end
+end