diff options
-rw-r--r-- | lib/arel/algebra/relations/relation.rb | 5 | ||||
-rw-r--r-- | lib/arel/engines/sql/relations/table.rb | 18 | ||||
-rw-r--r-- | spec/arel/algebra/unit/relations/relation_spec.rb | 3 | ||||
-rw-r--r-- | spec/arel/algebra/unit/relations/table_spec.rb | 1 | ||||
-rw-r--r-- | spec/arel/engines/sql/unit/primitives/attribute_spec.rb | 21 |
5 files changed, 39 insertions, 9 deletions
diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index e848c8aa1c..4cd3f8e109 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -84,7 +84,8 @@ module Arel module AttributeAccessable def [](index) - case index + @cached_attributes ||= {} + @cached_attributes[index] ||= case index when Symbol, String find_attribute_matching_name(index) when Attribute, Expression @@ -96,7 +97,7 @@ module Arel end def find_attribute_matching_name(name) - attributes.detect { |a| a.named?(name) } + attributes.detect { |a| a.named?(name) } || Attribute.new(self, name) end def find_attribute_matching_attribute(attribute) diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb index e4b75d6c3d..d10b761ea3 100644 --- a/lib/arel/engines/sql/relations/table.rb +++ b/lib/arel/engines/sql/relations/table.rb @@ -2,7 +2,7 @@ module Arel class Table < Relation include Recursion::BaseCase - cattr_accessor :engine + cattr_accessor :engine, :tables attr_reader :name, :engine, :table_alias, :options def initialize(name, options = {}) @@ -19,6 +19,7 @@ module Arel if @engine.connection begin require "arel/engines/sql/compilers/#{@engine.adapter_name.downcase}_compiler" + @@tables ||= engine.tables rescue LoadError raise "#{@engine.adapter_name} is not supported by Arel." end @@ -29,9 +30,20 @@ module Arel Table.new(name, options.merge(:as => table_alias)) end + def table_exists? + if @table_exists + true + else + @table_exists = @@tables.include?(name) || engine.table_exists?(name) + end + end + def attributes - @attributes ||= columns.collect do |column| - Attribute.new(self, column.name.to_sym) + return @attributes if defined?(@attributes) + if table_exists? + @attributes = columns.collect { |column| Attribute.new(self, column.name.to_sym) } + else + [] end end diff --git a/spec/arel/algebra/unit/relations/relation_spec.rb b/spec/arel/algebra/unit/relations/relation_spec.rb index cf6509fe6a..a1d1793d92 100644 --- a/spec/arel/algebra/unit/relations/relation_spec.rb +++ b/spec/arel/algebra/unit/relations/relation_spec.rb @@ -16,10 +16,9 @@ module Arel end describe 'when given a', Symbol, String do - it "returns the attribute with the same name, if it exists" do + it "returns the attribute with the same name" do check @relation[:id].should == @attribute1 check @relation['id'].should == @attribute1 - @relation[:does_not_exist].should be_nil end end end diff --git a/spec/arel/algebra/unit/relations/table_spec.rb b/spec/arel/algebra/unit/relations/table_spec.rb index 19c1ba2bea..d93446f1b9 100644 --- a/spec/arel/algebra/unit/relations/table_spec.rb +++ b/spec/arel/algebra/unit/relations/table_spec.rb @@ -10,7 +10,6 @@ module Arel describe 'when given a', Symbol do it "manufactures an attribute if the symbol names an attribute within the relation" do check @relation[:id].should == Attribute.new(@relation, :id) - @relation[:does_not_exist].should be_nil end end diff --git a/spec/arel/engines/sql/unit/primitives/attribute_spec.rb b/spec/arel/engines/sql/unit/primitives/attribute_spec.rb index 9f864dd3a1..8daa0d9fd5 100644 --- a/spec/arel/engines/sql/unit/primitives/attribute_spec.rb +++ b/spec/arel/engines/sql/unit/primitives/attribute_spec.rb @@ -9,7 +9,7 @@ module Arel describe '#column' do it "returns the corresponding column in the relation" do - @attribute.column.should == @relation.column_for(@attribute) + @attribute.column.should == @relation.column_for(@attribute) end end @@ -31,6 +31,25 @@ module Arel end end end + + describe 'for an inexistent attribute' do + it "manufactures sql" do + sql = @relation[:does_not_exist].to_sql + + adapter_is :mysql do + sql.should be_like(%Q{`users`.`does_not_exist`}) + end + + adapter_is :oracle do + sql.should be_like(%Q{"USERS"."DOEST_NOT_EXIST"}) + end + + adapter_is_not :mysql, :oracle do + sql.should be_like(%Q{"users"."does_not_exist"}) + end + end + end + end end end |