diff options
author | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-01-13 17:43:00 -0800 |
---|---|---|
committer | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-01-13 17:43:00 -0800 |
commit | 2e63ac91302e2df397a286fdaf9cea51635071a6 (patch) | |
tree | 5d8eb92b25c45ddbf9bb35655da34bdaecf44f1f | |
parent | 59cc0e235285feeeb652ebc17a128c769e2c9d8c (diff) | |
download | rails-2e63ac91302e2df397a286fdaf9cea51635071a6.tar.gz rails-2e63ac91302e2df397a286fdaf9cea51635071a6.tar.bz2 rails-2e63ac91302e2df397a286fdaf9cea51635071a6.zip |
removed support for scalar select (will return later); added support for aliased tables
-rw-r--r-- | lib/active_relation/primitives/attribute.rb | 4 | ||||
-rw-r--r-- | lib/active_relation/relations/alias.rb | 23 | ||||
-rw-r--r-- | lib/active_relation/relations/base.rb | 5 | ||||
-rw-r--r-- | lib/active_relation/relations/compound.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/deletion.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/insertion.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/join.rb | 4 | ||||
-rw-r--r-- | lib/active_relation/relations/rename.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/table.rb | 12 | ||||
-rw-r--r-- | spec/active_relation/primitives/attribute_spec.rb | 4 | ||||
-rw-r--r-- | spec/active_relation/relations/alias_spec.rb | 36 | ||||
-rw-r--r-- | spec/active_relation/relations/base_spec.rb | 8 | ||||
-rw-r--r-- | spec/active_relation/relations/table_spec.rb | 2 |
13 files changed, 81 insertions, 25 deletions
diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb index b13f9befe1..5ce3dfd531 100644 --- a/lib/active_relation/primitives/attribute.rb +++ b/lib/active_relation/primitives/attribute.rb @@ -14,7 +14,7 @@ module ActiveRelation end def qualified_name - "#{relation.table}.#{name}" + "#{relation.name}.#{name}" end def qualify @@ -78,7 +78,7 @@ module ActiveRelation include Aggregations def to_sql(options = {}) - "#{quote_table_name(relation.table)}.#{quote_column_name(name)}" + (options[:use_alias] && self.alias ? " AS #{self.alias.to_s.to_sql}" : "") + "#{quote_table_name(relation.name)}.#{quote_column_name(name)}" + (options[:use_alias] && self.alias ? " AS #{self.alias.to_s.to_sql}" : "") end end end diff --git a/lib/active_relation/relations/alias.rb b/lib/active_relation/relations/alias.rb index 5f4a10a672..2d1b9c1476 100644 --- a/lib/active_relation/relations/alias.rb +++ b/lib/active_relation/relations/alias.rb @@ -2,14 +2,35 @@ module ActiveRelation module Relations class Alias < Compound attr_reader :alias + alias_method :name, :alias def initialize(relation, aliaz) @relation, @alias = relation, aliaz end - + + def attributes + relation.attributes.collect(&method(:substitute)) + end + def ==(other) relation == other.relation and self.alias == other.alias end + + protected + def table_sql + "#{quote_table_name(relation.name)} AS #{quote_table_name(@alias)}" + end + + def attribute(name) + if unaliased_attribute = relation[name] + substitute(unaliased_attribute) + end + end + + private + def substitute(attribute) + Primitives::Attribute.new(self, attribute.name, attribute.alias) + end end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/base.rb b/lib/active_relation/relations/base.rb index 2c79911900..71d15f31f1 100644 --- a/lib/active_relation/relations/base.rb +++ b/lib/active_relation/relations/base.rb @@ -80,15 +80,14 @@ module ActiveRelation def to_sql(options = {}) sql = [ - "SELECT #{attributes.collect{ |a| a.to_sql(:use_alias => true, :use_parens => true) }.join(', ')}", - "FROM #{quote_table_name(table)}", + "SELECT #{attributes.collect{ |a| a.to_sql(:use_alias => true) }.join(', ')}", + "FROM #{table_sql}", (joins unless joins.blank?), ("WHERE #{selects.collect{|s| s.to_sql(:quote => false)}.join("\n\tAND ")}" unless selects.blank?), ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank?), ("LIMIT #{limit.to_sql}" unless limit.blank?), ("OFFSET #{offset.to_sql}" unless offset.blank?) ].compact.join("\n") - (options[:use_parens] ? "(#{sql})" : sql) + (self.alias ? " AS #{self.alias}" : "") end alias_method :to_s, :to_sql diff --git a/lib/active_relation/relations/compound.rb b/lib/active_relation/relations/compound.rb index 26ee92b365..46454eb628 100644 --- a/lib/active_relation/relations/compound.rb +++ b/lib/active_relation/relations/compound.rb @@ -3,7 +3,7 @@ module ActiveRelation class Compound < Base attr_reader :relation - delegate :attributes, :attribute, :joins, :selects, :orders, :table, :inserts, :limit, :offset, :alias, :to => :relation + delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/deletion.rb b/lib/active_relation/relations/deletion.rb index f218d9da6d..0276dc1bc4 100644 --- a/lib/active_relation/relations/deletion.rb +++ b/lib/active_relation/relations/deletion.rb @@ -8,7 +8,7 @@ module ActiveRelation def to_sql(options = {}) [ "DELETE", - "FROM #{quote_table_name(table)}", + "FROM #{table_sql}", ("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?) ].compact.join("\n") end diff --git a/lib/active_relation/relations/insertion.rb b/lib/active_relation/relations/insertion.rb index a0042a18a5..86581c23d7 100644 --- a/lib/active_relation/relations/insertion.rb +++ b/lib/active_relation/relations/insertion.rb @@ -10,7 +10,7 @@ module ActiveRelation def to_sql(options = {}) [ "INSERT", - "INTO #{quote_table_name(table)}", + "INTO #{table_sql}", "(#{record.keys.collect(&:to_sql).join(', ')})", "VALUES #{inserts.collect(&:to_sql).join(', ')}" ].join("\n") diff --git a/lib/active_relation/relations/join.rb b/lib/active_relation/relations/join.rb index 1bd1439dd6..3d50365c40 100644 --- a/lib/active_relation/relations/join.rb +++ b/lib/active_relation/relations/join.rb @@ -34,11 +34,11 @@ module ActiveRelation relation1[name] || relation2[name] end - delegate :table, :to => :relation1 + delegate :table_sql, :to => :relation1 private def join - "#{join_sql} #{quote_table_name(relation2.table)} ON #{predicates.collect { |p| p.to_sql(:quote => false) }.join(' AND ')}" + "#{join_sql} #{relation2.send(:table_sql)} ON #{predicates.collect { |p| p.to_sql(:quote => false) }.join(' AND ')}" end end end diff --git a/lib/active_relation/relations/rename.rb b/lib/active_relation/relations/rename.rb index 563b28922c..c4ba6ded88 100644 --- a/lib/active_relation/relations/rename.rb +++ b/lib/active_relation/relations/rename.rb @@ -13,7 +13,7 @@ module ActiveRelation end def attributes - relation.attributes.collect { |a| substitute(a) } + relation.attributes.collect(&method(:substitute)) end def qualify diff --git a/lib/active_relation/relations/table.rb b/lib/active_relation/relations/table.rb index d642851687..a370b4266d 100644 --- a/lib/active_relation/relations/table.rb +++ b/lib/active_relation/relations/table.rb @@ -1,10 +1,10 @@ module ActiveRelation module Relations class Table < Base - attr_reader :table + attr_reader :name - def initialize(table) - @table = table + def initialize(name) + @name = name end def attributes @@ -19,10 +19,14 @@ module ActiveRelation def attribute(name) attributes_by_name[name.to_s] end + + def table_sql + "#{quote_table_name(name)}" + end private def attributes_by_name - @attributes_by_name ||= connection.columns(table, "#{table} Columns").inject({}) do |attributes_by_name, column| + @attributes_by_name ||= connection.columns(name, "#{name} Columns").inject({}) do |attributes_by_name, column| attributes_by_name.merge(column.name => Primitives::Attribute.new(self, column.name.to_sym)) end end diff --git a/spec/active_relation/primitives/attribute_spec.rb b/spec/active_relation/primitives/attribute_spec.rb index 2aad844659..f1aa404a34 100644 --- a/spec/active_relation/primitives/attribute_spec.rb +++ b/spec/active_relation/primitives/attribute_spec.rb @@ -16,6 +16,10 @@ describe ActiveRelation::Primitives::Attribute do it "manufactures an attribute name prefixed with the relation's name" do @relation1[:id].qualified_name.should == 'foo.id' end + + it "manufactures an attribute name prefixed with the relation's aliased name" do + @relation1.as(:bar)[:id].qualified_name.should == 'bar.id' + end end describe '#qualify' do diff --git a/spec/active_relation/relations/alias_spec.rb b/spec/active_relation/relations/alias_spec.rb new file mode 100644 index 0000000000..6f25df3ddb --- /dev/null +++ b/spec/active_relation/relations/alias_spec.rb @@ -0,0 +1,36 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe ActiveRelation::Relations::Alias do + before do + @relation = ActiveRelation::Relations::Table.new(:users) + @alias_relation = @relation.as(:foo) + end + + describe '#name' do + it 'returns the alias' do + @alias_relation.name.should == :foo + end + end + + describe '#attributes' do + it 'manufactures sql deleting a table relation' do + @alias_relation.attributes.should == @relation.attributes.collect { |a| ActiveRelation::Primitives::Attribute.new(@alias_relation, a.name) } + end + end + + describe '[]' do + it 'manufactures attributes associated with the aliased relation' do + @alias_relation[:id].relation.should == @alias_relation + @alias_relation[:does_not_exist].should be_nil + end + end + + describe '#to_sql' do + it "manufactures an aliased select query" do + @alias_relation.to_sql.should be_like(""" + SELECT `foo`.`name`, `foo`.`id` + FROM `users` AS `foo` + """) + end + end +end
\ No newline at end of file diff --git a/spec/active_relation/relations/base_spec.rb b/spec/active_relation/relations/base_spec.rb index db112e679a..18063757df 100644 --- a/spec/active_relation/relations/base_spec.rb +++ b/spec/active_relation/relations/base_spec.rb @@ -99,12 +99,4 @@ describe ActiveRelation::Relations::Base do end end end - - describe '#to_sql' do - it "manufactures sql with scalar selects" do - @relation1.as(:tobias).to_sql(:use_parens => true).should be_like(""" - (SELECT `foo`.`name`, `foo`.`id` FROM `foo`) AS tobias - """) - end - end end
\ No newline at end of file diff --git a/spec/active_relation/relations/table_spec.rb b/spec/active_relation/relations/table_spec.rb index 62b8e44980..1418ac203f 100644 --- a/spec/active_relation/relations/table_spec.rb +++ b/spec/active_relation/relations/table_spec.rb @@ -6,7 +6,7 @@ describe ActiveRelation::Relations::Table do end describe '#to_sql' do - it "returns a simple SELECT query" do + it "manufactures a simple select query" do @relation.to_sql.should be_like(""" SELECT `users`.`name`, `users`.`id` FROM `users` |