diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/active_relation/extensions/base.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/predicates.rb | 136 | ||||
-rw-r--r-- | lib/active_relation/primitives/aggregation.rb | 28 | ||||
-rw-r--r-- | lib/active_relation/primitives/attribute.rb | 134 | ||||
-rw-r--r-- | lib/active_relation/relations.rb | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/alias.rb | 56 | ||||
-rw-r--r-- | lib/active_relation/relations/base.rb | 105 | ||||
-rw-r--r-- | lib/active_relation/relations/compound.rb | 10 | ||||
-rw-r--r-- | lib/active_relation/relations/deletion.rb | 24 | ||||
-rw-r--r-- | lib/active_relation/relations/insertion.rb | 36 | ||||
-rw-r--r-- | lib/active_relation/relations/join.rb | 80 | ||||
-rw-r--r-- | lib/active_relation/relations/order.rb | 28 | ||||
-rw-r--r-- | lib/active_relation/relations/projection.rb | 28 | ||||
-rw-r--r-- | lib/active_relation/relations/range.rb | 36 | ||||
-rw-r--r-- | lib/active_relation/relations/relation.rb | 103 | ||||
-rw-r--r-- | lib/active_relation/relations/rename.rb | 64 | ||||
-rw-r--r-- | lib/active_relation/relations/selection.rb | 40 | ||||
-rw-r--r-- | lib/active_relation/relations/table.rb | 62 |
18 files changed, 471 insertions, 503 deletions
diff --git a/lib/active_relation/extensions/base.rb b/lib/active_relation/extensions/base.rb index 0115586b00..c1b823f9a7 100644 --- a/lib/active_relation/extensions/base.rb +++ b/lib/active_relation/extensions/base.rb @@ -5,7 +5,7 @@ class ActiveRecord::Base end def relation - @relation ||= ActiveRelation::Relations::Table.new(table_name) + @relation ||= ActiveRelation::Table.new(table_name) end end diff --git a/lib/active_relation/predicates.rb b/lib/active_relation/predicates.rb index 84db60e3b9..55a6c852e2 100644 --- a/lib/active_relation/predicates.rb +++ b/lib/active_relation/predicates.rb @@ -1,87 +1,85 @@ module ActiveRelation - module Predicates - class Base - def ==(other) - self.class == other.class - end + class Predicate + def ==(other) + self.class == other.class end - - class Binary < Base - attr_reader :attribute, :operand + end + + class Binary < Predicate + attr_reader :attribute, :operand - def initialize(attribute, operand) - @attribute, @operand = attribute, operand - end + def initialize(attribute, operand) + @attribute, @operand = attribute, operand + end + + def ==(other) + super and @attribute == other.attribute and @operand == other.operand + end - def ==(other) - super and @attribute == other.attribute and @operand == other.operand - end + def qualify + self.class.new(attribute.qualify, operand.qualify) + end - def qualify - self.class.new(attribute.qualify, operand.qualify) - end + def to_sql(strategy = Sql::Predicate.new) + "#{attribute.to_sql(strategy)} #{predicate_sql} #{operand.to_sql(strategy)}" + end + end - def to_sql(strategy = Sql::Predicate.new) - "#{attribute.to_sql(strategy)} #{predicate_sql} #{operand.to_sql(strategy)}" - end + class Equality < Binary + def ==(other) + self.class == other.class and + ((attribute == other.attribute and operand == other.operand) or + (attribute == other.operand and operand == other.attribute)) end - - class Equality < Binary - def ==(other) - self.class == other.class and - ((attribute == other.attribute and operand == other.operand) or - (attribute == other.operand and operand == other.attribute)) - end - protected - def predicate_sql - '=' - end + protected + def predicate_sql + '=' end - - class GreaterThanOrEqualTo < Binary - protected - def predicate_sql - '>=' - end + end + + class GreaterThanOrEqualTo < Binary + protected + def predicate_sql + '>=' end - - class GreaterThan < Binary - protected - def predicate_sql - '>' - end + end + + class GreaterThan < Binary + protected + def predicate_sql + '>' end - - class LessThanOrEqualTo < Binary - protected - def predicate_sql - '<=' - end + end + + class LessThanOrEqualTo < Binary + protected + def predicate_sql + '<=' end - - class LessThan < Binary - protected - def predicate_sql - '<' - end + end + + class LessThan < Binary + protected + def predicate_sql + '<' end - - class Match < Binary - alias_method :regexp, :operand + end + + class Match < Binary + alias_method :regexp, :operand - def initialize(attribute, regexp) - @attribute, @regexp = attribute, regexp - end + def initialize(attribute, regexp) + @attribute, @regexp = attribute, regexp end - - class RelationInclusion < Binary - alias_method :relation, :operand - - protected - def predicate_sql - 'IN' - end + end + + class RelationInclusion < Binary + alias_method :relation, :operand + + protected + def predicate_sql + 'IN' end end end
\ No newline at end of file diff --git a/lib/active_relation/primitives/aggregation.rb b/lib/active_relation/primitives/aggregation.rb index 189eb33ac9..48f8946835 100644 --- a/lib/active_relation/primitives/aggregation.rb +++ b/lib/active_relation/primitives/aggregation.rb @@ -1,19 +1,17 @@ module ActiveRelation - module Primitives - class Aggregation - attr_reader :attribute, :function_sql - - def initialize(attribute, function_sql) - @attribute, @function_sql = attribute, function_sql - end - - def to_sql(strategy = nil) - "#{function_sql}(#{attribute.to_sql})" - end - - def ==(other) - self.class == other.class and attribute == other.attribute and function_sql == other.function_sql - end + class Aggregation + attr_reader :attribute, :function_sql + + def initialize(attribute, function_sql) + @attribute, @function_sql = attribute, function_sql + end + + def to_sql(strategy = nil) + "#{function_sql}(#{attribute.to_sql})" + end + + def ==(other) + self.class == other.class and attribute == other.attribute and function_sql == other.function_sql end end end
\ No newline at end of file diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb index 6ebaf1b292..90bbe8012b 100644 --- a/lib/active_relation/primitives/attribute.rb +++ b/lib/active_relation/primitives/attribute.rb @@ -1,83 +1,79 @@ module ActiveRelation - module Primitives - class Attribute - attr_reader :relation, :name, :alias - - def initialize(relation, name, aliaz = nil) - @relation, @name, @alias = relation, name, aliaz + class Attribute + attr_reader :relation, :name, :alias + + def initialize(relation, name, aliaz = nil) + @relation, @name, @alias = relation, name, aliaz + end + + def as(aliaz = nil) + Attribute.new(relation, name, aliaz) + end + + def qualified_name + "#{relation.name}.#{name}" + end + + def qualify + self.as(qualified_name) + end + + def ==(other) + relation == other.relation and name == other.name and @alias == other.alias + end + + module Predications + def equals(other) + Equality.new(self, other) end - - def as(aliaz = nil) - Attribute.new(relation, name, aliaz) + + def less_than(other) + LessThan.new(self, other) end - - def qualified_name - "#{relation.name}.#{name}" + + def less_than_or_equal_to(other) + LessThanOrEqualTo.new(self, other) end - - def qualify - self.as(qualified_name) + + def greater_than(other) + GreaterThan.new(self, other) end - - def ==(other) - relation == other.relation and name == other.name and @alias == other.alias + + def greater_than_or_equal_to(other) + GreaterThanOrEqualTo.new(self, other) end - module Predications - include Predicates - - def equals(other) - Equality.new(self, other) - end - - def less_than(other) - LessThan.new(self, other) - end - - def less_than_or_equal_to(other) - LessThanOrEqualTo.new(self, other) - end - - def greater_than(other) - GreaterThan.new(self, other) - end - - def greater_than_or_equal_to(other) - GreaterThanOrEqualTo.new(self, other) - end - - def matches(regexp) - Match.new(self, regexp) - end + def matches(regexp) + Match.new(self, regexp) + end + end + include Predications + + module Aggregations + def count + Aggregation.new(self, "COUNT") + end + + def sum + Aggregation.new(self, "SUM") + end + + def maximum + Aggregation.new(self, "MAX") end - include Predications - module Aggregations - def count - Aggregation.new(self, "COUNT") - end - - def sum - Aggregation.new(self, "SUM") - end - - def maximum - Aggregation.new(self, "MAX") - end - - def minimum - Aggregation.new(self, "MIN") - end - - def average - Aggregation.new(self, "AVG") - end + def minimum + Aggregation.new(self, "MIN") end - include Aggregations - - def to_sql(strategy = Sql::Predicate.new) - strategy.attribute relation.name, name, self.alias + + def average + Aggregation.new(self, "AVG") end end + include Aggregations + + def to_sql(strategy = Sql::Predicate.new) + strategy.attribute relation.name, name, self.alias + end end end
\ No newline at end of file diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb index 1eb58d3b42..9ae8f16524 100644 --- a/lib/active_relation/relations.rb +++ b/lib/active_relation/relations.rb @@ -1,4 +1,4 @@ -require 'active_relation/relations/base' +require 'active_relation/relations/relation' require 'active_relation/relations/compound' require 'active_relation/relations/table' require 'active_relation/relations/join' diff --git a/lib/active_relation/relations/alias.rb b/lib/active_relation/relations/alias.rb index 2d1b9c1476..63a92ccba1 100644 --- a/lib/active_relation/relations/alias.rb +++ b/lib/active_relation/relations/alias.rb @@ -1,36 +1,34 @@ 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 + class Alias < Compound + attr_reader :alias + alias_method :name, :alias - 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 + def initialize(relation, aliaz) + @relation, @alias = relation, aliaz + end - private - def substitute(attribute) - Primitives::Attribute.new(self, attribute.name, attribute.alias) + 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) + Attribute.new(self, attribute.name, attribute.alias) + 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 deleted file mode 100644 index d90d8ae3e6..0000000000 --- a/lib/active_relation/relations/base.rb +++ /dev/null @@ -1,105 +0,0 @@ -module ActiveRelation - module Relations - class Base - include Sql::Quoting - - module Iteration - include Enumerable - - def each(&block) - connection.select_all(to_s).each(&block) - end - - def first - connection.select_one(to_s) - end - end - include Iteration - - module Operations - def join(other) - JoinOperation.new("INNER JOIN", self, other) - end - - def outer_join(other) - JoinOperation.new("LEFT OUTER JOIN", self, other) - end - - def [](index) - case index - when Symbol - attribute(index) - when ::Range - Range.new(self, index) - end - end - - def include?(attribute) - Predicates::RelationInclusion.new(attribute, self) - end - - def select(*predicates) - Selection.new(self, *predicates) - end - - def project(*attributes) - Projection.new(self, *attributes) - end - - def as(aliaz) - Alias.new(self, aliaz) - end - - def order(*attributes) - Order.new(self, *attributes) - end - - def rename(attribute, aliaz) - Rename.new(self, attribute => aliaz) - end - - def insert(record) - Insertion.new(self, record) - end - - def delete - Deletion.new(self) - end - - JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do - def on(*predicates) - Join.new(join_sql, relation1, relation2, *predicates) - end - end - end - include Operations - - def to_sql(strategy = Sql::Select.new) - strategy.select [ - "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new) }.join(', ')}", - "FROM #{table_sql}", - (joins unless joins.blank?), - ("WHERE #{selects.collect{|s| s.to_sql(Sql::Predicate.new)}.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") - end - alias_method :to_s, :to_sql - - protected - def connection - ActiveRecord::Base.connection - end - - def attributes; [] end - def selects; [] end - def orders; [] end - def inserts; [] end - def joins; nil end - def limit; nil end - def offset; nil end - def alias; nil end - end - end -end
\ No newline at end of file diff --git a/lib/active_relation/relations/compound.rb b/lib/active_relation/relations/compound.rb index 46454eb628..d6da8eb8fa 100644 --- a/lib/active_relation/relations/compound.rb +++ b/lib/active_relation/relations/compound.rb @@ -1,9 +1,7 @@ module ActiveRelation - module Relations - class Compound < Base - attr_reader :relation - - delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation - end + class Compound < Relation + attr_reader :relation + + delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation 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 add6440c2a..4ac40a146b 100644 --- a/lib/active_relation/relations/deletion.rb +++ b/lib/active_relation/relations/deletion.rb @@ -1,17 +1,15 @@ module ActiveRelation - module Relations - class Deletion < Compound - def initialize(relation) - @relation = relation - end - - def to_sql(strategy = nil) - [ - "DELETE", - "FROM #{table_sql}", - ("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?) - ].compact.join("\n") - end + class Deletion < Compound + def initialize(relation) + @relation = relation end + + def to_sql(strategy = nil) + [ + "DELETE", + "FROM #{table_sql}", + ("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?) + ].compact.join("\n") + end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/insertion.rb b/lib/active_relation/relations/insertion.rb index c82513ce0f..31e4339ee0 100644 --- a/lib/active_relation/relations/insertion.rb +++ b/lib/active_relation/relations/insertion.rb @@ -1,25 +1,23 @@ module ActiveRelation - module Relations - class Insertion < Compound - attr_reader :record - - def initialize(relation, record) - @relation, @record = relation, record - end + class Insertion < Compound + attr_reader :record - def to_sql(strategy = nil) - [ - "INSERT", - "INTO #{table_sql}", - "(#{record.keys.collect(&:to_sql).join(', ')})", - "VALUES #{inserts.collect(&:to_sql).join(', ')}" - ].join("\n") - end + def initialize(relation, record) + @relation, @record = relation, record + end + + def to_sql(strategy = nil) + [ + "INSERT", + "INTO #{table_sql}", + "(#{record.keys.collect(&:to_sql).join(', ')})", + "VALUES #{inserts.collect(&:to_sql).join(', ')}" + ].join("\n") + end - protected - def inserts - relation.inserts + [record] - end + protected + def inserts + relation.inserts + [record] end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/join.rb b/lib/active_relation/relations/join.rb index 4e6c85979e..8ccd1e9c6c 100644 --- a/lib/active_relation/relations/join.rb +++ b/lib/active_relation/relations/join.rb @@ -1,45 +1,43 @@ module ActiveRelation - module Relations - class Join < Base - attr_reader :join_sql, :relation1, :relation2, :predicates - - def initialize(join_sql, relation1, relation2, *predicates) - @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates - end - - def ==(other) - predicates == other.predicates and - ((relation1 == other.relation1 and relation2 == other.relation2) or - (relation2 == other.relation1 and relation1 == other.relation2)) - end - - def qualify - Join.new(join_sql, relation1.qualify, relation2.qualify, *predicates.collect(&:qualify)) - end - - protected - def joins - [relation1.joins, relation2.joins, join].compact.join(" ") - end - - def selects - relation1.send(:selects) + relation2.send(:selects) - end - - def attributes - relation1.attributes + relation2.attributes - end - - def attribute(name) - relation1[name] || relation2[name] - end - - delegate :table_sql, :to => :relation1 - - private - def join - "#{join_sql} #{relation2.send(:table_sql)} ON #{predicates.collect { |p| p.to_sql(Sql::Predicate.new) }.join(' AND ')}" - end + class Join < Relation + attr_reader :join_sql, :relation1, :relation2, :predicates + + def initialize(join_sql, relation1, relation2, *predicates) + @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates + end + + def ==(other) + predicates == other.predicates and + ((relation1 == other.relation1 and relation2 == other.relation2) or + (relation2 == other.relation1 and relation1 == other.relation2)) + end + + def qualify + Join.new(join_sql, relation1.qualify, relation2.qualify, *predicates.collect(&:qualify)) + end + + protected + def joins + [relation1.joins, relation2.joins, join].compact.join(" ") + end + + def selects + relation1.send(:selects) + relation2.send(:selects) + end + + def attributes + relation1.attributes + relation2.attributes + end + + def attribute(name) + relation1[name] || relation2[name] + end + + delegate :table_sql, :to => :relation1 + + private + def join + "#{join_sql} #{relation2.send(:table_sql)} ON #{predicates.collect { |p| p.to_sql(Sql::Predicate.new) }.join(' AND ')}" end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/order.rb b/lib/active_relation/relations/order.rb index bca81c1b6d..d5c2a54cd1 100644 --- a/lib/active_relation/relations/order.rb +++ b/lib/active_relation/relations/order.rb @@ -1,19 +1,17 @@ module ActiveRelation - module Relations - class Order < Compound - attr_reader :orders - - def initialize(relation, *orders) - @relation, @orders = relation, orders - end - - def ==(other) - relation == other.relation and orders == other.orders - end - - def qualify - Order.new(relation.qualify, *orders.collect { |o| o.qualify }) - end + class Order < Compound + attr_reader :orders + + def initialize(relation, *orders) + @relation, @orders = relation, orders + end + + def ==(other) + relation == other.relation and orders == other.orders + end + + def qualify + Order.new(relation.qualify, *orders.collect { |o| o.qualify }) end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/projection.rb b/lib/active_relation/relations/projection.rb index 131db916f0..211e0607ac 100644 --- a/lib/active_relation/relations/projection.rb +++ b/lib/active_relation/relations/projection.rb @@ -1,19 +1,17 @@ module ActiveRelation - module Relations - class Projection < Compound - attr_reader :attributes - - def initialize(relation, *attributes) - @relation, @attributes = relation, attributes - end - - def ==(other) - self.class == other.class and relation == other.relation and attributes == other.attributes - end - - def qualify - Projection.new(relation.qualify, *attributes.collect(&:qualify)) - end + class Projection < Compound + attr_reader :attributes + + def initialize(relation, *attributes) + @relation, @attributes = relation, attributes + end + + def ==(other) + self.class == other.class and relation == other.relation and attributes == other.attributes + end + + def qualify + Projection.new(relation.qualify, *attributes.collect(&:qualify)) end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/range.rb b/lib/active_relation/relations/range.rb index d7e08efa06..e8b7f4b69d 100644 --- a/lib/active_relation/relations/range.rb +++ b/lib/active_relation/relations/range.rb @@ -1,23 +1,21 @@ module ActiveRelation - module Relations - class Range < Compound - attr_reader :range - - def initialize(relation, range) - @relation, @range = relation, range - end - - def ==(other) - relation == other.relation and range == other.range - end - - def limit - range.end - range.begin + 1 - end - - def offset - range.begin - end + class Range < Compound + attr_reader :range + + def initialize(relation, range) + @relation, @range = relation, range + end + + def ==(other) + relation == other.relation and range == other.range + end + + def limit + range.end - range.begin + 1 + end + + def offset + range.begin end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb new file mode 100644 index 0000000000..663450e69c --- /dev/null +++ b/lib/active_relation/relations/relation.rb @@ -0,0 +1,103 @@ +module ActiveRelation + class Relation + include Sql::Quoting + + module Iteration + include Enumerable + + def each(&block) + connection.select_all(to_s).each(&block) + end + + def first + connection.select_one(to_s) + end + end + include Iteration + + module Operations + def join(other) + JoinOperation.new("INNER JOIN", self, other) + end + + def outer_join(other) + JoinOperation.new("LEFT OUTER JOIN", self, other) + end + + def [](index) + case index + when Symbol + attribute(index) + when ::Range + Range.new(self, index) + end + end + + def include?(attribute) + RelationInclusion.new(attribute, self) + end + + def select(*predicates) + Selection.new(self, *predicates) + end + + def project(*attributes) + Projection.new(self, *attributes) + end + + def as(aliaz) + Alias.new(self, aliaz) + end + + def order(*attributes) + Order.new(self, *attributes) + end + + def rename(attribute, aliaz) + Rename.new(self, attribute => aliaz) + end + + def insert(record) + Insertion.new(self, record) + end + + def delete + Deletion.new(self) + end + + JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do + def on(*predicates) + Join.new(join_sql, relation1, relation2, *predicates) + end + end + end + include Operations + + def to_sql(strategy = Sql::Select.new) + strategy.select [ + "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new) }.join(', ')}", + "FROM #{table_sql}", + (joins unless joins.blank?), + ("WHERE #{selects.collect{|s| s.to_sql(Sql::Predicate.new)}.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") + end + alias_method :to_s, :to_sql + + protected + def connection + ActiveRecord::Base.connection + end + + def attributes; [] end + def selects; [] end + def orders; [] end + def inserts; [] end + def joins; nil end + def limit; nil end + def offset; nil end + def alias; nil end + end +end
\ No newline at end of file diff --git a/lib/active_relation/relations/rename.rb b/lib/active_relation/relations/rename.rb index c4ba6ded88..2977804db1 100644 --- a/lib/active_relation/relations/rename.rb +++ b/lib/active_relation/relations/rename.rb @@ -1,38 +1,36 @@ module ActiveRelation - module Relations - class Rename < Compound - attr_reader :schmattribute, :rename - - def initialize(relation, renames) - @schmattribute, @rename = renames.shift - @relation = renames.empty?? relation : Rename.new(relation, renames) - end - - def ==(other) - relation == other.relation and schmattribute == other.schmattribute and self.rename == other.rename - end - - def attributes - relation.attributes.collect(&method(:substitute)) - end - - def qualify - Rename.new(relation.qualify, schmattribute.qualify => self.rename) - end - - protected - def attribute(name) - case - when name == self.rename then schmattribute.as(self.rename) - when relation[name] == schmattribute then nil - else relation[name] - end - end - - private - def substitute(a) - a == schmattribute ? a.as(self.rename) : a + class Rename < Compound + attr_reader :schmattribute, :rename + + def initialize(relation, renames) + @schmattribute, @rename = renames.shift + @relation = renames.empty?? relation : Rename.new(relation, renames) + end + + def ==(other) + relation == other.relation and schmattribute == other.schmattribute and self.rename == other.rename + end + + def attributes + relation.attributes.collect(&method(:substitute)) + end + + def qualify + Rename.new(relation.qualify, schmattribute.qualify => self.rename) + end + + protected + def attribute(name) + case + when name == self.rename then schmattribute.as(self.rename) + when relation[name] == schmattribute then nil + else relation[name] end end + + private + def substitute(a) + a == schmattribute ? a.as(self.rename) : a + end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/selection.rb b/lib/active_relation/relations/selection.rb index e86dc627db..3ecea059d5 100644 --- a/lib/active_relation/relations/selection.rb +++ b/lib/active_relation/relations/selection.rb @@ -1,25 +1,23 @@ module ActiveRelation - module Relations - class Selection < Compound - attr_reader :predicate - - def initialize(relation, *predicates) - @predicate = predicates.shift - @relation = predicates.empty?? relation : Selection.new(relation, *predicates) - end - - def ==(other) - relation == other.relation and predicate == other.predicate - end - - def qualify - Selection.new(relation.qualify, predicate.qualify) - end - - protected - def selects - relation.send(:selects) + [predicate] - end + class Selection < Compound + attr_reader :predicate + + def initialize(relation, *predicates) + @predicate = predicates.shift + @relation = predicates.empty?? relation : Selection.new(relation, *predicates) + end + + def ==(other) + relation == other.relation and predicate == other.predicate + end + + def qualify + Selection.new(relation.qualify, predicate.qualify) + end + + protected + def selects + relation.send(:selects) + [predicate] end end end
\ No newline at end of file diff --git a/lib/active_relation/relations/table.rb b/lib/active_relation/relations/table.rb index a370b4266d..5220087318 100644 --- a/lib/active_relation/relations/table.rb +++ b/lib/active_relation/relations/table.rb @@ -1,39 +1,37 @@ module ActiveRelation - module Relations - class Table < Base - attr_reader :name - - def initialize(name) - @name = name - end - - def attributes - attributes_by_name.values - end + class Table < Relation + attr_reader :name + + def initialize(name) + @name = name + end + + def attributes + attributes_by_name.values + end + + def qualify + Rename.new self, qualifications + end - def qualify - Rename.new self, qualifications - end + protected + def attribute(name) + attributes_by_name[name.to_s] + end - protected - 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(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 - - def qualifications - attributes.zip(attributes.collect(&:qualified_name)).to_hash + def table_sql + "#{quote_table_name(name)}" + end + + private + def attributes_by_name + @attributes_by_name ||= connection.columns(name, "#{name} Columns").inject({}) do |attributes_by_name, column| + attributes_by_name.merge(column.name => Attribute.new(self, column.name.to_sym)) end end + + def qualifications + attributes.zip(attributes.collect(&:qualified_name)).to_hash + end end end
\ No newline at end of file |