From e8966bf9a86afb82c658cedd7e4baffa3a15a856 Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Mon, 19 May 2008 14:08:42 -0700 Subject: reorganized file structure --- lib/arel.rb | 3 +- lib/arel/engine.rb | 18 +++++++++ lib/arel/engines.rb | 1 - lib/arel/engines/engine.rb | 18 --------- lib/arel/relations.rb | 23 +++-------- lib/arel/relations/aggregation.rb | 40 ------------------- lib/arel/relations/alias.rb | 10 ----- lib/arel/relations/compound.rb | 26 ------------ lib/arel/relations/delete.rb | 25 ------------ lib/arel/relations/group.rb | 19 --------- lib/arel/relations/insert.rb | 28 ------------- lib/arel/relations/join.rb | 62 ----------------------------- lib/arel/relations/nil.rb | 10 ----- lib/arel/relations/operations.rb | 8 ++++ lib/arel/relations/operations/alias.rb | 10 +++++ lib/arel/relations/operations/group.rb | 19 +++++++++ lib/arel/relations/operations/join.rb | 62 +++++++++++++++++++++++++++++ lib/arel/relations/operations/order.rb | 19 +++++++++ lib/arel/relations/operations/project.rb | 23 +++++++++++ lib/arel/relations/operations/skip.rb | 15 +++++++ lib/arel/relations/operations/take.rb | 15 +++++++ lib/arel/relations/operations/where.rb | 21 ++++++++++ lib/arel/relations/order.rb | 19 --------- lib/arel/relations/project.rb | 23 ----------- lib/arel/relations/recursion.rb | 13 ------ lib/arel/relations/skip.rb | 15 ------- lib/arel/relations/take.rb | 15 ------- lib/arel/relations/update.rb | 30 -------------- lib/arel/relations/utilities.rb | 5 +++ lib/arel/relations/utilities/aggregation.rb | 40 +++++++++++++++++++ lib/arel/relations/utilities/compound.rb | 26 ++++++++++++ lib/arel/relations/utilities/nil.rb | 10 +++++ lib/arel/relations/utilities/recursion.rb | 13 ++++++ lib/arel/relations/where.rb | 21 ---------- lib/arel/relations/writes.rb | 3 ++ lib/arel/relations/writes/delete.rb | 25 ++++++++++++ lib/arel/relations/writes/insert.rb | 28 +++++++++++++ lib/arel/relations/writes/update.rb | 30 ++++++++++++++ lib/arel/relations/writing.rb | 4 -- lib/arel/session.rb | 47 ++++++++++++++++++++++ lib/arel/sessions/session.rb | 47 ---------------------- spec/arel/unit/relations/compound_spec.rb | 31 --------------- 42 files changed, 445 insertions(+), 475 deletions(-) create mode 100644 lib/arel/engine.rb delete mode 100644 lib/arel/engines.rb delete mode 100644 lib/arel/engines/engine.rb delete mode 100644 lib/arel/relations/aggregation.rb delete mode 100644 lib/arel/relations/alias.rb delete mode 100644 lib/arel/relations/compound.rb delete mode 100644 lib/arel/relations/delete.rb delete mode 100644 lib/arel/relations/group.rb delete mode 100644 lib/arel/relations/insert.rb delete mode 100644 lib/arel/relations/join.rb delete mode 100644 lib/arel/relations/nil.rb create mode 100644 lib/arel/relations/operations.rb create mode 100644 lib/arel/relations/operations/alias.rb create mode 100644 lib/arel/relations/operations/group.rb create mode 100644 lib/arel/relations/operations/join.rb create mode 100644 lib/arel/relations/operations/order.rb create mode 100644 lib/arel/relations/operations/project.rb create mode 100644 lib/arel/relations/operations/skip.rb create mode 100644 lib/arel/relations/operations/take.rb create mode 100644 lib/arel/relations/operations/where.rb delete mode 100644 lib/arel/relations/order.rb delete mode 100644 lib/arel/relations/project.rb delete mode 100644 lib/arel/relations/recursion.rb delete mode 100644 lib/arel/relations/skip.rb delete mode 100644 lib/arel/relations/take.rb delete mode 100644 lib/arel/relations/update.rb create mode 100644 lib/arel/relations/utilities.rb create mode 100644 lib/arel/relations/utilities/aggregation.rb create mode 100644 lib/arel/relations/utilities/compound.rb create mode 100644 lib/arel/relations/utilities/nil.rb create mode 100644 lib/arel/relations/utilities/recursion.rb delete mode 100644 lib/arel/relations/where.rb create mode 100644 lib/arel/relations/writes.rb create mode 100644 lib/arel/relations/writes/delete.rb create mode 100644 lib/arel/relations/writes/insert.rb create mode 100644 lib/arel/relations/writes/update.rb delete mode 100644 lib/arel/relations/writing.rb create mode 100644 lib/arel/session.rb delete mode 100644 lib/arel/sessions/session.rb delete mode 100644 spec/arel/unit/relations/compound_spec.rb diff --git a/lib/arel.rb b/lib/arel.rb index 75489c9c6e..b4fae65f73 100644 --- a/lib/arel.rb +++ b/lib/arel.rb @@ -8,5 +8,6 @@ require 'arel/extensions' require 'arel/sql' require 'arel/predicates' require 'arel/relations' -require 'arel/engines' +require 'arel/engine' +require 'arel/session' require 'arel/primitives' \ No newline at end of file diff --git a/lib/arel/engine.rb b/lib/arel/engine.rb new file mode 100644 index 0000000000..b0b7b4e955 --- /dev/null +++ b/lib/arel/engine.rb @@ -0,0 +1,18 @@ +module Arel + # this file is currently just a hack to adapt between activerecord::base which holds the connection specification + # and active relation. ultimately, this file should be in effect what the connection specification is in active record; + # that is: a spec of the database (url, password, etc.), a quoting adapter layer, and a connection pool. + class Engine + def initialize(ar = nil) + @ar = ar + end + + def connection + @ar.connection + end + + def method_missing(method, *args, &block) + @ar.connection.send(method, *args, &block) + end + end +end \ No newline at end of file diff --git a/lib/arel/engines.rb b/lib/arel/engines.rb deleted file mode 100644 index bb71537e9c..0000000000 --- a/lib/arel/engines.rb +++ /dev/null @@ -1 +0,0 @@ -require 'arel/engines/engine' \ No newline at end of file diff --git a/lib/arel/engines/engine.rb b/lib/arel/engines/engine.rb deleted file mode 100644 index b0b7b4e955..0000000000 --- a/lib/arel/engines/engine.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Arel - # this file is currently just a hack to adapt between activerecord::base which holds the connection specification - # and active relation. ultimately, this file should be in effect what the connection specification is in active record; - # that is: a spec of the database (url, password, etc.), a quoting adapter layer, and a connection pool. - class Engine - def initialize(ar = nil) - @ar = ar - end - - def connection - @ar.connection - end - - def method_missing(method, *args, &block) - @ar.connection.send(method, *args, &block) - end - end -end \ No newline at end of file diff --git a/lib/arel/relations.rb b/lib/arel/relations.rb index 364235fb49..3394fac7cb 100644 --- a/lib/arel/relations.rb +++ b/lib/arel/relations.rb @@ -1,19 +1,8 @@ -require 'arel/relations/recursion' require 'arel/relations/relation' -require 'arel/relations/nil' -require 'arel/relations/compound' -require 'arel/relations/writing' + +require 'arel/relations/utilities' + require 'arel/relations/table' -require 'arel/relations/aggregation' -require 'arel/relations/join' -require 'arel/relations/group' -require 'arel/relations/project' -require 'arel/relations/where' -require 'arel/relations/order' -require 'arel/relations/take' -require 'arel/relations/skip' -require 'arel/relations/delete' -require 'arel/relations/insert' -require 'arel/relations/update' -require 'arel/relations/alias' -require 'arel/sessions/session' \ No newline at end of file + +require 'arel/relations/writes' +require 'arel/relations/operations' \ No newline at end of file diff --git a/lib/arel/relations/aggregation.rb b/lib/arel/relations/aggregation.rb deleted file mode 100644 index 66150bff0a..0000000000 --- a/lib/arel/relations/aggregation.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Arel - class Aggregation < Compound - include Recursion::BaseCase - - def initialize(relation) - @relation = relation - end - - def wheres - [] - end - - def table_sql(formatter = Sql::TableReference.new(relation)) - formatter.select relation.select_sql, self - end - - def attributes - @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } - end - - def name - relation.name + '_aggregation' - end - - def ==(other) - Aggregation === other and - self.relation == other.relation - end - end - - class Relation - def externalize - @externalized ||= aggregation?? Aggregation.new(self) : self - end - - def aggregation? - false - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/alias.rb b/lib/arel/relations/alias.rb deleted file mode 100644 index d14a51f67a..0000000000 --- a/lib/arel/relations/alias.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Alias < Compound - include Recursion::BaseCase - alias_method :==, :equal? - - def initialize(relation) - @relation = relation - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/compound.rb b/lib/arel/relations/compound.rb deleted file mode 100644 index a77099e0de..0000000000 --- a/lib/arel/relations/compound.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Arel - class Compound < Relation - attr_reader :relation - hash_on :relation - delegate :joins, :wheres, :join?, :inserts, :taken, - :skipped, :name, :aggregation?, :column_for, - :engine, :table, :table_sql, - :to => :relation - - def attributes - @attributes ||= relation.attributes.collect { |a| a.bind(self) } - end - - def wheres - @wheres ||= relation.wheres.collect { |w| w.bind(self) } - end - - def groupings - @groupings ||= relation.groupings.collect { |g| g.bind(self) } - end - - def orders - @orders ||= relation.orders.collect { |o| o.bind(self) } - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/delete.rb b/lib/arel/relations/delete.rb deleted file mode 100644 index 7edc328e4a..0000000000 --- a/lib/arel/relations/delete.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Arel - class Deletion < Writing - def initialize(relation) - @relation = relation - end - - def to_sql(formatter = nil) - [ - "DELETE", - "FROM #{table_sql}", - ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), - ("LIMIT #{taken}" unless taken.blank? ), - ].compact.join("\n") - end - - def call(connection = engine.connection) - connection.delete(to_sql) - end - - def ==(other) - Deletion === other and - relation == other.relation - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/group.rb b/lib/arel/relations/group.rb deleted file mode 100644 index bc3a7f3437..0000000000 --- a/lib/arel/relations/group.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Group < Compound - attr_reader :groupings - - def initialize(relation, *groupings) - @relation, @groupings = relation, groupings.collect { |g| g.bind(relation) } - end - - def ==(other) - Group === other and - relation == other.relation and - groupings == other.groupings - end - - def aggregation? - true - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/insert.rb b/lib/arel/relations/insert.rb deleted file mode 100644 index b190ccb211..0000000000 --- a/lib/arel/relations/insert.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Arel - class Insert < Writing - attr_reader :record - - def initialize(relation, record) - @relation, @record = relation, record.bind(relation) - end - - def to_sql(formatter = nil) - [ - "INSERT", - "INTO #{table_sql}", - "(#{record.keys.collect(&:to_sql).join(', ')})", - "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" - ].join("\n") - end - - def call(connection = engine.connection) - connection.insert(to_sql) - end - - def ==(other) - Insert === other and - relation == other.relation and - record == other.record - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/join.rb b/lib/arel/relations/join.rb deleted file mode 100644 index acad75c817..0000000000 --- a/lib/arel/relations/join.rb +++ /dev/null @@ -1,62 +0,0 @@ -module Arel - class Join < Relation - attr_reader :join_sql, :relation1, :relation2, :predicates - delegate :engine, :name, :to => :relation1 - hash_on :relation1 - - def initialize(join_sql, relation1, relation2 = Nil.new, *predicates) - @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates - end - - def table_sql(formatter = Sql::TableReference.new(self)) - relation1.externalize.table_sql(formatter) - end - - def joins(environment, formatter = Sql::TableReference.new(environment)) - @joins ||= begin - this_join = [ - join_sql, - relation2.externalize.table_sql(formatter), - ("ON" unless predicates.blank?), - (ons + relation2.externalize.wheres).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ') - ].compact.join(" ") - [relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ") - end - end - - def attributes - @attributes ||= (relation1.externalize.attributes + - relation2.externalize.attributes).collect { |a| a.bind(self) } - end - - def wheres - relation1.externalize.wheres - end - - def ons - @ons ||= @predicates.collect { |p| p.bind(self) } - end - - # TESTME - def aggregation? - relation1.aggregation? or relation2.aggregation? - end - - def join? - true - end - - def ==(other) - Join === other and - predicates == other.predicates and - relation1 == other.relation1 and - relation2 == other.relation2 - end - end - - class Relation - def join? - false - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/nil.rb b/lib/arel/relations/nil.rb deleted file mode 100644 index 2dcfb47233..0000000000 --- a/lib/arel/relations/nil.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Nil < Relation - def table_sql(formatter = nil); '' end - def name; '' end - - def ==(other) - Nil === other - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/operations.rb b/lib/arel/relations/operations.rb new file mode 100644 index 0000000000..c598c7fcc9 --- /dev/null +++ b/lib/arel/relations/operations.rb @@ -0,0 +1,8 @@ +require 'arel/relations/operations/alias' +require 'arel/relations/operations/group' +require 'arel/relations/operations/join' +require 'arel/relations/operations/order' +require 'arel/relations/operations/project' +require 'arel/relations/operations/where' +require 'arel/relations/operations/skip' +require 'arel/relations/operations/take' \ No newline at end of file diff --git a/lib/arel/relations/operations/alias.rb b/lib/arel/relations/operations/alias.rb new file mode 100644 index 0000000000..d14a51f67a --- /dev/null +++ b/lib/arel/relations/operations/alias.rb @@ -0,0 +1,10 @@ +module Arel + class Alias < Compound + include Recursion::BaseCase + alias_method :==, :equal? + + def initialize(relation) + @relation = relation + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/group.rb b/lib/arel/relations/operations/group.rb new file mode 100644 index 0000000000..bc3a7f3437 --- /dev/null +++ b/lib/arel/relations/operations/group.rb @@ -0,0 +1,19 @@ +module Arel + class Group < Compound + attr_reader :groupings + + def initialize(relation, *groupings) + @relation, @groupings = relation, groupings.collect { |g| g.bind(relation) } + end + + def ==(other) + Group === other and + relation == other.relation and + groupings == other.groupings + end + + def aggregation? + true + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/join.rb b/lib/arel/relations/operations/join.rb new file mode 100644 index 0000000000..acad75c817 --- /dev/null +++ b/lib/arel/relations/operations/join.rb @@ -0,0 +1,62 @@ +module Arel + class Join < Relation + attr_reader :join_sql, :relation1, :relation2, :predicates + delegate :engine, :name, :to => :relation1 + hash_on :relation1 + + def initialize(join_sql, relation1, relation2 = Nil.new, *predicates) + @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates + end + + def table_sql(formatter = Sql::TableReference.new(self)) + relation1.externalize.table_sql(formatter) + end + + def joins(environment, formatter = Sql::TableReference.new(environment)) + @joins ||= begin + this_join = [ + join_sql, + relation2.externalize.table_sql(formatter), + ("ON" unless predicates.blank?), + (ons + relation2.externalize.wheres).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ') + ].compact.join(" ") + [relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ") + end + end + + def attributes + @attributes ||= (relation1.externalize.attributes + + relation2.externalize.attributes).collect { |a| a.bind(self) } + end + + def wheres + relation1.externalize.wheres + end + + def ons + @ons ||= @predicates.collect { |p| p.bind(self) } + end + + # TESTME + def aggregation? + relation1.aggregation? or relation2.aggregation? + end + + def join? + true + end + + def ==(other) + Join === other and + predicates == other.predicates and + relation1 == other.relation1 and + relation2 == other.relation2 + end + end + + class Relation + def join? + false + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/order.rb b/lib/arel/relations/operations/order.rb new file mode 100644 index 0000000000..ebb4dc0668 --- /dev/null +++ b/lib/arel/relations/operations/order.rb @@ -0,0 +1,19 @@ +module Arel + class Order < Compound + attr_reader :orderings + + def initialize(relation, *orderings) + @relation, @orderings = relation, orderings.collect { |o| o.bind(relation) } + end + + def orders + orderings + relation.orders + end + + def ==(other) + Order === other and + relation == other.relation and + orderings == other.orderings + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/project.rb b/lib/arel/relations/operations/project.rb new file mode 100644 index 0000000000..0efc13bdb3 --- /dev/null +++ b/lib/arel/relations/operations/project.rb @@ -0,0 +1,23 @@ +module Arel + class Project < Compound + attr_reader :projections + + def initialize(relation, *projections) + @relation, @projections = relation, projections + end + + def attributes + @attributes ||= projections.collect { |p| p.bind(self) } + end + + def aggregation? + attributes.any?(&:aggregation?) + end + + def ==(other) + Project === other and + relation == other.relation and + projections == other.projections + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/skip.rb b/lib/arel/relations/operations/skip.rb new file mode 100644 index 0000000000..01ac4c7204 --- /dev/null +++ b/lib/arel/relations/operations/skip.rb @@ -0,0 +1,15 @@ +module Arel + class Skip < Compound + attr_reader :skipped + + def initialize(relation, skipped) + @relation, @skipped = relation, skipped + end + + def ==(other) + Skip === other and + relation == other.relation and + skipped == other.skipped + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/take.rb b/lib/arel/relations/operations/take.rb new file mode 100644 index 0000000000..0a49891aee --- /dev/null +++ b/lib/arel/relations/operations/take.rb @@ -0,0 +1,15 @@ +module Arel + class Take < Compound + attr_reader :taken + + def initialize(relation, taken) + @relation, @taken = relation, taken + end + + def ==(other) + Take === other and + relation == other.relation and + taken == other.taken + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/operations/where.rb b/lib/arel/relations/operations/where.rb new file mode 100644 index 0000000000..ba34846c04 --- /dev/null +++ b/lib/arel/relations/operations/where.rb @@ -0,0 +1,21 @@ +module Arel + class Where < Compound + attr_reader :predicate + + def initialize(relation, *predicates) + predicate = predicates.shift + @relation = predicates.empty?? relation : Where.new(relation, *predicates) + @predicate = predicate.bind(@relation) + end + + def wheres + @wheres ||= (relation.wheres + [predicate]).collect { |p| p.bind(self) } + end + + def ==(other) + Where === other and + relation == other.relation and + predicate == other.predicate + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/order.rb b/lib/arel/relations/order.rb deleted file mode 100644 index ebb4dc0668..0000000000 --- a/lib/arel/relations/order.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Order < Compound - attr_reader :orderings - - def initialize(relation, *orderings) - @relation, @orderings = relation, orderings.collect { |o| o.bind(relation) } - end - - def orders - orderings + relation.orders - end - - def ==(other) - Order === other and - relation == other.relation and - orderings == other.orderings - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/project.rb b/lib/arel/relations/project.rb deleted file mode 100644 index 0efc13bdb3..0000000000 --- a/lib/arel/relations/project.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Arel - class Project < Compound - attr_reader :projections - - def initialize(relation, *projections) - @relation, @projections = relation, projections - end - - def attributes - @attributes ||= projections.collect { |p| p.bind(self) } - end - - def aggregation? - attributes.any?(&:aggregation?) - end - - def ==(other) - Project === other and - relation == other.relation and - projections == other.projections - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/recursion.rb b/lib/arel/relations/recursion.rb deleted file mode 100644 index 848b059507..0000000000 --- a/lib/arel/relations/recursion.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Arel - module Recursion - module BaseCase - def table - self - end - - def table_sql(formatter = Sql::TableReference.new(self)) - formatter.table self - end - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/skip.rb b/lib/arel/relations/skip.rb deleted file mode 100644 index 01ac4c7204..0000000000 --- a/lib/arel/relations/skip.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Arel - class Skip < Compound - attr_reader :skipped - - def initialize(relation, skipped) - @relation, @skipped = relation, skipped - end - - def ==(other) - Skip === other and - relation == other.relation and - skipped == other.skipped - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/take.rb b/lib/arel/relations/take.rb deleted file mode 100644 index 0a49891aee..0000000000 --- a/lib/arel/relations/take.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Arel - class Take < Compound - attr_reader :taken - - def initialize(relation, taken) - @relation, @taken = relation, taken - end - - def ==(other) - Take === other and - relation == other.relation and - taken == other.taken - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/update.rb b/lib/arel/relations/update.rb deleted file mode 100644 index 450f06af96..0000000000 --- a/lib/arel/relations/update.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Arel - class Update < Writing - attr_reader :assignments - - def initialize(relation, assignments) - @relation, @assignments = relation, assignments.bind(relation) - end - - def to_sql(formatter = nil) - [ - "UPDATE #{table_sql} SET", - assignments.collect do |attribute, value| - "#{value.format(attribute)} = #{attribute.format(value)}" - end.join(",\n"), - ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), - ("LIMIT #{taken}" unless taken.blank? ) - ].join("\n") - end - - def call(connection = engine.connection) - connection.update(to_sql) - end - - def ==(other) - Update === other and - relation == other.relation and - assignments == other.assignments - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/utilities.rb b/lib/arel/relations/utilities.rb new file mode 100644 index 0000000000..02c2e0a952 --- /dev/null +++ b/lib/arel/relations/utilities.rb @@ -0,0 +1,5 @@ +require 'arel/relations/utilities/compound' +require 'arel/relations/utilities/recursion' +require 'arel/relations/utilities/nil' +require 'arel/relations/utilities/aggregation' +require 'arel/relations/utilities/recursion' \ No newline at end of file diff --git a/lib/arel/relations/utilities/aggregation.rb b/lib/arel/relations/utilities/aggregation.rb new file mode 100644 index 0000000000..66150bff0a --- /dev/null +++ b/lib/arel/relations/utilities/aggregation.rb @@ -0,0 +1,40 @@ +module Arel + class Aggregation < Compound + include Recursion::BaseCase + + def initialize(relation) + @relation = relation + end + + def wheres + [] + end + + def table_sql(formatter = Sql::TableReference.new(relation)) + formatter.select relation.select_sql, self + end + + def attributes + @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } + end + + def name + relation.name + '_aggregation' + end + + def ==(other) + Aggregation === other and + self.relation == other.relation + end + end + + class Relation + def externalize + @externalized ||= aggregation?? Aggregation.new(self) : self + end + + def aggregation? + false + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/utilities/compound.rb b/lib/arel/relations/utilities/compound.rb new file mode 100644 index 0000000000..a77099e0de --- /dev/null +++ b/lib/arel/relations/utilities/compound.rb @@ -0,0 +1,26 @@ +module Arel + class Compound < Relation + attr_reader :relation + hash_on :relation + delegate :joins, :wheres, :join?, :inserts, :taken, + :skipped, :name, :aggregation?, :column_for, + :engine, :table, :table_sql, + :to => :relation + + def attributes + @attributes ||= relation.attributes.collect { |a| a.bind(self) } + end + + def wheres + @wheres ||= relation.wheres.collect { |w| w.bind(self) } + end + + def groupings + @groupings ||= relation.groupings.collect { |g| g.bind(self) } + end + + def orders + @orders ||= relation.orders.collect { |o| o.bind(self) } + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/utilities/nil.rb b/lib/arel/relations/utilities/nil.rb new file mode 100644 index 0000000000..2dcfb47233 --- /dev/null +++ b/lib/arel/relations/utilities/nil.rb @@ -0,0 +1,10 @@ +module Arel + class Nil < Relation + def table_sql(formatter = nil); '' end + def name; '' end + + def ==(other) + Nil === other + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/utilities/recursion.rb b/lib/arel/relations/utilities/recursion.rb new file mode 100644 index 0000000000..848b059507 --- /dev/null +++ b/lib/arel/relations/utilities/recursion.rb @@ -0,0 +1,13 @@ +module Arel + module Recursion + module BaseCase + def table + self + end + + def table_sql(formatter = Sql::TableReference.new(self)) + formatter.table self + end + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/where.rb b/lib/arel/relations/where.rb deleted file mode 100644 index ba34846c04..0000000000 --- a/lib/arel/relations/where.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Arel - class Where < Compound - attr_reader :predicate - - def initialize(relation, *predicates) - predicate = predicates.shift - @relation = predicates.empty?? relation : Where.new(relation, *predicates) - @predicate = predicate.bind(@relation) - end - - def wheres - @wheres ||= (relation.wheres + [predicate]).collect { |p| p.bind(self) } - end - - def ==(other) - Where === other and - relation == other.relation and - predicate == other.predicate - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/writes.rb b/lib/arel/relations/writes.rb new file mode 100644 index 0000000000..1495d9c857 --- /dev/null +++ b/lib/arel/relations/writes.rb @@ -0,0 +1,3 @@ +require 'arel/relations/writes/delete' +require 'arel/relations/writes/update' +require 'arel/relations/writes/insert' \ No newline at end of file diff --git a/lib/arel/relations/writes/delete.rb b/lib/arel/relations/writes/delete.rb new file mode 100644 index 0000000000..2eaad6d1da --- /dev/null +++ b/lib/arel/relations/writes/delete.rb @@ -0,0 +1,25 @@ +module Arel + class Deletion < Compound + def initialize(relation) + @relation = relation + end + + def to_sql(formatter = nil) + [ + "DELETE", + "FROM #{table_sql}", + ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), + ("LIMIT #{taken}" unless taken.blank? ), + ].compact.join("\n") + end + + def call(connection = engine.connection) + connection.delete(to_sql) + end + + def ==(other) + Deletion === other and + relation == other.relation + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/writes/insert.rb b/lib/arel/relations/writes/insert.rb new file mode 100644 index 0000000000..a1c4c93de5 --- /dev/null +++ b/lib/arel/relations/writes/insert.rb @@ -0,0 +1,28 @@ +module Arel + class Insert < Compound + attr_reader :record + + def initialize(relation, record) + @relation, @record = relation, record.bind(relation) + end + + def to_sql(formatter = nil) + [ + "INSERT", + "INTO #{table_sql}", + "(#{record.keys.collect(&:to_sql).join(', ')})", + "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" + ].join("\n") + end + + def call(connection = engine.connection) + connection.insert(to_sql) + end + + def ==(other) + Insert === other and + relation == other.relation and + record == other.record + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/writes/update.rb b/lib/arel/relations/writes/update.rb new file mode 100644 index 0000000000..760f4e931f --- /dev/null +++ b/lib/arel/relations/writes/update.rb @@ -0,0 +1,30 @@ +module Arel + class Update < Compound + attr_reader :assignments + + def initialize(relation, assignments) + @relation, @assignments = relation, assignments.bind(relation) + end + + def to_sql(formatter = nil) + [ + "UPDATE #{table_sql} SET", + assignments.collect do |attribute, value| + "#{value.format(attribute)} = #{attribute.format(value)}" + end.join(",\n"), + ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), + ("LIMIT #{taken}" unless taken.blank? ) + ].join("\n") + end + + def call(connection = engine.connection) + connection.update(to_sql) + end + + def ==(other) + Update === other and + relation == other.relation and + assignments == other.assignments + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/writing.rb b/lib/arel/relations/writing.rb deleted file mode 100644 index b871e5a520..0000000000 --- a/lib/arel/relations/writing.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Arel - class Writing < Compound - end -end \ No newline at end of file diff --git a/lib/arel/session.rb b/lib/arel/session.rb new file mode 100644 index 0000000000..8b72fd1fe6 --- /dev/null +++ b/lib/arel/session.rb @@ -0,0 +1,47 @@ +require 'singleton' + +module Arel + class Session + class << self + attr_accessor :instance + alias_method :manufacture, :new + + def start + if @started + yield + else + begin + @started = true + @instance = manufacture + metaclass.send :alias_method, :new, :instance + yield + ensure + metaclass.send :alias_method, :new, :manufacture + @started = false + end + end + end + end + + module CRUD + def create(insert) + insert.call(insert.engine.connection) + end + + def read(select) + (@read ||= Hash.new do |hash, select| + hash[select] = select.call(select.engine.connection) + end)[select] + end + + def update(update) + update.call(update.engine.connection) + end + + def delete(delete) + delete.call(delete.engine.connection) + end + end + include CRUD + end +end \ No newline at end of file diff --git a/lib/arel/sessions/session.rb b/lib/arel/sessions/session.rb deleted file mode 100644 index 8b72fd1fe6..0000000000 --- a/lib/arel/sessions/session.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'singleton' - -module Arel - class Session - class << self - attr_accessor :instance - alias_method :manufacture, :new - - def start - if @started - yield - else - begin - @started = true - @instance = manufacture - metaclass.send :alias_method, :new, :instance - yield - ensure - metaclass.send :alias_method, :new, :manufacture - @started = false - end - end - end - end - - module CRUD - def create(insert) - insert.call(insert.engine.connection) - end - - def read(select) - (@read ||= Hash.new do |hash, select| - hash[select] = select.call(select.engine.connection) - end)[select] - end - - def update(update) - update.call(update.engine.connection) - end - - def delete(delete) - delete.call(delete.engine.connection) - end - end - include CRUD - end -end \ No newline at end of file diff --git a/spec/arel/unit/relations/compound_spec.rb b/spec/arel/unit/relations/compound_spec.rb deleted file mode 100644 index 763e447db3..0000000000 --- a/spec/arel/unit/relations/compound_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper') - -module Arel - describe Compound do - before do - class ConcreteCompound < Compound - def initialize(relation) - @relation = relation - end - - def ==(other) - true - end - end - @relation = Table.new(:users) - @compound_relation = ConcreteCompound.new(@relation) - end - - describe '#attributes' do - it 'manufactures attributes associated with the compound relation' do - @compound_relation.attributes.should == @relation.attributes.collect { |a| a.bind(@compound_relation) } - end - end - - describe 'hashing' do - it 'implements hash equality' do - ConcreteCompound.new(@relation).should hash_the_same_as(ConcreteCompound.new(@relation)) - end - end - end -end \ No newline at end of file -- cgit v1.2.3